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

mbudiu 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 7481b85049 Check for correlation variables in project when 
constructing aggregate in SqlToRelConverter.createAggImpl
7481b85049 is described below

commit 7481b85049193a0342a4da1774d0d750752b5ac9
Author: Ian Bertolacci <[email protected]>
AuthorDate: Wed Aug 28 11:55:07 2024 -0700

    Check for correlation variables in project when constructing aggregate in 
SqlToRelConverter.createAggImpl
---
 .../apache/calcite/sql2rel/SqlToRelConverter.java  | 24 +++++--
 .../apache/calcite/test/SqlToRelConverterTest.java | 40 +++++++++++
 .../apache/calcite/test/SqlToRelConverterTest.xml  | 81 ++++++++++++++++++++++
 core/src/test/resources/sql/sub-query.iq           | 47 +++++++++++++
 4 files changed, 187 insertions(+), 5 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java 
b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index 12222b218b..b4f572d04c 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -3580,11 +3580,25 @@ public class SqlToRelConverter {
       final RelNode inputRel = bb.root();
 
       // Project the expressions required by agg and having.
-      bb.setRoot(
-          relBuilder.push(inputRel)
-              .projectNamed(preExprs.leftList(), preExprs.rightList(), false)
-              .build(),
-          false);
+      RelNode intermediateProject = relBuilder.push(inputRel)
+          .projectNamed(preExprs.leftList(), preExprs.rightList(), false)
+          .build();
+      final RelNode r2;
+      // deal with correlation
+      final CorrelationUse p = getCorrelationUse(bb, intermediateProject);
+      if (p != null) {
+        assert p.r instanceof Project;
+        // correlation variables have been normalized in p.r, we should use 
expressions
+        // in p.r instead of the original exprs
+        Project project1 = (Project) p.r;
+        r2 = relBuilder.push(bb.root())
+            .projectNamed(project1.getProjects(), 
project1.getRowType().getFieldNames(),
+                true, ImmutableSet.of(p.id))
+            .build();
+      } else {
+        r2 = intermediateProject;
+      }
+      bb.setRoot(r2, false);
       bb.mapRootRelToFieldProjection.put(bb.root(), r.groupExprProjection);
 
       // REVIEW jvs 31-Oct-2007:  doesn't the declaration of
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 7e4819aee4..345db9eb62 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -3770,6 +3770,46 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
     sql(sql).withExpand(false).withDecorrelate(false).ok();
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6554";>[CALCITE-6554]
+   * Nested correlated sub-query in aggregation does not have inner 
correlation variable bound
+   * to inner projection</a>. */
+  @Test void testCorrelationInProjectionWith1xNestedCorrelatedProjection() {
+    final String sql = "select e1.empno,\n"
+          + "  (select sum(e2.sal +\n"
+          + "    (select sum(e3.sal) from emp e3 where e3.mgr = e2.empno)\n"
+          + "   ) from emp e2 where e2.mgr = e1.empno)\n"
+          + "from emp e1";
+    sql(sql).withExpand(false).withDecorrelate(false).ok();
+  }
+
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6554";>[CALCITE-6554]
+   * Nested correlated sub-query in aggregation does not have inner 
correlation variable bound
+   * to inner projection</a>. */
+  @Test void testCorrelationInProjectionWith2xNestedCorrelatedProjection() {
+    final String sql = "select e1.empno,\n"
+        + "  (select sum(e2.sal +\n"
+        + "    (select sum(e3.sal + (select sum(e4.sal) from emp e4 where 
e4.mgr = e3.empno)\n"
+        + "      ) from emp e3 where e3.mgr = e2.empno)\n"
+        + "   ) from emp e2 where e2.mgr = e1.empno)\n"
+        + "from emp e1";
+    sql(sql).withExpand(false).withDecorrelate(false).ok();
+  }
+
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6554";>[CALCITE-6554]
+   * Nested correlated sub-query in aggregation does not have inner 
correlation variable bound
+   * to inner projection</a>. */
+  @Test void 
testCorrelationInProjectionWithCorrelatedProjectionWithNestedNonCorrelatedSubquery()
 {
+    final String sql = "select e1.empno,\n"
+        + "  (select sum(e2.sal +\n"
+        + "    (select sum(e3.sal) from emp e3 where e3.mgr = e1.empno)\n"
+        + "   ) from emp e2 where e2.mgr = e1.empno)\n"
+        + "from emp e1";
+    sql(sql).withExpand(false).withDecorrelate(false).ok();
+  }
+
   @Test void testCustomColumnResolving() {
     final String sql = "select k0 from struct.t";
     sql(sql).ok();
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 4946f20873..3feb6be58a 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -1128,6 +1128,62 @@ where exists (select * from emp
   and emp.deptno in (dept.deptno, dept.deptno))]]>
     </Resource>
   </TestCase>
