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>

Reply via email to