diff --git a/be/src/exprs/function/cast/function_cast.cpp b/be/src/exprs/function/cast/function_cast.cpp index e048f57b91e70f..c78f293a614227 100644 --- a/be/src/exprs/function/cast/function_cast.cpp +++ b/be/src/exprs/function/cast/function_cast.cpp @@ -386,8 +386,9 @@ class FunctionBuilderCast : public FunctionBuilderImpl { } bool skip_return_type_check() const override { return true; } - DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& arguments) const override { - return nullptr; + DataTypePtr get_return_type_impl(const ColumnsWithTypeAndName& /*arguments*/) const override { + throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, + "get_return_type is not implemented for {}", get_name()); } bool use_default_implementation_for_nulls() const override { return false; } diff --git a/be/src/exprs/function/function.cpp b/be/src/exprs/function/function.cpp index 590eb63829200d..8c79edfe594433 100644 --- a/be/src/exprs/function/function.cpp +++ b/be/src/exprs/function/function.cpp @@ -280,7 +280,10 @@ DataTypePtr FunctionBuilderImpl::get_return_type(const ColumnsWithTypeAndName& a auto return_type = get_return_type_impl( ColumnsWithTypeAndName(nested_block.begin(), nested_block.end())); if (!return_type) { - return nullptr; + throw Exception(ErrorCode::INTERNAL_ERROR, + "function return type is nullptr, function_name={}, " + "input_arguments={}", + get_name(), get_types_string(arguments)); } return make_nullable(return_type); } diff --git a/be/src/exprs/function/function.h b/be/src/exprs/function/function.h index 9e0aebdabaf032..8bbeeddf40fd44 100644 --- a/be/src/exprs/function/function.h +++ b/be/src/exprs/function/function.h @@ -343,7 +343,6 @@ class FunctionBuilderImpl : public IFunctionBuilder { virtual DataTypePtr get_return_type_impl(const DataTypes& /*arguments*/) const { throw doris::Exception(ErrorCode::NOT_IMPLEMENTED_ERROR, "get_return_type is not implemented for {}", get_name()); - return nullptr; } /** If use_default_implementation_for_nulls() is true, than change arguments for get_return_type() and build_impl(): diff --git a/be/src/exprs/function/function_struct_element.cpp b/be/src/exprs/function/function_struct_element.cpp index 770698259ee1be..5026c10ed1396b 100644 --- a/be/src/exprs/function/function_struct_element.cpp +++ b/be/src/exprs/function/function_struct_element.cpp @@ -76,8 +76,7 @@ class FunctionStructElement : public IFunction { size_t index; auto st = get_element_index(*struct_type, index_column, index_type, &index); if (!st.ok()) { - // will handle nullptr outside - return nullptr; + throw doris::Exception(st); } // The struct_element is marked as AlwaysNullable in fe. return make_nullable(struct_type->get_elements()[index]); diff --git a/be/test/exprs/function/function_struct_element_test.cpp b/be/test/exprs/function/function_struct_element_test.cpp index 0f98955e85f70d..a2cce4770a7aeb 100644 --- a/be/test/exprs/function/function_struct_element_test.cpp +++ b/be/test/exprs/function/function_struct_element_test.cpp @@ -62,6 +62,25 @@ TEST(FunctionStructElementTest, test_return_type) { std::cout << "Return type: " << return_type->get_name() << std::endl; } +TEST(FunctionStructElementTest, test_return_type_invalid_field) { + auto index_type = std::make_shared(); + auto index_column = ColumnHelper::create_column({"key4"}); + + DataTypes struct_types = {std::make_shared(), std::make_shared(), + std::make_shared()}; + Strings names = {"key1", "key2", "key3"}; + auto type_struct = std::make_shared(struct_types, names); + + auto argument_template = ColumnsWithTypeAndName {{nullptr, type_struct, "struct"}, + {index_column, index_type, "index"}}; + + EXPECT_THROW(SimpleFunctionFactory::instance().get_function( + "struct_element", argument_template, + std::make_shared(std::make_shared()), + {true}, BeExecVersionManager::get_newest_version()), + doris::Exception); +} + TEST(FunctionStructElementTest, test_return_column) { auto index_type = std::make_shared(); @@ -114,4 +133,4 @@ TEST(FunctionStructElementTest, test_return_column) { EXPECT_TRUE(block.get_by_position(2).column->is_nullable()); } -} // namespace doris \ No newline at end of file +} // namespace doris diff --git a/be/test/exprs/function/simple_function_factory_test.cpp b/be/test/exprs/function/simple_function_factory_test.cpp index 86f344a3f03db7..553c89eff5f763 100644 --- a/be/test/exprs/function/simple_function_factory_test.cpp +++ b/be/test/exprs/function/simple_function_factory_test.cpp @@ -35,7 +35,9 @@ class FunctionBeTestMock : public IFunction { size_t get_number_of_arguments() const override { return 0; } - DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { return nullptr; } + DataTypePtr get_return_type_impl(const DataTypes& /*arguments*/) const override { + throw doris::Exception(ErrorCode::INTERNAL_ERROR, "BEUT TEST: nullptr return type"); + } Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, uint32_t result, size_t input_rows_count) const override { @@ -95,4 +97,4 @@ TEST_F(SimpleFunctionFactoryTest, test_return_all) { } } -} // namespace doris \ No newline at end of file +} // namespace doris