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 b32658f86638..e599b8be01d9 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 @@ -1399,7 +1399,7 @@ private static RelDataType arrayInsertReturnType(SqlOperatorBinding opBinding) { @LibraryOperator(libraries = {SPARK}) public static final SqlFunction ARRAY_REPEAT = SqlBasicFunction.create(SqlKind.ARRAY_REPEAT, - ReturnTypes.TO_ARRAY, + ReturnTypes.TO_ARRAY.andThen(SqlTypeTransforms.TO_NULLABLE), OperandTypes.sequence( "ARRAY_REPEAT(ANY, INTEGER)", OperandTypes.ANY, OperandTypes.typeName(SqlTypeName.INTEGER))); diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java index 51a13e0bc50a..fcb80a860206 100644 --- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java +++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java @@ -1990,6 +1990,20 @@ private void checkSemiOrAntiJoinProjectTranspose(JoinRelType type) { .check(); } + /** Test case for + * [CALCITE-6349] CoreRules.PROJECT_REDUCE_EXPRESSIONS crashes on expression + * with ARRAY_REPEAT. */ + @Test void testArrayRepeat() { + final String sql = "select array_repeat(1, null)"; + sql(sql) + .withFactory( + t -> t.withOperatorTable( + opTab -> SqlLibraryOperatorTableFactory.INSTANCE.getOperatorTable( + SqlLibrary.STANDARD, SqlLibrary.SPARK))) + .withRule(CoreRules.PROJECT_REDUCE_EXPRESSIONS) + .check(); + } + @Test void testDistinctCountMixed() { final String sql = "select deptno, count(distinct deptno, job) as cddj,\n" + " sum(sal) as s\n" diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml index bc940b804c8f..2fda17e231ec 100644 --- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml +++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml @@ -1283,6 +1283,23 @@ LogicalProject(DEPTNO=[$0], EXPR$1=[OR(AND(IS NOT NULL($5), <>($2, 0)), AND(<($3 LogicalAggregate(group=[{0}], i=[LITERAL_AGG(true)]) LogicalProject(MGR=[$3]) LogicalTableScan(table=[[CATALOG, SALES, EMP]]) +]]> + + + + + + + + + + + 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 69523906db6c..72539f189d5c 100644 --- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java +++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java @@ -6793,7 +6793,7 @@ void checkRegexpExtract(SqlOperatorFixture f0, FunctionAlias functionAlias) { f.checkScalar("array_repeat(map[1, 'a', 2, 'b'], 2)", "[{1=a, 2=b}, {1=a, 2=b}]", "(INTEGER NOT NULL, CHAR(1) NOT NULL) MAP NOT NULL ARRAY NOT NULL"); f.checkScalar("array_repeat(cast(null as integer), 2)", "[null, null]", - "INTEGER ARRAY NOT NULL"); + "INTEGER ARRAY"); // elements cast f.checkScalar("array_repeat(cast(1 as tinyint), 2)", "[1, 1]", "TINYINT NOT NULL ARRAY NOT NULL");