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>