[fix](Nereids): don't pushdown project when project contains both side of join (#32214)
This commit is contained in:
@ -38,6 +38,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* Rule for pushdown project through left-semi/anti join
|
||||
* Just push down project inside join to avoid to push the top of Join-Cluster.
|
||||
* Note this rule is only used to push down project between join for join ordering.
|
||||
* <pre>
|
||||
* Join Join
|
||||
* | |
|
||||
@ -61,6 +62,9 @@ public class PushDownProjectThroughSemiJoin implements ExplorationRuleFactory {
|
||||
.whenNot(j -> j.left().child().hasDistributeHint())
|
||||
.then(topJoin -> {
|
||||
LogicalProject<LogicalJoin<GroupPlan, GroupPlan>> project = topJoin.left();
|
||||
if (projectBothJoinSide(project)) {
|
||||
return null;
|
||||
}
|
||||
Plan newLeft = pushdownProject(project);
|
||||
return topJoin.withChildren(newLeft, topJoin.right());
|
||||
}).toRule(RuleType.PUSH_DOWN_PROJECT_THROUGH_SEMI_JOIN_LEFT),
|
||||
@ -72,12 +76,27 @@ public class PushDownProjectThroughSemiJoin implements ExplorationRuleFactory {
|
||||
.whenNot(j -> j.right().child().hasDistributeHint())
|
||||
.then(topJoin -> {
|
||||
LogicalProject<LogicalJoin<GroupPlan, GroupPlan>> project = topJoin.right();
|
||||
if (projectBothJoinSide(project)) {
|
||||
return null;
|
||||
}
|
||||
Plan newRight = pushdownProject(project);
|
||||
return topJoin.withChildren(topJoin.left(), newRight);
|
||||
}).toRule(RuleType.PUSH_DOWN_PROJECT_THROUGH_SEMI_JOIN_RIGHT)
|
||||
);
|
||||
}
|
||||
|
||||
private boolean projectBothJoinSide(LogicalProject<LogicalJoin<GroupPlan, GroupPlan>> project) {
|
||||
// if project contains both side of join, it can't be pushed.
|
||||
// such as:
|
||||
// Project(l, null as r)
|
||||
// ------ L(l) left anti join R(r)
|
||||
LogicalJoin<?, ?> join = project.child();
|
||||
Set<Slot> projectOutput = project.getOutputSet();
|
||||
boolean containLeft = join.left().getOutput().stream().anyMatch(projectOutput::contains);
|
||||
boolean containRight = join.right().getOutput().stream().anyMatch(projectOutput::contains);
|
||||
return containRight && containLeft;
|
||||
}
|
||||
|
||||
private Plan pushdownProject(LogicalProject<LogicalJoin<GroupPlan, GroupPlan>> project) {
|
||||
LogicalJoin<GroupPlan, GroupPlan> join = project.child();
|
||||
Set<Slot> conditionLeftSlots = CBOUtils.joinChildConditionSlots(join, true);
|
||||
|
||||
Reference in New Issue
Block a user