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))",

Reply via email to