This is an automated email from the ASF dual-hosted git repository. mbudiu pushed a commit to branch issue6779 in repository https://gitbox.apache.org/repos/asf/calcite.git
commit f0bf38b3c31cfdb4f592f7ecccdde3cc880720f9 Author: Mihai Budiu <[email protected]> AuthorDate: Fri Jan 10 16:13:40 2025 -0800 [CALCITE-6779] Casts from UUID to DATE should be invalid Signed-off-by: Mihai Budiu <[email protected]> --- .../calcite/sql/type/SqlTypeCoercionRule.java | 4 +-- .../org/apache/calcite/sql/type/SqlTypeName.java | 2 +- .../org/apache/calcite/test/SqlValidatorTest.java | 29 ++++++++++++++++++++++ .../org/apache/calcite/test/SqlOperatorTest.java | 8 +++--- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeCoercionRule.java b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeCoercionRule.java index c982572b19..303d5bd1e0 100644 --- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeCoercionRule.java +++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeCoercionRule.java @@ -171,7 +171,7 @@ public class SqlTypeCoercionRule implements SqlTypeMappingRule { .add(SqlTypeName.UUID) .build()); - // VARCHAR is castable from BOOLEAN, DATE, TIME, TIMESTAMP, numeric types, binary and + // VARCHAR is castable from BOOLEAN, DATE, TIME, TIMESTAMP, numeric types, binary, uuid, and // intervals coerceRules.add(SqlTypeName.VARCHAR, coerceRules.copyValues(SqlTypeName.VARCHAR) @@ -190,7 +190,7 @@ public class SqlTypeCoercionRule implements SqlTypeMappingRule { .add(SqlTypeName.UUID) .build()); - // CHAR is castable from BOOLEAN, DATE, TIME, TIMESTAMP, numeric types, binary and + // CHAR is castable from BOOLEAN, DATE, TIME, TIMESTAMP, numeric types, binary, uuid, and // intervals coerceRules.add(SqlTypeName.CHAR, coerceRules.copyValues(SqlTypeName.CHAR) diff --git a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java index d73408cdbe..c984acbffe 100644 --- a/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java +++ b/core/src/main/java/org/apache/calcite/sql/type/SqlTypeName.java @@ -175,7 +175,7 @@ public enum SqlTypeName { ImmutableList.of(BOOLEAN); public static final List<SqlTypeName> BINARY_TYPES = - ImmutableList.of(BINARY, VARBINARY, UUID); + ImmutableList.of(BINARY, VARBINARY); public static final List<SqlTypeName> INT_TYPES = ImmutableList.of(TINYINT, SMALLINT, INTEGER, BIGINT); diff --git a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java index 7d71667455..aa054d9bb0 100644 --- a/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java +++ b/core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java @@ -779,6 +779,35 @@ public class SqlValidatorTest extends SqlValidatorTestCase { expr("_UTF16'a'||_UTF16'b'||_UTF16'c'").ok(); } + /** Test case for <a href="https://issues.apache.org/jira/browse/CALCITE-6779">[CALCITE-6779] + * Casts from UUID to DATE should be invalid</a>. */ + @Test void testUuidCasts() { + final String error = "Cast function cannot convert value of type UUID to type.*"; + expr("^CAST(UUID '123e4567-e89b-12d3-a456-426655440000' AS TIME)^").fails(error); + expr("^CAST(UUID '123e4567-e89b-12d3-a456-426655440000' AS DATE)^").fails(error); + expr("^CAST(UUID '123e4567-e89b-12d3-a456-426655440000' AS TIMESTAMP)^").fails(error); + expr("^CAST(UUID '123e4567-e89b-12d3-a456-426655440000' AS INT)^").fails(error); + expr("^CAST(UUID '123e4567-e89b-12d3-a456-426655440000' AS DOUBLE)^").fails(error); + + final String error2 = "Cast function cannot convert value of type.* to type UUID.*"; + expr("^CAST(TIME '10:00:00' AS UUID)^").fails(error2); + expr("^CAST(DATE '2024-01-01' AS UUID)^").fails(error2); + expr("^CAST(TIMESTAMP '2024-01-01 00:00:00' AS UUID)^").fails(error2); + expr("^CAST(2 AS UUID)^").fails(error2); + expr("^CAST(2.0e0 AS UUID)^").fails(error2); + + expr("CAST(UUID '123e4567-e89b-12d3-a456-426655440000' AS UUID)").ok(); + expr("CAST(UUID '123e4567-e89b-12d3-a456-426655440000' AS VARCHAR)").ok(); + expr("CAST(UUID '123e4567-e89b-12d3-a456-426655440000' AS CHAR(2))").ok(); + expr("CAST(UUID '123e4567-e89b-12d3-a456-426655440000' AS BINARY(2))").ok(); + expr("CAST(UUID '123e4567-e89b-12d3-a456-426655440000' AS VARBINARY)").ok(); + + expr("CAST('123e4567-e89b-12d3-a456-426655440000' AS UUID)").ok(); + expr("CAST(CAST('123e4567-e89b-12d3-a456-426655440000' AS VARCHAR) AS UUID)").ok(); + expr("CAST(x'123e4567e89b12d3a456426655440000' AS UUID)").ok(); + expr("CAST(CAST(x'123e4567e89b12d3a456426655440000' AS VARBINARY) AS UUID)").ok(); + } + @Test void testConcatWithCharset() { sql("_UTF16'a'||_UTF16'b'||_UTF16'c'") .assertCharset(isCharset("UTF-16LE")); diff --git a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java index 0df2aa6702..bc68c4b47c 100644 --- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java +++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java @@ -11262,9 +11262,7 @@ public class SqlOperatorTest { + "'SUBSTRING\\(<BINARY> FROM <INTEGER>\\)'\n" + "'SUBSTRING\\(<BINARY> FROM <INTEGER> FOR <INTEGER>\\)'\n" + "'SUBSTRING\\(<VARBINARY> FROM <INTEGER>\\)'\n" - + "'SUBSTRING\\(<VARBINARY> FROM <INTEGER> FOR <INTEGER>\\)'\n" - + "'SUBSTRING\\(<UUID> FROM <INTEGER>\\)'\n" - + "'SUBSTRING\\(<UUID> FROM <INTEGER> FOR <INTEGER>\\)'", false); + + "'SUBSTRING\\(<VARBINARY> FROM <INTEGER> FOR <INTEGER>\\)'", false); } /** Tests the {@code SUBSTRING} operator. Many test cases that used to be @@ -11320,12 +11318,12 @@ public class SqlOperatorTest { String.format(Locale.ROOT, "^substring('string', CAST(%d AS DOUBLE), " + "CAST(%d AS DOUBLE))^", Byte.MIN_VALUE, Byte.MAX_VALUE + 10), "Cannot apply 'SUBSTRING' to arguments of type " - + ".*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*", false); + + ".*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*", false); f.checkFails( String.format(Locale.ROOT, "^substring('string', CAST(%d AS DECIMAL), " + "CAST(%d AS DECIMAL))^", Byte.MIN_VALUE, Byte.MAX_VALUE + 10), "Cannot apply 'SUBSTRING' to arguments of type " - + ".*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*", + + ".*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*", false); f.checkFails("substring('abc' from 1 for -1)", "Substring error: negative substring length not allowed",
