From 911bd0e818386c5082ec59e25a902c209bd198f5 Mon Sep 17 00:00:00 2001 From: zhangstar333 <87313068+zhangstar333@users.noreply.github.com> Date: Tue, 15 Aug 2023 10:16:48 +0800 Subject: [PATCH] [bug](if) fix if function not handle const nullable value (#22823) fix if function not handle const nullable value --- be/src/vec/exprs/vectorized_fn_call.cpp | 8 ++-- be/src/vec/functions/if.cpp | 56 +++++++++++++++++++------ 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/be/src/vec/exprs/vectorized_fn_call.cpp b/be/src/vec/exprs/vectorized_fn_call.cpp index 7055125ba4..1843d732a2 100644 --- a/be/src/vec/exprs/vectorized_fn_call.cpp +++ b/be/src/vec/exprs/vectorized_fn_call.cpp @@ -56,10 +56,7 @@ namespace doris::vectorized { const std::string AGG_STATE_SUFFIX = "_state"; -VectorizedFnCall::VectorizedFnCall(const TExprNode& node) : VExpr(node) { - _expr_name = fmt::format("VectorizedFnCall[{}](arguments={},return={})", _fn.name.function_name, - get_child_names(), _data_type->get_name()); -} +VectorizedFnCall::VectorizedFnCall(const TExprNode& node) : VExpr(node) {} Status VectorizedFnCall::prepare(RuntimeState* state, const RowDescriptor& desc, VExprContext* context) { @@ -70,6 +67,9 @@ Status VectorizedFnCall::prepare(RuntimeState* state, const RowDescriptor& desc, argument_template.emplace_back(nullptr, child->data_type(), child->expr_name()); } + _expr_name = fmt::format("VectorizedFnCall[{}](arguments={},return={})", _fn.name.function_name, + get_child_names(), _data_type->get_name()); + if (_fn.binary_type == TFunctionBinaryType::RPC) { _function = FunctionRPC::create(_fn, argument_template, _data_type); } else if (_fn.binary_type == TFunctionBinaryType::JAVA_UDF) { diff --git a/be/src/vec/functions/if.cpp b/be/src/vec/functions/if.cpp index a07f6c5192..77f1c0ae53 100644 --- a/be/src/vec/functions/if.cpp +++ b/be/src/vec/functions/if.cpp @@ -396,28 +396,58 @@ public: const ColumnWithTypeAndName& arg_then, const ColumnWithTypeAndName& arg_else, size_t result, size_t input_rows_count) { + auto then_type_is_nullable = arg_then.type->is_nullable(); + auto else_type_is_nullable = arg_else.type->is_nullable(); + if (!then_type_is_nullable && !else_type_is_nullable) { + return false; + } + auto* then_is_nullable = check_and_get_column(*arg_then.column); auto* else_is_nullable = check_and_get_column(*arg_else.column); + bool then_column_is_const_nullable = false; + bool else_column_is_const_nullable = false; + if (then_type_is_nullable == true && then_is_nullable == nullptr) { + //this case is a const(nullable column) + auto& const_column = assert_cast(*arg_then.column); + then_is_nullable = + assert_cast(const_column.get_data_column_ptr().get()); + then_column_is_const_nullable = true; + } - if (!then_is_nullable && !else_is_nullable) { - return false; + if (else_type_is_nullable == true && else_is_nullable == nullptr) { + //this case is a const(nullable column) + auto& const_column = assert_cast(*arg_else.column); + else_is_nullable = + assert_cast(const_column.get_data_column_ptr().get()); + else_column_is_const_nullable = true; } /** Calculate null mask of result and nested column separately. */ ColumnPtr result_null_mask; { - Block temporary_block( - {arg_cond, - {then_is_nullable ? then_is_nullable->get_null_map_column_ptr() - : DataTypeUInt8().create_column_const_with_default_value( - input_rows_count), - std::make_shared(), ""}, - {else_is_nullable ? else_is_nullable->get_null_map_column_ptr() - : DataTypeUInt8().create_column_const_with_default_value( - input_rows_count), - std::make_shared(), ""}, - {nullptr, std::make_shared(), ""}}); + // get nullmap from column: + // a. get_null_map_column_ptr() : it's a real nullable column, so could get it from nullable column + // b. create a const_nullmap_column: it's a not nullable column or a const nullable column, contain a const value + Block temporary_block; + temporary_block.insert(arg_cond); + auto then_nested_null_map = + (then_type_is_nullable == true && then_column_is_const_nullable == false) + ? then_is_nullable->get_null_map_column_ptr() + : DataTypeUInt8().create_column_const_with_default_value( + input_rows_count); + temporary_block.insert({then_nested_null_map, std::make_shared(), + "then_column_null_map"}); + + auto else_nested_null_map = + (else_type_is_nullable == true && else_column_is_const_nullable == false) + ? else_is_nullable->get_null_map_column_ptr() + : DataTypeUInt8().create_column_const_with_default_value( + input_rows_count); + temporary_block.insert({else_nested_null_map, std::make_shared(), + "else_column_null_map"}); + temporary_block.insert( + {nullptr, std::make_shared(), "result_column_null_map"}); execute_impl(context, temporary_block, {0, 1, 2}, 3, temporary_block.rows());