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); }
