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 8b4136bbd1 [CALCITE-6680] RexImpTable erroneously declares 
NullPolicy.NONE for IS_EMPTY
8b4136bbd1 is described below

commit 8b4136bbd183f10e72c2ec02bef9caf1748631c2
Author: Mihai Budiu <[email protected]>
AuthorDate: Thu Nov 7 17:52:14 2024 -0800

    [CALCITE-6680] RexImpTable erroneously declares NullPolicy.NONE for IS_EMPTY
    
    Signed-off-by: Mihai Budiu <[email protected]>
---
 babel/src/test/resources/sql/spark.iq              | 219 +++++++++++++++++++++
 .../calcite/adapter/enumerable/RexImpTable.java    |  22 +--
 .../apache/calcite/jdbc/JavaTypeFactoryImpl.java   |  13 +-
 .../org/apache/calcite/runtime/SqlFunctions.java   |  46 ++++-
 .../apache/calcite/test/ReflectiveSchemaTest.java  |  18 +-
 .../org/apache/calcite/test/SqlFunctionsTest.java  |  14 +-
 .../test/enumerable/EnumerableCalcTest.java        |  14 ++
 .../test/schemata/catchall/CatchallSchema.java     |  11 +-
 8 files changed, 318 insertions(+), 39 deletions(-)

diff --git a/babel/src/test/resources/sql/spark.iq 
b/babel/src/test/resources/sql/spark.iq
index d4d512489b..ec4f471e5d 100644
--- a/babel/src/test/resources/sql/spark.iq
+++ b/babel/src/test/resources/sql/spark.iq
@@ -448,4 +448,223 @@ EXPR$0
 [2.111111111111112, 2.1]
 !ok
 
