morrySnow commented on code in PR #66806:
URL: https://github.com/apache/doris/pull/66806#discussion_r3869316107


##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/EliminateJoinCondition.java:
##########
@@ -19,36 +19,88 @@
 
 import org.apache.doris.nereids.rules.Rule;
 import org.apache.doris.nereids.rules.RuleType;
+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.StatementScopeIdGenerator;
 import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
+import org.apache.doris.nereids.trees.plans.Plan;
+import org.apache.doris.nereids.trees.plans.logical.LogicalEmptyRelation;
+import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
+import org.apache.doris.nereids.trees.plans.logical.LogicalProject;
+
+import com.google.common.collect.ImmutableList;
 
 import java.util.List;
+import java.util.Set;
 import java.util.stream.Collectors;
 
 /**
- * Eliminate true Condition in Join Condition.
+ * Eliminate constant conditions in Join Condition.
  */
 public class EliminateJoinCondition extends OneRewriteRuleFactory {
 
     @Override
     public Rule build() {
-        return logicalJoin().then(join -> {
-            List<Expression> hashJoinConjuncts = 
join.getHashJoinConjuncts().stream()
-                    .filter(expression -> 
!expression.equals(BooleanLiteral.TRUE))
-                    .collect(Collectors.toList());
-            List<Expression> otherJoinConjuncts = 
join.getOtherJoinConjuncts().stream()
-                    .filter(expression -> 
!expression.equals(BooleanLiteral.TRUE))
-                    .collect(Collectors.toList());
-            List<Expression> markJoinConjuncts = 
join.getMarkJoinConjuncts().stream()
-                    .filter(expression -> 
!expression.equals(BooleanLiteral.TRUE))
-                    .collect(Collectors.toList());
-            if (hashJoinConjuncts.size() == join.getHashJoinConjuncts().size()
-                    && otherJoinConjuncts.size() == 
join.getOtherJoinConjuncts().size()
-                    && markJoinConjuncts.size() == 
join.getMarkJoinConjuncts().size()) {
-                return null;
+        return logicalJoin()
+                .then(EliminateJoinCondition::eliminateJoinCondition)
+                .toRule(RuleType.ELIMINATE_JOIN_CONDITION);
+    }
+
+    static Plan eliminateJoinCondition(LogicalJoin<? extends Plan, ? extends 
Plan> join) {
+        List<Expression> hashJoinConjuncts = 
removeTrueConjuncts(join.getHashJoinConjuncts());
+        List<Expression> otherJoinConjuncts = 
removeTrueConjuncts(join.getOtherJoinConjuncts());
+        List<Expression> markJoinConjuncts = 
removeTrueConjuncts(join.getMarkJoinConjuncts());
+
+        if (!join.isMarkJoin() && (containsFalseOrNull(hashJoinConjuncts)
+                || containsFalseOrNull(otherJoinConjuncts))) {
+            switch (join.getJoinType()) {
+                case INNER_JOIN:
+                case CROSS_JOIN:
+                    return new 
LogicalEmptyRelation(StatementScopeIdGenerator.newRelationId(), 
join.getOutput());
+                case LEFT_OUTER_JOIN:
+                    return projectNullPaddedJoinOutput(join, join.left());
+                case RIGHT_OUTER_JOIN:
+                    return projectNullPaddedJoinOutput(join, join.right());
+                default:
+                    break;
+            }
+        }
+
+        if (hashJoinConjuncts.size() == join.getHashJoinConjuncts().size()
+                && otherJoinConjuncts.size() == 
join.getOtherJoinConjuncts().size()
+                && markJoinConjuncts.size() == 
join.getMarkJoinConjuncts().size()) {
+            return null;
+        }
+        return join.withJoinConjuncts(hashJoinConjuncts, otherJoinConjuncts, 
markJoinConjuncts,
+                join.getJoinReorderContext());
+    }
+
+    private static List<Expression> removeTrueConjuncts(List<Expression> 
conjuncts) {
+        return conjuncts.stream()
+                .filter(expression -> !expression.equals(BooleanLiteral.TRUE))
+                .collect(Collectors.toList());
+    }
+
+    private static boolean containsFalseOrNull(List<Expression> conjuncts) {
+        return conjuncts.stream()
+                .anyMatch(expression -> 
expression.equals(BooleanLiteral.FALSE) || expression.isNullLiteral());
+    }
+
+    private static LogicalProject<Plan> projectNullPaddedJoinOutput(
+            LogicalJoin<? extends Plan, ? extends Plan> join, Plan 
preservedChild) {
+        Set<Slot> preservedOutput = preservedChild.getOutputSet();
+        ImmutableList.Builder<NamedExpression> projects =
+                ImmutableList.builderWithExpectedSize(join.getOutput().size());
+        for (Slot output : join.getOutput()) {
+            if (preservedOutput.contains(output)) {
+                projects.add(output);
+            } else {
+                projects.add(new Alias(new NullLiteral(output.getDataType()), 
output));

Review Comment:
   为什么要穿这个output给alias,new alias的时候将output的exprid传个alias就可以了吧?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to