[feat](Nereids): Reject Commutativity Swap for Nested Loop Joins Affecting Parallelism (#34639) (#34798)

This commit is contained in:
谢健
2024-05-15 16:52:26 +08:00
committed by GitHub
parent ab9ff0447d
commit 91a154988d
3 changed files with 35 additions and 2 deletions

View File

@ -25,9 +25,11 @@ import org.apache.doris.nereids.trees.expressions.Not;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.functions.scalar.BitmapContains;
import org.apache.doris.nereids.trees.plans.GroupPlan;
import org.apache.doris.nereids.trees.plans.JoinType;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
import org.apache.doris.nereids.util.JoinUtils;
import org.apache.doris.planner.NestedLoopJoinNode;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.thrift.TRuntimeFilterType;
@ -66,6 +68,11 @@ public class JoinCommute extends OneExplorationRuleFactory {
// commuting nest loop mark join or left anti mark join is not supported by be
.whenNot(join -> join.isMarkJoin() && (join.getHashJoinConjuncts().isEmpty()
|| join.getJoinType().isLeftAntiJoin()))
// For a nested loop join, if commutativity causes a join that could originally be executed
// in parallel to become non-parallelizable, then we reject this swap.
.whenNot(join -> JoinUtils.shouldNestedLoopJoin(join)
&& NestedLoopJoinNode.canParallelize(JoinType.toJoinOperator(join.getJoinType()))
&& !NestedLoopJoinNode.canParallelize(JoinType.toJoinOperator(join.getJoinType().swap())))
.then(join -> {
LogicalJoin<Plan, Plan> newJoin = join.withTypeChildren(join.getJoinType().swap(),
join.right(), join.left(), null);

View File

@ -73,12 +73,16 @@ public class NestedLoopJoinNode extends JoinNodeBase {
tupleIds.addAll(inner.getOutputTupleIds());
}
public boolean canParallelize() {
public static boolean canParallelize(JoinOperator joinOp) {
return joinOp == JoinOperator.CROSS_JOIN || joinOp == JoinOperator.INNER_JOIN
|| joinOp == JoinOperator.LEFT_OUTER_JOIN || joinOp == JoinOperator.LEFT_SEMI_JOIN
|| joinOp == JoinOperator.LEFT_ANTI_JOIN || joinOp == JoinOperator.NULL_AWARE_LEFT_ANTI_JOIN;
}
public boolean canParallelize() {
return canParallelize(joinOp);
}
public void setJoinConjuncts(List<Expr> joinConjuncts) {
this.joinConjuncts = joinConjuncts;
}