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 <[email protected]>
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() {