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 <[email protected]>
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 <[email protected]>
---
.../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) {