diff --git a/core/trino-main/src/test/java/io/trino/sql/TestExpressionInterpreter.java b/core/trino-main/src/test/java/io/trino/sql/TestExpressionInterpreter.java index 9e766646e332..13a3b6d32e16 100644 --- a/core/trino-main/src/test/java/io/trino/sql/TestExpressionInterpreter.java +++ b/core/trino-main/src/test/java/io/trino/sql/TestExpressionInterpreter.java @@ -833,6 +833,17 @@ public void testCastRealToBoundedVarchar() .hasMessage("Value 1200000.0 cannot be represented as varchar(5)"); } + @Test + public void testCastDateToBoundedVarchar() + { + assertEvaluatedEquals("CAST(DATE '2013-02-02' AS varchar(10))", "'2013-02-02'"); + assertEvaluatedEquals("CAST(DATE '-2013-02-02' AS varchar(50))", "'-2013-02-02'"); + + // incorrect behavior: the result value does not fit in the type + assertEvaluatedEquals("CAST(DATE '2013-02-02' AS varchar(9))", "'2013-02-02'"); + assertEvaluatedEquals("CAST(DATE '-2013-02-02' AS varchar(9))", "'-2013-02-02'"); + } + @Test public void testCastToBoolean() { diff --git a/core/trino-main/src/test/java/io/trino/sql/planner/iterative/rule/TestSimplifyExpressions.java b/core/trino-main/src/test/java/io/trino/sql/planner/iterative/rule/TestSimplifyExpressions.java index caef4dcb197f..e0bbb653f177 100644 --- a/core/trino-main/src/test/java/io/trino/sql/planner/iterative/rule/TestSimplifyExpressions.java +++ b/core/trino-main/src/test/java/io/trino/sql/planner/iterative/rule/TestSimplifyExpressions.java @@ -44,6 +44,7 @@ import static io.trino.sql.planner.TypeAnalyzer.createTestingTypeAnalyzer; import static io.trino.sql.planner.iterative.rule.SimplifyExpressions.rewrite; import static java.util.stream.Collectors.toList; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.testng.Assert.assertEquals; public class TestSimplifyExpressions @@ -242,6 +243,23 @@ public void testCastRealToBoundedVarchar() assertSimplifies("CAST(REAL '12e2' AS varchar(3)) = '1200.0'", "CAST(REAL '12e2' AS varchar(3)) = '1200.0'"); } + @Test + public void testCastDateToBoundedVarchar() + { + // the varchar type length is enough to contain the date's representation + assertSimplifies("CAST(DATE '2013-02-02' AS varchar(10))", "'2013-02-02'"); + assertSimplifies("CAST(DATE '2013-02-02' AS varchar(50))", "CAST('2013-02-02' AS varchar(50))"); + + // the cast operator returns a value that is too long for the expected type ('2013-02-02' for varchar(3)) + // the LiteralEncoder detects the mismatch and fails + assertThatThrownBy(() -> simplify("CAST(DATE '2013-02-02' AS varchar(3))")) + .hasMessage("Value [2013-02-02] does not fit in type varchar(3)"); + + // the cast operator returns a value that is too long for the expected type ('2013-02-02' for varchar(3)) + // the value is nested in a comparison expression, so the mismatch is not detected by the LiteralEncoder + assertSimplifies("CAST(DATE '2013-02-02' AS varchar(3)) = '2013-02-02'", "true"); + } + private static void assertSimplifies(String expression, String expected) { Expression expectedExpression = normalize(rewriteIdentifiersToSymbolReferences(SQL_PARSER.createExpression(expected, new ParsingOptions()))); diff --git a/core/trino-main/src/test/java/io/trino/type/TestDateTimeOperators.java b/core/trino-main/src/test/java/io/trino/type/TestDateTimeOperators.java index e2a07063083d..49298c7593fb 100644 --- a/core/trino-main/src/test/java/io/trino/type/TestDateTimeOperators.java +++ b/core/trino-main/src/test/java/io/trino/type/TestDateTimeOperators.java @@ -32,6 +32,7 @@ import static io.trino.spi.type.TimestampType.createTimestampType; import static io.trino.spi.type.TimestampWithTimeZoneType.TIMESTAMP_TZ_MILLIS; import static io.trino.spi.type.VarcharType.VARCHAR; +import static io.trino.spi.type.VarcharType.createVarcharType; import static io.trino.testing.DateTimeTestingUtils.sqlTimestampOf; import static io.trino.testing.TestingSession.testSessionBuilder; import static org.joda.time.DateTimeZone.UTC; @@ -264,6 +265,18 @@ public void testDateCastFromVarchar() assertInvalidFunction("DATE '392251590-07-12'", INVALID_CAST_ARGUMENT, "Value cannot be cast to date: 392251590-07-12"); } + @Test + public void testDateCastToVarchar() + { + assertFunction("cast(DATE '2013-02-02' AS varchar)", VARCHAR, "2013-02-02"); + assertFunction("cast(DATE '13-2-2' AS varchar)", VARCHAR, "0013-02-02"); + assertFunction("cast(DATE '2013-02-02' AS varchar(50))", createVarcharType(50), "2013-02-02"); + assertFunction("cast(DATE '2013-02-02' AS varchar(10))", createVarcharType(10), "2013-02-02"); + + // cast operator returns a value that does not fit in the result type. this causes error in the LiteralEncoder + assertFunctionThrowsIncorrectly("cast(DATE '2013-02-02' AS varchar(9))", IllegalArgumentException.class, "Value .2013-02-02. does not fit in type varchar.9."); + } + private static SqlDate toDate(DateTime dateTime) { return new SqlDate((int) TimeUnit.MILLISECONDS.toDays(dateTime.getMillis()));