+# Tests for CALCITE-6680
+# RexImpTable erroneously declares NullPolicy.NONE for IS_EMPTY
+# Added as Babel tests since they need the ARRAY() and MAP() functions
+
+CREATE OR REPLACE TABLE COMPLEX(
+   KEY INT, "list" INT ARRAY, "long" BIGINT, "map" MAP<VARCHAR, INT>, "set" 
INT MULTISET);
+(0 rows modified)
+
+!update
+
+INSERT INTO COMPLEX (VALUES
+ (0, NULL, 5, NULL, NULL),
+ -- Apparently there is no function of constructor to create an empty multiset
+ (1, array(), 4, NULL, multiset[1] MULTISET EXCEPT multiset[1]),
+ (2, ARRAY[0], 3, MAP(), multiset[0]),
+ (3, ARRAY[0, 1], 2, MAP['zero', 0], multiset[0, 1]),
+ (4, ARRAY[0, 1, 2], 1, MAP['zero', 0, 'one', 1], multiset[0, 1, 2]),
+ (5, ARRAY[0, 1, 2, 3], 0, MAP['zero', 0, 'one', 1, 'two', 2], multiset[0, 1, 
2, 3])
+);
+(6 rows modified)
+
+!update
+!set outputformat mysql
+
+SELECT * FROM COMPLEX WHERE "list" IS EMPTY;
++-----+------+------+-----+-----+
+| KEY | list | long | map | set |
++-----+------+------+-----+-----+
+|   1 | []   |    4 |     | []  |
++-----+------+------+-----+-----+
+(1 row)
+
+!ok
+
+SELECT * FROM COMPLEX WHERE "set" IS EMPTY;
++-----+------+------+-----+-----+
+| KEY | list | long | map | set |
++-----+------+------+-----+-----+
+|   1 | []   |    4 |     | []  |
++-----+------+------+-----+-----+
+(1 row)
+
+!ok
+
+SELECT * FROM COMPLEX WHERE "map" IS EMPTY;
++-----+------+------+-----+-----+
+| KEY | list | long | map | set |
++-----+------+------+-----+-----+
+|   2 | [0]  |    3 | {}  | [0] |
++-----+------+------+-----+-----+
+(1 row)
+
+!ok
+
+SELECT ARRAY_INSERT("list", 1, 2) AS list FROM COMPLEX;
++-----------------+
+| LIST            |
++-----------------+
+| [2, 0, 1, 2, 3] |
+| [2, 0, 1, 2]    |
+| [2, 0, 1]       |
+| [2, 0]          |
+| [2]             |
+|                 |
++-----------------+
+(6 rows)
+
+!ok
+
+SELECT "set" MULTISET UNION "set" AS u FROM COMPLEX;
++--------------------------+
+| U                        |
++--------------------------+
+| [0, 0]                   |
+| [0, 1, 0, 1]             |
+| [0, 1, 2, 0, 1, 2]       |
+| [0, 1, 2, 3, 0, 1, 2, 3] |
+| []                       |
+|                          |
++--------------------------+
+(6 rows)
+
+!ok
+
+SELECT "set" MULTISET UNION DISTINCT "set" AS u FROM COMPLEX;
++--------------+
+| U            |
++--------------+
+| [0, 1, 2, 3] |
+| [0, 1, 2]    |
+| [0, 1]       |
+| [0]          |
+| []           |
+|              |
++--------------+
+(6 rows)
+
+!ok
+
+SELECT "set" MULTISET INTERSECT "set" AS u FROM COMPLEX;
++--------------+
+| U            |
++--------------+
+| [0, 1, 2, 3] |
+| [0, 1, 2]    |
+| [0, 1]       |
+| [0]          |
+| []           |
+|              |
++--------------+
+(6 rows)
+
+!ok
+
+SELECT "set" MULTISET INTERSECT DISTINCT "set" AS u FROM COMPLEX;
++--------------+
+| U            |
++--------------+
+| [0, 1, 2, 3] |
+| [0, 1, 2]    |
+| [0, 1]       |
+| [0]          |
+| []           |
+|              |
++--------------+
+(6 rows)
+
+!ok
+
+SELECT "set" IS A SET AS u FROM COMPLEX;
++-------+
+| U     |
++-------+
+| false |
+| true  |
+| true  |
+| true  |
+| true  |
+| true  |
++-------+
+(6 rows)
+
+!ok
+
+SELECT (multiset[3] SUBMULTISET OF "set") FROM COMPLEX;
++--------+
+| EXPR$0 |
++--------+
+| false  |
+| false  |
+| false  |
+| false  |
+| true   |
+|        |
++--------+
+(6 rows)
+
+!ok
+
+SELECT "set" MULTISET EXCEPT "set" AS u FROM COMPLEX;
++----+
+| U  |
++----+
+| [] |
+| [] |
+| [] |
+| [] |
+| [] |
+|    |
++----+
+(6 rows)
+
+!ok
+
+SELECT KEY, "list" IS NULL AS N FROM COMPLEX;
++-----+-------+
+| KEY | N     |
++-----+-------+
+|   0 | true  |
+|   1 | false |
+|   2 | false |
+|   3 | false |
+|   4 | false |
+|   5 | false |
++-----+-------+
+(6 rows)
+
+!ok
+
+SELECT KEY, "map" IS NULL AS N FROM COMPLEX;
++-----+-------+
+| KEY | N     |
++-----+-------+
+|   0 | true  |
+|   1 | true  |
+|   2 | false |
+|   3 | false |
+|   4 | false |
+|   5 | false |
++-----+-------+
+(6 rows)
+
+!ok
+
+SELECT KEY, "set" IS NULL AS N FROM COMPLEX;
++-----+-------+
+| KEY | N     |
++-----+-------+
+|   0 | true  |
+|   1 | false |
+|   2 | false |
+|   3 | false |
+|   4 | false |
+|   5 | false |
++-----+-------+
+(6 rows)
+
+!ok
+
 # End spark.iq
