[fix](nereids) fix merge project with window function bug (#19280)

1. don't merge projects if any window function exists
2. bypass SimplifyArithmeticRule for decimalV3 type
This commit is contained in:
starocean999
2023-05-06 10:38:14 +08:00
committed by GitHub
parent 3ddedb676c
commit a72eee24f1
4 changed files with 89 additions and 2 deletions

View File

@ -81,6 +81,10 @@ public class SimplifyArithmeticRule extends AbstractExpressionRewriteRule {
List<Operand> variables = Lists.newArrayList();
List<Operand> constants = Lists.newArrayList();
// TODO currently we don't process decimalV3 for simplicity.
if (flattedExpressions.stream().anyMatch(operand -> operand.expression.getDataType().isDecimalV3Type())) {
return arithmetic;
}
// 2. move variables to left side and move constants to right sid.
flattedExpressions.forEach(operand -> {
if (operand.expression.isConstant()) {

View File

@ -21,6 +21,7 @@ import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleType;
import org.apache.doris.nereids.rules.rewrite.OneRewriteRuleFactory;
import org.apache.doris.nereids.trees.expressions.NamedExpression;
import org.apache.doris.nereids.trees.expressions.WindowExpression;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
@ -40,9 +41,12 @@ public class MergeProjects extends OneRewriteRuleFactory {
@Override
public Rule build() {
// TODO modify ExtractAndNormalizeWindowExpression to handle nested window functions
// here we just don't merge two projects if there is any window function
return logicalProject(logicalProject())
.then(project -> mergeProjects(project))
.toRule(RuleType.MERGE_PROJECTS);
.whenNot(project -> containsWindowExpression(project.getProjects())
&& containsWindowExpression(project.child().getProjects()))
.then(project -> mergeProjects(project)).toRule(RuleType.MERGE_PROJECTS);
}
public static Plan mergeProjects(LogicalProject project) {
@ -51,4 +55,8 @@ public class MergeProjects extends OneRewriteRuleFactory {
LogicalProject newProject = childProject.canEliminate() ? project : childProject;
return newProject.withProjectsAndChild(projectExpressions, childProject.child(0));
}
private boolean containsWindowExpression(List<NamedExpression> expressions) {
return expressions.stream().anyMatch(expr -> expr.anyMatch(WindowExpression.class::isInstance));
}
}