This is an automated email from the ASF dual-hosted git repository.
dataroaring pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.0 by this push:
new e4f5f18ef4e branch-3.0: [fix](function) check return type is nullptr
in FunctionBasePtr::build #49737 (#49762)
e4f5f18ef4e is described below
commit e4f5f18ef4e9aef137c1a80ebf5cc7d270754687
Author: Mryange <[email protected]>
AuthorDate: Wed Apr 9 09:47:26 2025 +0800
branch-3.0: [fix](function) check return type is nullptr in
FunctionBasePtr::build #49737 (#49762)
https://github.com/apache/doris/pull/49737
---
.../vec/functions/array/function_array_cum_sum.cpp | 10 +--
.../functions/array/function_array_difference.h | 8 +-
.../vec/functions/array/function_array_element.h | 6 +-
.../array/function_array_enumerate_uniq.cpp | 1 -
be/src/vec/functions/function.h | 8 ++
.../vec/function/simple_function_factory_test.cpp | 98 ++++++++++++++++++++++
6 files changed, 116 insertions(+), 15 deletions(-)
diff --git a/be/src/vec/functions/array/function_array_cum_sum.cpp
b/be/src/vec/functions/array/function_array_cum_sum.cpp
index 24750b55f6c..73a87fd7cf2 100644
--- a/be/src/vec/functions/array/function_array_cum_sum.cpp
+++ b/be/src/vec/functions/array/function_array_cum_sum.cpp
@@ -86,14 +86,10 @@ public:
}
if (return_type) {
return std::make_shared<DataTypeArray>(make_nullable(return_type));
- } else {
- throw doris::Exception(
- ErrorCode::INVALID_ARGUMENT,
- "Function of {}, return type get wrong: and input argument
is: {}", name,
- arguments[0]->get_name());
}
-
- return nullptr;
+ throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
+ "Function of {}, return type get wrong: and
input argument is: {}",
+ name, arguments[0]->get_name());
}
Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
diff --git a/be/src/vec/functions/array/function_array_difference.h
b/be/src/vec/functions/array/function_array_difference.h
index 9eca677f033..46cda52516a 100644
--- a/be/src/vec/functions/array/function_array_difference.h
+++ b/be/src/vec/functions/array/function_array_difference.h
@@ -95,12 +95,10 @@ public:
if (return_type) {
return std::make_shared<DataTypeArray>(is_nullable ?
make_nullable(return_type)
: return_type);
- } else {
- throw doris::Exception(
- ErrorCode::INVALID_ARGUMENT,
- "Function of {}, return type get wrong: and input argument
is: {}", name,
- arguments[0]->get_name());
}
+ throw doris::Exception(ErrorCode::INVALID_ARGUMENT,
+ "Function of {}, return type get wrong: and
input argument is: {}",
+ name, arguments[0]->get_name());
}
Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
diff --git a/be/src/vec/functions/array/function_array_element.h
b/be/src/vec/functions/array/function_array_element.h
index b1a55e6f1a5..ea729e7be3f 100644
--- a/be/src/vec/functions/array/function_array_element.h
+++ b/be/src/vec/functions/array/function_array_element.h
@@ -90,8 +90,10 @@ public:
return make_nullable(
check_and_get_data_type<DataTypeMap>(arg_0.get())->get_value_type());
} else {
- LOG(ERROR) << "element_at only support array and map so far.";
- return nullptr;
+ throw doris::Exception(
+ ErrorCode::INVALID_ARGUMENT,
+ fmt::format("element_at only support array and map so far,
but got {}",
+ arg_0->get_name()));
}
}
diff --git a/be/src/vec/functions/array/function_array_enumerate_uniq.cpp
b/be/src/vec/functions/array/function_array_enumerate_uniq.cpp
index 4c073386e4d..bb9dd9c04cc 100644
--- a/be/src/vec/functions/array/function_array_enumerate_uniq.cpp
+++ b/be/src/vec/functions/array/function_array_enumerate_uniq.cpp
@@ -82,7 +82,6 @@ public:
throw doris::Exception(
ErrorCode::INVALID_ARGUMENT,
"Incorrect number of arguments for array_enumerate_uniq
function");
- __builtin_unreachable();
}
bool is_nested_nullable = false;
for (size_t i = 0; i < arguments.size(); ++i) {
diff --git a/be/src/vec/functions/function.h b/be/src/vec/functions/function.h
index ff987d130cd..edc214e5f36 100644
--- a/be/src/vec/functions/function.h
+++ b/be/src/vec/functions/function.h
@@ -295,6 +295,14 @@ public:
FunctionBasePtr build(const ColumnsWithTypeAndName& arguments,
const DataTypePtr& return_type) const final {
const DataTypePtr& func_return_type = get_return_type(arguments);
+ if (func_return_type == nullptr) {
+ throw doris::Exception(
+ ErrorCode::INTERNAL_ERROR,
+ "function return type check failed, function_name={}, "
+ "expect_return_type={}, real_return_type is nullptr,
input_arguments={}",
+ get_name(), return_type->get_name(),
get_types_string(arguments));
+ }
+
// check return types equal.
if (!(return_type->equals(*func_return_type) ||
// For null constant argument, `get_return_type` would return
diff --git a/be/test/vec/function/simple_function_factory_test.cpp
b/be/test/vec/function/simple_function_factory_test.cpp
new file mode 100644
index 00000000000..41ff70c6dac
--- /dev/null
+++ b/be/test/vec/function/simple_function_factory_test.cpp
@@ -0,0 +1,98 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "vec/functions/simple_function_factory.h"
+
+#include <gtest/gtest.h>
+
+#include <memory>
+
+#include "vec/data_types/data_type_number.h"
+
+namespace doris::vectorized {
+
+class FunctionBeTestMock : public IFunction {
+public:
+ static constexpr auto name = "be_test_mock";
+
+ static FunctionPtr create() { return
std::make_shared<FunctionBeTestMock>(); }
+
+ String get_name() const override { return name; }
+
+ size_t get_number_of_arguments() const override { return 0; }
+
+ DataTypePtr get_return_type_impl(const DataTypes& arguments) const
override { return nullptr; }
+
+ Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
+ size_t result, size_t input_rows_count) const override
{
+ return Status::OK();
+ }
+};
+
+class SimpleFunctionFactoryTest : public testing::Test {
+ void SetUp() override {
+ static std::once_flag oc;
+ std::call_once(oc, []() {
+
SimpleFunctionFactory::instance().register_function<FunctionBeTestMock>();
+ });
+ }
+
+ ColumnsWithTypeAndName arguments(size_t size) {
+ ColumnsWithTypeAndName args;
+ for (size_t i = 0; i < size; ++i) {
+ args.emplace_back(nullptr, std::make_shared<DataTypeInt64>(), "");
+ }
+ return args;
+ }
+
+ void TearDown() override {}
+};
+
+TEST_F(SimpleFunctionFactoryTest, test_return_type_check) {
+ EXPECT_THROW(SimpleFunctionFactory::instance().get_function(
+ "be_test_mock", {}, std::make_shared<DataTypeInt64>(),
+ {.enable_decimal256 = false},
BeExecVersionManager::get_newest_version()),
+ doris::Exception);
+}
+
+TEST_F(SimpleFunctionFactoryTest, test_return_all) {
+ auto factory = SimpleFunctionFactory::instance();
+
+ for (auto [name, builder] : factory.function_creators) {
+ auto function = builder();
+ auto func_impl =
std::dynamic_pointer_cast<FunctionBuilderImpl>(function);
+ EXPECT_NE(func_impl, nullptr);
+ if (func_impl->is_variadic()) {
+ continue;
+ }
+ std::cout << func_impl->get_name() << std::endl;
+ ///TODO: Currently, many DCHECK statements exist within
get_return_type_impl.
+ // In the future, after replacing all these DCHECK statements with
exceptions, we will be able to enumerate all the functions.
+
+ // try {
+ // auto return_type = func_impl->get_return_type_impl(
+ // arguments(func_impl->get_number_of_arguments()));
+ // EXPECT_NE(return_type, nullptr) << func_impl->get_name();
+ // } catch (const doris::Exception& e) {
+ // std::cout << "Exception message: " << e.what() << std::endl; //
使用what()方法
+ // SUCCEED();
+ // } catch (...) {
+ // }
+ }
+}
+
+} // namespace doris::vectorized
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]