This is an automated email from the ASF dual-hosted git repository.
jakevin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 1027dd52ba [feature](Nereids): Pushdown SemiJoin in RBO. (#18099)
1027dd52ba is described below
commit 1027dd52ba95f1fef9a1dd73eb1e4c65037425e5
Author: jakevin <[email protected]>
AuthorDate: Sun Mar 26 20:58:43 2023 +0800
[feature](Nereids): Pushdown SemiJoin in RBO. (#18099)
---
.../doris/nereids/jobs/batch/NereidsRewriter.java | 17 ++-
.../org/apache/doris/nereids/rules/RuleSet.java | 4 -
.../org/apache/doris/nereids/rules/RuleType.java | 7 +-
.../rules/rewrite/logical/SemiJoinCommute.java | 38 +++++++
.../logical}/SemiJoinLogicalJoinTranspose.java | 33 ++----
.../SemiJoinLogicalJoinTransposeProject.java | 35 ++----
.../join/SemiJoinLogicalJoinTransposeTest.java | 126 ---------------------
.../SemiJoinLogicalJoinTransposeProjectTest.java | 32 ++----
.../logical/SemiJoinLogicalJoinTransposeTest.java | 96 ++++++++++++++++
.../apache/doris/nereids/sqltest/InferTest.java | 6 +-
10 files changed, 181 insertions(+), 213 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/NereidsRewriter.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/NereidsRewriter.java
index d5939e61f3..26bfd2b5bb 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/NereidsRewriter.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/jobs/batch/NereidsRewriter.java
@@ -63,6 +63,8 @@ import
org.apache.doris.nereids.rules.rewrite.logical.PruneOlapScanTablet;
import org.apache.doris.nereids.rules.rewrite.logical.PushFilterInsideJoin;
import org.apache.doris.nereids.rules.rewrite.logical.PushdownLimit;
import org.apache.doris.nereids.rules.rewrite.logical.ReorderJoin;
+import
org.apache.doris.nereids.rules.rewrite.logical.SemiJoinLogicalJoinTranspose;
+import
org.apache.doris.nereids.rules.rewrite.logical.SemiJoinLogicalJoinTransposeProject;
import org.apache.doris.nereids.rules.rewrite.logical.SplitLimit;
import com.google.common.collect.ImmutableList;
@@ -155,6 +157,13 @@ public class NereidsRewriter extends BatchRewriteJob {
// efficient because it can find the new plans and apply
transform wherever it is
bottomUp(RuleSet.PUSH_DOWN_FILTERS),
+ // pushdown SEMI Join
+ topDown(
+ // new SemiJoinCommute(),
+ new SemiJoinLogicalJoinTranspose(),
+ new SemiJoinLogicalJoinTransposeProject()
+ ),
+
topDown(
new MergeFilters(),
new ReorderJoin(),
@@ -169,16 +178,16 @@ public class NereidsRewriter extends BatchRewriteJob {
),
topic("Column pruning and infer predicate",
- custom(RuleType.COLUMN_PRUNING, () -> new ColumnPruning()),
+ custom(RuleType.COLUMN_PRUNING, ColumnPruning::new),
- custom(RuleType.INFER_PREDICATES, () -> new InferPredicates()),
+ custom(RuleType.INFER_PREDICATES, InferPredicates::new),
// column pruning create new project, so we should use
PUSH_DOWN_FILTERS
// to change filter-project to project-filter
bottomUp(RuleSet.PUSH_DOWN_FILTERS),
// after eliminate outer join in the PUSH_DOWN_FILTERS, we can
infer more predicate and push down
- custom(RuleType.INFER_PREDICATES, () -> new InferPredicates()),
+ custom(RuleType.INFER_PREDICATES, InferPredicates::new),
bottomUp(RuleSet.PUSH_DOWN_FILTERS),
@@ -190,7 +199,7 @@ public class NereidsRewriter extends BatchRewriteJob {
),
// this rule should invoke after ColumnPruning
- custom(RuleType.ELIMINATE_UNNECESSARY_PROJECT, () -> new
EliminateUnnecessaryProject()),
+ custom(RuleType.ELIMINATE_UNNECESSARY_PROJECT,
EliminateUnnecessaryProject::new),
// we need to execute this rule at the end of rewrite
// to avoid two consecutive same project appear when we do
optimization.
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java
index ada9c98ad3..b5aca02751 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleSet.java
@@ -26,8 +26,6 @@ import
org.apache.doris.nereids.rules.exploration.join.OuterJoinLAsscom;
import org.apache.doris.nereids.rules.exploration.join.OuterJoinLAsscomProject;
import
org.apache.doris.nereids.rules.exploration.join.PushdownProjectThroughInnerJoin;
import
org.apache.doris.nereids.rules.exploration.join.PushdownProjectThroughSemiJoin;
-import
org.apache.doris.nereids.rules.exploration.join.SemiJoinLogicalJoinTranspose;
-import
org.apache.doris.nereids.rules.exploration.join.SemiJoinLogicalJoinTransposeProject;
import
org.apache.doris.nereids.rules.exploration.join.SemiJoinSemiJoinTranspose;
import
org.apache.doris.nereids.rules.exploration.join.SemiJoinSemiJoinTransposeProject;
import org.apache.doris.nereids.rules.implementation.AggregateStrategies;
@@ -86,8 +84,6 @@ public class RuleSet {
public static final List<Rule> OTHER_REORDER_RULES = planRuleFactories()
.add(OuterJoinLAsscom.INSTANCE)
.add(OuterJoinLAsscomProject.INSTANCE)
- .add(SemiJoinLogicalJoinTranspose.LEFT_DEEP)
- .add(SemiJoinLogicalJoinTransposeProject.LEFT_DEEP)
.add(SemiJoinSemiJoinTranspose.INSTANCE)
.add(SemiJoinSemiJoinTransposeProject.INSTANCE)
.add(LogicalJoinSemiJoinTranspose.INSTANCE)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
index cf04bc3024..d08eb03aa4 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/RuleType.java
@@ -130,6 +130,11 @@ public enum RuleType {
PUSHDOWN_ALIAS_THROUGH_JOIN(RuleTypeClass.REWRITE),
PUSHDOWN_FILTER_THROUGH_SET_OPERATION(RuleTypeClass.REWRITE),
COLUMN_PRUNING(RuleTypeClass.REWRITE),
+
+ LOGICAL_SEMI_JOIN_LOGICAL_JOIN_TRANSPOSE(RuleTypeClass.REWRITE),
+ LOGICAL_SEMI_JOIN_LOGICAL_JOIN_TRANSPOSE_PROJECT(RuleTypeClass.REWRITE),
+ LOGICAL_SEMI_JOIN_COMMUTE(RuleTypeClass.REWRITE),
+
// expression of plan rewrite
REWRITE_ONE_ROW_RELATION_EXPRESSION(RuleTypeClass.REWRITE),
REWRITE_PROJECT_EXPRESSION(RuleTypeClass.REWRITE),
@@ -218,8 +223,6 @@ public enum RuleType {
LOGICAL_OUTER_JOIN_LASSCOM_PROJECT(RuleTypeClass.EXPLORATION),
LOGICAL_OUTER_JOIN_ASSOC(RuleTypeClass.EXPLORATION),
LOGICAL_OUTER_JOIN_ASSOC_PROJECT(RuleTypeClass.EXPLORATION),
- LOGICAL_SEMI_JOIN_LOGICAL_JOIN_TRANSPOSE(RuleTypeClass.EXPLORATION),
-
LOGICAL_SEMI_JOIN_LOGICAL_JOIN_TRANSPOSE_PROJECT(RuleTypeClass.EXPLORATION),
LOGICAL_JOIN_LOGICAL_SEMI_JOIN_TRANSPOSE(RuleTypeClass.EXPLORATION),
LOGICAL_JOIN_LOGICAL_SEMI_JOIN_TRANSPOSE_PROJECT(RuleTypeClass.EXPLORATION),
LOGICAL_SEMI_JOIN_SEMI_JOIN_TRANSPOSE(RuleTypeClass.EXPLORATION),
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinCommute.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinCommute.java
new file mode 100644
index 0000000000..176fe7190d
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinCommute.java
@@ -0,0 +1,38 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.rules.rewrite.logical;
+
+import org.apache.doris.nereids.rules.Rule;
+import org.apache.doris.nereids.rules.RuleType;
+import org.apache.doris.nereids.rules.rewrite.OneRewriteRuleFactory;
+import org.apache.doris.nereids.trees.plans.logical.LogicalJoin;
+
+/**
+ * RightSemiJoin -> LeftSemiJoin
+ */
+public class SemiJoinCommute extends OneRewriteRuleFactory {
+ @Override
+ public Rule build() {
+ return logicalJoin()
+ .when(join -> join.getJoinType().isRightSemiOrAntiJoin())
+ .whenNot(LogicalJoin::hasJoinHint)
+ .whenNot(LogicalJoin::isMarkJoin)
+ .then(join -> join.withTypeChildren(join.getJoinType().swap(),
join.right(), join.left()))
+ .toRule(RuleType.LOGICAL_SEMI_JOIN_COMMUTE);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinLogicalJoinTranspose.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinLogicalJoinTranspose.java
similarity index 77%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinLogicalJoinTranspose.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinLogicalJoinTranspose.java
index 158ff03abc..f795b5632f 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinLogicalJoinTranspose.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinLogicalJoinTranspose.java
@@ -15,14 +15,13 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.exploration.join;
+package org.apache.doris.nereids.rules.rewrite.logical;
import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleType;
-import org.apache.doris.nereids.rules.exploration.OneExplorationRuleFactory;
-import
org.apache.doris.nereids.rules.exploration.join.SemiJoinLogicalJoinTransposeProject.ContainsType;
+import org.apache.doris.nereids.rules.rewrite.OneRewriteRuleFactory;
+import
org.apache.doris.nereids.rules.rewrite.logical.SemiJoinLogicalJoinTransposeProject.ContainsType;
import org.apache.doris.nereids.trees.expressions.ExprId;
-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;
@@ -37,21 +36,10 @@ import java.util.Set;
* <li>SemiJoin(LogicalJoin(X, Y), Z) -> LogicalJoin(X, SemiJoin(Y, Z))
* </ul>
*/
-public class SemiJoinLogicalJoinTranspose extends OneExplorationRuleFactory {
-
- public static final SemiJoinLogicalJoinTranspose LEFT_DEEP = new
SemiJoinLogicalJoinTranspose(true);
-
- public static final SemiJoinLogicalJoinTranspose ALL = new
SemiJoinLogicalJoinTranspose(false);
-
- private final boolean leftDeep;
-
- public SemiJoinLogicalJoinTranspose(boolean leftDeep) {
- this.leftDeep = leftDeep;
- }
-
+public class SemiJoinLogicalJoinTranspose extends OneRewriteRuleFactory {
@Override
public Rule build() {
- return logicalJoin(logicalJoin(), group())
+ return logicalJoin(logicalJoin(), any())
.when(topJoin -> (topJoin.getJoinType().isLeftSemiOrAntiJoin()
&& (topJoin.left().getJoinType().isInnerJoin()
|| topJoin.left().getJoinType().isLeftOuterJoin()
@@ -59,10 +47,10 @@ public class SemiJoinLogicalJoinTranspose extends
OneExplorationRuleFactory {
.whenNot(topJoin -> topJoin.hasJoinHint() ||
topJoin.left().hasJoinHint())
.whenNot(LogicalJoin::isMarkJoin)
.then(topSemiJoin -> {
- LogicalJoin<GroupPlan, GroupPlan> bottomJoin =
topSemiJoin.left();
- GroupPlan a = bottomJoin.left();
- GroupPlan b = bottomJoin.right();
- GroupPlan c = topSemiJoin.right();
+ LogicalJoin<Plan, Plan> bottomJoin = topSemiJoin.left();
+ Plan a = bottomJoin.left();
+ Plan b = bottomJoin.right();
+ Plan c = topSemiJoin.right();
Set<ExprId> conjunctsIds =
topSemiJoin.getConditionExprId();
ContainsType containsType =
SemiJoinLogicalJoinTransposeProject.containsChildren(conjunctsIds,
@@ -84,9 +72,6 @@ public class SemiJoinLogicalJoinTranspose extends
OneExplorationRuleFactory {
Plan newBottomSemiJoin = topSemiJoin.withChildren(a,
c);
return bottomJoin.withChildren(newBottomSemiJoin, b);
} else {
- if (leftDeep) {
- return null;
- }
/*
* topSemiJoin newTopJoin
* / \ / \
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinLogicalJoinTransposeProject.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinLogicalJoinTransposeProject.java
similarity index 80%
rename from
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinLogicalJoinTransposeProject.java
rename to
fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinLogicalJoinTransposeProject.java
index 46aca17216..aeabe44000 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinLogicalJoinTransposeProject.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinLogicalJoinTransposeProject.java
@@ -15,13 +15,13 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.exploration.join;
+package org.apache.doris.nereids.rules.rewrite.logical;
import org.apache.doris.nereids.rules.Rule;
import org.apache.doris.nereids.rules.RuleType;
-import org.apache.doris.nereids.rules.exploration.OneExplorationRuleFactory;
+import org.apache.doris.nereids.rules.rewrite.OneRewriteRuleFactory;
import org.apache.doris.nereids.trees.expressions.ExprId;
-import org.apache.doris.nereids.trees.plans.GroupPlan;
+import org.apache.doris.nereids.trees.expressions.Slot;
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;
@@ -38,33 +38,23 @@ import java.util.Set;
* <li>SemiJoin(LogicalJoin(X, Y), Z) -> LogicalJoin(X, SemiJoin(Y, Z))
* </ul>
*/
-public class SemiJoinLogicalJoinTransposeProject extends
OneExplorationRuleFactory {
- public static final SemiJoinLogicalJoinTransposeProject LEFT_DEEP = new
SemiJoinLogicalJoinTransposeProject(true);
-
- public static final SemiJoinLogicalJoinTransposeProject ALL = new
SemiJoinLogicalJoinTransposeProject(false);
-
- private final boolean leftDeep;
-
- public SemiJoinLogicalJoinTransposeProject(boolean leftDeep) {
- this.leftDeep = leftDeep;
- }
-
+public class SemiJoinLogicalJoinTransposeProject extends OneRewriteRuleFactory
{
@Override
public Rule build() {
- return logicalJoin(logicalProject(logicalJoin()), group())
+ return logicalJoin(logicalProject(logicalJoin()), any())
.when(topJoin -> (topJoin.getJoinType().isLeftSemiOrAntiJoin()
&& (topJoin.left().child().getJoinType().isInnerJoin()
||
topJoin.left().child().getJoinType().isLeftOuterJoin()
||
topJoin.left().child().getJoinType().isRightOuterJoin())))
.whenNot(join -> join.hasJoinHint() ||
join.left().child().hasJoinHint())
.whenNot(join -> join.isMarkJoin() ||
join.left().child().isMarkJoin())
- .when(join -> JoinReorderUtils.isAllSlotProject(join.left()))
+ .when(join -> join.left().getProjects().stream().allMatch(expr
-> expr instanceof Slot))
.then(topSemiJoin -> {
- LogicalProject<LogicalJoin<GroupPlan, GroupPlan>> project
= topSemiJoin.left();
- LogicalJoin<GroupPlan, GroupPlan> bottomJoin =
project.child();
- GroupPlan a = bottomJoin.left();
- GroupPlan b = bottomJoin.right();
- GroupPlan c = topSemiJoin.right();
+ LogicalProject<LogicalJoin<Plan, Plan>> project =
topSemiJoin.left();
+ LogicalJoin<Plan, Plan> bottomJoin = project.child();
+ Plan a = bottomJoin.left();
+ Plan b = bottomJoin.right();
+ Plan c = topSemiJoin.right();
Set<ExprId> conjunctsIds =
topSemiJoin.getConditionExprId();
ContainsType containsType = containsChildren(conjunctsIds,
a.getOutputExprIdSet(),
@@ -90,9 +80,6 @@ public class SemiJoinLogicalJoinTransposeProject extends
OneExplorationRuleFacto
Plan newTopJoin =
bottomJoin.withChildren(newBottomSemiJoin, b);
return project.withChildren(newTopJoin);
} else {
- if (leftDeep) {
- return null;
- }
/*-
* topSemiJoin project
* / \ |
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinLogicalJoinTransposeTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinLogicalJoinTransposeTest.java
deleted file mode 100644
index beb2dcbb23..0000000000
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinLogicalJoinTransposeTest.java
+++ /dev/null
@@ -1,126 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.apache.doris.nereids.rules.exploration.join;
-
-import org.apache.doris.common.Pair;
-import org.apache.doris.nereids.memo.Group;
-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.trees.plans.logical.LogicalOlapScan;
-import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
-import org.apache.doris.nereids.util.LogicalPlanBuilder;
-import org.apache.doris.nereids.util.MemoTestUtils;
-import org.apache.doris.nereids.util.PlanChecker;
-import org.apache.doris.nereids.util.PlanConstructor;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-public class SemiJoinLogicalJoinTransposeTest {
- private static final LogicalOlapScan scan1 =
PlanConstructor.newLogicalOlapScan(0, "t1", 0);
- private static final LogicalOlapScan scan2 =
PlanConstructor.newLogicalOlapScan(1, "t2", 0);
- private static final LogicalOlapScan scan3 =
PlanConstructor.newLogicalOlapScan(2, "t3", 0);
-
- @Test
- public void testSemiJoinLogicalTransposeLAsscom() {
- /*
- * topSemiJoin newTopJoin
- * / \ / \
- * bottomJoin C --> newBottomSemiJoin B
- * / \ / \
- * A B A C
- */
- LogicalPlan topJoin = new LogicalPlanBuilder(scan1)
- .join(scan2, JoinType.INNER_JOIN, Pair.of(0, 0)) // t1.id =
t2.id
- .join(scan3, JoinType.LEFT_SEMI_JOIN, Pair.of(0, 0)) // t1.id
= t3.id
- .build();
-
- PlanChecker.from(MemoTestUtils.createConnectContext(), topJoin)
-
.applyExploration(SemiJoinLogicalJoinTranspose.LEFT_DEEP.build())
- .checkMemo(memo -> {
- Group root = memo.getRoot();
- Assertions.assertEquals(2,
root.getLogicalExpressions().size());
- Plan plan =
memo.copyOut(root.getLogicalExpressions().get(1), false);
-
- LogicalJoin<?, ?> newTopJoin = (LogicalJoin<?, ?>) plan;
- LogicalJoin<?, ?> newBottomJoin = (LogicalJoin<?, ?>)
newTopJoin.left();
- Assertions.assertEquals(JoinType.INNER_JOIN,
newTopJoin.getJoinType());
- Assertions.assertEquals(JoinType.LEFT_SEMI_JOIN,
newBottomJoin.getJoinType());
-
- LogicalOlapScan newBottomJoinLeft = (LogicalOlapScan)
newBottomJoin.left();
- LogicalOlapScan newBottomJoinRight = (LogicalOlapScan)
newBottomJoin.right();
- LogicalOlapScan newTopJoinRight = (LogicalOlapScan)
newTopJoin.right();
-
- Assertions.assertEquals("t1",
newBottomJoinLeft.getTable().getName());
- Assertions.assertEquals("t3",
newBottomJoinRight.getTable().getName());
- Assertions.assertEquals("t2",
newTopJoinRight.getTable().getName());
- });
- }
-
- @Test
- public void testSemiJoinLogicalTransposeLAsscomFail() {
- LogicalPlan topJoin = new LogicalPlanBuilder(scan1)
- .join(scan2, JoinType.INNER_JOIN, Pair.of(0, 0)) // t1.id =
t2.id
- .join(scan3, JoinType.LEFT_SEMI_JOIN, Pair.of(2, 0)) // t2.id
= t3.id
- .build();
-
- PlanChecker.from(MemoTestUtils.createConnectContext(), topJoin)
-
.applyExploration(SemiJoinLogicalJoinTranspose.LEFT_DEEP.build())
- .checkMemo(memo -> {
- Group root = memo.getRoot();
- Assertions.assertEquals(1,
root.getLogicalExpressions().size());
- });
- }
-
- @Test
- public void testSemiJoinLogicalTransposeAll() {
- /*
- * topSemiJoin newTopJoin
- * / \ / \
- * bottomJoin C --> A newBottomSemiJoin
- * / \ / \
- * A B B C
- */
- LogicalPlan topJoin = new LogicalPlanBuilder(scan1)
- .join(scan2, JoinType.INNER_JOIN, Pair.of(0, 0)) // t1.id =
t2.id
- .join(scan3, JoinType.LEFT_SEMI_JOIN, Pair.of(2, 0)) // t2.id
= t3.id
- .build();
-
- PlanChecker.from(MemoTestUtils.createConnectContext(), topJoin)
- .applyExploration(SemiJoinLogicalJoinTranspose.ALL.build())
- .checkMemo(memo -> {
- Group root = memo.getRoot();
- Assertions.assertEquals(2,
root.getLogicalExpressions().size());
- Plan plan =
memo.copyOut(root.getLogicalExpressions().get(1), false);
-
- LogicalJoin<?, ?> newTopJoin = (LogicalJoin<?, ?>) plan;
- LogicalJoin<?, ?> newBottomJoin = (LogicalJoin<?, ?>)
newTopJoin.right();
- Assertions.assertEquals(JoinType.INNER_JOIN,
newTopJoin.getJoinType());
- Assertions.assertEquals(JoinType.LEFT_SEMI_JOIN,
newBottomJoin.getJoinType());
-
- LogicalOlapScan newTopJoinLeft = (LogicalOlapScan)
newTopJoin.left();
- LogicalOlapScan newBottomJoinLeft = (LogicalOlapScan)
newBottomJoin.left();
- LogicalOlapScan newBottomJoinRight = (LogicalOlapScan)
newBottomJoin.right();
-
- Assertions.assertEquals("t1",
newTopJoinLeft.getTable().getName());
- Assertions.assertEquals("t2",
newBottomJoinLeft.getTable().getName());
- Assertions.assertEquals("t3",
newBottomJoinRight.getTable().getName());
- });
- }
-}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinLogicalJoinTransposeProjectTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinLogicalJoinTransposeProjectTest.java
similarity index 78%
rename from
fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinLogicalJoinTransposeProjectTest.java
rename to
fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinLogicalJoinTransposeProjectTest.java
index 7b42fe4e5d..88ba0417f0 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/exploration/join/SemiJoinLogicalJoinTransposeProjectTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinLogicalJoinTransposeProjectTest.java
@@ -15,10 +15,9 @@
// specific language governing permissions and limitations
// under the License.
-package org.apache.doris.nereids.rules.exploration.join;
+package org.apache.doris.nereids.rules.rewrite.logical;
import org.apache.doris.common.Pair;
-import org.apache.doris.nereids.memo.Group;
import org.apache.doris.nereids.trees.plans.JoinType;
import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
@@ -29,7 +28,6 @@ import org.apache.doris.nereids.util.PlanChecker;
import org.apache.doris.nereids.util.PlanConstructor;
import com.google.common.collect.ImmutableList;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class SemiJoinLogicalJoinTransposeProjectTest implements
MemoPatternMatchSupported {
@@ -38,7 +36,7 @@ class SemiJoinLogicalJoinTransposeProjectTest implements
MemoPatternMatchSupport
private static final LogicalOlapScan scan3 =
PlanConstructor.newLogicalOlapScan(2, "t3", 0);
@Test
- void testSemiJoinLogicalTransposeProjectLAsscom() {
+ void pushLeft() {
/*-
* topSemiJoin project
* / \ |
@@ -55,8 +53,8 @@ class SemiJoinLogicalJoinTransposeProjectTest implements
MemoPatternMatchSupport
.build();
PlanChecker.from(MemoTestUtils.createConnectContext(), topJoin)
-
.applyExploration(SemiJoinLogicalJoinTransposeProject.LEFT_DEEP.build())
- .matchesExploration(
+ .applyTopDown(new SemiJoinLogicalJoinTransposeProject())
+ .matchesFromRoot(
logicalProject(
innerLogicalJoin(
leftSemiLogicalJoin(
@@ -70,23 +68,7 @@ class SemiJoinLogicalJoinTransposeProjectTest implements
MemoPatternMatchSupport
}
@Test
- void testSemiJoinLogicalTransposeProjectLAsscomFail() {
- LogicalPlan topJoin = new LogicalPlanBuilder(scan1)
- .join(scan2, JoinType.INNER_JOIN, Pair.of(0, 0)) // t1.id =
t2.id
- .project(ImmutableList.of(0, 2)) // t1.id, t2.id
- .join(scan3, JoinType.LEFT_SEMI_JOIN, Pair.of(1, 0)) // t2.id
= t3.id
- .build();
-
- PlanChecker.from(MemoTestUtils.createConnectContext(), topJoin)
-
.applyExploration(SemiJoinLogicalJoinTransposeProject.LEFT_DEEP.build())
- .checkMemo(memo -> {
- Group root = memo.getRoot();
- Assertions.assertEquals(1,
root.getLogicalExpressions().size());
- });
- }
-
- @Test
- void testSemiJoinLogicalTransposeProjectAll() {
+ void pushRight() {
/*-
* topSemiJoin project
* / \ |
@@ -103,8 +85,8 @@ class SemiJoinLogicalJoinTransposeProjectTest implements
MemoPatternMatchSupport
.build();
PlanChecker.from(MemoTestUtils.createConnectContext(), topJoin)
-
.applyExploration(SemiJoinLogicalJoinTransposeProject.ALL.build())
- .matchesExploration(
+ .applyTopDown(new SemiJoinLogicalJoinTransposeProject())
+ .matchesFromRoot(
logicalProject(
logicalJoin(
logicalOlapScan().when(scan ->
scan.getTable().getName().equals("t1")),
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinLogicalJoinTransposeTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinLogicalJoinTransposeTest.java
new file mode 100644
index 0000000000..cccb8890b7
--- /dev/null
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/rules/rewrite/logical/SemiJoinLogicalJoinTransposeTest.java
@@ -0,0 +1,96 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.nereids.rules.rewrite.logical;
+
+import org.apache.doris.common.Pair;
+import org.apache.doris.nereids.memo.Group;
+import org.apache.doris.nereids.trees.plans.JoinType;
+import org.apache.doris.nereids.trees.plans.logical.LogicalOlapScan;
+import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
+import org.apache.doris.nereids.util.LogicalPlanBuilder;
+import org.apache.doris.nereids.util.MemoPatternMatchSupported;
+import org.apache.doris.nereids.util.MemoTestUtils;
+import org.apache.doris.nereids.util.PlanChecker;
+import org.apache.doris.nereids.util.PlanConstructor;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class SemiJoinLogicalJoinTransposeTest implements
MemoPatternMatchSupported {
+ private static final LogicalOlapScan scan1 =
PlanConstructor.newLogicalOlapScan(0, "t1", 0);
+ private static final LogicalOlapScan scan2 =
PlanConstructor.newLogicalOlapScan(1, "t2", 0);
+ private static final LogicalOlapScan scan3 =
PlanConstructor.newLogicalOlapScan(2, "t3", 0);
+
+ @Test
+ public void pushLeft() {
+ /*
+ * topSemiJoin newTopJoin
+ * / \ / \
+ * bottomJoin C --> newBottomSemiJoin B
+ * / \ / \
+ * A B A C
+ */
+ LogicalPlan topJoin = new LogicalPlanBuilder(scan1)
+ .join(scan2, JoinType.INNER_JOIN, Pair.of(0, 0)) // t1.id =
t2.id
+ .join(scan3, JoinType.LEFT_SEMI_JOIN, Pair.of(0, 0)) // t1.id
= t3.id
+ .build();
+
+ PlanChecker.from(MemoTestUtils.createConnectContext(), topJoin)
+ .applyTopDown(new SemiJoinLogicalJoinTranspose())
+ .matchesFromRoot(
+ innerLogicalJoin(
+ leftSemiLogicalJoin(
+ logicalOlapScan().when(scan ->
scan.getTable().getName().equals("t1")),
+ logicalOlapScan().when(scan ->
scan.getTable().getName().equals("t3"))
+ ),
+ logicalOlapScan().when(scan ->
scan.getTable().getName().equals("t2"))
+ )
+ );
+ }
+
+ @Test
+ public void pushRight() {
+ /*
+ * topSemiJoin newTopJoin
+ * / \ / \
+ * bottomJoin C --> A newBottomSemiJoin
+ * / \ / \
+ * A B B C
+ */
+ LogicalPlan topJoin = new LogicalPlanBuilder(scan1)
+ .join(scan2, JoinType.INNER_JOIN, Pair.of(0, 0)) // t1.id =
t2.id
+ .join(scan3, JoinType.LEFT_SEMI_JOIN, Pair.of(2, 0)) // t2.id
= t3.id
+ .build();
+
+ PlanChecker.from(MemoTestUtils.createConnectContext(), topJoin)
+ .applyTopDown(new SemiJoinLogicalJoinTranspose())
+ .checkMemo(memo -> {
+ Group root = memo.getRoot();
+ Assertions.assertEquals(1,
root.getLogicalExpressions().size());
+ })
+ .matchesFromRoot(
+ innerLogicalJoin(
+ logicalOlapScan().when(scan ->
scan.getTable().getName().equals("t1")),
+ leftSemiLogicalJoin(
+ logicalOlapScan().when(scan ->
scan.getTable().getName().equals("t2")),
+ logicalOlapScan().when(scan ->
scan.getTable().getName().equals("t3"))
+ )
+ )
+ );
+ }
+}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/sqltest/InferTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/sqltest/InferTest.java
index 48b5026d1e..010a920023 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/nereids/sqltest/InferTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/sqltest/InferTest.java
@@ -82,10 +82,8 @@ public class InferTest extends SqlTestBase {
.analyze(sql)
.rewrite()
.matches(
- leftSemiLogicalJoin(
- logicalProject(
- innerLogicalJoin()
- ),
+ innerLogicalJoin(
+ leftSemiLogicalJoin(),
logicalProject()
)
);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]