Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions be/src/vec/functions/array/function_array_cum_sum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,10 @@ class FunctionArrayCumSum : public IFunction {
}
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,
Expand Down
8 changes: 3 additions & 5 deletions be/src/vec/functions/array/function_array_difference.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,10 @@ class FunctionArrayDifference : public IFunction {
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,
Expand Down
6 changes: 4 additions & 2 deletions be/src/vec/functions/array/function_array_element.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,10 @@ class FunctionArrayElement : public IFunction {
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()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
8 changes: 8 additions & 0 deletions be/src/vec/functions/function.h
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,14 @@ 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));
}

// check return types equal.
if (!(return_type->equals(*func_return_type) ||
// For null constant argument, `get_return_type` would return
Expand Down
98 changes: 98 additions & 0 deletions be/test/vec/function/simple_function_factory_test.cpp
Original file line number Diff line number Diff line change
@@ -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,
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<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
Loading