diff --git a/be/src/vec/functions/function_convert_tz.h b/be/src/vec/functions/function_convert_tz.h index d0a600a9e41a86..b570c6d3153909 100644 --- a/be/src/vec/functions/function_convert_tz.h +++ b/be/src/vec/functions/function_convert_tz.h @@ -165,18 +165,23 @@ class FunctionConvertTZ : public IFunction { default_preprocess_parameter_columns(argument_columns, col_const, {1, 2}, block, arguments); - if (col_const[1] && col_const[2]) { + if (convert_tz_state->use_state) { auto result_column = ColumnType::create(); - if (convert_tz_state->use_state) { - execute_tz_const_with_state( - convert_tz_state, assert_cast(argument_columns[0].get()), - assert_cast(result_column.get()), - assert_cast(result_null_map_column.get())->get_data(), - input_rows_count); - } else { - return Status::RuntimeError("ConvertTzState is not initialized in function {}", - get_name()); - } + execute_tz_const_with_state( + convert_tz_state, assert_cast(argument_columns[0].get()), + assert_cast(result_column.get()), + assert_cast(result_null_map_column.get())->get_data(), + input_rows_count); + block.get_by_position(result).column = ColumnNullable::create( + std::move(result_column), std::move(result_null_map_column)); + } else if (col_const[1] && col_const[2]) { + auto result_column = ColumnType::create(); + execute_tz_const(context, assert_cast(argument_columns[0].get()), + assert_cast(argument_columns[1].get()), + assert_cast(argument_columns[2].get()), + assert_cast(result_column.get()), + assert_cast(result_null_map_column.get())->get_data(), + input_rows_count); block.get_by_position(result).column = ColumnNullable::create( std::move(result_column), std::move(result_null_map_column)); } else { @@ -261,6 +266,21 @@ class FunctionConvertTZ : public IFunction { } } + static void execute_tz_const(FunctionContext* context, const ColumnType* date_column, + const ColumnString* from_tz_column, + const ColumnString* to_tz_column, ReturnColumnType* result_column, + NullMap& result_null_map, size_t input_rows_count) { + auto from_tz = from_tz_column->get_data_at(0).to_string(); + auto to_tz = to_tz_column->get_data_at(0).to_string(); + for (size_t i = 0; i < input_rows_count; i++) { + if (result_null_map[i]) { + result_column->insert_default(); + continue; + } + execute_inner_loop(date_column, from_tz, to_tz, result_column, result_null_map, i); + } + } + static void execute_inner_loop(const ColumnType* date_column, const std::string& from_tz_name, const std::string& to_tz_name, ReturnColumnType* result_column, NullMap& result_null_map, const size_t index_now) { diff --git a/be/src/vec/functions/function_ifnull.h b/be/src/vec/functions/function_ifnull.h index 9deb7f8d71f7d5..03b059013dd6e9 100644 --- a/be/src/vec/functions/function_ifnull.h +++ b/be/src/vec/functions/function_ifnull.h @@ -81,7 +81,10 @@ class FunctionIfNull : public IFunction { size_t result, size_t input_rows_count) const override { ColumnWithTypeAndName& col_left = block.get_by_position(arguments[0]); if (col_left.column->only_null()) { - block.get_by_position(result).column = block.get_by_position(arguments[1]).column; + // Here we need to use convert_to_full_column_if_const because only_null() is a runtime function. + // If the second parameter is constant, it will cause the execution to rely on runtime information to determine whether it is constant. + block.get_by_position(result).column = + block.get_by_position(arguments[1]).column->convert_to_full_column_if_const(); return Status::OK(); } diff --git a/be/test/vec/function/function_convert_tz_test.cpp b/be/test/vec/function/function_convert_tz_test.cpp new file mode 100644 index 00000000000000..70d419f0ba1552 --- /dev/null +++ b/be/test/vec/function/function_convert_tz_test.cpp @@ -0,0 +1,59 @@ +// 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/function_convert_tz.h" + +#include +#include + +#include + +#include "common/status.h" +#include "function_test_util.h" +#include "testutil/column_helper.h" +#include "vec/core/types.h" +#include "vec/data_types/data_type_date_time.h" +#include "vec/data_types/data_type_string.h" +#include "vec/data_types/data_type_time_v2.h" + +namespace doris::vectorized { + +TEST(FunctionConvertTZTest, test_no_open_but_execute_const) { + FunctionConvertTZ func; + FunctionContext ctx; + std::shared_ptr state = std::make_shared(); + state->use_state = false; + ctx.set_function_state(FunctionContext::FRAGMENT_LOCAL, state); + + ColumnNumbers arguments {0, 1, 2}; + + Block block {ColumnWithTypeAndName {ColumnHelper::create_column({1}), + std::make_shared(), "date"}, + ColumnWithTypeAndName { + ColumnConst::create(ColumnHelper::create_column({""}), 1), + std::make_shared(), "from_tz"}, + ColumnWithTypeAndName { + ColumnConst::create(ColumnHelper::create_column({""}), 1), + std::make_shared(), "to_tz"}, + ColumnWithTypeAndName {nullptr, std::make_shared(), "result"}}; + + auto st = func.execute(&ctx, block, arguments, 3, 1); + + EXPECT_EQ(st.ok(), true) << st.msg(); +} + +} // namespace doris::vectorized