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

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


The following commit(s) were added to refs/heads/master by this push:
     new 6842b70  [CALCITE-4206] RelDecorrelator outputs wrong plan for 
correlate sort with fetch limit
6842b70 is described below

commit 6842b70b52d556f2be973df6090e0cb69d5f565d
Author: yuzhao.cyz <[email protected]>
AuthorDate: Tue Sep 1 19:46:27 2020 +0800

    [CALCITE-4206] RelDecorrelator outputs wrong plan for correlate sort with 
fetch limit
    
    Can not decorrelate if the sort has per-correlate-key attributes like
    offset or fetch limit, because these attributes scope would
    change to global after decorrelation. They should take effect within
    the scope of the correlation key actually.
---
 .../apache/calcite/sql2rel/RelDecorrelator.java    | 12 ++++--
 .../apache/calcite/test/SqlToRelConverterTest.java | 17 ++++++++
 .../apache/calcite/test/SqlToRelConverterTest.xml  | 45 ++++++++++++++++++----
 3 files changed, 62 insertions(+), 12 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java 
b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
index 161439f..3c4020d 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelDecorrelator.java
@@ -438,6 +438,13 @@ public class RelDecorrelator implements ReflectiveVisitor {
       // If input has not been rewritten, do not rewrite this rel.
       return null;
     }
+    // Can not decorrelate if the sort has per-correlate-key attributes like
+    // offset or fetch limit, because these attributes scope would change to
+    // global after decorrelation. They should take effect within the scope
+    // of the correlation key actually.
+    if (rel.offset != null || rel.fetch != null) {
+      return null;
+    }
     final RelNode newInput = frame.r;
 
     Mappings.TargetMapping mapping =
@@ -448,12 +455,9 @@ public class RelDecorrelator implements ReflectiveVisitor {
     RelCollation oldCollation = rel.getCollation();
     RelCollation newCollation = RexUtil.apply(mapping, oldCollation);
 
-    final int offset = rel.offset == null ? -1 : 
RexLiteral.intValue(rel.offset);
-    final int fetch = rel.fetch == null ? -1 : RexLiteral.intValue(rel.fetch);
-
     final RelNode newSort = relBuilder
             .push(newInput)
-            .sortLimit(offset, fetch, relBuilder.fields(newCollation))
+            .sortLimit(-1, -1, relBuilder.fields(newCollation))
             .build();
 
     // Sort does not change input ordering
diff --git 
a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java 
b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
index 38053e1..ea756cc 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -1247,6 +1247,23 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
     sql(sql).ok();
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-4206";>[CALCITE-4206]
+   * RelDecorrelator outputs wrong plan for correlate sort with fetch 
limit</a>. */
+  @Test void testCorrelateSortWithLimit() {
+    final String sql = "SELECT deptno, ename \n"
+        + "FROM\n"
+        + "  (SELECT DISTINCT deptno FROM emp) t1,\n"
+        + "  LATERAL (\n"
+        + "    SELECT ename, sal\n"
+        + "    FROM emp\n"
+        + "    WHERE deptno = t1.deptno\n"
+        + "    ORDER BY sal\n"
+        + "    DESC LIMIT 3\n"
+        + "  )";
+    sql(sql).ok();
+  }
+
   @Test void testSample() {
     final String sql =
         "select * from emp tablesample substitute('DATASET1') where empno > 5";
diff --git 
a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml 
b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
index c3d2d74..b1eab2a 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -521,6 +521,33 @@ LogicalProject(DEPTNO=[$0], NUM=[$2])
 ]]>
         </Resource>
     </TestCase>
+    <TestCase name="testCorrelateSortWithLimit">
+        <Resource name="sql">
+            <![CDATA[SELECT deptno, ename
+FROM
+  (SELECT DISTINCT deptno FROM emp) t1,
+  LATERAL (
+    SELECT ename, sal
+    FROM emp
+    WHERE deptno = t1.deptno
+    ORDER BY sal
+    DESC LIMIT 3
+  )]]>
+        </Resource>
+        <Resource name="plan">
+            <![CDATA[
+LogicalProject(DEPTNO=[$0], ENAME=[$1])
+  LogicalCorrelate(correlation=[$cor0], joinType=[inner], 
requiredColumns=[{0}])
+    LogicalAggregate(group=[{0}])
+      LogicalProject(DEPTNO=[$7])
+        LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+    LogicalSort(sort0=[$1], dir0=[DESC], fetch=[3])
+      LogicalProject(ENAME=[$1], SAL=[$5])
+        LogicalFilter(condition=[=($7, $cor0.DEPTNO)])
+          LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+        </Resource>
+    </TestCase>
     <TestCase name="testCorrelatedSubQueryInAggregate">
         <Resource name="sql">
             <![CDATA[SELECT SUM(
@@ -2529,14 +2556,16 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], 
MGR=[$3], HIREDATE=[$4], SAL=[$
         <Resource name="plan">
             <![CDATA[
 LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8])
-  LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], DEPTNO0=[CAST($9):INTEGER], 
$f1=[CAST($10):BOOLEAN])
-    LogicalJoin(condition=[=($7, $9)], joinType=[inner])
-      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
-      LogicalAggregate(group=[{0}], agg#0=[MIN($1)])
-        LogicalProject(DEPTNO=[$1], $f0=[true])
-          LogicalSort(fetch=[1])
-            LogicalProject(EXPR$0=[1], DEPTNO=[$0])
-              LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
+  LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], 
SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], $f0=[$9])
+    LogicalFilter(condition=[IS NOT NULL($9)])
+      LogicalCorrelate(correlation=[$cor0], joinType=[left], 
requiredColumns=[{7}])
+        LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+        LogicalAggregate(group=[{}], agg#0=[MIN($0)])
+          LogicalProject($f0=[true])
+            LogicalSort(fetch=[1])
+              LogicalProject(EXPR$0=[1])
+                LogicalFilter(condition=[=($cor0.DEPTNO, $0)])
+                  LogicalTableScan(table=[[CATALOG, SALES, DEPT]])
 ]]>
         </Resource>
     </TestCase>

Reply via email to