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 <yanxuech...@selectdb.com>
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: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to