cherry-pick from master 38493 1. fold child when const expr not folded 2. do not fold function `sleep` 3. move all exceptional expression into shouldSkipFold before mysql [test]>explain select sleep(sign(1)*100); +-----------------------------------------------+ | Explain String(Nereids Planner) | +-----------------------------------------------+ | PLAN FRAGMENT 0 | | OUTPUT EXPRS: | | sleep(cast((sign(1.0) * 100) as INT))[#0] | | PARTITION: UNPARTITIONED | | | | HAS_COLO_PLAN_NODE: false | | | | VRESULT SINK | | MYSQL_PROTOCAL | | | | 0:VUNION(32) | | constant exprs: | | sleep(CAST((sign(1) * 100) AS int)) | +-----------------------------------------------+ 13 rows in set (15.02 sec) mysql [test]>select sleep(sign(1)*100); +-----------------------------------------------------+ | sleep(cast((sign(cast(1 as DOUBLE)) * 100) as INT)) | +-----------------------------------------------------+ | 1 | +-----------------------------------------------------+ 1 row in set (1 min 55.34 sec) after mysql [test]>explain select sleep(sign(1)*100); +---------------------------------+ | Explain String(Nereids Planner) | +---------------------------------+ | PLAN FRAGMENT 0 | | OUTPUT EXPRS: | | sleep(100)[#0] | | PARTITION: UNPARTITIONED | | | | HAS_COLO_PLAN_NODE: false | | | | VRESULT SINK | | MYSQL_PROTOCAL | | | | 0:VUNION(32) | | constant exprs: | | sleep(100) | +---------------------------------+ 13 rows in set (0.23 sec) mysql [test]> select sleep(sign(1)*100); +-----------------------------------------------------+ | sleep(cast((sign(cast(1 as DOUBLE)) * 100) as INT)) | +-----------------------------------------------------+ | 1 | +-----------------------------------------------------+ 1 row in set (1 min 40.37 sec) Co-authored-by: Pxl <pxl290@qq.com>
This commit is contained in:
@ -37,7 +37,10 @@ import org.apache.doris.nereids.trees.expressions.ArrayItemReference;
|
||||
import org.apache.doris.nereids.trees.expressions.Cast;
|
||||
import org.apache.doris.nereids.trees.expressions.Expression;
|
||||
import org.apache.doris.nereids.trees.expressions.Match;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.BoundFunction;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.generator.TableGeneratingFunction;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.NonNullable;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.Nullable;
|
||||
import org.apache.doris.nereids.trees.expressions.functions.scalar.Sleep;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.ArrayLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
|
||||
@ -55,7 +58,6 @@ import org.apache.doris.nereids.trees.expressions.literal.LargeIntLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.Literal;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.MapLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.NumericLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.SmallIntLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
|
||||
import org.apache.doris.nereids.trees.expressions.literal.StructLiteral;
|
||||
@ -157,7 +159,11 @@ public class FoldConstantRuleOnBE implements ExpressionPatternRuleFactory {
|
||||
Expression root, Map<String, Expression> constMap, Map<String, Expression> resultMap) {
|
||||
for (Entry<String, Expression> entry : constMap.entrySet()) {
|
||||
if (entry.getValue().equals(root)) {
|
||||
return resultMap.get(entry.getKey());
|
||||
if (resultMap.containsKey(entry.getKey())) {
|
||||
return resultMap.get(entry.getKey());
|
||||
} else {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
}
|
||||
List<Expression> newChildren = new ArrayList<>();
|
||||
@ -174,38 +180,7 @@ public class FoldConstantRuleOnBE implements ExpressionPatternRuleFactory {
|
||||
|
||||
private static void collectConst(Expression expr, Map<String, Expression> constMap,
|
||||
Map<String, TExpr> tExprMap, IdGenerator<ExprId> idGenerator) {
|
||||
if (expr.isConstant()) {
|
||||
// Do not constant fold cast(null as dataType) because we cannot preserve the
|
||||
// cast-to-types and that can lead to query failures, e.g., CTAS
|
||||
if (expr instanceof Cast) {
|
||||
if (((Cast) expr).child().isNullLiteral()) {
|
||||
return;
|
||||
}
|
||||
if (skipSleepFunction(((Cast) expr).child())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// skip literal expr
|
||||
if (expr.isLiteral()) {
|
||||
return;
|
||||
}
|
||||
// eg: avg_state(1) return is agg function serialize data
|
||||
// and some type can't find a literal to represent.
|
||||
// time type: need add a time literal in nereids
|
||||
// IPv6 type: need get a library to output the compressed address format
|
||||
if (expr.getDataType().isAggStateType() || expr.getDataType().isObjectType()
|
||||
|| expr.getDataType().isVariantType() || expr.getDataType().isTimeLikeType()
|
||||
|| expr.getDataType().isIPv6Type()) {
|
||||
return;
|
||||
}
|
||||
// first need pass PlanTranslatorContext value,
|
||||
// and ArrayItemReference translate, can't findColumnRef
|
||||
// Match need give more info rather then as left child a NULL, in
|
||||
// match_phrase_prefix/MATCH_PHRASE/MATCH_PHRASE/MATCH_ANY
|
||||
if (skipSleepFunction(expr) || (expr instanceof TableGeneratingFunction)
|
||||
|| (expr instanceof ArrayItemReference) || (expr instanceof Match)) {
|
||||
return;
|
||||
}
|
||||
if (expr.isConstant() && !shouldSkipFold(expr)) {
|
||||
String id = idGenerator.getNextId().toString();
|
||||
constMap.put(id, expr);
|
||||
Expr staleExpr;
|
||||
@ -229,17 +204,58 @@ public class FoldConstantRuleOnBE implements ExpressionPatternRuleFactory {
|
||||
}
|
||||
}
|
||||
|
||||
// if sleep(5) will cause rpc timeout
|
||||
private static boolean skipSleepFunction(Expression expr) {
|
||||
if (expr instanceof Sleep) {
|
||||
Expression param = expr.child(0);
|
||||
if (param instanceof Cast) {
|
||||
param = param.child(0);
|
||||
}
|
||||
if (param instanceof NumericLiteral) {
|
||||
return ((NumericLiteral) param).getDouble() >= 5.0;
|
||||
}
|
||||
// Some expressions should not do constant folding
|
||||
private static boolean shouldSkipFold(Expression expr) {
|
||||
// Skip literal expr
|
||||
if (expr.isLiteral()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Frontend can not represent those types
|
||||
if (expr.getDataType().isAggStateType() || expr.getDataType().isObjectType()
|
||||
|| expr.getDataType().isVariantType() || expr.getDataType().isTimeLikeType()
|
||||
|| expr.getDataType().isIPv6Type()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Frontend can not represent geo types
|
||||
if (expr instanceof BoundFunction && ((BoundFunction) expr).getName().toLowerCase().startsWith("st_")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TableGeneratingFunction need pass PlanTranslatorContext value
|
||||
if (expr instanceof TableGeneratingFunction) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// ArrayItemReference translate can't findColumnRef
|
||||
if (expr instanceof ArrayItemReference) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Match need give more info rather then as left child a NULL, in
|
||||
// match_phrase_prefix/MATCH_PHRASE/MATCH_PHRASE/MATCH_ANY
|
||||
if (expr instanceof Match) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// sleep will cause rpc timeout
|
||||
if (expr instanceof Sleep) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Do not constant fold cast(null as dataType) because we cannot preserve the
|
||||
// cast-to-types and that can lead to query failures, e.g., CTAS
|
||||
if (expr instanceof Cast && ((Cast) expr).child().isNullLiteral()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// This kind of function is often used to change the attributes of columns.
|
||||
// Folding will make it impossible to construct columns such as nullable(1).
|
||||
if (expr instanceof Nullable || expr instanceof NonNullable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user