Skip to content

Commit

Permalink
[CALCITE-6779] Casts from UUID to DATE should be invalid
Browse files Browse the repository at this point in the history
Signed-off-by: Mihai Budiu <mbudiu@feldera.com>
  • Loading branch information
mihaibudiu committed Jan 11, 2025
1 parent c1b9bdc commit 63d57c2
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ private SqlTypeCoercionRule(Map<SqlTypeName, ImmutableSet<SqlTypeName>> map) {
.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)
Expand All @@ -190,7 +190,7 @@ private SqlTypeCoercionRule(Map<SqlTypeName, ImmutableSet<SqlTypeName>> map) {
.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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
29 changes: 29 additions & 0 deletions core/src/test/java/org/apache/calcite/test/SqlValidatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,35 @@ static SqlOperatorTable operatorTableFor(SqlLibrary library) {
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"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11262,9 +11262,7 @@ void checkEndsWith(SqlOperatorFixture f0, FunctionAlias functionAlias) {
+ "'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
Expand Down Expand Up @@ -11320,12 +11318,12 @@ private static void checkSubstringFunction(SqlOperatorFixture f) {
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",
Expand Down

0 comments on commit 63d57c2

Please sign in to comment.