You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jc...@apache.org on 2020/02/27 04:52:24 UTC

[calcite] 02/02: [CALCITE-3824] JoinProjectTransposeRule should skip Projects containing windowing expression (Vineet Garg)

This is an automated email from the ASF dual-hosted git repository.

jcamacho pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git

commit 8f39d6d136c427afeed108c5b499331c1c84bbdf
Author: Vineet Garg <vg...@apache.org>
AuthorDate: Tue Feb 25 18:06:34 2020 -0800

    [CALCITE-3824] JoinProjectTransposeRule should skip Projects containing windowing expression (Vineet Garg)
    
    Close apache/calcite#1830
---
 .../rel/rules/JoinProjectTransposeRule.java        | 12 ++++++++++
 .../org/apache/calcite/test/RelOptRulesTest.java   |  9 +++++++
 .../org/apache/calcite/test/RelOptRulesTest.xml    | 28 ++++++++++++++++++++++
 3 files changed, 49 insertions(+)

diff --git a/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java
index b777028..a93fd22 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/JoinProjectTransposeRule.java
@@ -35,6 +35,7 @@ import org.apache.calcite.rel.type.RelDataTypeField;
 import org.apache.calcite.rex.RexBuilder;
 import org.apache.calcite.rex.RexLocalRef;
 import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexOver;
 import org.apache.calcite.rex.RexProgram;
 import org.apache.calcite.rex.RexProgramBuilder;
 import org.apache.calcite.sql.validate.SqlValidatorUtil;
@@ -168,6 +169,17 @@ public class JoinProjectTransposeRule extends RelOptRule {
       rightProj = null;
       rightJoinChild = joinRel.getRight();
     }
+
+    // Skip projects containing over clause
+    if (leftProj != null && RexOver.containsOver(leftProj.getChildExps(), null)) {
+      leftProj = null;
+      leftJoinChild = joinRel.getLeft();
+    }
+    if (rightProj != null && RexOver.containsOver(rightProj.getChildExps(), null)) {
+      rightProj = null;
+      rightJoinChild = joinRel.getRight();
+    }
+
     if ((leftProj == null) && (rightProj == null)) {
       return;
     }
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 970c228..4654cc5 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -887,6 +887,15 @@ public class RelOptRulesTest extends RelOptTestBase {
         .check();
   }
 
+  @Test public void testJoinProjectTransposeWindow() {
+    final String sql = "select *\n"
+        + "from dept a\n"
+        + "join (select rank() over (order by name) as r, 1 + 1 from dept) as b\n"
+        + "on a.name = b.r";
+    sql(sql)
+        .withRule(JoinProjectTransposeRule.BOTH_PROJECT)
+        .check();
+  }
 
   /**
    * Test case for
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 1e1848d..76c9310 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -3622,6 +3622,34 @@ LogicalIntersect(all=[true])
 ]]>
         </Resource>
     </TestCase>
+    <TestCase name="testJoinProjectTransposeWindow">
+        <Resource name="sql">
+            <![CDATA[select *
+from dept a
+join (select rank() over (order by name) as r, 1 + 1 from dept) as b
+on a.name = b.r]]>
+        </Resource>
+        <Resource name="planBefore">
+            <![CDATA[
+LogicalProject(DEPTNO=[$0], NAME=[$1], R=[$3], EXPR$1=[$4])
+  LogicalJoin(condition=[=($2, $3)], joinType=[inner])
+    LogicalProject(DEPTNO=[$0], NAME=[$1], NAME0=[CAST($1):BIGINT NOT NULL])
+      LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+    LogicalProject(R=[RANK() OVER (ORDER BY $1 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)], EXPR$1=[+(1, 1)])
+      LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+        </Resource>
+        <Resource name="planAfter">
+            <![CDATA[
+LogicalProject(DEPTNO=[$0], NAME=[$1], R=[$3], EXPR$1=[$4])
+  LogicalProject(DEPTNO=[$0], NAME=[$1], NAME0=[CAST($1):BIGINT NOT NULL], R=[$2], EXPR$1=[$3])
+    LogicalJoin(condition=[=(CAST($1):BIGINT NOT NULL, $2)], joinType=[inner])
+      LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+      LogicalProject(R=[RANK() OVER (ORDER BY $1 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)], EXPR$1=[+(1, 1)])
+        LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+]]>
+        </Resource>
+    </TestCase>
     <TestCase name="testJoinPushTransitivePredicatesRule">
         <Resource name="sql">
             <![CDATA[select d.deptno from sales.emp d where d.deptno