+  <TestCase name="testCorrelationInProjectionWith1xNestedCorrelatedProjection">
+    <Resource name="sql">
+      <![CDATA[select e1.empno,
+  (select sum(e2.sal +
+    (select sum(e3.sal) from emp e3 where e3.mgr = e2.empno)
+   ) from emp e2 where e2.mgr = e1.empno)
+from emp e1]]>
+    </Resource>
+    <Resource name="plan">
+      <![CDATA[
+LogicalProject(variablesSet=[[$cor0]], EMPNO=[$0], EXPR$1=[$SCALAR_QUERY({
+LogicalAggregate(group=[{}], EXPR$0=[SUM($0)])
+  LogicalProject(variablesSet=[[$cor1]], $f0=[+($5, $SCALAR_QUERY({
+LogicalAggregate(group=[{}], EXPR$0=[SUM($0)])
+  LogicalProject(SAL=[$5])
+    LogicalFilter(condition=[=($3, $cor1.EMPNO)])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+}))])
+    LogicalFilter(condition=[=($3, $cor0.EMPNO)])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+})])
+  LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase name="testCorrelationInProjectionWith2xNestedCorrelatedProjection">
+    <Resource name="sql">
+      <![CDATA[select e1.empno,
+  (select sum(e2.sal +
+    (select sum(e3.sal + (select sum(e4.sal) from emp e4 where e4.mgr = 
e3.empno)
+      ) from emp e3 where e3.mgr = e2.empno)
+   ) from emp e2 where e2.mgr = e1.empno)
+from emp e1]]>
+    </Resource>
+    <Resource name="plan">
+      <![CDATA[
+LogicalProject(variablesSet=[[$cor0]], EMPNO=[$0], EXPR$1=[$SCALAR_QUERY({
+LogicalAggregate(group=[{}], EXPR$0=[SUM($0)])
+  LogicalProject(variablesSet=[[$cor1]], $f0=[+($5, $SCALAR_QUERY({
+LogicalAggregate(group=[{}], EXPR$0=[SUM($0)])
+  LogicalProject(variablesSet=[[$cor2]], $f0=[+($5, $SCALAR_QUERY({
+LogicalAggregate(group=[{}], EXPR$0=[SUM($0)])
+  LogicalProject(SAL=[$5])
+    LogicalFilter(condition=[=($3, $cor2.EMPNO)])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+}))])
+    LogicalFilter(condition=[=($3, $cor1.EMPNO)])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+}))])
+    LogicalFilter(condition=[=($3, $cor0.EMPNO)])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+})])
+  LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+    </Resource>
+  </TestCase>
   <TestCase name="testCorrelationInProjectionWithCorrelatedProjection">
     <Resource name="sql">
       <![CDATA[select cardinality(arr) from (
@@ -1142,6 +1198,31 @@ LogicalProject(DEPTNO=[$cor0.DEPTNO])
 }))])
   LogicalProject(DEPTNO=[$7], ENAME=[$1])
     LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+]]>
