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

commit 15f4ef98618e66e7e5cc70128dc0f7a7e6cb135c
Author: ChengJie1053 <[email protected]>
AuthorDate: Mon Sep 2 22:50:07 2024 +0800

    [CALCITE-6565] Invalid unparse for CHAR without precision in MssqlSqlDialect
---
 .../apache/calcite/rel/type/RelDataTypeSystemImpl.java   |  6 +++---
 .../org/apache/calcite/sql/dialect/MssqlSqlDialect.java  | 16 ++++++++++++++++
 .../calcite/rel/rel2sql/RelToSqlConverterTest.java       |  6 ++++++
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java 
b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java
index 1b057909e3..b7fe0d8680 100644
--- a/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java
+++ b/core/src/main/java/org/apache/calcite/rel/type/RelDataTypeSystemImpl.java
@@ -57,7 +57,7 @@ public abstract class RelDataTypeSystemImpl implements 
RelDataTypeSystem {
     case INTERVAL_SECOND:
       return SqlTypeName.MAX_INTERVAL_FRACTIONAL_SECOND_PRECISION;
     default:
-      return -1;
+      return RelDataType.SCALE_NOT_SPECIFIED;
     }
   }
 
@@ -114,7 +114,7 @@ public abstract class RelDataTypeSystemImpl implements 
RelDataTypeSystem {
       // (microseconds) per SQL99 part 2 section 6.1 syntax rule 30.
       return 0;
     default:
-      return -1;
+      return RelDataType.PRECISION_NOT_SPECIFIED;
     }
   }
 
@@ -226,7 +226,7 @@ public abstract class RelDataTypeSystemImpl implements 
RelDataTypeSystem {
 
   @Override public int getNumTypeRadix(SqlTypeName typeName) {
     if (typeName.getFamily() == SqlTypeFamily.NUMERIC
-        && getDefaultPrecision(typeName) != -1) {
+        && getDefaultPrecision(typeName) != 
RelDataType.PRECISION_NOT_SPECIFIED) {
       return 10;
     }
     return 0;
diff --git 
a/core/src/main/java/org/apache/calcite/sql/dialect/MssqlSqlDialect.java 
b/core/src/main/java/org/apache/calcite/sql/dialect/MssqlSqlDialect.java
index 0867133956..6f32a33a4a 100644
--- a/core/src/main/java/org/apache/calcite/sql/dialect/MssqlSqlDialect.java
+++ b/core/src/main/java/org/apache/calcite/sql/dialect/MssqlSqlDialect.java
@@ -18,7 +18,9 @@ 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.rel.type.RelDataTypeSystem;
+import org.apache.calcite.rel.type.RelDataTypeSystemImpl;
 import org.apache.calcite.sql.SqlAbstractDateTimeLiteral;
 import org.apache.calcite.sql.SqlBasicFunction;
 import org.apache.calcite.sql.SqlCall;
@@ -37,6 +39,7 @@ import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.calcite.sql.type.OperandTypes;
 import org.apache.calcite.sql.type.ReturnTypes;
+import org.apache.calcite.sql.type.SqlTypeName;
 
 import org.checkerframework.checker.nullness.qual.Nullable;
 
@@ -47,9 +50,22 @@ import static java.util.Objects.requireNonNull;
  * database.
  */
 public class MssqlSqlDialect extends SqlDialect {
+    /**
+     * Mssql type system.
+     */
+  public static final RelDataTypeSystem MSSQL_TYPE_SYSTEM =
+            new RelDataTypeSystemImpl() {
+      @Override public int getDefaultPrecision(SqlTypeName typeName) {
+          if (typeName == SqlTypeName.CHAR) {
+            return RelDataType.PRECISION_NOT_SPECIFIED;
+          }
+          return super.getDefaultPrecision(typeName);
+      }
+  };
   public static final Context DEFAULT_CONTEXT = SqlDialect.EMPTY_CONTEXT
       .withDatabaseProduct(SqlDialect.DatabaseProduct.MSSQL)
       .withIdentifierQuoteString("[")
+      .withDataTypeSystem(MSSQL_TYPE_SYSTEM)
       .withCaseSensitive(false)
       .withNullCollation(NullCollation.LOW);
 
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 b30595d5f0..d855bb96c3 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
@@ -3684,12 +3684,15 @@ class RelToSqlConverterTest {
     String query = "select cast(\"product_id\" as char) from \"product\"";
     final String expectedMysql = "SELECT CAST(`product_id` AS CHAR)\n"
         + "FROM `foodmart`.`product`";
+    final String expectedMssql = "SELECT CAST([product_id] AS CHAR)\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)
+        .withMssql().ok(expectedMssql)
         .withHive().ok(expectedHive)
         .withSpark().ok(expectedSpark);
   }
@@ -3698,12 +3701,15 @@ class RelToSqlConverterTest {
     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 expectedMssql = "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)
+        .withMssql().ok(expectedMssql)
         .withHive().ok(expectedHive)
         .withSpark().ok(expectedSpark);
   }

Reply via email to