From 00647a531046e0064d75e5dc5f288302be1634dc Mon Sep 17 00:00:00 2001 From: Mryange Date: Tue, 1 Apr 2025 19:55:19 +0800 Subject: [PATCH 1/2] upd --- .../array/function_array_cum_sum.cpp | 10 +- .../array/function_array_difference.h | 8 +- .../functions/array/function_array_element.h | 6 +- .../array/function_array_enumerate_uniq.cpp | 1 - be/src/vec/functions/function.h | 9 ++ .../function/simple_function_factory_test.cpp | 98 +++++++++++++++++++ 6 files changed, 117 insertions(+), 15 deletions(-) create mode 100644 be/test/vec/function/simple_function_factory_test.cpp 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 5fba7d4a619bd5..3b72610310768d 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 @@ class FunctionArrayCumSum : public IFunction { } if (return_type) { return std::make_shared(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 149e311e9405be..f9ab6f093af32e 100644 --- a/be/src/vec/functions/array/function_array_difference.h +++ b/be/src/vec/functions/array/function_array_difference.h @@ -93,12 +93,10 @@ class FunctionArrayDifference : public IFunction { if (return_type) { return std::make_shared(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 96bbd48d8a241b..a7e69c6aaea814 100644 --- a/be/src/vec/functions/array/function_array_element.h +++ b/be/src/vec/functions/array/function_array_element.h @@ -92,8 +92,10 @@ class FunctionArrayElement : public IFunction { return make_nullable( check_and_get_data_type(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 bdee406655f196..55c511daf81417 100644 --- a/be/src/vec/functions/array/function_array_enumerate_uniq.cpp +++ b/be/src/vec/functions/array/function_array_enumerate_uniq.cpp @@ -80,7 +80,6 @@ class FunctionArrayEnumerateUniq : public IFunction { 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 92282c483948e6..feeefd7f5aedd3 100644 --- a/be/src/vec/functions/function.h +++ b/be/src/vec/functions/function.h @@ -266,6 +266,15 @@ class FunctionBuilderImpl : public IFunctionBuilder { 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)); + return nullptr; + } + // 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 00000000000000..d5dc8d6ecf3256 --- /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 + +#include + +#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(); } + + 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, + uint32_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(); + }); + } + + ColumnsWithTypeAndName arguments(size_t size) { + ColumnsWithTypeAndName args; + for (size_t i = 0; i < size; ++i) { + args.emplace_back(nullptr, std::make_shared(), ""); + } + return args; + } + + void TearDown() override {} +}; + +TEST_F(SimpleFunctionFactoryTest, test_return_type_check) { + EXPECT_THROW(SimpleFunctionFactory::instance().get_function( + "be_test_mock", {}, std::make_shared(), + {.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(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 From 6b5e5c4a0cff50302f066ec61242b2b0806af111 Mon Sep 17 00:00:00 2001 From: Mryange Date: Tue, 1 Apr 2025 19:58:47 +0800 Subject: [PATCH 2/2] remove return --- be/src/vec/functions/function.h | 1 - 1 file changed, 1 deletion(-) diff --git a/be/src/vec/functions/function.h b/be/src/vec/functions/function.h index feeefd7f5aedd3..5cc7a9693afddc 100644 --- a/be/src/vec/functions/function.h +++ b/be/src/vec/functions/function.h @@ -272,7 +272,6 @@ class FunctionBuilderImpl : public IFunctionBuilder { "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)); - return nullptr; } // check return types equal.