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 b9455ef08d [CALCITE-6419] Invalid unparse for VARCHAR without precision in HiveSqlDialect And SparkSqlDialect b9455ef08d is described below commit b9455ef08ddc948b74037d38e18809ad4ae83ef3 Author: Xiong Duan <nobigo...@gmail.com> AuthorDate: Fri May 24 20:23:50 2024 +0800 [CALCITE-6419] Invalid unparse for VARCHAR without precision in HiveSqlDialect And SparkSqlDialect --- .../apache/calcite/sql/dialect/HiveSqlDialect.java | 7 +++ .../calcite/sql/dialect/SparkSqlDialect.java | 15 ++++++ .../calcite/rel/rel2sql/RelToSqlConverterTest.java | 53 +++++++++++++++++++++- 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java b/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java index a6f9c4cae0..f6a69beae2 100644 --- a/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java +++ b/core/src/main/java/org/apache/calcite/sql/dialect/HiveSqlDialect.java @@ -141,6 +141,13 @@ public class HiveSqlDialect extends SqlDialect { new SqlAlienSystemTypeNameSpec("INT", type.getSqlTypeName(), SqlParserPos.ZERO); return new SqlDataTypeSpec(typeNameSpec, SqlParserPos.ZERO); + case VARCHAR: + if (type.getPrecision() == -1) { + return new SqlDataTypeSpec( + new SqlAlienSystemTypeNameSpec("STRING", type.getSqlTypeName(), + SqlParserPos.ZERO), SqlParserPos.ZERO); + } + break; default: break; } 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 303b21a204..85ed75c90f 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 @@ -18,8 +18,11 @@ package org.apache.calcite.sql.dialect; import org.apache.calcite.avatica.util.TimeUnitRange; import org.apache.calcite.config.NullCollation; +import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.sql.JoinType; +import org.apache.calcite.sql.SqlAlienSystemTypeNameSpec; import org.apache.calcite.sql.SqlCall; +import org.apache.calcite.sql.SqlDataTypeSpec; import org.apache.calcite.sql.SqlDialect; import org.apache.calcite.sql.SqlKind; import org.apache.calcite.sql.SqlLiteral; @@ -28,6 +31,9 @@ import org.apache.calcite.sql.SqlUtil; import org.apache.calcite.sql.SqlWriter; import org.apache.calcite.sql.fun.SqlFloorFunction; import org.apache.calcite.sql.fun.SqlStdOperatorTable; +import org.apache.calcite.sql.parser.SqlParserPos; +import org.apache.calcite.sql.type.BasicSqlType; +import org.apache.calcite.sql.type.SqlTypeName; import org.checkerframework.checker.nullness.qual.Nullable; @@ -136,4 +142,13 @@ public class SparkSqlDialect extends SqlDialect { super.unparseCall(writer, call, leftPrec, rightPrec); } } + + @Override public @Nullable SqlNode getCastSpec(RelDataType type) { + if (type instanceof BasicSqlType && type.getSqlTypeName() == SqlTypeName.VARCHAR) { + return new SqlDataTypeSpec( + new SqlAlienSystemTypeNameSpec("STRING", type.getSqlTypeName(), + SqlParserPos.ZERO), SqlParserPos.ZERO); + } + return super.getCastSpec(type); + } } 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 346b91b925..9412625a91 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 @@ -3513,15 +3513,66 @@ class RelToSqlConverterTest { sql(query).dialect(mySqlDialect(NullCollation.LAST)).ok(expected); } + /** Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-6419">[CALCITE-6419] + * Invalid unparse for VARCHAR without precision in HiveSqlDialect And SparkSqlDialect</a>. */ @Test void testCastToVarchar() { String query = "select cast(\"product_id\" as varchar) from \"product\""; final String expectedClickHouse = "SELECT CAST(`product_id` AS `String`)\n" + "FROM `foodmart`.`product`"; final String expectedMysql = "SELECT CAST(`product_id` AS CHAR)\n" + "FROM `foodmart`.`product`"; + final String expectedHive = "SELECT CAST(product_id AS STRING)\n" + + "FROM foodmart.product"; + final String expectedSpark = "SELECT CAST(product_id AS STRING)\n" + + "FROM foodmart.product"; sql(query) .withClickHouse().ok(expectedClickHouse) - .withMysql().ok(expectedMysql); + .withMysql().ok(expectedMysql) + .withHive().ok(expectedHive) + .withSpark().ok(expectedSpark); + } + + @Test void testCastToVarcharWithPrecision() { + String query = "select cast(\"product_id\" as varchar(5)) from \"product\""; + final String expectedMysql = "SELECT CAST(`product_id` AS CHAR(5))\n" + + "FROM `foodmart`.`product`"; + final String expectedHive = "SELECT CAST(product_id AS VARCHAR(5))\n" + + "FROM foodmart.product"; + final String expectedSpark = "SELECT CAST(product_id AS STRING)\n" + + "FROM foodmart.product"; + sql(query) + .withMysql().ok(expectedMysql) + .withHive().ok(expectedHive) + .withSpark().ok(expectedSpark); + } + + @Test void testCastToChar() { + String query = "select cast(\"product_id\" as char) from \"product\""; + final String expectedMysql = "SELECT CAST(`product_id` AS CHAR(1))\n" + + "FROM `foodmart`.`product`"; + final String expectedHive = "SELECT CAST(product_id AS CHAR(1))\n" + + "FROM foodmart.product"; + final String expectedSpark = "SELECT CAST(product_id AS CHAR(1))\n" + + "FROM foodmart.product"; + sql(query) + .withMysql().ok(expectedMysql) + .withHive().ok(expectedHive) + .withSpark().ok(expectedSpark); + } + + @Test void testCastToCharWithPrecision() { + String query = "select cast(\"product_id\" as char(5)) from \"product\""; + final String expectedMysql = "SELECT CAST(`product_id` AS CHAR(5))\n" + + "FROM `foodmart`.`product`"; + final String expectedHive = "SELECT CAST(product_id AS CHAR(5))\n" + + "FROM foodmart.product"; + final String expectedSpark = "SELECT CAST(product_id AS CHAR(5))\n" + + "FROM foodmart.product"; + sql(query) + .withMysql().ok(expectedMysql) + .withHive().ok(expectedHive) + .withSpark().ok(expectedSpark); } @Test void testSelectQueryWithLimitClauseWithoutOrder() {