This is an automated email from the ASF dual-hosted git repository.
taiyangli pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-gluten.git
The following commit(s) were added to refs/heads/main by this push:
new feed276ab6 [GLUTEN-9083][CH] Fix array_sort exception (#9040)
feed276ab6 is described below
commit feed276ab6ce71cb57d4e9a9af57aaf2122f7292
Author: 李扬 <[email protected]>
AuthorDate: Tue Mar 18 18:29:07 2025 +0800
[GLUTEN-9083][CH] Fix array_sort exception (#9040)
* fix array_sort issue
* revert tests
---
.../execution/GlutenClickHouseTPCHNullableSuite.scala | 5 +++++
.../arrayHighOrderFunctions.cpp | 19 ++++++++++++++++++-
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git
a/backends-clickhouse/src/test/scala/org/apache/gluten/execution/GlutenClickHouseTPCHNullableSuite.scala
b/backends-clickhouse/src/test/scala/org/apache/gluten/execution/GlutenClickHouseTPCHNullableSuite.scala
index e33d241510..89c094f268 100644
---
a/backends-clickhouse/src/test/scala/org/apache/gluten/execution/GlutenClickHouseTPCHNullableSuite.scala
+++
b/backends-clickhouse/src/test/scala/org/apache/gluten/execution/GlutenClickHouseTPCHNullableSuite.scala
@@ -252,4 +252,9 @@ class GlutenClickHouseTPCHNullableSuite extends
GlutenClickHouseTPCHAbstractSuit
}
})
}
+
+ test("Fix array_sort issue-9038") {
+ val sql = "select array_sort(split(l_comment, ' ')) from lineitem limit 10"
+ runSql(sql) { _ => }
+ }
}
diff --git
a/cpp-ch/local-engine/Parser/scalar_function_parser/arrayHighOrderFunctions.cpp
b/cpp-ch/local-engine/Parser/scalar_function_parser/arrayHighOrderFunctions.cpp
index 3a06c77c7a..6b735ed175 100644
---
a/cpp-ch/local-engine/Parser/scalar_function_parser/arrayHighOrderFunctions.cpp
+++
b/cpp-ch/local-engine/Parser/scalar_function_parser/arrayHighOrderFunctions.cpp
@@ -100,7 +100,7 @@ public:
/// The difference of both types will result in runtime exceptions
in function capture.
const auto & src_array_type = parsed_args[0]->result_type;
DataTypePtr dst_array_type =
std::make_shared<DataTypeArray>(lambda_args.front().type);
- if (isNullableOrLowCardinalityNullable(src_array_type))
+ if (src_array_type->isNullable())
dst_array_type =
std::make_shared<DataTypeNullable>(dst_array_type);
const auto * dst_array_arg =
ActionsDAGUtil::convertNodeTypeIfNeeded(actions_dag, parsed_args[0],
dst_array_type);
return toFunctionNode(actions_dag, ch_func_name, {parsed_args[1],
dst_array_arg});
@@ -170,13 +170,16 @@ class FunctionParserArraySort : public FunctionParser
{
public:
static constexpr auto name = "array_sort";
+
explicit FunctionParserArraySort(ParserContextPtr parser_context_) :
FunctionParser(parser_context_) {}
~FunctionParserArraySort() override = default;
+
String getName() const override { return name; }
String getCHFunctionName(const substrait::Expression_ScalarFunction &
scalar_function) const override
{
return "arraySortSpark";
}
+
const DB::ActionsDAG::Node *
parse(const substrait::Expression_ScalarFunction & substrait_func,
DB::ActionsDAG & actions_dag) const override
{
@@ -191,6 +194,20 @@ public:
return toFunctionNode(actions_dag, ch_func_name, {parsed_args[0]});
}
+ auto lambda_args = collectLambdaArguments(parser_context,
substrait_func.arguments()[1].value().scalar_function());
+ if (lambda_args.size() != 2 ||
!lambda_args.front().type->equals(*(lambda_args.back().type)))
+ throw DB::Exception(
+ DB::ErrorCodes::BAD_ARGUMENTS, "array_sort function must have
a lambda function with two arguments of the same type");
+
+ /// In case lambda argument types are T, and the array has type
Array(Nullable(T)) or Nullable(Array(Nullable(T))).
+ /// We need to convert the array type to Array(T) or
Nullable(Array(T)) to match the lambda argument types, otherwise it will cause
runtime exceptions
+ /// in function capture.
+ const auto & src_array_type = parsed_args[0]->result_type;
+ DataTypePtr dst_array_type =
std::make_shared<DataTypeArray>(lambda_args.front().type);
+ if (src_array_type->isNullable())
+ dst_array_type =
std::make_shared<DataTypeNullable>(dst_array_type);
+ parsed_args[0] = ActionsDAGUtil::convertNodeTypeIfNeeded(actions_dag,
parsed_args[0], dst_array_type);
+
return toFunctionNode(actions_dag, ch_func_name, {parsed_args[1],
parsed_args[0]});
}
private:
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]