Skip to content

Commit 3ab85f3

Browse files
authored
[fix](arrayfuncs) fix array min/max func (apache#39307)
in fe we will check the params same with be in be we throw exception if params is not support otherwise we will meet coredump like this ``` start BE in local mode /mnt/disk1/wangqiannan/amory/doris/be/src/vec/functions/array/function_array_aggregation.cpp:150:26: runtime error: member call on null pointer of type 'doris::vectorized::IAggregateFunction' #0 0x55dc04c6b409 in doris::vectorized::ArrayAggregateImpl<(doris::vectorized::AggregateOperation)1>::get_return_type(std::vector<std::shared_ptr<doris::vectorized::IDataType const>, std::allocator<std::shared_ptr<doris::vectorized::IDataType const>>> const&) /mnt/disk1/wangqiannan/amory/doris/be/src/vec/functions/array/function_array_aggregation.cpp:150:26 #1 0x55dc04c6a41f in doris::vectorized::FunctionArrayMapped<doris::vectorized::ArrayAggregateImpl<(doris::vectorized::AggregateOperation)1>, doris::vectorized::NameArrayMax>::get_return_type_impl(std::vector<std::shared_ptr<doris::vectorized::IDataType const>, std::allocator<std::shared_ptr<doris::vectorized::IDataType const>>> const&) const /mnt/disk1/wangqiannan/amory/doris/be/src/vec/functions/array/function_array_mapped.h:71:16 #2 0x55dc049b06cb in doris::vectorized::FunctionBuilderImpl::get_return_type_impl(std::vector<doris::vectorized::ColumnWithTypeAndName, std::allocator<doris::vectorized::ColumnWithTypeAndName>> const&) const /mnt/disk1/wangqiannan/amory/doris/be/src/vec/functions/function.h:339:16 #3 0x55dc049c1385 in doris::vectorized::DefaultFunctionBuilder::get_return_type_impl(std::vector<doris::vectorized::ColumnWithTypeAndName, std::allocator<doris::vectorized::ColumnWithTypeAndName>> const&) const /mnt/disk1/wangqiannan/amory/doris/be/src/vec/functions/function.h:579:26 #4 0x55dc0b0a5652 in doris::vectorized::FunctionBuilderImpl::get_return_type_without_low_cardinality(std::vector<doris::vectorized::ColumnWithTypeAndName, std::allocator<doris::vectorized::ColumnWithTypeAndName>> const&) const /mnt/disk1/wangqiannan/amory/doris/be/src/vec/functions/function.cpp:283:12 #5 0x55dc0b0a5fd4 in doris::vectorized::FunctionBuilderImpl::get_return_type(std::vector<doris::vectorized::ColumnWithTypeAndName, std::allocator<doris::vectorized::ColumnWithTypeAndName>> const&) const /mnt/disk1/wangqiannan/amory/doris/be/src/vec/functions/function.cpp:298:17 #6 0x55dc04997050 in doris::vectorized::FunctionBuilderImpl::build(std::vector<doris::vectorized::ColumnWithTypeAndName, std::allocator<doris::vectorized::ColumnWithTypeAndName>> const&, std::shared_ptr<doris::vectorized::IDataType const> const&) const /mnt/disk1/wangqiannan/amory/doris/be/src/vec/functions/function.h:296:47 #7 0x55dbde3d727f in doris::vectorized::SimpleFunctionFactory::get_function(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<doris::vectorized::ColumnWithTypeAndName, std::allocator<doris::vectorized::ColumnWithTypeAndName>> const&, std::shared_ptr<doris::vectorized::IDataType const> const&, int) /mnt/disk1/wangqiannan/amory/doris/be/src/vec/functions/simple_function_factory.h:193:32 #8 0x55dc04984b4d in doris::vectorized::VectorizedFnCall::prepare(doris::RuntimeState*, doris::RowDescriptor const&, doris::vectorized::VExprContext*) /mnt/disk1/wangqiannan/amory/doris/be/src/vec/exprs/vectorized_fn_call.cpp:111:55 #9 0x55dc04ab9b7a in doris::vectorized::VExprContext::prepare(doris::RuntimeState*, doris::RowDescriptor const&) /mnt/disk1/wangqiannan/amory/doris/be/src/vec/exprs/vexpr_context.cpp:64:5 #10 0x55dbdf625845 in doris::Status doris::FoldConstantExecutor::_prepare_and_open<doris::vectorized::VExprContext>(doris::vectorized::VExprContext*) /mnt/disk1/wangqiannan/amory/doris/be/src/runtime/fold_constant_executor.cpp:185:5 #11 0x55dbdf60db76 in doris::FoldConstantExecutor::fold_constant_vexpr(doris::TFoldConstantParams const&, doris::PConstantExprResult*) /mnt/disk1/wangqiannan/amory/doris/be/src/runtime/fold_constant_executor.cpp:94:13 #12 0x55dbdf4f58d6 in doris::PInternalService::_fold_constant_expr(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, doris::PConstantExprResult*) /mnt/disk1/wangqiannan/amory/doris/be/src/service/internal_service.cpp:1498:5 #13 0x55dbdf544e3e in doris::PInternalService::fold_constant_expr(google::protobuf::RpcController*, doris::PConstantExprRequest const*, doris::PConstantExprResult*, google::protobuf::Closure*)::$_0::operator()() const /mnt/disk1/wangqiannan/amory/doris/be/src/service/internal_service.cpp:1476:14 #14 0x55dbdf54431e in void std::__invoke_impl<void, doris::PInternalService::fold_constant_expr(google::protobuf::RpcController*, doris::PConstantExprRequest const*, doris::PConstantExprResult*, google::protobuf::Closure*)::$_0&>(std::__invoke_other, doris::PInternalService::fold_constant_expr(google::protobuf::RpcController*, doris::PConstantExprRequest const*, doris::PConstantExprResult*, google::protobuf::Closure*)::$_0&) /mnt/disk1/wangqiannan/tool/ldb_toolchain_16/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:61:14 #15 0x55dbdf54425e in std::enable_if<is_invocable_r_v<void, doris::PInternalService::fold_constant_expr(google::protobuf::RpcController*, doris::PConstantExprRequest const*, doris::PConstantExprResult*, google::protobuf::Closure*)::$_0&>, void>::type std::__invoke_r<void, doris::PInternalService::fold_constant_expr(google::protobuf::RpcController*, doris::PConstantExprRequest const*, doris::PConstantExprResult*, google::protobuf::Closure*)::$_0&>(doris::PInternalService::fold_constant_expr(google::protobuf::RpcController*, doris::PConstantExprRequest const*, doris::PConstantExprResult*, google::protobuf::Closure*)::$_0&) /mnt/disk1/wangqiannan/tool/ldb_toolchain_16/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/invoke.h:111:2 #16 0x55dbdf543f35 in std::_Function_handler<void (), doris::PInternalService::fold_constant_expr(google::protobuf::RpcController*, doris::PConstantExprRequest const*, doris::PConstantExprResult*, google::protobuf::Closure*)::$_0>::_M_invoke(std::_Any_data const&) /mnt/disk1/wangqiannan/tool/ldb_toolchain_16/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:291:9 #17 0x55dbd8cd425a in std::function<void ()>::operator()() const /mnt/disk1/wangqiannan/tool/ldb_toolchain_16/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/std_function.h:560:9 apache#18 0x55dbdf59ee14 in doris::WorkThreadPool<false>::work_thread(int) /mnt/disk1/wangqiannan/amory/doris/be/src/util/work_thread_pool.hpp:158:17 @@@ ```
1 parent 7372c99 commit 3ab85f3

File tree

7 files changed

+106
-1
lines changed

7 files changed

+106
-1
lines changed

be/src/vec/functions/array/function_array_aggregation.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,13 @@ struct ArrayAggregateImpl {
147147
const DataTypeArray* data_type_array =
148148
static_cast<const DataTypeArray*>(remove_nullable(arguments[0]).get());
149149
auto function = Function::create(data_type_array->get_nested_type());
150-
return function->get_return_type();
150+
if (function) {
151+
return function->get_return_type();
152+
} else {
153+
throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
154+
"Unexpected type {} for aggregation {}",
155+
data_type_array->get_nested_type()->get_name(), operation);
156+
}
151157
}
152158

