morrySnow commented on code in PR #16449:
URL: https://github.com/apache/doris/pull/16449#discussion_r1104455166
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/InApplyToJoin.java:
##########
@@ -63,7 +63,9 @@ public Rule build() {
throw new AnalysisException("nereids don't support bitmap
runtime filter");
}
if (((InSubquery) apply.getSubqueryExpr()).isNot()) {
- return new LogicalJoin<>(JoinType.NULL_AWARE_LEFT_ANTI_JOIN,
Lists.newArrayList(),
+ return new LogicalJoin<>(
+ predicate.nullable() ?
JoinType.NULL_AWARE_LEFT_ANTI_JOIN : JoinType.LEFT_ANTI_JOIN,
+ Lists.newArrayList(),
Review Comment:
i don't think this is good enough. think about that
if we have a outer join under apply and the outer join could trans to inner
join. then we should turn NULL_AWARE_LEFT_ANTI_JOIN in LEFT_ANTI_JOIN after the
outer join elimination.
##########
fe/fe-core/src/test/java/org/apache/doris/nereids/util/LogicalPlanBuilder.java:
##########
@@ -84,6 +85,18 @@ public LogicalPlanBuilder alias(List<Integer> slotsIndex,
List<String> alias) {
return from(project);
}
+ public LogicalPlanBuilder complexAlias(List<Integer> slotsIndex,
List<String> alias) {
+ Preconditions.checkArgument(slotsIndex.size() == alias.size());
Review Comment:
add error msg in check
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/JoinReorderUtils.java:
##########
@@ -79,10 +80,67 @@ public static Set<ExprId> combineProjectAndChildExprId(Plan
b, List<NamedExpress
* If projectExprs is empty or project output equal plan output, return
the original plan.
*/
public static Plan projectOrSelf(List<NamedExpression> projectExprs, Plan
plan) {
- if (projectExprs.isEmpty() ||
projectExprs.stream().map(NamedExpression::getExprId).collect(Collectors.toSet())
- .equals(plan.getOutputExprIdSet())) {
+ if (projectExprs.isEmpty() ||
projectExprs.stream().map(NamedExpression::getExprId)
+
.collect(Collectors.toSet()).equals(plan.getOutputExprIdSet())) {
return plan;
}
return new LogicalProject<>(projectExprs, plan);
}
+
+ /**
+ * - prevent reorder when hyper edge is in projection. like project A.id +
B.id as ab join C on ab = C.id
+ */
+ static boolean checkProjectForJoin(LogicalProject<LogicalJoin<GroupPlan,
GroupPlan>> project) {
Review Comment:
```suggestion
static boolean
checkHyperEdgeProjectForJoin(LogicalProject<LogicalJoin<GroupPlan, GroupPlan>>
project) {
```
##########
fe/fe-core/src/test/java/org/apache/doris/nereids/util/LogicalPlanBuilder.java:
##########
@@ -84,6 +85,18 @@ public LogicalPlanBuilder alias(List<Integer> slotsIndex,
List<String> alias) {
return from(project);
}
+ public LogicalPlanBuilder complexAlias(List<Integer> slotsIndex,
List<String> alias) {
+ Preconditions.checkArgument(slotsIndex.size() == alias.size());
+
+ List<NamedExpression> projectExprs = Lists.newArrayList();
Review Comment:
use a `ImmutableList.Builder` is better
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/JoinReorderUtils.java:
##########
@@ -79,10 +80,67 @@ public static Set<ExprId> combineProjectAndChildExprId(Plan
b, List<NamedExpress
* If projectExprs is empty or project output equal plan output, return
the original plan.
*/
public static Plan projectOrSelf(List<NamedExpression> projectExprs, Plan
plan) {
- if (projectExprs.isEmpty() ||
projectExprs.stream().map(NamedExpression::getExprId).collect(Collectors.toSet())
- .equals(plan.getOutputExprIdSet())) {
+ if (projectExprs.isEmpty() ||
projectExprs.stream().map(NamedExpression::getExprId)
+
.collect(Collectors.toSet()).equals(plan.getOutputExprIdSet())) {
return plan;
}
return new LogicalProject<>(projectExprs, plan);
}
+
+ /**
+ * - prevent reorder when hyper edge is in projection. like project A.id +
B.id as ab join C on ab = C.id
+ */
+ static boolean checkProjectForJoin(LogicalProject<LogicalJoin<GroupPlan,
GroupPlan>> project) {
+ List<NamedExpression> exprs = project.getProjects();
+ Set<ExprId> leftExprIds = project.child().left().getOutputExprIdSet();
+ Set<ExprId> rightExprIds =
project.child().right().getOutputExprIdSet();
+ return exprs.stream().allMatch(expr -> {
+ Set<ExprId> exprIds = expr.getInputSlotExprIds();
+ boolean findInLeft = false;
+ boolean findInRight = false;
+ for (ExprId id : exprIds) {
+ findInLeft = findInLeft || leftExprIds.contains(id);
+ findInRight = findInRight || rightExprIds.contains(id);
+ }
+ return !(findInLeft && findInRight);
+ });
+ }
+
+ /**
+ * topJoin newTopJoin
+ * / \ / \
+ * project C newLeftProject newRightProject
+ * / ──► / \
+ * bottomJoin newBottomJoin B
+ * / \ / \
+ * A B A C
+ *
+ * calculate the replace map for new top and bottom join conjuncts
+ * @param projects project's output
Review Comment:
```suggestion
* calculate the replace map for new top and bottom join conjuncts
*
* @param projects project's output
```
##########
fe/fe-core/src/test/java/org/apache/doris/nereids/util/LogicalPlanBuilder.java:
##########
@@ -84,6 +85,18 @@ public LogicalPlanBuilder alias(List<Integer> slotsIndex,
List<String> alias) {
return from(project);
}
+ public LogicalPlanBuilder complexAlias(List<Integer> slotsIndex,
List<String> alias) {
+ Preconditions.checkArgument(slotsIndex.size() == alias.size());
+
+ List<NamedExpression> projectExprs = Lists.newArrayList();
+ for (int i = 0; i < slotsIndex.size(); i++) {
+ projectExprs.add(new Alias(new
Abs(this.plan.getOutput().get(slotsIndex.get(i))),
Review Comment:
Abs?
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinSemiJoinTransposeProject.java:
##########
@@ -52,36 +58,69 @@ public class SemiJoinSemiJoinTransposeProject extends
OneExplorationRuleFactory
@Override
public Rule build() {
return logicalJoin(logicalProject(logicalJoin()), group())
+ .whenNot(join -> join.hasJoinHint() ||
join.left().child().hasJoinHint())
.when(this::typeChecker)
.when(topSemi -> InnerJoinLAsscom.checkReorder(topSemi,
topSemi.left().child()))
.whenNot(join -> join.hasJoinHint() ||
join.left().child().hasJoinHint())
- .when(join -> JoinReorderUtils.checkProject(join.left()))
+ .when(join ->
JoinReorderUtils.checkProjectForJoin(join.left()))
.then(topSemi -> {
LogicalJoin<GroupPlan, GroupPlan> bottomSemi =
topSemi.left().child();
LogicalProject abProject = topSemi.left();
GroupPlan a = bottomSemi.left();
GroupPlan b = bottomSemi.right();
GroupPlan c = topSemi.right();
Set<ExprId> aOutputExprIdSet = a.getOutputExprIdSet();
- Set<NamedExpression> acProjects = new
HashSet<NamedExpression>(abProject.getProjects());
+ Set<NamedExpression> acProjects =
+ new
HashSet<NamedExpression>(abProject.getProjects());
+ /* ********** replace Conjuncts by projects ********** */
+ Map<ExprId, Expression> replaceMapForNewTopJoin = new
HashMap<>();
+ Map<ExprId, Expression> replaceMapForNewBottomJoin = new
HashMap<>();
+ boolean needNewProjectChildForA =
JoinReorderUtils.processProjects(abProject.getProjects(),
+ aOutputExprIdSet, replaceMapForNewTopJoin,
replaceMapForNewBottomJoin);
+
+ /* ********** swap Conjuncts ********** */
+ List<Expression> newTopHashJoinConjuncts =
bottomSemi.getHashJoinConjuncts();
+ List<Expression> newTopOtherJoinConjuncts =
bottomSemi.getOtherJoinConjuncts();
+ List<Expression> newBottomHashJoinConjuncts =
topSemi.getHashJoinConjuncts();
+ List<Expression> newBottomOtherJoinConjuncts =
topSemi.getOtherJoinConjuncts();
+
+ // replace top join conjuncts
+ newTopHashJoinConjuncts =
+
JoinUtils.replaceJoinConjuncts(newTopHashJoinConjuncts,
replaceMapForNewTopJoin);
+ newTopOtherJoinConjuncts =
+
JoinUtils.replaceJoinConjuncts(newTopOtherJoinConjuncts,
replaceMapForNewTopJoin);
+
+ bottomSemi.getHashJoinConjuncts()
+ .forEach(expression ->
expression.getInputSlots().forEach(slot -> {
+ if
(aOutputExprIdSet.contains(slot.getExprId())) {
+ acProjects.add(slot);
+ }
+ }));
+
+ LogicalJoin newBottomSemi;
+ if (needNewProjectChildForA) {
+ newBottomSemi =
+ new LogicalJoin<>(topSemi.getJoinType(),
newBottomHashJoinConjuncts,
+ newBottomOtherJoinConjuncts,
JoinHint.NONE,
+
JoinReorderUtils.projectOrSelf(Lists.newArrayList(acProjects), a),
+ c, bottomSemi.getJoinReorderContext());
+ } else {
+ newBottomHashJoinConjuncts = JoinUtils
+
.replaceJoinConjuncts(newBottomHashJoinConjuncts, replaceMapForNewBottomJoin);
+ newBottomOtherJoinConjuncts = JoinUtils
+
.replaceJoinConjuncts(newBottomOtherJoinConjuncts, replaceMapForNewBottomJoin);
+ newBottomSemi = new
LogicalJoin<>(topSemi.getJoinType(),
+ newBottomHashJoinConjuncts,
newBottomOtherJoinConjuncts,
+ JoinHint.NONE, a, c,
bottomSemi.getJoinReorderContext());
+ }
- bottomSemi.getHashJoinConjuncts().forEach(
- expression -> expression.getInputSlots().forEach(
- slot -> {
- if
(aOutputExprIdSet.contains(slot.getExprId())) {
- acProjects.add(slot);
- }
- })
- );
- LogicalJoin newBottomSemi = new
LogicalJoin<>(topSemi.getJoinType(), topSemi.getHashJoinConjuncts(),
- topSemi.getOtherJoinConjuncts(), JoinHint.NONE, a,
c,
- bottomSemi.getJoinReorderContext());
newBottomSemi.getJoinReorderContext().setHasCommute(false);
newBottomSemi.getJoinReorderContext().setHasLAsscom(false);
- LogicalProject acProject = new
LogicalProject<>(Lists.newArrayList(acProjects), newBottomSemi);
- LogicalJoin newTopSemi = new
LogicalJoin<>(bottomSemi.getJoinType(),
- bottomSemi.getHashJoinConjuncts(),
bottomSemi.getOtherJoinConjuncts(), JoinHint.NONE,
- acProject, b, topSemi.getJoinReorderContext());
+
+ Plan left =
JoinReorderUtils.projectOrSelf(Lists.newArrayList(acProjects), newBottomSemi);
Review Comment:
use Immutable collections as far as possible
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinLAsscomProject.java:
##########
@@ -137,17 +127,43 @@ public Rule build() {
JoinUtils.addSlotsUsedByOn(bUsedSlots, newRightProjects);
JoinUtils.addSlotsUsedByOn(aUsedSlots, newLeftProjects);
- if (!newLeftProjects.isEmpty()) {
- newLeftProjects.addAll(cOutputSet);
- }
-
/* ********** new Plan ********** */
- LogicalJoin<GroupPlan, GroupPlan> newBottomJoin = new
LogicalJoin<>(topJoin.getJoinType(),
- newBottomHashConjuncts, newBottomOtherConjuncts,
JoinHint.NONE,
- a, c, bottomJoin.getJoinReorderContext());
+ LogicalJoin newBottomJoin;
+ if (needNewProjectChildForA) {
+ /*
+ * topJoin newTopJoin
+ * / \ / \
+ * project C newLeftProject
newRightProject
+ * / ──► / \
+ * bottomJoin newBottomJoin B
+ * / \ / \
+ * A B A C
+ * /
+ * needNewProjectChildForA
+ */
+ // create a new project node as A's child
+ newBottomJoin = new
LogicalJoin<>(topJoin.getJoinType(),
+ newBottomHashConjuncts,
newBottomOtherConjuncts,
+ JoinHint.NONE,
JoinReorderUtils.projectOrSelf(newLeftProjects, a), c,
+ bottomJoin.getJoinReorderContext());
+ } else {
+ // replace the join conjuncts
+ newBottomHashConjuncts =
JoinUtils.replaceJoinConjuncts(
+ newBottomHashConjuncts,
replaceMapForNewBottomJoin);
+ newBottomOtherConjuncts =
JoinUtils.replaceJoinConjuncts(
+ newBottomOtherConjuncts,
replaceMapForNewBottomJoin);
+ newBottomJoin = new
LogicalJoin<>(topJoin.getJoinType(),
+ newBottomHashConjuncts,
newBottomOtherConjuncts,
+ JoinHint.NONE, a, c,
bottomJoin.getJoinReorderContext());
+ }
newBottomJoin.getJoinReorderContext().setHasLAsscom(false);
newBottomJoin.getJoinReorderContext().setHasCommute(false);
+ // new left project should contain all output slots from C
+ if (!newLeftProjects.isEmpty()) {
+ newLeftProjects.addAll(cOutputSet);
+ }
Review Comment:
has bugs? newLeftProject as done under A if needNewProjectChildForA, do it
again may lead to some exprs contains slots not from its child
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/JoinReorderUtils.java:
##########
@@ -79,10 +80,67 @@ public static Set<ExprId> combineProjectAndChildExprId(Plan
b, List<NamedExpress
* If projectExprs is empty or project output equal plan output, return
the original plan.
*/
public static Plan projectOrSelf(List<NamedExpression> projectExprs, Plan
plan) {
- if (projectExprs.isEmpty() ||
projectExprs.stream().map(NamedExpression::getExprId).collect(Collectors.toSet())
- .equals(plan.getOutputExprIdSet())) {
+ if (projectExprs.isEmpty() ||
projectExprs.stream().map(NamedExpression::getExprId)
+
.collect(Collectors.toSet()).equals(plan.getOutputExprIdSet())) {
return plan;
}
return new LogicalProject<>(projectExprs, plan);
}
+
+ /**
+ * - prevent reorder when hyper edge is in projection. like project A.id +
B.id as ab join C on ab = C.id
+ */
+ static boolean checkProjectForJoin(LogicalProject<LogicalJoin<GroupPlan,
GroupPlan>> project) {
+ List<NamedExpression> exprs = project.getProjects();
+ Set<ExprId> leftExprIds = project.child().left().getOutputExprIdSet();
+ Set<ExprId> rightExprIds =
project.child().right().getOutputExprIdSet();
+ return exprs.stream().allMatch(expr -> {
+ Set<ExprId> exprIds = expr.getInputSlotExprIds();
+ boolean findInLeft = false;
+ boolean findInRight = false;
+ for (ExprId id : exprIds) {
+ findInLeft = findInLeft || leftExprIds.contains(id);
+ findInRight = findInRight || rightExprIds.contains(id);
+ }
+ return !(findInLeft && findInRight);
+ });
+ }
+
+ /**
+ * topJoin newTopJoin
+ * / \ / \
+ * project C newLeftProject newRightProject
+ * / ──► / \
+ * bottomJoin newBottomJoin B
+ * / \ / \
+ * A B A C
+ *
+ * calculate the replace map for new top and bottom join conjuncts
+ * @param projects project's output
+ * @param leftBottomOutputs A's output
+ * @param replaceMapForNewTopJoin output param, as the name indicated
+ * @param replaceMapForNewBottomJoin output param, as the name indicated
+ * @return return true, if a new project node should be created as A's
child
+ */
+ public static boolean processProjects(List<NamedExpression> projects,
Set<ExprId> leftBottomOutputs,
Review Comment:
```suggestion
public static boolean
needCreateLeftBottomChildProject(List<NamedExpression> projects, Set<ExprId>
leftBottomOutputs,
```
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/InnerJoinLAsscomProject.java:
##########
@@ -137,17 +127,43 @@ public Rule build() {
JoinUtils.addSlotsUsedByOn(bUsedSlots, newRightProjects);
JoinUtils.addSlotsUsedByOn(aUsedSlots, newLeftProjects);
- if (!newLeftProjects.isEmpty()) {
- newLeftProjects.addAll(cOutputSet);
- }
-
/* ********** new Plan ********** */
- LogicalJoin<GroupPlan, GroupPlan> newBottomJoin = new
LogicalJoin<>(topJoin.getJoinType(),
- newBottomHashConjuncts, newBottomOtherConjuncts,
JoinHint.NONE,
- a, c, bottomJoin.getJoinReorderContext());
+ LogicalJoin newBottomJoin;
+ if (needNewProjectChildForA) {
+ /*
+ * topJoin newTopJoin
+ * / \ / \
+ * project C newLeftProject
newRightProject
+ * / ──► / \
+ * bottomJoin newBottomJoin B
+ * / \ / \
+ * A B A C
+ * /
+ * needNewProjectChildForA
Review Comment:
right chart is not right? newLeftProjects should at top of A
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/OuterJoinLAsscomProject.java:
##########
@@ -139,18 +117,48 @@ public Rule build() {
JoinUtils.addSlotsUsedByOn(bUsedSlots, newRightProjects);
JoinUtils.addSlotsUsedByOn(aUsedSlots, newLeftProjects);
- if (!newLeftProjects.isEmpty()) {
- Set<Slot> nullableCOutputSet =
forceToNullable(cOutputSet);
- newLeftProjects.addAll(nullableCOutputSet);
- }
-
/* ********** new Plan ********** */
- LogicalJoin<GroupPlan, GroupPlan> newBottomJoin = new
LogicalJoin<>(topJoin.getJoinType(),
- newBottomHashConjuncts, newBottomOtherConjuncts,
JoinHint.NONE,
- a, c, bottomJoin.getJoinReorderContext());
+ LogicalJoin newBottomJoin;
+ if (needNewProjectChildForA) {
+ /*
+ * topJoin newTopJoin
+ * / \ / \
+ * project C newLeftProject
newRightProject
+ * / ──► / \
+ * bottomJoin newBottomJoin B
+ * / \ / \
+ * A B A C
+ * /
+ * needNewProjectChildForA
+ */
+ // create a new project node as A's child
+ newBottomJoin = new
LogicalJoin<>(topJoin.getJoinType(),
+ newBottomHashConjuncts,
newBottomOtherConjuncts,
+ JoinHint.NONE,
JoinReorderUtils.projectOrSelf(newLeftProjects, a), c,
+ bottomJoin.getJoinReorderContext());
+ } else {
+ // replace the join conjuncts
+ newBottomHashConjuncts =
JoinUtils.replaceJoinConjuncts(
+ newBottomHashConjuncts,
replaceMapForNewBottomJoin);
+ newBottomOtherConjuncts =
JoinUtils.replaceJoinConjuncts(
+ newBottomOtherConjuncts,
replaceMapForNewBottomJoin);
+ newBottomJoin = new
LogicalJoin<>(topJoin.getJoinType(),
+ newBottomHashConjuncts,
newBottomOtherConjuncts,
+ JoinHint.NONE, a, c,
bottomJoin.getJoinReorderContext());
+ }
newBottomJoin.getJoinReorderContext().setHasLAsscom(false);
newBottomJoin.getJoinReorderContext().setHasCommute(false);
+ // new left project should contain all output slots from C
+ if (!newLeftProjects.isEmpty()) {
+ if (topJoin.getJoinType().isLeftJoin()) {
+ Set<Slot> nullableCOutputSet =
forceToNullable(cOutputSet);
+ newLeftProjects.addAll(nullableCOutputSet);
+ } else {
+ newLeftProjects.addAll(cOutputSet);
+ }
Review Comment:
maybe has the same bug in InnterJoinLAsscomProject
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/JoinReorderUtils.java:
##########
@@ -79,10 +80,67 @@ public static Set<ExprId> combineProjectAndChildExprId(Plan
b, List<NamedExpress
* If projectExprs is empty or project output equal plan output, return
the original plan.
*/
public static Plan projectOrSelf(List<NamedExpression> projectExprs, Plan
plan) {
- if (projectExprs.isEmpty() ||
projectExprs.stream().map(NamedExpression::getExprId).collect(Collectors.toSet())
- .equals(plan.getOutputExprIdSet())) {
+ if (projectExprs.isEmpty() ||
projectExprs.stream().map(NamedExpression::getExprId)
+
.collect(Collectors.toSet()).equals(plan.getOutputExprIdSet())) {
return plan;
}
return new LogicalProject<>(projectExprs, plan);
}
+
+ /**
+ * - prevent reorder when hyper edge is in projection. like project A.id +
B.id as ab join C on ab = C.id
+ */
+ static boolean checkProjectForJoin(LogicalProject<LogicalJoin<GroupPlan,
GroupPlan>> project) {
+ List<NamedExpression> exprs = project.getProjects();
+ Set<ExprId> leftExprIds = project.child().left().getOutputExprIdSet();
+ Set<ExprId> rightExprIds =
project.child().right().getOutputExprIdSet();
+ return exprs.stream().allMatch(expr -> {
+ Set<ExprId> exprIds = expr.getInputSlotExprIds();
+ boolean findInLeft = false;
+ boolean findInRight = false;
+ for (ExprId id : exprIds) {
+ findInLeft = findInLeft || leftExprIds.contains(id);
+ findInRight = findInRight || rightExprIds.contains(id);
+ }
+ return !(findInLeft && findInRight);
+ });
+ }
+
+ /**
+ * topJoin newTopJoin
+ * / \ / \
+ * project C newLeftProject newRightProject
+ * / ──► / \
+ * bottomJoin newBottomJoin B
+ * / \ / \
+ * A B A C
+ *
+ * calculate the replace map for new top and bottom join conjuncts
+ * @param projects project's output
+ * @param leftBottomOutputs A's output
+ * @param replaceMapForNewTopJoin output param, as the name indicated
+ * @param replaceMapForNewBottomJoin output param, as the name indicated
+ * @return return true, if a new project node should be created as A's
child
Review Comment:
```suggestion
* @param replaceMapForNewBottomJoin output param, as the name indicated
*
* @return return true, if a new project node should be created as A's
child
```
##########
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinSemiJoinTransposeProject.java:
##########
@@ -52,36 +58,69 @@ public class SemiJoinSemiJoinTransposeProject extends
OneExplorationRuleFactory
@Override
public Rule build() {
return logicalJoin(logicalProject(logicalJoin()), group())
+ .whenNot(join -> join.hasJoinHint() ||
join.left().child().hasJoinHint())
.when(this::typeChecker)
.when(topSemi -> InnerJoinLAsscom.checkReorder(topSemi,
topSemi.left().child()))
.whenNot(join -> join.hasJoinHint() ||
join.left().child().hasJoinHint())
- .when(join -> JoinReorderUtils.checkProject(join.left()))
+ .when(join ->
JoinReorderUtils.checkProjectForJoin(join.left()))
.then(topSemi -> {
LogicalJoin<GroupPlan, GroupPlan> bottomSemi =
topSemi.left().child();
LogicalProject abProject = topSemi.left();
GroupPlan a = bottomSemi.left();
GroupPlan b = bottomSemi.right();
GroupPlan c = topSemi.right();
Set<ExprId> aOutputExprIdSet = a.getOutputExprIdSet();
- Set<NamedExpression> acProjects = new
HashSet<NamedExpression>(abProject.getProjects());
+ Set<NamedExpression> acProjects =
+ new
HashSet<NamedExpression>(abProject.getProjects());
+ /* ********** replace Conjuncts by projects ********** */
+ Map<ExprId, Expression> replaceMapForNewTopJoin = new
HashMap<>();
+ Map<ExprId, Expression> replaceMapForNewBottomJoin = new
HashMap<>();
+ boolean needNewProjectChildForA =
JoinReorderUtils.processProjects(abProject.getProjects(),
+ aOutputExprIdSet, replaceMapForNewTopJoin,
replaceMapForNewBottomJoin);
+
+ /* ********** swap Conjuncts ********** */
+ List<Expression> newTopHashJoinConjuncts =
bottomSemi.getHashJoinConjuncts();
+ List<Expression> newTopOtherJoinConjuncts =
bottomSemi.getOtherJoinConjuncts();
+ List<Expression> newBottomHashJoinConjuncts =
topSemi.getHashJoinConjuncts();
+ List<Expression> newBottomOtherJoinConjuncts =
topSemi.getOtherJoinConjuncts();
+
+ // replace top join conjuncts
+ newTopHashJoinConjuncts =
+
JoinUtils.replaceJoinConjuncts(newTopHashJoinConjuncts,
replaceMapForNewTopJoin);
+ newTopOtherJoinConjuncts =
+
JoinUtils.replaceJoinConjuncts(newTopOtherJoinConjuncts,
replaceMapForNewTopJoin);
+
+ bottomSemi.getHashJoinConjuncts()
+ .forEach(expression ->
expression.getInputSlots().forEach(slot -> {
+ if
(aOutputExprIdSet.contains(slot.getExprId())) {
+ acProjects.add(slot);
+ }
+ }));
+
+ LogicalJoin newBottomSemi;
+ if (needNewProjectChildForA) {
+ newBottomSemi =
+ new LogicalJoin<>(topSemi.getJoinType(),
newBottomHashJoinConjuncts,
+ newBottomOtherJoinConjuncts,
JoinHint.NONE,
+
JoinReorderUtils.projectOrSelf(Lists.newArrayList(acProjects), a),
+ c, bottomSemi.getJoinReorderContext());
+ } else {
+ newBottomHashJoinConjuncts = JoinUtils
+
.replaceJoinConjuncts(newBottomHashJoinConjuncts, replaceMapForNewBottomJoin);
+ newBottomOtherJoinConjuncts = JoinUtils
+
.replaceJoinConjuncts(newBottomOtherJoinConjuncts, replaceMapForNewBottomJoin);
+ newBottomSemi = new
LogicalJoin<>(topSemi.getJoinType(),
+ newBottomHashJoinConjuncts,
newBottomOtherJoinConjuncts,
+ JoinHint.NONE, a, c,
bottomSemi.getJoinReorderContext());
+ }
- bottomSemi.getHashJoinConjuncts().forEach(
- expression -> expression.getInputSlots().forEach(
- slot -> {
- if
(aOutputExprIdSet.contains(slot.getExprId())) {
- acProjects.add(slot);
- }
- })
- );
- LogicalJoin newBottomSemi = new
LogicalJoin<>(topSemi.getJoinType(), topSemi.getHashJoinConjuncts(),
- topSemi.getOtherJoinConjuncts(), JoinHint.NONE, a,
c,
- bottomSemi.getJoinReorderContext());
newBottomSemi.getJoinReorderContext().setHasCommute(false);
newBottomSemi.getJoinReorderContext().setHasLAsscom(false);
- LogicalProject acProject = new
LogicalProject<>(Lists.newArrayList(acProjects), newBottomSemi);
- LogicalJoin newTopSemi = new
LogicalJoin<>(bottomSemi.getJoinType(),
- bottomSemi.getHashJoinConjuncts(),
bottomSemi.getOtherJoinConjuncts(), JoinHint.NONE,
- acProject, b, topSemi.getJoinReorderContext());
+
+ Plan left =
JoinReorderUtils.projectOrSelf(Lists.newArrayList(acProjects), newBottomSemi);
Review Comment:
same as innerjoinlasscomproject
--
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]