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() {

Reply via email to