diff --git a/be/src/exec/pipeline/table_function_operator.cpp b/be/src/exec/pipeline/table_function_operator.cpp index 673976a019f9a..d02ddb0317044 100644 --- a/be/src/exec/pipeline/table_function_operator.cpp +++ b/be/src/exec/pipeline/table_function_operator.cpp @@ -67,8 +67,7 @@ Status TableFunctionOperator::prepare(RuntimeState* state) { } if (table_function_name == "unnest" && arg_types.size() > 1) { - _table_function = vectorized::get_table_function(table_function_name, {INVALID_TYPE}, {INVALID_TYPE}, - table_fn.binary_type); + _table_function = vectorized::get_table_function(table_function_name, {}, {}, table_fn.binary_type); } else { _table_function = vectorized::get_table_function(table_function_name, arg_types, return_types, table_fn.binary_type); diff --git a/be/src/exec/vectorized/table_function_node.cpp b/be/src/exec/vectorized/table_function_node.cpp index 1c23e9c27c9fd..8017442734ed1 100644 --- a/be/src/exec/vectorized/table_function_node.cpp +++ b/be/src/exec/vectorized/table_function_node.cpp @@ -59,8 +59,7 @@ Status TableFunctionNode::init(const TPlanNode& tnode, RuntimeState* state) { } if (table_function_name == "unnest" && arg_types.size() > 1) { - _table_function = vectorized::get_table_function(table_function_name, {INVALID_TYPE}, {INVALID_TYPE}, - table_fn.binary_type); + _table_function = vectorized::get_table_function(table_function_name, {}, {}, table_fn.binary_type); } else { _table_function = vectorized::get_table_function(table_function_name, arg_types, return_types, table_fn.binary_type); diff --git a/be/src/exprs/table_function/table_function_factory.cpp b/be/src/exprs/table_function/table_function_factory.cpp index 4577b52c3a6da..4b03daff57fb6 100644 --- a/be/src/exprs/table_function/table_function_factory.cpp +++ b/be/src/exprs/table_function/table_function_factory.cpp @@ -82,7 +82,7 @@ TableFunctionResolver::TableFunctionResolver() { // and there is no special treatment for different types of input parameters, // this is just for compatibility and find the corresponding function TableFunctionPtr multi_unnest = std::make_shared(); - add_function_mapping("unnest", {INVALID_TYPE}, {INVALID_TYPE}, multi_unnest); + add_function_mapping("unnest", {}, {}, multi_unnest); TableFunctionPtr func_json_each = std::make_shared(); add_function_mapping("json_each", {TYPE_JSON}, {TYPE_VARCHAR, TYPE_JSON}, func_json_each); diff --git a/fe/fe-core/src/main/java/com/starrocks/catalog/FunctionSet.java b/fe/fe-core/src/main/java/com/starrocks/catalog/FunctionSet.java index d5911347c7965..64001de38583f 100644 --- a/fe/fe-core/src/main/java/com/starrocks/catalog/FunctionSet.java +++ b/fe/fe-core/src/main/java/com/starrocks/catalog/FunctionSet.java @@ -624,7 +624,7 @@ public Function getFunction(Function desc, Function.CompareMode mode) { return null; } - // Finally check for non-strict supertypes + // Finally, check for non-strict supertypes for (Function f : fns) { if (f.compare(desc, Function.CompareMode.IS_NONSTRICT_SUPERTYPE_OF) && isCastMatchAllowed(desc, f)) { return checkPolymorphicFunction(f, desc.getArgs()); @@ -1253,7 +1253,7 @@ private Function checkPolymorphicFunction(Function fn, Type[] paramTypes) { // Because unnest is a variadic function, and the types of multiple parameters may be inconsistent, // the current SR variadic function parsing can only support variadic parameters of the same type. // The unnest is treated specially here, and the type of the child is directly used as the unnest function type. - if (fn.functionName().equalsIgnoreCase("UNNEST")) { + if (fn.functionName().equals("unnest")) { List realTableFnRetTypes = new ArrayList<>(); for (Type paramType : paramTypes) { if (!paramType.isArrayType()) { diff --git a/fe/fe-core/src/main/java/com/starrocks/sql/analyzer/QueryAnalyzer.java b/fe/fe-core/src/main/java/com/starrocks/sql/analyzer/QueryAnalyzer.java index 21eee100fe0fc..db2546bf7590a 100644 --- a/fe/fe-core/src/main/java/com/starrocks/sql/analyzer/QueryAnalyzer.java +++ b/fe/fe-core/src/main/java/com/starrocks/sql/analyzer/QueryAnalyzer.java @@ -668,7 +668,7 @@ public Scope visitTableFunction(TableFunctionRelation node, Scope scope) { node.setChildExpressions(node.getFunctionParams().exprs()); if (node.getColumnNames() == null) { - if (tableFunction.getFunctionName().getFunction().equalsIgnoreCase("unnest")) { + if (tableFunction.getFunctionName().getFunction().equals("unnest")) { // If the unnest variadic function does not explicitly specify column name, // all column names are `unnest`. This refers to the return column name of postgresql. List columnNames = new ArrayList<>(); diff --git a/fe/fe-core/src/test/java/com/starrocks/sql/analyzer/AnalyzeLateralTest.java b/fe/fe-core/src/test/java/com/starrocks/sql/analyzer/AnalyzeLateralTest.java index 9eef836c6a213..7d6ed78b360a9 100644 --- a/fe/fe-core/src/test/java/com/starrocks/sql/analyzer/AnalyzeLateralTest.java +++ b/fe/fe-core/src/test/java/com/starrocks/sql/analyzer/AnalyzeLateralTest.java @@ -47,6 +47,12 @@ public void testUnnest() { "Table Function clause cannot contain aggregations"); } + @Test + public void testUpperCase() { + analyzeSuccess("select v1,t.* from tarray, UNNEST(v3) t"); + analyzeSuccess("select * from tarray, UNNEST(v3, ['a', 'b', 'c']) as t(unnest_1, unnest_2)"); + } + @Test public void testVarArgs() { analyzeSuccess("select * from tarray, unnest(v3) as t(unnest_1)"); @@ -64,5 +70,9 @@ public void testVarArgs() { "table t has 1 columns available but 2 columns specified"); analyzeFail("select * from tarray, unnest(v3) as t(unnest_1, unnest_2)", "table t has 2 columns available but 1 columns specified"); + + analyzeFail("select * from tarray, unnest(null, null) as t(unnest_1, unnest_2)", "Unknown table function"); + analyzeFail("select * from tarray, unnest(v3, null) as t(unnest_1, unnest_2)", "Unknown table function"); + analyzeFail("select * from tarray, unnest(null, v3) as t(unnest_1, unnest_2)", "Unknown table function"); } } \ No newline at end of file