This is an automated email from the ASF dual-hosted git repository.

jakevin pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git

commit 1e4fa20d55bb3c7b44df7231df78fe594b59f3b3
Author: jackwener <jakevin...@gmail.com>
AuthorDate: Tue Mar 19 17:36:50 2024 +0800

    [fix](Nereids): slot set in condition can be empty (#32169)
    
    (cherry picked from commit ca092139a007dca99006d8247d9926947b1490d3)
---
 .../rules/rewrite/PullUpProjectUnderLimit.java     |  6 ++--
 .../rules/rewrite/PullUpProjectUnderTopN.java      | 38 +++++++++++++++++-----
 .../apache/doris/nereids/trees/plans/JoinType.java |  4 +++
 3 files changed, 37 insertions(+), 11 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PullUpProjectUnderLimit.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PullUpProjectUnderLimit.java
index a1a4ac4d219..cc2e6388a60 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PullUpProjectUnderLimit.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PullUpProjectUnderLimit.java
@@ -21,6 +21,7 @@ import org.apache.doris.nereids.rules.Rule;
 import org.apache.doris.nereids.rules.RuleType;
 import org.apache.doris.nereids.trees.expressions.Slot;
 import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
 import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
 import org.apache.doris.nereids.util.PlanUtils;
 
@@ -36,9 +37,10 @@ import java.util.stream.Collectors;
 public class PullUpProjectUnderLimit extends OneRewriteRuleFactory {
     @Override
     public Rule build() {
-        return logicalLimit(logicalProject().whenNot(p -> p.isAllSlots()))
+        return logicalLimit(logicalProject(logicalJoin().when(j -> 
j.getJoinType().isLeftRightOuterOrCrossJoin()))
+                .whenNot(p -> p.isAllSlots()))
                 .then(limit -> {
-                    LogicalProject<Plan> project = limit.child();
+                    LogicalProject<LogicalJoin<Plan, Plan>> project = 
limit.child();
                     Set<Slot> allUsedSlots = 
project.getProjects().stream().flatMap(ne -> ne.getInputSlots().stream())
                             .collect(Collectors.toSet());
                     Set<Slot> outputSet = project.child().getOutputSet();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PullUpProjectUnderTopN.java
 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PullUpProjectUnderTopN.java
index b02edd9033b..469444006d1 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PullUpProjectUnderTopN.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PullUpProjectUnderTopN.java
@@ -20,41 +20,61 @@ package org.apache.doris.nereids.rules.rewrite;
 import org.apache.doris.nereids.properties.OrderKey;
 import org.apache.doris.nereids.rules.Rule;
 import org.apache.doris.nereids.rules.RuleType;
+import org.apache.doris.nereids.trees.expressions.Expression;
 import org.apache.doris.nereids.trees.expressions.Slot;
 import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
 import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
+import org.apache.doris.nereids.trees.plans.logical.LogicalTopN;
+import org.apache.doris.nereids.util.ExpressionUtils;
 import org.apache.doris.nereids.util.PlanUtils;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
- * Pull up Project under TopN.
+ * Pull up Project under TopN for PushDownTopNThroughJoin
  */
 public class PullUpProjectUnderTopN extends OneRewriteRuleFactory {
     @Override
     public Rule build() {
-        return logicalTopN(logicalProject().whenNot(p -> p.isAllSlots()))
-                .whenNot(topN -> 
topN.child().hasPushedDownToProjectionFunctions())
+        return logicalTopN(
+                logicalProject(logicalJoin().when(j -> 
j.getJoinType().isLeftRightOuterOrCrossJoin()))
+                        .whenNot(p -> p.isAllSlots()))
                 .then(topN -> {
-                    LogicalProject<Plan> project = topN.child();
+                    LogicalProject<LogicalJoin<Plan, Plan>> project = 
topN.child();
                     Set<Slot> outputSet = project.child().getOutputSet();
-                    if 
(!topN.getOrderKeys().stream().map(OrderKey::getExpr).flatMap(e -> 
e.getInputSlots().stream())
-                            .allMatch(outputSet::contains)) {
-                        return null;
+
+                    Map<Slot, Expression> slotMap = 
ExpressionUtils.generateReplaceMap(project.getProjects());
+                    List<OrderKey> newOrderKeys = new ArrayList<>();
+                    for (OrderKey orderKey : topN.getOrderKeys()) {
+                        if (!(orderKey.getExpr() instanceof Slot)) {
+                            return null;
+                        }
+                        Expression expression = slotMap.get((Slot) 
orderKey.getExpr());
+                        if (expression instanceof Slot) {
+                            
newOrderKeys.add(orderKey.withExpression(expression));
+                        } else {
+                            return null;
+                        }
                     }
+
                     Set<Slot> allUsedSlots = 
project.getProjects().stream().flatMap(ne -> ne.getInputSlots().stream())
                             .collect(Collectors.toSet());
+                    LogicalTopN<Plan> newTopN = 
topN.withOrderKeys(newOrderKeys);
                     if (outputSet.size() == allUsedSlots.size()) {
                         
Preconditions.checkState(outputSet.equals(allUsedSlots));
-                        return 
project.withChildren(topN.withChildren(project.child()));
+                        return 
project.withChildren(newTopN.withChildren(project.child()));
                     } else {
                         Plan columnProject = 
PlanUtils.projectOrSelf(ImmutableList.copyOf(allUsedSlots),
                                 project.child());
-                        return 
project.withChildren(topN.withChildren(columnProject));
+                        return 
project.withChildren(newTopN.withChildren(columnProject));
                     }
                 }).toRule(RuleType.PULL_UP_PROJECT_UNDER_TOPN);
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/JoinType.java 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/JoinType.java
index bb5e1aed245..3423b13168b 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/JoinType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/JoinType.java
@@ -152,6 +152,10 @@ public enum JoinType {
         return this == RIGHT_OUTER_JOIN;
     }
 
+    public final boolean isLeftRightOuterOrCrossJoin() {
+        return this == LEFT_OUTER_JOIN || this == RIGHT_OUTER_JOIN || this == 
CROSS_JOIN;
+    }
+
     public final boolean isLeftSemiOrAntiJoin() {
         return this == LEFT_SEMI_JOIN || this == LEFT_ANTI_JOIN || this == 
NULL_AWARE_LEFT_ANTI_JOIN;
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to