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

xiong 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 d336724daa [CALCITE-6785] RelToSqlConverter generate wrong sql when 
UNNEST has a correlate variable
d336724daa is described below

commit d336724daacbc68b7823f4c02b14f890b052f4f0
Author: Xiong Duan <[email protected]>
AuthorDate: Sun Jan 19 09:32:47 2025 +0800

    [CALCITE-6785] RelToSqlConverter generate wrong sql when UNNEST has a 
correlate variable
---
 .../calcite/rel/rel2sql/RelToSqlConverter.java     | 30 +++++++++++++++++-----
 .../org/apache/calcite/sql/SqlLateralOperator.java |  2 +-
 .../rel/rel2sql/RelToSqlConverterStructsTest.java  |  2 +-
 .../calcite/rel/rel2sql/RelToSqlConverterTest.java | 22 ++++++++++++++++
 .../java/org/apache/calcite/test/PigRelOpTest.java |  6 ++---
 5 files changed, 50 insertions(+), 12 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java 
b/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
index 353e2fa3a4..b171d88d03 100644
--- a/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
+++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
@@ -405,13 +405,29 @@ public Result visit(Correlate e) {
             .resetAlias(e.getCorrelVariable(), e.getInput(0).getRowType());
     parseCorrelTable(e, leftResult);
     final Result rightResult = visitInput(e, 1);
-    final SqlNode rightLateral =
-        SqlStdOperatorTable.LATERAL.createCall(POS, rightResult.node);
-    final SqlNode rightLateralAs =
-        SqlStdOperatorTable.AS.createCall(POS, rightLateral,
-            new SqlIdentifier(
-                requireNonNull(rightResult.neededAlias,
-                    () -> "rightResult.neededAlias is null, node is " + 
rightResult.node), POS));
+    final SqlNode rightResultNode = rightResult.node;
+    final SqlIdentifier id =
+        new SqlIdentifier(
+            requireNonNull(rightResult.neededAlias,
+                () -> "rightResult.neededAlias is null, node is " + 
rightResultNode), POS);
+    SqlNode rightLateral =
+        SqlStdOperatorTable.LATERAL.createCall(POS, rightResultNode);
+    SqlNode rightLateralAs;
+    if (rightResultNode.getKind() == SqlKind.AS) {
+      // If node already is an AS node, we need to replace the alias
+      // For example:
+      // Before: AS "t1" ("xs") AS "t10"
+      // Now:AS "t10" ("xs")
+      SqlCall sqlRightCall = (SqlCall) rightResultNode;
+      List<SqlNode> operands = new ArrayList<>(sqlRightCall.getOperandList());
+      rightLateral =
+          SqlStdOperatorTable.LATERAL.createCall(POS, operands.get(0));
+      operands.set(0, rightLateral);
+      operands.set(1, id);
+      rightLateralAs =  SqlStdOperatorTable.AS.createCall(POS, operands);
+    } else {
+      rightLateralAs =  SqlStdOperatorTable.AS.createCall(POS, rightLateral, 
id);
+    }
 
     final SqlNode join =
         new SqlJoin(POS,
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlLateralOperator.java 
b/core/src/main/java/org/apache/calcite/sql/SqlLateralOperator.java
index f515e5d335..437343a7fc 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlLateralOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlLateralOperator.java
@@ -39,7 +39,7 @@ public SqlLateralOperator(SqlKind kind) {
   @Override public void unparse(SqlWriter writer, SqlCall call, int leftPrec,
       int rightPrec) {
     final Set<SqlKind> specialOperandKinds =
-        ImmutableSet.of(SqlKind.COLLECTION_TABLE, SqlKind.SELECT, SqlKind.AS);
+        ImmutableSet.of(SqlKind.COLLECTION_TABLE, SqlKind.SELECT, SqlKind.AS, 
SqlKind.UNNEST);
     if (call.operandCount() == 1
         && specialOperandKinds.contains(call.operand(0).getKind())) {
       // Do not create ( ) around the following TABLE clause.
diff --git 
a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterStructsTest.java
 
b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterStructsTest.java
index ccc422da83..ee7f6cae47 100644
--- 
a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterStructsTest.java
+++ 
b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterStructsTest.java
@@ -81,7 +81,7 @@ private RelToSqlConverterTest.Sql sql(String sql) {
     final String expected = "SELECT \"$cor0\".\"a\", \"t10\".\"xs\" AS \"x\"\n"
         + "FROM (SELECT \"a\", \"n1\".\"n11\".\"b\", \"n1\".\"n12\".\"c\", 
\"n2\".\"d\", \"xs\", \"e\"\n"
         + "FROM \"myDb\".\"myTable\") AS \"$cor0\",\nLATERAL UNNEST (SELECT 
\"$cor0\".\"xs\"\n"
-        + "FROM (VALUES (0)) AS \"t\" (\"ZERO\")) AS \"t1\" (\"xs\") AS 
\"t10\"";
+        + "FROM (VALUES (0)) AS \"t\" (\"ZERO\")) AS \"t10\" (\"xs\")";
     sql(query).schema(CalciteAssert.SchemaSpec.MY_DB).ok(expected);
   }
 }
diff --git 
a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java 
b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
index de3e11382a..6b82317b7d 100644
--- 
a/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
+++ 
b/core/src/test/java/org/apache/calcite/rel/rel2sql/RelToSqlConverterTest.java
@@ -1739,6 +1739,28 @@ private static String toSql(RelNode root, SqlDialect 
dialect,
     assertThat(toSql(root), isLinux(expectedSql));
   }
 
+  /** Test case for
+   * <a 
href="https://issues.apache.org/jira/browse/CALCITE-6785";>[CALCITE-6785]
+   * RelToSqlConverter generate wrong sql when UNNEST has a correlate 
variable</a>. */
+  @Test void testUnnestWithCorrelate() {
+    final String sql = "SELECT\n"
+        + "    \"department_id\",\n"
+        + "    SPLIT (\"department_description\", ','),\n"
+        + "    UNNESTVALUES AS UNNESTALIAS\n"
+        + "FROM\n"
+        + "    \"foodmart\".\"department\",\n"
+        + "    UNNEST(SPLIT (\"department_description\", ',')) AS 
UNNESTVALUES";
+
+    final String expected = "SELECT \"$cor0\".\"department_id\", "
+        + "SPLIT(\"$cor0\".\"department_description\", ','), \"t10\".\"col_0\" 
AS \"UNNESTALIAS\"\n"
+        + "FROM (SELECT \"department_id\", \"department_description\", "
+        + "SPLIT(\"department_description\", ',') AS \"$f2\"\n"
+        + "FROM \"foodmart\".\"department\") AS \"$cor0\",\n"
+        + "LATERAL UNNEST (SELECT \"$cor0\".\"$f2\"\n"
+        + "FROM (VALUES (0)) AS \"t\" (\"ZERO\")) AS \"t10\" (\"col_0\")";
+    sql(sql).withLibrary(SqlLibrary.BIG_QUERY).ok(expected);
+  }
+
   /** Test case for
    * <a 
href="https://issues.apache.org/jira/browse/CALCITE-5395";>[CALCITE-5395]
    * RelToSql converter fails when SELECT * is under a semi-join node</a>. */
diff --git a/piglet/src/test/java/org/apache/calcite/test/PigRelOpTest.java 
b/piglet/src/test/java/org/apache/calcite/test/PigRelOpTest.java
index 26905b3fe8..9c982a82ed 100644
--- a/piglet/src/test/java/org/apache/calcite/test/PigRelOpTest.java
+++ b/piglet/src/test/java/org/apache/calcite/test/PigRelOpTest.java
@@ -392,8 +392,8 @@ private Fluent pig(String script) {
         + "    WHERE JOB <> 'CLERK'\n"
         + "    GROUP BY DEPTNO, JOB) AS $cor1,\n"
         + "  LATERAL UNNEST (SELECT $cor1.$f2 AS $f0\n"
-        + "    FROM (VALUES (0)) AS t (ZERO)) AS t3 (EMPNO, ENAME, JOB,"
-        + " MGR, HIREDATE, SAL, COMM, DEPTNO) AS t30\n"
+        + "    FROM (VALUES (0)) AS t (ZERO)) AS t30 (EMPNO, ENAME, JOB,"
+        + " MGR, HIREDATE, SAL, COMM, DEPTNO)\n"
         + "ORDER BY $cor1.DEPTNO, $cor1.JOB";
     pig(script).assertRel(hasTree(plan))
         .assertSql(is(sql));
@@ -488,7 +488,7 @@ private Fluent pig(String script) {
         + "            ORDER BY SAL) AS t6\n"
         + "        GROUP BY $f0) AS t8) AS $cor5,\n"
         + "  LATERAL UNNEST (SELECT $cor5.X AS $f0\n"
-        + "    FROM (VALUES (0)) AS t (ZERO)) AS t11 (ENAME, JOB, DEPTNO, SAL) 
AS t110\n"
+        + "    FROM (VALUES (0)) AS t (ZERO)) AS t110 (ENAME, JOB, DEPTNO, 
SAL)\n"
         + "ORDER BY $cor5.group";
     pig(script).assertRel(hasTree(plan))
         .assertResult(is(result))

Reply via email to