+    </Resource>
+  </TestCase>
+  <TestCase 
name="testCorrelationInProjectionWithCorrelatedProjectionWithNestedNonCorrelatedSubquery">
+    <Resource name="sql">
+      <![CDATA[select e1.empno,
+  (select sum(e2.sal +
+    (select sum(e3.sal) from emp e3 where e3.mgr = e1.empno)
+   ) from emp e2 where e2.mgr = e1.empno)
+from emp e1]]>
+    </Resource>
+    <Resource name="plan">
+      <![CDATA[
+LogicalProject(variablesSet=[[$cor1]], EMPNO=[$0], EXPR$1=[$SCALAR_QUERY({
+LogicalAggregate(group=[{}], EXPR$0=[SUM($0)])
+  LogicalProject($f0=[+($5, $SCALAR_QUERY({
+LogicalAggregate(group=[{}], EXPR$0=[SUM($0)])
+  LogicalProject(SAL=[$5])
+    LogicalFilter(condition=[=($3, $cor1.EMPNO)])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+}))])
+    LogicalFilter(condition=[=($3, $cor1.EMPNO)])
+      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+})])
+  LogicalTableScan(table=[[CATALOG, SALES, EMP]])
 ]]>
     </Resource>
   </TestCase>
diff --git a/core/src/test/resources/sql/sub-query.iq 
b/core/src/test/resources/sql/sub-query.iq
index 27e3321b84..7bfedac3a8 100644
--- a/core/src/test/resources/sql/sub-query.iq
+++ b/core/src/test/resources/sql/sub-query.iq
@@ -668,6 +668,53 @@ FROM (SELECT 1 AS a) AS t;
 
 !ok
 
+# [CALCITE-6554] nested correlated sub-query in aggregation does not have 
inner correlation variable bound to inner projection
+SELECT ename,
+       (SELECT Sum(sal + COALESCE((SELECT Sum(sal) FROM "scott".emp AS subord2
+                   WHERE
+                           subord2.mgr =
+                           subord.empno), 0))
+        FROM   "scott".emp AS subord
+        WHERE  subord.mgr = bosses.empno) AS deep2sal
+FROM   "scott".emp AS bosses;
++--------+----------+
+| ENAME  | DEEP2SAL |
++--------+----------+
+| ADAMS  |          |
+| ALLEN  |          |
+| BLAKE  |  6550.00 |
+| CLARK  |  1300.00 |
+| FORD   |   800.00 |
+| JAMES  |          |
+| JONES  |  7900.00 |
+| KING   | 22125.00 |
+| MARTIN |          |
+| MILLER |          |
+| SCOTT  |  1100.00 |
+| SMITH  |          |
+| TURNER |          |
+| WARD   |          |
++--------+----------+
+(14 rows)
+
+!ok
+
+EnumerableCalc(expr#0..3=[{inputs}], ENAME=[$t1], DEEP2SAL=[$t3])
+  EnumerableMergeJoin(condition=[=($0, $2)], joinType=[left])
+    EnumerableCalc(expr#0..7=[{inputs}], proj#0..1=[{exprs}])
+      EnumerableTableScan(table=[[scott, EMP]])
+    EnumerableSort(sort0=[$0], dir0=[ASC])
+      EnumerableAggregate(group=[{0}], EXPR$0=[SUM($1)])
+        EnumerableCalc(expr#0..4=[{inputs}], expr#5=[IS NOT NULL($t4)], 
expr#6=[0.00:DECIMAL(19, 2)], expr#7=[CASE($t5, $t4, $t6)], expr#8=[+($t2, 
$t7)], MGR9=[$t1], $f0=[$t8])
+          EnumerableMergeJoin(condition=[=($0, $3)], joinType=[left])
+            EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NOT NULL($t3)], 
EMPNO=[$t0], MGR=[$t3], SAL=[$t5], $condition=[$t8])
+              EnumerableTableScan(table=[[scott, EMP]])
+            EnumerableSort(sort0=[$0], dir0=[ASC])
+              EnumerableAggregate(group=[{3}], EXPR$0=[SUM($5)])
+                EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NOT 
NULL($t3)], proj#0..7=[{exprs}], $condition=[$t8])
+                  EnumerableTableScan(table=[[scott, EMP]])
+!plan
+
 # [CALCITE-1494] Inefficient plan for correlated sub-queries
 # Plan must have only one scan each of emp and dept.
 select sal

Reply via email to