This is an automated email from the ASF dual-hosted git repository.
mihaibudiu 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 1a6b127d59 [CALCITE-7704] ARRAY_INSERT crashes in code generation with
array-of-arrays argument
1a6b127d59 is described below
commit 1a6b127d59702660589af59d192613fcef4cd81c
Author: Mihai Budiu <[email protected]>
AuthorDate: Mon Aug 10 15:21:22 2026 -0700
[CALCITE-7704] ARRAY_INSERT crashes in code generation with array-of-arrays
argument
Signed-off-by: Mihai Budiu <[email protected]>
---
.../org/apache/calcite/sql/validate/SqlValidatorUtil.java | 8 ++++++--
.../main/java/org/apache/calcite/test/SqlOperatorTest.java | 14 ++++++++++++++
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
index ca1b2f9276..b4465ab434 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorUtil.java
@@ -1476,14 +1476,18 @@ private static void adjustTypeForArrayFunctions(
// such as spark array, the SqlKind is other function.
// however, the name is same for those different array forms.
&& "ARRAY".equals(((SqlBasicCall)
operand).getOperator().getName())) {
- call.setOperand(idx, castArrayElementTo(validator, operand,
targetType));
+ RelDataType elementType =
+ arrayOperands ? targetType
+ : requireNonNull(targetType.getComponentType(),
+ () -> "componentType of " + targetType);
+ call.setOperand(idx, castArrayElementTo(validator, operand,
elementType));
// The rewrite changes the element types of the array constructor,
// so the type the validator has recorded for it must change too
RelDataType priorType =
validator.getValidatedNodeTypeIfKnown(operand);
if (priorType != null) {
validator.setValidatedNodeType(operand,
SqlTypeUtil.createArrayType(opBinding.getTypeFactory(),
- targetType, priorType.isNullable()));
+ elementType, priorType.isNullable()));
}
} else {
RelDataType castType = targetType;
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 95381426f9..6082c27638 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -8358,6 +8358,10 @@ void checkRegexpExtract(SqlOperatorFixture f0,
FunctionAlias functionAlias) {
+ "array[cast(3 as double)])",
"[[1.0, 2.0], [3.0]]",
"DOUBLE NOT NULL ARRAY NOT NULL ARRAY NOT NULL");
+ // Test case for [CALCITE-7704]
+ // ARRAY_INSERT crashes in code generation with array-of-arrays argument
+ f.checkScalar("array_append(array[array[cast(1 as double)]], array[2])",
+ "[[1.0], [2.0]]", "DOUBLE NOT NULL ARRAY NOT NULL ARRAY NOT NULL");
// element cast to the biggest type
f.checkScalar("array_append(array(cast(1 as tinyint)), 2)", "[1, 2]",
@@ -8707,6 +8711,10 @@ void checkRegexpExtract(SqlOperatorFixture f0,
FunctionAlias functionAlias) {
f.checkScalar("array_prepend(array_distinct(array[1, 2, 3]), "
+ "cast(4 as double))",
"[4.0, 1.0, 2.0, 3.0]", "DOUBLE NOT NULL ARRAY NOT NULL");
+ // Test case for [CALCITE-7704]
+ // ARRAY_INSERT crashes in code generation with array-of-arrays argument
+ f.checkScalar("array_prepend(array[array[cast(1 as double)]], array[2])",
+ "[[2.0], [1.0]]", "DOUBLE NOT NULL ARRAY NOT NULL ARRAY NOT NULL");
// element cast to the biggest type
f.checkScalar("array_prepend(array(1), cast(3 as float))", "[3.0, 1.0]",
@@ -9064,6 +9072,12 @@ void checkArrayReverseFunc(SqlOperatorFixture f0,
SqlFunction function,
+ "cast(array[array[1, 2]] as integer array array), 1, "
+ "array[cast(3 as double)])",
"[[3.0], [1.0, 2.0]]", "DOUBLE NOT NULL ARRAY ARRAY NOT NULL");
+ // Test case for [CALCITE-7704]
+ // ARRAY_INSERT crashes in code generation with array-of-arrays argument
+ f1.checkScalar("array_insert(array[array[cast(1 as double)]], 1,
array[2])",
+ "[[2.0], [1.0]]", "DOUBLE NOT NULL ARRAY ARRAY NOT NULL");
+ f1.checkScalar("array_insert(array[array[1]], 1, array[2.5])",
+ "[[2.5], [1.0]]", "DECIMAL(11, 1) NOT NULL ARRAY ARRAY NOT NULL");
f1.checkScalar("array_insert(array[1, 2, 3], 3, 4)",
"[1, 2, 4, 3]", "INTEGER ARRAY NOT NULL");