diff --git 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index 20680a67b5..b954a595ed 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -1008,7 +1008,7 @@ public class RexImpTable {
       // Multisets & arrays
       defineMethod(CARDINALITY, BuiltInMethod.COLLECTION_SIZE.method,
           NullPolicy.STRICT);
-      defineMethod(SLICE, BuiltInMethod.SLICE.method, NullPolicy.NONE);
+      defineMethod(SLICE, BuiltInMethod.SLICE.method, NullPolicy.STRICT);
       defineMethod(ELEMENT, BuiltInMethod.ELEMENT.method, NullPolicy.STRICT);
       defineMethod(STRUCT_ACCESS, BuiltInMethod.STRUCT_ACCESS.method, 
NullPolicy.ANY);
       defineMethod(MEMBER_OF, BuiltInMethod.MEMBER_OF.method, NullPolicy.NONE);
@@ -1019,7 +1019,7 @@ public class RexImpTable {
       defineMethod(ARRAY_EXCEPT, BuiltInMethod.ARRAY_EXCEPT.method, 
NullPolicy.ANY);
       defineMethod(ARRAY_JOIN, BuiltInMethod.ARRAY_TO_STRING.method,
           NullPolicy.STRICT);
-      defineMethod(ARRAY_INSERT, BuiltInMethod.ARRAY_INSERT.method, 
NullPolicy.NONE);
+      defineMethod(ARRAY_INSERT, BuiltInMethod.ARRAY_INSERT.method, 
NullPolicy.ARG0);
       defineMethod(ARRAY_INTERSECT, BuiltInMethod.ARRAY_INTERSECT.method, 
NullPolicy.ANY);
       defineMethod(ARRAY_LENGTH, BuiltInMethod.COLLECTION_SIZE.method, 
NullPolicy.STRICT);
       defineMethod(ARRAY_MAX, BuiltInMethod.ARRAY_MAX.method, 
NullPolicy.STRICT);
@@ -1048,27 +1048,27 @@ public class RexImpTable {
       define(ARRAY_CONCAT, new ArrayConcatImplementor());
       define(SORT_ARRAY, new SortArrayImplementor());
       final MethodImplementor isEmptyImplementor =
-          new MethodImplementor(BuiltInMethod.IS_EMPTY.method, NullPolicy.NONE,
+          new MethodImplementor(BuiltInMethod.IS_EMPTY.method, 
NullPolicy.STRICT,
               false);
       define(IS_EMPTY, isEmptyImplementor);
       define(IS_NOT_EMPTY, NotImplementor.of(isEmptyImplementor));
       final MethodImplementor isASetImplementor =
-          new MethodImplementor(BuiltInMethod.IS_A_SET.method, NullPolicy.NONE,
+          new MethodImplementor(BuiltInMethod.IS_A_SET.method, 
NullPolicy.STRICT,
               false);
       define(IS_A_SET, isASetImplementor);
       define(IS_NOT_A_SET, NotImplementor.of(isASetImplementor));
       defineMethod(MULTISET_INTERSECT_DISTINCT,
-          BuiltInMethod.MULTISET_INTERSECT_DISTINCT.method, NullPolicy.NONE);
+          BuiltInMethod.MULTISET_INTERSECT_DISTINCT.method, NullPolicy.STRICT);
       defineMethod(MULTISET_INTERSECT,
-          BuiltInMethod.MULTISET_INTERSECT_ALL.method, NullPolicy.NONE);
+          BuiltInMethod.MULTISET_INTERSECT_ALL.method, NullPolicy.STRICT);
       defineMethod(MULTISET_EXCEPT_DISTINCT,
-          BuiltInMethod.MULTISET_EXCEPT_DISTINCT.method, NullPolicy.NONE);
-      defineMethod(MULTISET_EXCEPT, BuiltInMethod.MULTISET_EXCEPT_ALL.method, 
NullPolicy.NONE);
+          BuiltInMethod.MULTISET_EXCEPT_DISTINCT.method, NullPolicy.STRICT);
+      defineMethod(MULTISET_EXCEPT, BuiltInMethod.MULTISET_EXCEPT_ALL.method, 
NullPolicy.STRICT);
       defineMethod(MULTISET_UNION_DISTINCT,
-          BuiltInMethod.MULTISET_UNION_DISTINCT.method, NullPolicy.NONE);
-      defineMethod(MULTISET_UNION, BuiltInMethod.MULTISET_UNION_ALL.method, 
NullPolicy.NONE);
+          BuiltInMethod.MULTISET_UNION_DISTINCT.method, NullPolicy.STRICT);
+      defineMethod(MULTISET_UNION, BuiltInMethod.MULTISET_UNION_ALL.method, 
NullPolicy.STRICT);
       final MethodImplementor subMultisetImplementor =
-          new MethodImplementor(BuiltInMethod.SUBMULTISET_OF.method, 
NullPolicy.NONE, false);
+          new MethodImplementor(BuiltInMethod.SUBMULTISET_OF.method, 
NullPolicy.STRICT, false);
       define(SUBMULTISET_OF, subMultisetImplementor);
       define(NOT_SUBMULTISET_OF, NotImplementor.of(subMultisetImplementor));
 
diff --git 
a/core/src/main/java/org/apache/calcite/jdbc/JavaTypeFactoryImpl.java 
b/core/src/main/java/org/apache/calcite/jdbc/JavaTypeFactoryImpl.java
index 1b015fe2f9..6092bcafae 100644
--- a/core/src/main/java/org/apache/calcite/jdbc/JavaTypeFactoryImpl.java
+++ b/core/src/main/java/org/apache/calcite/jdbc/JavaTypeFactoryImpl.java
@@ -126,17 +126,20 @@ public class JavaTypeFactoryImpl
       final Types.ArrayType arrayType = (Types.ArrayType) type;
       final RelDataType componentRelType =
           createType(arrayType.getComponentType());
-      return createArrayType(
-          createTypeWithNullability(componentRelType,
+      RelDataType result =
+          createArrayType(
+              createTypeWithNullability(componentRelType,
               arrayType.componentIsNullable()), 
arrayType.maximumCardinality());
+      return createTypeWithNullability(result, true);
     }
     if (type instanceof Types.MapType) {
       final Types.MapType mapType = (Types.MapType) type;
       final RelDataType keyRelType = createType(mapType.getKeyType());
       final RelDataType valueRelType = createType(mapType.getValueType());
-      return createMapType(
-          createTypeWithNullability(keyRelType, mapType.keyIsNullable()),
-          createTypeWithNullability(valueRelType, mapType.valueIsNullable()));
+      RelDataType result =
+          createMapType(createTypeWithNullability(keyRelType, 
mapType.keyIsNullable()),
+              createTypeWithNullability(valueRelType, 
mapType.valueIsNullable()));
+      return createTypeWithNullability(result, true);
     }
     if (!(type instanceof Class)) {
       throw new UnsupportedOperationException("TODO: implement " + type);
diff --git a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java 
b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
index 980ed5e0fe..68f77fa2d0 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -3804,12 +3804,18 @@ public class SqlFunctions {
   // Helpers
 
   /** Helper for implementing MIN. Somewhat similar to LEAST operator. */
-  public static <T extends Comparable<T>> T lesser(T b0, T b1) {
-    return b0 == null || b0.compareTo(b1) > 0 ? b1 : b0;
+  public static @Nullable <T extends Comparable<T>> T lesser(@Nullable T b0, 
@Nullable T b1) {
+    if (b0 == null) {
+      return b1;
+    }
+    if (b1 == null) {
+      return b0;
+    }
+    return b0.compareTo(b1) > 0 ? b1 : b0;
   }
 
   /** LEAST operator. */
-  public static <T extends Comparable<T>> T least(T b0, T b1) {
+  public static @Nullable <T extends Comparable<T>> T least(@Nullable T b0, 
@Nullable T b1) {
     return b0 == null || b1 != null && b0.compareTo(b1) > 0 ? b1 : b0;
   }
 
@@ -3877,13 +3883,41 @@ public class SqlFunctions {
     return b0 > b1 ? b1 : b0;
   }
 
+  public static @Nullable <T extends Comparable<T>> List<T> lesser(
+      @Nullable List<T> b0, @Nullable List<T> b1) {
+    if (b0 == null) {
+      return b1;
+    }
+    if (b1 == null) {
+      return b0;
+    }
+    return lt(b0, b1) ? b0 : b1;
+  }
+
+  public static @Nullable <T extends Comparable<T>> List<T> greater(
+      @Nullable List<T> b0, @Nullable List<T> b1) {
+    if (b0 == null) {
+      return b1;
+    }
+    if (b1 == null) {
+      return b0;
+    }
+    return gt(b0, b1) ? b0 : b1;
+  }
+
   /** Helper for implementing MAX. Somewhat similar to GREATEST operator. */
-  public static <T extends Comparable<T>> T greater(T b0, T b1) {
-    return b0 == null || b0.compareTo(b1) < 0 ? b1 : b0;
+  public static @Nullable <T extends Comparable<T>> T greater(@Nullable T b0, 
@Nullable T b1) {
+    if (b0 == null) {
+      return b1;
+    }
+    if (b1 == null) {
+      return b0;
+    }
+    return b0.compareTo(b1) < 0 ? b1 : b0;
   }
 
   /** GREATEST operator. */
-  public static <T extends Comparable<T>> T greatest(T b0, T b1) {
+  public static @Nullable <T extends Comparable<T>> T greatest(@Nullable T b0, 
@Nullable T b1) {
     return b0 == null || b1 != null && b0.compareTo(b1) < 0 ? b1 : b0;
   }
 
diff --git 
a/core/src/test/java/org/apache/calcite/test/ReflectiveSchemaTest.java 
b/core/src/test/java/org/apache/calcite/test/ReflectiveSchemaTest.java
index d00ce08168..bc2c45096d 100644
--- a/core/src/test/java/org/apache/calcite/test/ReflectiveSchemaTest.java
+++ b/core/src/test/java/org/apache/calcite/test/ReflectiveSchemaTest.java
@@ -311,8 +311,20 @@ public class ReflectiveSchemaTest {
             + "primitiveBoolean=true\n");
     with.query("select * from \"s\".\"everyTypes\"")
         .returns(""
-            + "primitiveBoolean=false; primitiveByte=0; primitiveChar=\u0000; 
primitiveShort=0; primitiveInt=0; primitiveLong=0; primitiveFloat=0.0; 
primitiveDouble=0.0; wrapperBoolean=false; wrapperByte=0; 
wrapperCharacter=\u0000; wrapperShort=0; wrapperInteger=0; wrapperLong=0; 
wrapperFloat=0.0; wrapperDouble=0.0; sqlDate=1970-01-01; sqlTime=00:00:00; 
sqlTimestamp=1970-01-01 00:00:00; utilDate=1970-01-01 00:00:00; string=1; 
bigDecimal=0\n"
-            + "primitiveBoolean=true; primitiveByte=127; primitiveChar=\uffff; 
primitiveShort=32767; primitiveInt=2147483647; 
primitiveLong=9223372036854775807; primitiveFloat=3.4028235E38; 
primitiveDouble=1.7976931348623157E308; wrapperBoolean=null; wrapperByte=null; 
wrapperCharacter=null; wrapperShort=null; wrapperInteger=null; 
wrapperLong=null; wrapperFloat=null; wrapperDouble=null; sqlDate=null; 
sqlTime=null; sqlTimestamp=null; utilDate=null; string=null; 
bigDecimal=null\n");
+            + "primitiveBoolean=false; primitiveByte=0; primitiveChar=\u0000; "
+            + "primitiveShort=0; primitiveInt=0; primitiveLong=0; 
primitiveFloat=0.0; "
+            + "primitiveDouble=0.0; wrapperBoolean=false; wrapperByte=0; 
wrapperCharacter=\u0000; "
+            + "wrapperShort=0; wrapperInteger=0; wrapperLong=0; 
wrapperFloat=0.0; "
+            + "wrapperDouble=0.0; sqlDate=1970-01-01; sqlTime=00:00:00; "
+            + "sqlTimestamp=1970-01-01 00:00:00; utilDate=1970-01-01 00:00:00; 
"
+            + "string=1; bigDecimal=0; list=[]\n"
+            + "primitiveBoolean=true; primitiveByte=127; primitiveChar=\uffff; 
"
+            + "primitiveShort=32767; primitiveInt=2147483647; 
primitiveLong=9223372036854775807; "
+            + "primitiveFloat=3.4028235E38; 
primitiveDouble=1.7976931348623157E308; "
+            + "wrapperBoolean=null; wrapperByte=null; wrapperCharacter=null; 
wrapperShort=null; "
+            + "wrapperInteger=null; wrapperLong=null; wrapperFloat=null; 
wrapperDouble=null; "
+            + "sqlDate=null; sqlTime=null; sqlTimestamp=null; utilDate=null; 
string=null; "
+            + "bigDecimal=null; list=null\n");
   }
 
   /** Tests NOT for nullable columns.
@@ -498,6 +510,8 @@ public class ReflectiveSchemaTest {
       return input.getTimestamp(1);
     case java.sql.Types.DECIMAL:
       return input.getBigDecimal(1);
+    case java.sql.Types.ARRAY:
+      return input.getArray(1);
     default:
       throw new AssertionError(type);
     }
diff --git a/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java 
b/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
index 253deb08dc..34f833eeb6 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlFunctionsTest.java
@@ -719,12 +719,7 @@ class SqlFunctionsTest {
   @Test void testLesser() {
     assertThat(lesser("a", "bc"), is("a"));
     assertThat(lesser("bc", "ac"), is("ac"));
-    try {
-      Object o = lesser("a", null);
-      fail("Expected NPE, got " + o);
-    } catch (NullPointerException e) {
-      // ok
-    }
+    assertThat(lesser("a", null), is("a"));
     assertThat(lesser(null, "a"), is("a"));
     assertThat(lesser((String) null, null), nullValue());
   }
@@ -732,12 +727,7 @@ class SqlFunctionsTest {
   @Test void testGreater() {
     assertThat(greater("a", "bc"), is("bc"));
     assertThat(greater("bc", "ac"), is("bc"));
-    try {
-      Object o = greater("a", null);
-      fail("Expected NPE, got " + o);
-    } catch (NullPointerException e) {
-      // ok
-    }
+    assertThat(greater("a", null), is("a"));
     assertThat(greater(null, "a"), is("a"));
     assertThat(greater((String) null, null), nullValue());
   }
diff --git 
a/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCalcTest.java 
b/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCalcTest.java
index 7e801e18f8..708f077662 100644
--- 
a/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCalcTest.java
+++ 
b/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCalcTest.java
@@ -20,6 +20,7 @@ import org.apache.calcite.adapter.java.ReflectiveSchema;
 import org.apache.calcite.sql.SqlOperator;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.test.CalciteAssert;
+import org.apache.calcite.test.schemata.catchall.CatchallSchema;
 import org.apache.calcite.test.schemata.hr.HrSchema;
 
 import org.junit.jupiter.api.Test;
@@ -115,4 +116,17 @@ class EnumerableCalcTest {
                     builder.field("name"))
                 .build());
   }
+
+  /** Test case for <a 
href="https://issues.apache.org/jira/browse/CALCITE-6680";>[CALCITE-6680]
+   * RexImpTable erroneously declares NullPolicy.NONE for IS_EMPTY</a>. */
+  @Test public void testEmptyCheckOnArray() {
+    CalciteAssert.that()
+        .withSchema("s", new ReflectiveSchema(new CatchallSchema()))
+        .withRel(builder -> builder
+            .scan("s", "everyTypes")
+            .project(builder.call(SqlStdOperatorTable.IS_EMPTY, 
builder.field("list")))
+            .build())
+        .planContains("input_value != null && input_value.isEmpty()")
+        .returnsUnordered("$f0=false", "$f0=true");
+  }
 }
diff --git 
a/testkit/src/main/java/org/apache/calcite/test/schemata/catchall/CatchallSchema.java
 
b/testkit/src/main/java/org/apache/calcite/test/schemata/catchall/CatchallSchema.java
index 2cea53190a..df1c8dbb9a 100644
--- 
a/testkit/src/main/java/org/apache/calcite/test/schemata/catchall/CatchallSchema.java
+++ 
b/testkit/src/main/java/org/apache/calcite/test/schemata/catchall/CatchallSchema.java
@@ -16,6 +16,7 @@
  */
 package org.apache.calcite.test.schemata.catchall;
 
+import org.apache.calcite.adapter.java.Array;
 import org.apache.calcite.linq4j.Enumerable;
 import org.apache.calcite.linq4j.Linq4j;
 import org.apache.calcite.linq4j.tree.Primitive;
@@ -30,6 +31,7 @@ import java.sql.Time;
 import java.sql.Timestamp;
 import java.util.Arrays;
 import java.util.BitSet;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 
@@ -54,13 +56,13 @@ public class CatchallSchema {
           false, (byte) 0, (char) 0, (short) 0, 0, 0L, 0F, 0D,
           false, (byte) 0, (char) 0, (short) 0, 0, 0L, 0F, 0D,
           new java.sql.Date(0), new Time(0), new Timestamp(0),
-          new Date(0), "1", BigDecimal.ZERO),
+          new Date(0), "1", BigDecimal.ZERO, Collections.emptyList()),
       new EveryType(
           true, Byte.MAX_VALUE, Character.MAX_VALUE, Short.MAX_VALUE,
           Integer.MAX_VALUE, Long.MAX_VALUE, Float.MAX_VALUE,
           Double.MAX_VALUE,
           null, null, null, null, null, null, null, null,
-          null, null, null, null, null, null),
+          null, null, null, null, null, null, null),
   };
 
   public final AllPrivate[] allPrivates =
@@ -127,6 +129,7 @@ public class CatchallSchema {
     public final @Nullable Date utilDate;
     public final @Nullable String string;
     public final @Nullable BigDecimal bigDecimal;
+    public final @Nullable @Array(component = String.class) List<String> list;
 
     public EveryType(
         boolean primitiveBoolean,
@@ -150,7 +153,8 @@ public class CatchallSchema {
         @Nullable Timestamp sqlTimestamp,
         @Nullable Date utilDate,
         @Nullable String string,
-        @Nullable BigDecimal bigDecimal) {
+        @Nullable BigDecimal bigDecimal,
+        @Nullable List<String> list) {
       this.primitiveBoolean = primitiveBoolean;
       this.primitiveByte = primitiveByte;
       this.primitiveChar = primitiveChar;
@@ -173,6 +177,7 @@ public class CatchallSchema {
       this.utilDate = utilDate;
       this.string = string;
       this.bigDecimal = bigDecimal;
+      this.list = list;
     }
 
     public static Enumerable<Field> fields() {

Reply via email to