This is an automated email from the ASF dual-hosted git repository. rubenql pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/main by this push: new bde9110ca6 [CALCITE-5843] Constant expression with nested casts causes a compiler crash bde9110ca6 is described below commit bde9110ca6d0905eb6973cbacb5c1bb10e04cdce Author: Mihai Budiu <mbu...@gmail.com> AuthorDate: Fri Aug 11 10:19:53 2023 -0700 [CALCITE-5843] Constant expression with nested casts causes a compiler crash Signed-off-by: Mihai Budiu <mbu...@gmail.com> --- .../apache/calcite/linq4j/tree/Expressions.java | 10 +++++++- .../org/apache/calcite/linq4j/tree/Primitive.java | 29 ++++++++++++++++++++++ .../org/apache/calcite/test/SqlOperatorTest.java | 11 ++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java index 5f0b87f9e0..2e49cbcb05 100644 --- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java +++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Expressions.java @@ -570,7 +570,15 @@ public abstract class Expressions { value = new BigInteger(stringValue); } if (primitive != null) { - value = primitive.parse(stringValue); + if (value instanceof Number) { + Number valueNumber = (Number) value; + value = primitive.numberValue(valueNumber); + if (value == null) { + value = primitive.parse(stringValue); + } + } else { + value = primitive.parse(stringValue); + } } } } diff --git a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Primitive.java b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Primitive.java index b27c48b043..066b1a5f00 100644 --- a/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Primitive.java +++ b/linq4j/src/main/java/org/apache/calcite/linq4j/tree/Primitive.java @@ -366,6 +366,35 @@ public enum Primitive { return (List<Double>) asList((Object) elements); } + /** + * Converts a number into a value of the type + * specified by this primitive. + * + * @param value Value to convert. + * @return The converted value, or null if the + * conversion cannot be performed. + */ + public @Nullable Object numberValue(Number value) { + switch (this) { + case BYTE: + return value.byteValue(); + case CHAR: + return (char) value.intValue(); + case SHORT: + return value.shortValue(); + case INT: + return value.intValue(); + case LONG: + return value.longValue(); + case FLOAT: + return value.floatValue(); + case DOUBLE: + return value.doubleValue(); + default: + return null; + } + } + /** * Converts a collection of boxed primitives into an array of primitives. * 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 53147eb9ac..4ae29895df 100644 --- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java +++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java @@ -687,6 +687,17 @@ public class SqlOperatorTest { "654342432412312"); } + /** + * Test case for <a href="https://issues.apache.org/jira/browse/CALCITE-5843"> + * Constant expression with nested casts causes a compiler crash</a>. */ + @Test public void testConstantCast() { + SqlOperatorFixture f = fixture(); + f.checkScalarExact("CAST(CAST('32767.4' AS FLOAT) AS SMALLINT)", + "SMALLINT NOT NULL", "32767"); + f.checkScalarExact("CAST(CAST('32767.4' AS FLOAT) AS CHAR)", + "CHAR(1) NOT NULL", "3"); + } + @ParameterizedTest @MethodSource("safeParameters") void testCastStringToDecimal(CastType castType, SqlOperatorFixture f) {