diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/SparkSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/SparkSqlDialect.java index 42cd259e5154..07ae9c28381d 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/SparkSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/SparkSqlDialect.java @@ -30,6 +30,7 @@ import org.apache.calcite.sql.SqlLiteral; import org.apache.calcite.sql.SqlNode; import org.apache.calcite.sql.SqlNodeList; +import org.apache.calcite.sql.SqlUnnestOperator; import org.apache.calcite.sql.SqlUtil; import org.apache.calcite.sql.SqlWriter; import org.apache.calcite.sql.fun.SqlCase; @@ -155,6 +156,20 @@ public SparkSqlDialect(SqlDialect.Context context) { case POSITION: SqlUtil.unparseFunctionSyntax(SqlStdOperatorTable.POSITION, writer, call, false); break; + case UNNEST: + if (call.getOperator() instanceof SqlUnnestOperator + && ((SqlUnnestOperator) call.getOperator()).withOrdinality) { + writer.keyword("POSEXPLODE"); + } else { + writer.keyword("EXPLODE"); + } + final SqlWriter.Frame frame = writer.startList(SqlWriter.FrameTypeEnum.FUN_CALL, "(", ")"); + for (SqlNode operand : call.getOperandList()) { + writer.sep(","); + operand.unparse(writer, 0, 0); + } + writer.endList(frame); + break; default: super.unparseCall(writer, call, leftPrec, rightPrec); } 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 fd13824c8733..5083a73072fc 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 @@ -7814,9 +7814,30 @@ private void checkLiteral2(String expression, String expected) { final String expectedHsqldb = "SELECT *\n" + "FROM UNNEST((SELECT ARRAY[1, 2, 3]\n" + "FROM (VALUES (0)) AS t (ZERO))) AS t0 (col_0)"; + final String expectedSpark = "SELECT *\n" + + "FROM EXPLODE((SELECT ARRAY (1, 2, 3)\n" + + "FROM (VALUES (0)) `t` (`ZERO`))) `t0` (`col_0`)"; sql(sql).ok(expected). withPostgresql().ok(expectedPostgresql). - withHsqldb().ok(expectedHsqldb); + withHsqldb().ok(expectedHsqldb). + withSpark().ok(expectedSpark); + } + + /** Test case for + * [CALCITE-7246] + * UNNEST in spark should convert to EXPLODE/POSEXPLODE . + */ + @Test void testUnnestArrayWithOrdinality() { + final String query = "SELECT * FROM UNNEST(ARRAY[1,2,3]) WITH ORDINALITY"; + final String expected = "SELECT *\n" + + "FROM UNNEST((SELECT ARRAY[1, 2, 3]\n" + + "FROM (VALUES (0)) AS \"t\" (\"ZERO\"))) WITH ORDINALITY AS \"t0\" (\"col_0\", \"ORDINALITY\")"; + final String expectedSpark = "SELECT *\n" + + "FROM POSEXPLODE((SELECT ARRAY (1, 2, 3)\n" + + "FROM (VALUES (0)) `t` (`ZERO`))) `t0` (`col_0`, `ORDINALITY`)"; + sql(query) + .ok(expected) + .withSpark().ok(expectedSpark); } @Test void testWithinGroup1() {