This is an automated email from the ASF dual-hosted git repository.
gabriellee pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 3a3c4b9b9dc [fix](function) Fix the issue where using convert_tz and
ifnull together causes an error. (#48029)
3a3c4b9b9dc is described below
commit 3a3c4b9b9dc095ad95b86bdba7143dceaa1e14c8
Author: Mryange <[email protected]>
AuthorDate: Wed Feb 19 14:37:21 2025 +0800
[fix](function) Fix the issue where using convert_tz and ifnull together
causes an error. (#48029)
In this PR https://github.com/apache/doris/pull/40366, an optimization
was introduced.
However, because ifnull would return const at runtime (even if there was
no const column during open), t
his would cause an error: "ConvertTzState is not initialized in function
convert_tz".
---
be/src/vec/functions/function_convert_tz.h | 42 +++++++++++-----
be/src/vec/functions/function_ifnull.h | 5 +-
be/test/vec/function/function_convert_tz_test.cpp | 59 +++++++++++++++++++++++
3 files changed, 94 insertions(+), 12 deletions(-)
diff --git a/be/src/vec/functions/function_convert_tz.h
b/be/src/vec/functions/function_convert_tz.h
index 962d3f59882..df0e84e33c8 100644
--- a/be/src/vec/functions/function_convert_tz.h
+++ b/be/src/vec/functions/function_convert_tz.h
@@ -166,18 +166,23 @@ public:
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<const
ColumnType*>(argument_columns[0].get()),
- assert_cast<ReturnColumnType*>(result_column.get()),
-
assert_cast<ColumnUInt8*>(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<const
ColumnType*>(argument_columns[0].get()),
+ assert_cast<ReturnColumnType*>(result_column.get()),
+
assert_cast<ColumnUInt8*>(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<const
ColumnType*>(argument_columns[0].get()),
+ assert_cast<const
ColumnString*>(argument_columns[1].get()),
+ assert_cast<const
ColumnString*>(argument_columns[2].get()),
+
assert_cast<ReturnColumnType*>(result_column.get()),
+
assert_cast<ColumnUInt8*>(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 {
@@ -262,6 +267,21 @@ private:
}
}
+ 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 9cd1ef5b36e..48e58d28b68 100644
--- a/be/src/vec/functions/function_ifnull.h
+++ b/be/src/vec/functions/function_ifnull.h
@@ -81,7 +81,10 @@ public:
uint32_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 00000000000..70d419f0ba1
--- /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 <gtest/gtest.h>
+#include <stdint.h>
+
+#include <vector>
+
+#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<DataTypeDateV2> func;
+ FunctionContext ctx;
+ std::shared_ptr<ConvertTzState> state = std::make_shared<ConvertTzState>();
+ state->use_state = false;
+ ctx.set_function_state(FunctionContext::FRAGMENT_LOCAL, state);
+
+ ColumnNumbers arguments {0, 1, 2};
+
+ Block block {ColumnWithTypeAndName
{ColumnHelper::create_column<DataTypeDateV2>({1}),
+ std::make_shared<DataTypeDateV2>(),
"date"},
+ ColumnWithTypeAndName {
+
ColumnConst::create(ColumnHelper::create_column<DataTypeString>({""}), 1),
+ std::make_shared<DataTypeString>(), "from_tz"},
+ ColumnWithTypeAndName {
+
ColumnConst::create(ColumnHelper::create_column<DataTypeString>({""}), 1),
+ std::make_shared<DataTypeString>(), "to_tz"},
+ ColumnWithTypeAndName {nullptr,
std::make_shared<DataTypeDateV2>(), "result"}};
+
+ auto st = func.execute(&ctx, block, arguments, 3, 1);
+
+ EXPECT_EQ(st.ok(), true) << st.msg();
+}
+
+} // namespace doris::vectorized
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]