This is an automated email from the ASF dual-hosted git repository.
zabetak pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push:
new c1ca226587 [CALCITE-6737] LoptOptimizeJoinRule can not identify
selfjoin on unique join keys
c1ca226587 is described below
commit c1ca2265873b9c964f2511a2612c4360dd14b936
Author: Krisztian Kasa <[email protected]>
AuthorDate: Wed Dec 18 13:44:10 2024 +0100
[CALCITE-6737] LoptOptimizeJoinRule can not identify selfjoin on unique
join keys
---
.../apache/calcite/rel/rules/LoptMultiJoin.java | 4 ++--
.../calcite/rel/rules/LoptOptimizeJoinRule.java | 4 ++--
.../org/apache/calcite/test/RelOptRulesTest.java | 13 +++++++++++
.../org/apache/calcite/test/RelOptRulesTest.xml | 25 ++++++++++++++++++++++
4 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/LoptMultiJoin.java
b/core/src/main/java/org/apache/calcite/rel/rules/LoptMultiJoin.java
index 1aa93d7b59..f76f74e75e 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/LoptMultiJoin.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/LoptMultiJoin.java
@@ -720,7 +720,7 @@ public class LoptMultiJoin {
final Map<Integer, Integer> leftFactorColMapping = new HashMap<>();
for (int i = 0; i < left.getRowType().getFieldCount(); i++) {
final RelColumnOrigin colOrigin = mq.getColumnOrigin(left, i);
- if (colOrigin != null && colOrigin.isDerived()) {
+ if (colOrigin != null && !colOrigin.isDerived()) {
leftFactorColMapping.put(
colOrigin.getOriginColumnOrdinal(),
i);
@@ -734,7 +734,7 @@ public class LoptMultiJoin {
RelNode right = getJoinFactor(rightFactor);
for (int i = 0; i < right.getRowType().getFieldCount(); i++) {
final RelColumnOrigin colOrigin = mq.getColumnOrigin(right, i);
- if (colOrigin == null || !colOrigin.isDerived()) {
+ if (colOrigin == null || colOrigin.isDerived()) {
continue;
}
Integer leftOffset =
diff --git
a/core/src/main/java/org/apache/calcite/rel/rules/LoptOptimizeJoinRule.java
b/core/src/main/java/org/apache/calcite/rel/rules/LoptOptimizeJoinRule.java
index 48b129aaaa..90a0c9be82 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/LoptOptimizeJoinRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/LoptOptimizeJoinRule.java
@@ -2067,12 +2067,12 @@ public class LoptOptimizeJoinRule
for (IntPair pair : joinInfo.pairs()) {
final RelColumnOrigin leftOrigin =
mq.getColumnOrigin(leftRel, pair.source);
- if (leftOrigin == null || !leftOrigin.isDerived()) {
+ if (leftOrigin == null || leftOrigin.isDerived()) {
return false;
}
final RelColumnOrigin rightOrigin =
mq.getColumnOrigin(rightRel, pair.target);
- if (rightOrigin == null || !rightOrigin.isDerived()) {
+ if (rightOrigin == null || rightOrigin.isDerived()) {
return false;
}
if (leftOrigin.getOriginColumnOrdinal()
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 8b57500eec..680c8298a1 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -9480,4 +9480,17 @@ class RelOptRulesTest extends RelOptTestBase {
.check();
}
+ @Test void testLoptOptimizeJoinRulePrioritizeSelfJoin() {
+ HepProgram program = new HepProgramBuilder()
+ .addMatchOrder(HepMatchOrder.BOTTOM_UP)
+ .addRuleInstance(CoreRules.JOIN_TO_MULTI_JOIN)
+ .build();
+
+ sql("select e.empno from emp e"
+ + " inner join dept d on d.deptno = e.deptno"
+ + " inner join emp e2 on e.empno = e2.empno")
+ .withPre(program)
+ .withRule(CoreRules.MULTI_JOIN_OPTIMIZE)
+ .check();
+ }
}
diff --git
a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index 5f08355a97..fba6338e05 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -6794,6 +6794,31 @@ EnumerableLimitSort(sort0=[$0], dir0=[ASC], offset=[5],
fetch=[10])
EnumerableTableScan(table=[[CATALOG, SALES, EMP]])
EnumerableProject(MGR=[$3])
EnumerableTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ </TestCase>
+ <TestCase name="testLoptOptimizeJoinRulePrioritizeSelfJoin">
+ <Resource name="sql">
+ <![CDATA[select e.empno from emp e inner join dept d on d.deptno =
e.deptno inner join emp e2 on e.empno = e2.empno]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject(EMPNO=[$0])
+ MultiJoin(joinFilter=[AND(=($0, $11), =($9, $7))], isFullOuterJoin=[false],
joinTypes=[[INNER, INNER, INNER]], outerJoinConditions=[[NULL, NULL, NULL]],
projFields=[[ALL, ALL, ALL]])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+LogicalProject(EMPNO=[$0])
+ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4],
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[$18], NAME=[$19],
EMPNO0=[$0], ENAME0=[$1], JOB0=[$2], MGR0=[$3], HIREDATE0=[$4], SAL0=[$5],
COMM0=[$6], DEPTNO1=[$7], SLACKER0=[$8])
+ LogicalJoin(condition=[=($18, $7)], joinType=[inner])
+ LogicalJoin(condition=[=($9, $0)], joinType=[inner])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+ LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
]]>
</Resource>
</TestCase>