924060929 commented on code in PR #10479: URL: https://github.com/apache/doris/pull/10479#discussion_r920091457
########## fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/JoinCommutative.java: ########## @@ -50,11 +51,54 @@ enum SwapType { @Override public Rule<Plan> build() { - return innerLogicalJoin().then(join -> new LogicalJoin( - join.getJoinType().swap(), - join.getCondition(), - join.right(), - join.left()) - ).toRule(RuleType.LOGICAL_JOIN_COMMUTATIVE); + return innerLogicalJoin().then(join -> { + if (check(join)) { + return null; + } + boolean isBottomJoin = isBottomJoin(join); + if (swapType == SwapType.BOTTOM_JOIN && !isBottomJoin) { + return null; + } + + LogicalJoin newJoin = new LogicalJoin( + join.getJoinType(), + join.getCondition(), + join.right(), join.left() + ); + newJoin.getJoinReorderContext().copyFrom(join.getJoinReorderContext()); + newJoin.getJoinReorderContext().setHasCommute(true); + if (swapType == SwapType.ZIG_ZAG && !isBottomJoin) { + newJoin.getJoinReorderContext().setHasCommuteZigZag(true); + } + + return newJoin; + }).toRule(RuleType.LOGICAL_JOIN_COMMUTATIVE); + } + + + private boolean check(LogicalJoin join) { + if (join.getJoinReorderContext().hasCommute() || join.getJoinReorderContext().hasExchange()) { + return false; + } + return true; + } + + private boolean isBottomJoin(LogicalJoin join) { + if (join.left() instanceof LogicalProject) { Review Comment: the pattern `innerLogicalJoin()` will capture the INNER LogicalJoin with GroupPlan as children. So this line never working. You can wait @wangshuo128 add the tree pattern, then you can capture the children by some type, e.g. ```java innerLogicalJoin(tree(LogicalProject.class, LogicalJoin.class), tree(LogicalProject.class, LogicalJoin.class)).then(topJoin -> ... ) ``` ########## fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/JoinLAsscom.java: ########## @@ -38,14 +50,101 @@ public class JoinLAsscom extends OneExplorationRuleFactory { @Override public Rule<Plan> build() { return innerLogicalJoin(innerLogicalJoin(), any()).then(topJoin -> { + if (!check(topJoin)) { + return null; + } + LogicalJoin<GroupPlan, GroupPlan> bottomJoin = topJoin.left(); GroupPlan a = bottomJoin.left(); GroupPlan b = bottomJoin.right(); Plan c = topJoin.right(); - Plan newBottomJoin = new LogicalJoin(bottomJoin.getJoinType(), bottomJoin.getCondition(), a, c); - return new LogicalJoin(bottomJoin.getJoinType(), topJoin.getCondition(), newBottomJoin, b); + Optional<Expression> optTopJoinOnClause = topJoin.getCondition(); + assert (optTopJoinOnClause.isPresent()); + Expression topJoinOnClause = optTopJoinOnClause.get(); + Optional<Expression> optBottomJoinOnClause = bottomJoin.getCondition(); + // TODO: empty onClause. + assert (optBottomJoinOnClause.isPresent()); + Expression bottomJoinOnClause = optBottomJoinOnClause.get(); + + List<SlotReference> aSlots = a.collect(SlotReference.class::isInstance); + List<SlotReference> bSlots = b.collect(SlotReference.class::isInstance); + List<SlotReference> cSlots = c.collect(SlotReference.class::isInstance); + + // Check whether lhs and rhs (both are List<SlotReference>>) are intersecting. + BiPredicate<List<SlotReference>, List<SlotReference>> isIntersecting = (lhs, rhs) -> { + for (SlotReference lSlot : lhs) { + for (SlotReference rSlot : rhs) { + // TODO: tmp judge intersecting + if (lSlot.getExprId() != rSlot.getExprId()) { + return false; Review Comment: this intersecting logic is right? `lSlot.getExprId()` should equals to **all of** the `rSlot.getExprId()`? ########## fe/fe-core/src/main/java/org/apache/doris/nereids/util/Utils.java: ########## @@ -32,4 +44,115 @@ public static String quoteIfNeeded(String part) { return part.matches("\\w*[\\w&&[^\\d]]+\\w*") ? part : part.replace("`", "``"); } + + /** + * Split predicates with `And` form recursively. + * <p> + * Some examples: + * a and b -> a, b + * (a and b) and c -> a, b, c + * (a or b) and (c and d) -> (a and b), c , d Review Comment: (a or b) and (c and d) -> (a or b), c , d ########## fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/JoinLAsscom.java: ########## @@ -38,14 +50,101 @@ public class JoinLAsscom extends OneExplorationRuleFactory { @Override public Rule<Plan> build() { return innerLogicalJoin(innerLogicalJoin(), any()).then(topJoin -> { + if (!check(topJoin)) { + return null; + } + LogicalJoin<GroupPlan, GroupPlan> bottomJoin = topJoin.left(); GroupPlan a = bottomJoin.left(); GroupPlan b = bottomJoin.right(); Plan c = topJoin.right(); - Plan newBottomJoin = new LogicalJoin(bottomJoin.getJoinType(), bottomJoin.getCondition(), a, c); - return new LogicalJoin(bottomJoin.getJoinType(), topJoin.getCondition(), newBottomJoin, b); + Optional<Expression> optTopJoinOnClause = topJoin.getCondition(); + assert (optTopJoinOnClause.isPresent()); Review Comment: assert just working when running unit test, are you sure not throw exception in the production environment? ########## fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/JoinCommutative.java: ########## @@ -50,11 +51,54 @@ enum SwapType { @Override public Rule<Plan> build() { - return innerLogicalJoin().then(join -> new LogicalJoin( - join.getJoinType().swap(), - join.getCondition(), - join.right(), - join.left()) - ).toRule(RuleType.LOGICAL_JOIN_COMMUTATIVE); + return innerLogicalJoin().then(join -> { + if (check(join)) { + return null; + } + boolean isBottomJoin = isBottomJoin(join); + if (swapType == SwapType.BOTTOM_JOIN && !isBottomJoin) { + return null; + } + + LogicalJoin newJoin = new LogicalJoin( + join.getJoinType(), + join.getCondition(), + join.right(), join.left() + ); + newJoin.getJoinReorderContext().copyFrom(join.getJoinReorderContext()); Review Comment: why not add a immutable JoinReorderContext field into LogicalJoin and create in the constructor -- 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: commits-unsubscr...@doris.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org