153159
static Status execute(Block& block, const ColumnNumbers& arguments, size_t result,

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayMax.java

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.doris.nereids.trees.expressions.functions.scalar;
1919

2020
import org.apache.doris.catalog.FunctionSignature;
21+
import org.apache.doris.nereids.exceptions.AnalysisException;
2122
import org.apache.doris.nereids.trees.expressions.Expression;
2223
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
2324
import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
@@ -50,6 +51,14 @@ public ArrayMax(Expression arg) {
5051
super("array_max", arg);
5152
}
5253

54+
@Override
55+
public void checkLegalityBeforeTypeCoercion() {
56+
DataType argType = child().getDataType();
57+
if (((ArrayType) argType).getItemType().isComplexType()) {
58+
throw new AnalysisException("array_max does not support complex types: " + toSql());
59+
}
60+
}
61+
5362
@Override
5463
public DataType getDataType() {
5564
return ((ArrayType) (child().getDataType())).getItemType();

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayMin.java

+9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package org.apache.doris.nereids.trees.expressions.functions.scalar;
1919

2020
import org.apache.doris.catalog.FunctionSignature;
21+
import org.apache.doris.nereids.exceptions.AnalysisException;
2122
import org.apache.doris.nereids.trees.expressions.Expression;
2223
import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
2324
import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
@@ -50,6 +51,14 @@ public ArrayMin(Expression arg) {
5051
super("array_min", arg);
5152
}
5253

54+
@Override
55+
public void checkLegalityBeforeTypeCoercion() {
56+
DataType argType = child().getDataType();
57+
if (((ArrayType) argType).getItemType().isComplexType()) {
58+
throw new AnalysisException("array_min does not support complex types: " + toSql());
59+
}
60+
}
61+
5362
@Override
5463
public DataType getDataType() {
5564
return ((ArrayType) (child().getDataType())).getItemType();

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArrayReverseSort.java

+10
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
package org.apache.doris.nereids.trees.expressions.functions.scalar;
1919

2020
import org.apache.doris.catalog.FunctionSignature;
21+
import org.apache.doris.nereids.exceptions.AnalysisException;
2122
import org.apache.doris.nereids.trees.expressions.Expression;
2223
import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
2324
import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
2425
import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
2526
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
2627
import org.apache.doris.nereids.types.ArrayType;
28+
import org.apache.doris.nereids.types.DataType;
2729
import org.apache.doris.nereids.types.coercion.AnyDataType;
2830

2931
import com.google.common.base.Preconditions;
@@ -48,6 +50,14 @@ public ArrayReverseSort(Expression arg) {
4850
super("array_reverse_sort", arg);
4951
}
5052

53+
@Override
54+
public void checkLegalityBeforeTypeCoercion() {
55+
DataType argType = child().getDataType();
56+
if (((ArrayType) argType).getItemType().isComplexType()) {
57+
throw new AnalysisException("array_reverse_sort does not support complex types: " + toSql());
58+
}
59+
}
60+
5161
/**
5262
* withChildren.
5363
*/

fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/ArraySort.java

+10
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,14 @@
1818
package org.apache.doris.nereids.trees.expressions.functions.scalar;
1919

2020
import org.apache.doris.catalog.FunctionSignature;
21+
import org.apache.doris.nereids.exceptions.AnalysisException;
2122
import org.apache.doris.nereids.trees.expressions.Expression;
2223
import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
2324
import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
2425
import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
2526
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
2627
import org.apache.doris.nereids.types.ArrayType;
28+
import org.apache.doris.nereids.types.DataType;
2729
import org.apache.doris.nereids.types.coercion.AnyDataType;
2830

2931
import com.google.common.base.Preconditions;
@@ -48,6 +50,14 @@ public ArraySort(Expression arg) {
4850
super("array_sort", arg);
4951
}
5052

53+
@Override
54+
public void checkLegalityBeforeTypeCoercion() {
55+
DataType argType = child().getDataType();
56+
if (((ArrayType) argType).getItemType().isComplexType()) {
57+
throw new AnalysisException("array_sort does not support complex types: " + toSql());
58+
}
59+
}
60+
5161
/**
5262
* withChildren.
5363
*/

regression-test/suites/nereids_function_p0/scalar_function/Array.groovy

+30
Original file line numberDiff line numberDiff line change
@@ -1311,6 +1311,36 @@ suite("nereids_scalar_fn_Array") {
13111311
sql """ set debug_skip_fold_constant=true; """
13121312
qt_array_empty_be """select array()"""
13131313

1314+
// array_min/max with nested array for args
1315+
test {
1316+
sql "select array_min(array(1,2,3),array(4,5,6));"
1317+
check{result, exception, startTime, endTime ->
1318+
assertTrue(exception != null)
1319+
logger.info(exception.message)
1320+
}
1321+
}
1322+
test {
1323+
sql "select array_max(array(1,2,3),array(4,5,6));"
1324+
check{result, exception, startTime, endTime ->
1325+
assertTrue(exception != null)
1326+
logger.info(exception.message)
1327+
}
1328+
}
1329+
1330+
test {
1331+
sql "select array_min(array(split_by_string('a,b,c',',')));"
1332+
check{result, exception, startTime, endTime ->
1333+
assertTrue(exception != null)
1334+
logger.info(exception.message)
1335+
}
1336+
}
1337+
test {
1338+
sql "select array_max(array(split_by_string('a,b,c',',')));"
1339+
check{result, exception, startTime, endTime ->
1340+
assertTrue(exception != null)
1341+
logger.info(exception.message)
1342+
}
1343+
}
13141344
// array_map with string is can be succeed
13151345
qt_sql_array_map """select array_map(x->x!='', split_by_string('amory,is,better,committing', ','))"""
13161346

regression-test/suites/query_p0/sql_functions/array_functions/test_array_functions_by_literal.groovy

+31
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,37 @@ suite("test_array_functions_by_literal") {
411411
assert("${ex}".contains("errCode = 2, detailMessage = No matching function with signature: array_intersect"))
412412
}
413413

414+
// array_min/max with nested array for args
415+
test {
416+
sql "select array_min(array(1,2,3),array(4,5,6));"
417+
check{result, exception, startTime, endTime ->
418+
assertTrue(exception != null)
419+
logger.info(exception.message)
420+
}
421+
}
422+
test {
423+
sql "select array_max(array(1,2,3),array(4,5,6));"
424+
check{result, exception, startTime, endTime ->
425+
assertTrue(exception != null)
426+
logger.info(exception.message)
427+
}
428+
}
429+
430+
test {
431+
sql "select array_min(array(split_by_string('a,b,c',',')));"
432+
check{result, exception, startTime, endTime ->
433+
assertTrue(exception != null)
434+
logger.info(exception.message)
435+
}
436+
}
437+
test {
438+
sql "select array_max(array(split_by_string('a,b,c',',')));"
439+
check{result, exception, startTime, endTime ->
440+
assertTrue(exception != null)
441+
logger.info(exception.message)
442+
}
443+
}
444+
414445
// array_map with string is can be succeed
415446
qt_sql_array_map """ select array_map(x->x!='', split_by_string('amory,is,better,committing', ',')) """
416447

0 commit comments

Comments
 (0)