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",

Reply via email to