This is an automated email from the ASF dual-hosted git repository.
mbudiu 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 c928877530 [CALCITE-6723] Type inference for ARRAY_INSERT function is
incorrect
c928877530 is described below
commit c9288775300b44271beb2c4c0ffd1c54247412b4
Author: Mihai Budiu <[email protected]>
AuthorDate: Mon Dec 9 20:33:13 2024 -0800
[CALCITE-6723] Type inference for ARRAY_INSERT function is incorrect
Signed-off-by: Mihai Budiu <[email protected]>
---
.../calcite/sql/fun/SqlLibraryOperators.java | 18 +++++++---------
.../org/apache/calcite/test/SqlOperatorTest.java | 24 +++++++++++-----------
2 files changed, 19 insertions(+), 23 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
index 8403354713..bd89741be1 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
@@ -1537,21 +1537,17 @@ public abstract class SqlLibraryOperators {
ImmutableList.of(componentType, elementType2));
requireNonNull(type, "inferred array element type");
- if (elementType2.isNullable()) {
- type = opBinding.getTypeFactory().createTypeWithNullability(type, true);
- }
+ // The spec says that "ARRAY_INSERT may pad the array with NULL values if
the
+ // position is large", it implies that in the result the element type is
always nullable.
+ type = opBinding.getTypeFactory().createTypeWithNullability(type, true);
// make explicit CAST for array elements and inserted element to the
biggest type
// if array component type not equals to inserted element type
if (!componentType.equalsSansFieldNames(elementType2)) {
- // 0, 2 is the operand index to be CAST
// For array_insert, 0 is the array arg and 2 is the inserted element
- if (componentType.equalsSansFieldNames(type)) {
- SqlValidatorUtil.
- adjustTypeForArrayFunctions(type, opBinding, 2);
- } else {
- SqlValidatorUtil.
- adjustTypeForArrayFunctions(type, opBinding, 0);
- }
+ SqlValidatorUtil.
+ adjustTypeForArrayFunctions(type, opBinding, 2);
+ SqlValidatorUtil.
+ adjustTypeForArrayFunctions(type, opBinding, 0);
}
boolean nullable = arrayType.isNullable() || elementType1.isNullable();
return SqlTypeUtil.createArrayType(opBinding.getTypeFactory(), type,
nullable);
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 1d8e3669dd..7219888558 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -8221,36 +8221,36 @@ public class SqlOperatorTest {
+ "and not exceeds the allowed limit.", true);
f1.checkScalar("array_insert(array[1, 2, 3], 3, 4)",
- "[1, 2, 4, 3]", "INTEGER NOT NULL ARRAY NOT NULL");
+ "[1, 2, 4, 3]", "INTEGER ARRAY NOT NULL");
f1.checkScalar("array_insert(array[1, 2, 3], 3, cast(null as integer))",
"[1, 2, null, 3]", "INTEGER ARRAY NOT NULL");
f1.checkScalar("array_insert(array[2, 3, 4], 1, 1)",
- "[1, 2, 3, 4]", "INTEGER NOT NULL ARRAY NOT NULL");
+ "[1, 2, 3, 4]", "INTEGER ARRAY NOT NULL");
f1.checkScalar("array_insert(array[1, 3, 4], -1, 2)",
- "[1, 3, 4, 2]", "INTEGER NOT NULL ARRAY NOT NULL");
+ "[1, 3, 4, 2]", "INTEGER ARRAY NOT NULL");
f1.checkScalar("array_insert(array[1, 3, 4], -3, 2)",
- "[1, 2, 3, 4]", "INTEGER NOT NULL ARRAY NOT NULL");
+ "[1, 2, 3, 4]", "INTEGER ARRAY NOT NULL");
f1.checkScalar("array_insert(array[2, 3, null, 4], -6, 1)",
"[1, null, 2, 3, null, 4]", "INTEGER ARRAY NOT NULL");
// check complex type
f1.checkScalar("array_insert(array[array[1,2]], 1, array[1])",
- "[[1], [1, 2]]", "INTEGER NOT NULL ARRAY NOT NULL ARRAY NOT NULL");
+ "[[1], [1, 2]]", "INTEGER NOT NULL ARRAY ARRAY NOT NULL");
f1.checkScalar("array_insert(array[array[1,2]], -1, array[1])",
- "[[1, 2], [1]]", "INTEGER NOT NULL ARRAY NOT NULL ARRAY NOT NULL");
+ "[[1, 2], [1]]", "INTEGER NOT NULL ARRAY ARRAY NOT NULL");
f1.checkScalar("array_insert(array[map[1, 'a']], 1, map[2, 'b'])",
"[{2=b}, {1=a}]",
- "(INTEGER NOT NULL, CHAR(1) NOT NULL) MAP NOT NULL ARRAY NOT NULL");
+ "(INTEGER NOT NULL, CHAR(1) NOT NULL) MAP ARRAY NOT NULL");
f1.checkScalar("array_insert(array[map[1, 'a']], -1, map[2, 'b'])",
"[{1=a}, {2=b}]",
- "(INTEGER NOT NULL, CHAR(1) NOT NULL) MAP NOT NULL ARRAY NOT NULL");
+ "(INTEGER NOT NULL, CHAR(1) NOT NULL) MAP ARRAY NOT NULL");
// element cast to the biggest type
f1.checkScalar("array_insert(array(1, 2, 3), 3, cast(4 as tinyint))",
- "[1, 2, 4, 3]", "INTEGER NOT NULL ARRAY NOT NULL");
+ "[1, 2, 4, 3]", "INTEGER ARRAY NOT NULL");
f1.checkScalar("array_insert(array(1, 2, 3), 3, cast(4 as double))",
- "[1.0, 2.0, 4.0, 3.0]", "DOUBLE NOT NULL ARRAY NOT NULL");
+ "[1.0, 2.0, 4.0, 3.0]", "DOUBLE ARRAY NOT NULL");
f1.checkScalar("array_insert(array(1, 2, 3), 3, cast(4 as float))",
- "[1.0, 2.0, 4.0, 3.0]", "FLOAT NOT NULL ARRAY NOT NULL");
+ "[1.0, 2.0, 4.0, 3.0]", "FLOAT ARRAY NOT NULL");
f1.checkScalar("array_insert(array(1, 2, 3), 3, cast(4 as bigint))",
- "[1, 2, 4, 3]", "BIGINT NOT NULL ARRAY NOT NULL");
+ "[1, 2, 4, 3]", "BIGINT ARRAY NOT NULL");
f1.checkScalar("array_insert(array(1, 2, 3), 3, cast(null as bigint))",
"[1, 2, null, 3]", "BIGINT ARRAY NOT NULL");
f1.checkScalar("array_insert(array(1, 2, 3), 3, cast(null as float))",