[fix](nereids)when clause cannot be regarded as common sub expression (#33358)

* when clause cannot be regarded as common sub expression
This commit is contained in:
minghong
2024-04-10 10:24:39 +08:00
committed by yiguolei
parent 31984bb4f0
commit 215f402df7
3 changed files with 26 additions and 5 deletions

View File

@ -22,6 +22,7 @@ import org.apache.doris.nereids.trees.expressions.Alias;
import org.apache.doris.nereids.trees.expressions.Expression;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.WhenClause;
import org.apache.doris.nereids.trees.expressions.visitor.DefaultExpressionRewriter;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.physical.PhysicalProject;
@ -82,9 +83,16 @@ public class CommonSubExpressionOpt extends PlanPostProcessor {
Set<Expression> exprsInDepth = CommonSubExpressionCollector
.getExpressionsFromDepthMap(i, collector.commonExprByDepth);
exprsInDepth.forEach(expr -> {
Expression rewritten = expr.accept(ExpressionReplacer.INSTANCE, aliasMap);
Alias alias = new Alias(rewritten);
aliasMap.put(expr, alias);
if (!(expr instanceof WhenClause)) {
// case whenClause1 whenClause2 END
// whenClause should not be regarded as common-sub-expression, because
// cse will be replaced by a slot, after rewrite the case clause becomes:
// 'case slot whenClause2 END'
// This is illegal.
Expression rewritten = expr.accept(ExpressionReplacer.INSTANCE, aliasMap);
Alias alias = new Alias(rewritten);
aliasMap.put(expr, alias);
}
});
layer.addAll(aliasMap.values());
multiLayers.add(layer);

View File

@ -27,4 +27,12 @@
12093 13093 14093 15093
-- !cse_4 --
12093 13093 14093 15093
12093 13093 14093 15093
-- !cse_5 --
1 2
2 3
2 5
5 6
6 7

View File

@ -45,5 +45,10 @@ suite('cse') {
qt_cse_4 """select sum(s_nationkey),sum(s_nationkey) + count(1) ,sum(s_nationkey) + 2 * count(1) , sum(s_nationkey) + 3 * count(1) from supplier ;"""
// when clause cannot be regarded as common-sub-expression.
// if "when r_regionkey=1 then 0" is regarded as a common-sub-expression, but if it will be replaced by a slot, and hence the case clause
// become syntax illegal: case cseSlot when r_regionkey=2 the 1 else ....
qt_cse_5 """select (case r_regionkey when 1 then 0 when 2 then 1 else r_regionkey+1 END) + 1 As x,
(case r_regionkey when 1 then 0 when 2 then 3 else r_regionkey+1 END) + 2 as y
from region order by x, y;"""
}