be/src/exprs/function/function_convert_tz.cpp
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #include <cctz/time_zone.h> |
19 | | |
20 | | #include <cstddef> |
21 | | #include <cstdint> |
22 | | #include <memory> |
23 | | #include <string> |
24 | | #include <tuple> |
25 | | #include <utility> |
26 | | |
27 | | #include "common/status.h" |
28 | | #include "core/assert_cast.h" |
29 | | #include "core/binary_cast.hpp" |
30 | | #include "core/block/block.h" |
31 | | #include "core/block/column_numbers.h" |
32 | | #include "core/block/column_with_type_and_name.h" |
33 | | #include "core/column/column.h" |
34 | | #include "core/column/column_const.h" |
35 | | #include "core/column/column_nullable.h" |
36 | | #include "core/column/column_string.h" |
37 | | #include "core/column/column_vector.h" |
38 | | #include "core/data_type/data_type.h" |
39 | | #include "core/data_type/data_type_date.h" |
40 | | #include "core/data_type/data_type_date_or_datetime_v2.h" |
41 | | #include "core/data_type/data_type_date_time.h" |
42 | | #include "core/data_type/data_type_nullable.h" |
43 | | #include "core/data_type/data_type_string.h" |
44 | | #include "core/data_type/data_type_timestamp_ns.h" |
45 | | #include "core/data_type/define_primitive_type.h" |
46 | | #include "core/data_type/primitive_type.h" |
47 | | #include "core/string_ref.h" |
48 | | #include "core/types.h" |
49 | | #include "core/value/vdatetime_value.h" |
50 | | #include "exec/common/util.hpp" |
51 | | #include "exprs/aggregate/aggregate_function.h" |
52 | | #include "exprs/function/datetime_errors.h" |
53 | | #include "exprs/function/function.h" |
54 | | #include "exprs/function/function_helpers.h" |
55 | | #include "exprs/function/simple_function_factory.h" |
56 | | #include "exprs/function_context.h" |
57 | | #include "util/timezone_utils.h" |
58 | | |
59 | | namespace doris { |
60 | | |
61 | | struct ConvertTzState { |
62 | | bool use_state = false; |
63 | | bool is_valid = false; |
64 | | cctz::time_zone from_tz; |
65 | | cctz::time_zone to_tz; |
66 | | }; |
67 | | |
68 | | template <PrimitiveType Type> |
69 | | class FunctionConvertTZ : public IFunction { |
70 | | constexpr static PrimitiveType PType = Type; |
71 | | using DateValueType = PrimitiveTypeTraits<PType>::CppType; |
72 | | using ColumnType = PrimitiveTypeTraits<PType>::ColumnType; |
73 | | |
74 | | public: |
75 | | static constexpr auto name = "convert_tz"; |
76 | | |
77 | 91 | static FunctionPtr create() { return std::make_shared<FunctionConvertTZ<PType>>(); }_ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE6createEv Line | Count | Source | 77 | 76 | static FunctionPtr create() { return std::make_shared<FunctionConvertTZ<PType>>(); } |
_ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE6createEv Line | Count | Source | 77 | 15 | static FunctionPtr create() { return std::make_shared<FunctionConvertTZ<PType>>(); } |
|
78 | | |
79 | 2 | String get_name() const override { return name; }_ZNK5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE8get_nameB5cxx11Ev Line | Count | Source | 79 | 1 | String get_name() const override { return name; } |
_ZNK5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE8get_nameB5cxx11Ev Line | Count | Source | 79 | 1 | String get_name() const override { return name; } |
|
80 | | |
81 | 73 | size_t get_number_of_arguments() const override { return 3; }_ZNK5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE23get_number_of_argumentsEv Line | Count | Source | 81 | 67 | size_t get_number_of_arguments() const override { return 3; } |
_ZNK5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE23get_number_of_argumentsEv Line | Count | Source | 81 | 6 | size_t get_number_of_arguments() const override { return 3; } |
|
82 | | |
83 | 16 | DataTypes get_variadic_argument_types_impl() const override { |
84 | 16 | return {std::make_shared<typename PrimitiveTypeTraits<PType>::DataType>(), |
85 | 16 | std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()}; |
86 | 16 | } _ZNK5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE32get_variadic_argument_types_implEv Line | Count | Source | 83 | 8 | DataTypes get_variadic_argument_types_impl() const override { | 84 | 8 | return {std::make_shared<typename PrimitiveTypeTraits<PType>::DataType>(), | 85 | 8 | std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()}; | 86 | 8 | } |
_ZNK5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE32get_variadic_argument_types_implEv Line | Count | Source | 83 | 8 | DataTypes get_variadic_argument_types_impl() const override { | 84 | 8 | return {std::make_shared<typename PrimitiveTypeTraits<PType>::DataType>(), | 85 | 8 | std::make_shared<DataTypeString>(), std::make_shared<DataTypeString>()}; | 86 | 8 | } |
|
87 | | |
88 | 73 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
89 | 73 | DataTypePtr result_type; |
90 | 73 | if constexpr (PType == TYPE_TIMESTAMP_NS) { |
91 | 6 | result_type = std::make_shared<DataTypeTimeStampNs>(); |
92 | 67 | } else { |
93 | 67 | result_type = create_datetimev2(arguments[0]->get_scale()); |
94 | 67 | } |
95 | 73 | return have_nullable(arguments) ? make_nullable(result_type) : result_type; |
96 | 73 | } _ZNK5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE Line | Count | Source | 88 | 67 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { | 89 | 67 | DataTypePtr result_type; | 90 | | if constexpr (PType == TYPE_TIMESTAMP_NS) { | 91 | | result_type = std::make_shared<DataTypeTimeStampNs>(); | 92 | 67 | } else { | 93 | 67 | result_type = create_datetimev2(arguments[0]->get_scale()); | 94 | 67 | } | 95 | 67 | return have_nullable(arguments) ? make_nullable(result_type) : result_type; | 96 | 67 | } |
_ZNK5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE Line | Count | Source | 88 | 6 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { | 89 | 6 | DataTypePtr result_type; | 90 | 6 | if constexpr (PType == TYPE_TIMESTAMP_NS) { | 91 | 6 | result_type = std::make_shared<DataTypeTimeStampNs>(); | 92 | | } else { | 93 | | result_type = create_datetimev2(arguments[0]->get_scale()); | 94 | | } | 95 | 6 | return have_nullable(arguments) ? make_nullable(result_type) : result_type; | 96 | 6 | } |
|
97 | | |
98 | | // default value of timezone is invalid, should skip to avoid wrong exception |
99 | 164 | bool use_default_implementation_for_nulls() const override { return false; }_ZNK5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE36use_default_implementation_for_nullsEv Line | Count | Source | 99 | 152 | bool use_default_implementation_for_nulls() const override { return false; } |
_ZNK5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE36use_default_implementation_for_nullsEv Line | Count | Source | 99 | 12 | bool use_default_implementation_for_nulls() const override { return false; } |
|
100 | | |
101 | 408 | Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { |
102 | 408 | if (scope == FunctionContext::THREAD_LOCAL) { |
103 | 336 | return Status::OK(); |
104 | 336 | } |
105 | 72 | std::shared_ptr<ConvertTzState> state = std::make_shared<ConvertTzState>(); |
106 | | |
107 | 72 | context->set_function_state(scope, state); |
108 | 72 | DCHECK_EQ(context->get_num_args(), 3); |
109 | 72 | const auto* const_from_tz = context->get_constant_col(1); |
110 | 72 | const auto* const_to_tz = context->get_constant_col(2); |
111 | | |
112 | | // ConvertTzState is used only when both the second and third parameters are constants |
113 | 72 | if (const_from_tz != nullptr && const_to_tz != nullptr) { |
114 | 47 | state->use_state = true; |
115 | 47 | init_convert_tz_state(state, const_from_tz, const_to_tz); |
116 | 47 | } else { |
117 | 25 | state->use_state = false; |
118 | 25 | } |
119 | | |
120 | 72 | return IFunction::open(context, scope); |
121 | 408 | } _ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE4openEPNS_15FunctionContextENS3_18FunctionStateScopeE Line | Count | Source | 101 | 391 | Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { | 102 | 391 | if (scope == FunctionContext::THREAD_LOCAL) { | 103 | 325 | return Status::OK(); | 104 | 325 | } | 105 | 66 | std::shared_ptr<ConvertTzState> state = std::make_shared<ConvertTzState>(); | 106 | | | 107 | 66 | context->set_function_state(scope, state); | 108 | 66 | DCHECK_EQ(context->get_num_args(), 3); | 109 | 66 | const auto* const_from_tz = context->get_constant_col(1); | 110 | 66 | const auto* const_to_tz = context->get_constant_col(2); | 111 | | | 112 | | // ConvertTzState is used only when both the second and third parameters are constants | 113 | 66 | if (const_from_tz != nullptr && const_to_tz != nullptr) { | 114 | 42 | state->use_state = true; | 115 | 42 | init_convert_tz_state(state, const_from_tz, const_to_tz); | 116 | 42 | } else { | 117 | 24 | state->use_state = false; | 118 | 24 | } | 119 | | | 120 | 66 | return IFunction::open(context, scope); | 121 | 391 | } |
_ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE4openEPNS_15FunctionContextENS3_18FunctionStateScopeE Line | Count | Source | 101 | 17 | Status open(FunctionContext* context, FunctionContext::FunctionStateScope scope) override { | 102 | 17 | if (scope == FunctionContext::THREAD_LOCAL) { | 103 | 11 | return Status::OK(); | 104 | 11 | } | 105 | 6 | std::shared_ptr<ConvertTzState> state = std::make_shared<ConvertTzState>(); | 106 | | | 107 | 6 | context->set_function_state(scope, state); | 108 | 6 | DCHECK_EQ(context->get_num_args(), 3); | 109 | 6 | const auto* const_from_tz = context->get_constant_col(1); | 110 | 6 | const auto* const_to_tz = context->get_constant_col(2); | 111 | | | 112 | | // ConvertTzState is used only when both the second and third parameters are constants | 113 | 6 | if (const_from_tz != nullptr && const_to_tz != nullptr) { | 114 | 5 | state->use_state = true; | 115 | 5 | init_convert_tz_state(state, const_from_tz, const_to_tz); | 116 | 5 | } else { | 117 | 1 | state->use_state = false; | 118 | 1 | } | 119 | | | 120 | 6 | return IFunction::open(context, scope); | 121 | 17 | } |
|
122 | | |
123 | | void init_convert_tz_state(std::shared_ptr<ConvertTzState> state, |
124 | | const ColumnPtrWrapper* const_from_tz, |
125 | 47 | const ColumnPtrWrapper* const_to_tz) { |
126 | 47 | auto const_data_from_tz = const_from_tz->column_ptr->get_data_at(0); |
127 | 47 | auto const_data_to_tz = const_to_tz->column_ptr->get_data_at(0); |
128 | | |
129 | | // from_tz and to_tz must both be non-null. |
130 | 47 | if (const_data_from_tz.data == nullptr || const_data_to_tz.data == nullptr) { |
131 | 0 | state->is_valid = false; |
132 | 0 | return; |
133 | 0 | } |
134 | | |
135 | 47 | auto from_tz_name = const_data_from_tz.to_string(); |
136 | 47 | auto to_tz_name = const_data_to_tz.to_string(); |
137 | | |
138 | 47 | if (!TimezoneUtils::find_cctz_time_zone(from_tz_name, state->from_tz)) [[unlikely]] { |
139 | 2 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, |
140 | 2 | from_tz_name); |
141 | 2 | } |
142 | 45 | if (!TimezoneUtils::find_cctz_time_zone(to_tz_name, state->to_tz)) [[unlikely]] { |
143 | 2 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, |
144 | 2 | to_tz_name); |
145 | 2 | } |
146 | 43 | state->is_valid = true; |
147 | 43 | } _ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE21init_convert_tz_stateESt10shared_ptrINS_14ConvertTzStateEEPKNS_16ColumnPtrWrapperES8_ Line | Count | Source | 125 | 42 | const ColumnPtrWrapper* const_to_tz) { | 126 | 42 | auto const_data_from_tz = const_from_tz->column_ptr->get_data_at(0); | 127 | 42 | auto const_data_to_tz = const_to_tz->column_ptr->get_data_at(0); | 128 | | | 129 | | // from_tz and to_tz must both be non-null. | 130 | 42 | if (const_data_from_tz.data == nullptr || const_data_to_tz.data == nullptr) { | 131 | 0 | state->is_valid = false; | 132 | 0 | return; | 133 | 0 | } | 134 | | | 135 | 42 | auto from_tz_name = const_data_from_tz.to_string(); | 136 | 42 | auto to_tz_name = const_data_to_tz.to_string(); | 137 | | | 138 | 42 | if (!TimezoneUtils::find_cctz_time_zone(from_tz_name, state->from_tz)) [[unlikely]] { | 139 | 2 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, | 140 | 2 | from_tz_name); | 141 | 2 | } | 142 | 40 | if (!TimezoneUtils::find_cctz_time_zone(to_tz_name, state->to_tz)) [[unlikely]] { | 143 | 2 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, | 144 | 2 | to_tz_name); | 145 | 2 | } | 146 | 38 | state->is_valid = true; | 147 | 38 | } |
_ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE21init_convert_tz_stateESt10shared_ptrINS_14ConvertTzStateEEPKNS_16ColumnPtrWrapperES8_ Line | Count | Source | 125 | 5 | const ColumnPtrWrapper* const_to_tz) { | 126 | 5 | auto const_data_from_tz = const_from_tz->column_ptr->get_data_at(0); | 127 | 5 | auto const_data_to_tz = const_to_tz->column_ptr->get_data_at(0); | 128 | | | 129 | | // from_tz and to_tz must both be non-null. | 130 | 5 | if (const_data_from_tz.data == nullptr || const_data_to_tz.data == nullptr) { | 131 | 0 | state->is_valid = false; | 132 | 0 | return; | 133 | 0 | } | 134 | | | 135 | 5 | auto from_tz_name = const_data_from_tz.to_string(); | 136 | 5 | auto to_tz_name = const_data_to_tz.to_string(); | 137 | | | 138 | 5 | if (!TimezoneUtils::find_cctz_time_zone(from_tz_name, state->from_tz)) [[unlikely]] { | 139 | 0 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, | 140 | 0 | from_tz_name); | 141 | 0 | } | 142 | 5 | if (!TimezoneUtils::find_cctz_time_zone(to_tz_name, state->to_tz)) [[unlikely]] { | 143 | 0 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, | 144 | 0 | to_tz_name); | 145 | 0 | } | 146 | 5 | state->is_valid = true; | 147 | 5 | } |
|
148 | | |
149 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
150 | 91 | uint32_t result, size_t input_rows_count) const override { |
151 | 91 | auto* convert_tz_state = reinterpret_cast<ConvertTzState*>( |
152 | 91 | context->get_function_state(FunctionContext::FRAGMENT_LOCAL)); |
153 | 91 | if (!convert_tz_state) { |
154 | 0 | return Status::RuntimeError( |
155 | 0 | "funciton context for function '{}' must have ConvertTzState;", get_name()); |
156 | 0 | } |
157 | | |
158 | 91 | auto result_null_map_column = ColumnUInt8::create(input_rows_count, 0); |
159 | 91 | NullMap& result_null_map = result_null_map_column->get_data(); |
160 | | |
161 | 91 | ColumnPtr argument_columns[3]; |
162 | 91 | bool col_const[3]; |
163 | | |
164 | | // calculate result null map and col_const |
165 | 364 | for (int i = 0; i < 3; ++i) { |
166 | 273 | ColumnPtr& col = block.get_by_position(arguments[i]).column; |
167 | 273 | col_const[i] = is_column_const(*col); |
168 | 273 | const NullMap* null_map = VectorizedUtils::get_null_map(col); |
169 | 273 | if (null_map) { |
170 | 122 | VectorizedUtils::update_null_map(result_null_map, *null_map, col_const[i]); |
171 | 122 | } |
172 | 273 | } |
173 | | |
174 | | // Extract nested columns from const(nullable) wrappers |
175 | 91 | argument_columns[0] = col_const[0] ? static_cast<const ColumnConst&>( |
176 | 1 | *block.get_by_position(arguments[0]).column) |
177 | 1 | .convert_to_full_column() |
178 | 91 | : block.get_by_position(arguments[0]).column; |
179 | 91 | argument_columns[0] = remove_nullable(argument_columns[0]); |
180 | 91 | default_preprocess_parameter_columns(argument_columns, col_const, {1, 2}, block, arguments); |
181 | 91 | argument_columns[1] = remove_nullable(argument_columns[1]); |
182 | 91 | argument_columns[2] = remove_nullable(argument_columns[2]); |
183 | | |
184 | 91 | auto result_column = ColumnType::create(); |
185 | 91 | if (convert_tz_state->use_state) { |
186 | | // ignore argument columns, use cached timezone input in state |
187 | 56 | execute_tz_const_with_state(convert_tz_state, |
188 | 56 | assert_cast<const ColumnType*>(argument_columns[0].get()), |
189 | 56 | result_column.get(), result_null_map, input_rows_count); |
190 | 56 | } else if (col_const[1] && col_const[2]) { |
191 | | // arguments are const |
192 | 0 | execute_tz_const(context, assert_cast<const ColumnType*>(argument_columns[0].get()), |
193 | 0 | assert_cast<const ColumnString*>(argument_columns[1].get()), |
194 | 0 | assert_cast<const ColumnString*>(argument_columns[2].get()), |
195 | 0 | result_column.get(), result_null_map, input_rows_count); |
196 | 35 | } else { |
197 | 35 | _execute(context, assert_cast<const ColumnType*>(argument_columns[0].get()), |
198 | 35 | assert_cast<const ColumnString*>(argument_columns[1].get()), |
199 | 35 | assert_cast<const ColumnString*>(argument_columns[2].get()), |
200 | 35 | result_column.get(), result_null_map, input_rows_count); |
201 | 35 | } //if const |
202 | | |
203 | 91 | if (block.get_data_type(result)->is_nullable()) { |
204 | 75 | block.get_by_position(result).column = ColumnNullable::create( |
205 | 75 | std::move(result_column), std::move(result_null_map_column)); |
206 | 75 | } else { |
207 | 16 | block.get_by_position(result).column = std::move(result_column); |
208 | 16 | } |
209 | 91 | return Status::OK(); |
210 | 91 | } _ZNK5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Line | Count | Source | 150 | 85 | uint32_t result, size_t input_rows_count) const override { | 151 | 85 | auto* convert_tz_state = reinterpret_cast<ConvertTzState*>( | 152 | 85 | context->get_function_state(FunctionContext::FRAGMENT_LOCAL)); | 153 | 85 | if (!convert_tz_state) { | 154 | 0 | return Status::RuntimeError( | 155 | 0 | "funciton context for function '{}' must have ConvertTzState;", get_name()); | 156 | 0 | } | 157 | | | 158 | 85 | auto result_null_map_column = ColumnUInt8::create(input_rows_count, 0); | 159 | 85 | NullMap& result_null_map = result_null_map_column->get_data(); | 160 | | | 161 | 85 | ColumnPtr argument_columns[3]; | 162 | 85 | bool col_const[3]; | 163 | | | 164 | | // calculate result null map and col_const | 165 | 340 | for (int i = 0; i < 3; ++i) { | 166 | 255 | ColumnPtr& col = block.get_by_position(arguments[i]).column; | 167 | 255 | col_const[i] = is_column_const(*col); | 168 | 255 | const NullMap* null_map = VectorizedUtils::get_null_map(col); | 169 | 255 | if (null_map) { | 170 | 117 | VectorizedUtils::update_null_map(result_null_map, *null_map, col_const[i]); | 171 | 117 | } | 172 | 255 | } | 173 | | | 174 | | // Extract nested columns from const(nullable) wrappers | 175 | 85 | argument_columns[0] = col_const[0] ? static_cast<const ColumnConst&>( | 176 | 1 | *block.get_by_position(arguments[0]).column) | 177 | 1 | .convert_to_full_column() | 178 | 85 | : block.get_by_position(arguments[0]).column; | 179 | 85 | argument_columns[0] = remove_nullable(argument_columns[0]); | 180 | 85 | default_preprocess_parameter_columns(argument_columns, col_const, {1, 2}, block, arguments); | 181 | 85 | argument_columns[1] = remove_nullable(argument_columns[1]); | 182 | 85 | argument_columns[2] = remove_nullable(argument_columns[2]); | 183 | | | 184 | 85 | auto result_column = ColumnType::create(); | 185 | 85 | if (convert_tz_state->use_state) { | 186 | | // ignore argument columns, use cached timezone input in state | 187 | 51 | execute_tz_const_with_state(convert_tz_state, | 188 | 51 | assert_cast<const ColumnType*>(argument_columns[0].get()), | 189 | 51 | result_column.get(), result_null_map, input_rows_count); | 190 | 51 | } else if (col_const[1] && col_const[2]) { | 191 | | // arguments are const | 192 | 0 | execute_tz_const(context, assert_cast<const ColumnType*>(argument_columns[0].get()), | 193 | 0 | assert_cast<const ColumnString*>(argument_columns[1].get()), | 194 | 0 | assert_cast<const ColumnString*>(argument_columns[2].get()), | 195 | 0 | result_column.get(), result_null_map, input_rows_count); | 196 | 34 | } else { | 197 | 34 | _execute(context, assert_cast<const ColumnType*>(argument_columns[0].get()), | 198 | 34 | assert_cast<const ColumnString*>(argument_columns[1].get()), | 199 | 34 | assert_cast<const ColumnString*>(argument_columns[2].get()), | 200 | 34 | result_column.get(), result_null_map, input_rows_count); | 201 | 34 | } //if const | 202 | | | 203 | 85 | if (block.get_data_type(result)->is_nullable()) { | 204 | 72 | block.get_by_position(result).column = ColumnNullable::create( | 205 | 72 | std::move(result_column), std::move(result_null_map_column)); | 206 | 72 | } else { | 207 | 13 | block.get_by_position(result).column = std::move(result_column); | 208 | 13 | } | 209 | 85 | return Status::OK(); | 210 | 85 | } |
_ZNK5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Line | Count | Source | 150 | 6 | uint32_t result, size_t input_rows_count) const override { | 151 | 6 | auto* convert_tz_state = reinterpret_cast<ConvertTzState*>( | 152 | 6 | context->get_function_state(FunctionContext::FRAGMENT_LOCAL)); | 153 | 6 | if (!convert_tz_state) { | 154 | 0 | return Status::RuntimeError( | 155 | 0 | "funciton context for function '{}' must have ConvertTzState;", get_name()); | 156 | 0 | } | 157 | | | 158 | 6 | auto result_null_map_column = ColumnUInt8::create(input_rows_count, 0); | 159 | 6 | NullMap& result_null_map = result_null_map_column->get_data(); | 160 | | | 161 | 6 | ColumnPtr argument_columns[3]; | 162 | 6 | bool col_const[3]; | 163 | | | 164 | | // calculate result null map and col_const | 165 | 24 | for (int i = 0; i < 3; ++i) { | 166 | 18 | ColumnPtr& col = block.get_by_position(arguments[i]).column; | 167 | 18 | col_const[i] = is_column_const(*col); | 168 | 18 | const NullMap* null_map = VectorizedUtils::get_null_map(col); | 169 | 18 | if (null_map) { | 170 | 5 | VectorizedUtils::update_null_map(result_null_map, *null_map, col_const[i]); | 171 | 5 | } | 172 | 18 | } | 173 | | | 174 | | // Extract nested columns from const(nullable) wrappers | 175 | 6 | argument_columns[0] = col_const[0] ? static_cast<const ColumnConst&>( | 176 | 0 | *block.get_by_position(arguments[0]).column) | 177 | 0 | .convert_to_full_column() | 178 | 6 | : block.get_by_position(arguments[0]).column; | 179 | 6 | argument_columns[0] = remove_nullable(argument_columns[0]); | 180 | 6 | default_preprocess_parameter_columns(argument_columns, col_const, {1, 2}, block, arguments); | 181 | 6 | argument_columns[1] = remove_nullable(argument_columns[1]); | 182 | 6 | argument_columns[2] = remove_nullable(argument_columns[2]); | 183 | | | 184 | 6 | auto result_column = ColumnType::create(); | 185 | 6 | if (convert_tz_state->use_state) { | 186 | | // ignore argument columns, use cached timezone input in state | 187 | 5 | execute_tz_const_with_state(convert_tz_state, | 188 | 5 | assert_cast<const ColumnType*>(argument_columns[0].get()), | 189 | 5 | result_column.get(), result_null_map, input_rows_count); | 190 | 5 | } else if (col_const[1] && col_const[2]) { | 191 | | // arguments are const | 192 | 0 | execute_tz_const(context, assert_cast<const ColumnType*>(argument_columns[0].get()), | 193 | 0 | assert_cast<const ColumnString*>(argument_columns[1].get()), | 194 | 0 | assert_cast<const ColumnString*>(argument_columns[2].get()), | 195 | 0 | result_column.get(), result_null_map, input_rows_count); | 196 | 1 | } else { | 197 | 1 | _execute(context, assert_cast<const ColumnType*>(argument_columns[0].get()), | 198 | 1 | assert_cast<const ColumnString*>(argument_columns[1].get()), | 199 | 1 | assert_cast<const ColumnString*>(argument_columns[2].get()), | 200 | 1 | result_column.get(), result_null_map, input_rows_count); | 201 | 1 | } //if const | 202 | | | 203 | 6 | if (block.get_data_type(result)->is_nullable()) { | 204 | 3 | block.get_by_position(result).column = ColumnNullable::create( | 205 | 3 | std::move(result_column), std::move(result_null_map_column)); | 206 | 3 | } else { | 207 | 3 | block.get_by_position(result).column = std::move(result_column); | 208 | 3 | } | 209 | 6 | return Status::OK(); | 210 | 6 | } |
|
211 | | |
212 | | private: |
213 | | static void _execute(FunctionContext* context, const ColumnType* date_column, |
214 | | const ColumnString* from_tz_column, const ColumnString* to_tz_column, |
215 | | ColumnType* result_column, NullMap& result_null_map, |
216 | 35 | size_t input_rows_count) { |
217 | 138 | for (size_t i = 0; i < input_rows_count; i++) { |
218 | 103 | if (result_null_map[i]) { |
219 | 0 | result_column->insert_default(); |
220 | 0 | continue; |
221 | 0 | } |
222 | 103 | auto from_tz = from_tz_column->get_data_at(i).to_string(); |
223 | 103 | auto to_tz = to_tz_column->get_data_at(i).to_string(); |
224 | 103 | execute_inner_loop(date_column, from_tz, to_tz, result_column, result_null_map, i); |
225 | 103 | } |
226 | 35 | } _ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE8_executeEPNS_15FunctionContextEPKNS_12ColumnVectorILS1_26EEEPKNS_9ColumnStrIjEESC_PS6_RNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEm Line | Count | Source | 216 | 34 | size_t input_rows_count) { | 217 | 136 | for (size_t i = 0; i < input_rows_count; i++) { | 218 | 102 | if (result_null_map[i]) { | 219 | 0 | result_column->insert_default(); | 220 | 0 | continue; | 221 | 0 | } | 222 | 102 | auto from_tz = from_tz_column->get_data_at(i).to_string(); | 223 | 102 | auto to_tz = to_tz_column->get_data_at(i).to_string(); | 224 | 102 | execute_inner_loop(date_column, from_tz, to_tz, result_column, result_null_map, i); | 225 | 102 | } | 226 | 34 | } |
_ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE8_executeEPNS_15FunctionContextEPKNS_12ColumnVectorILS1_43EEEPKNS_9ColumnStrIjEESC_PS6_RNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEm Line | Count | Source | 216 | 1 | size_t input_rows_count) { | 217 | 2 | for (size_t i = 0; i < input_rows_count; i++) { | 218 | 1 | if (result_null_map[i]) { | 219 | 0 | result_column->insert_default(); | 220 | 0 | continue; | 221 | 0 | } | 222 | 1 | auto from_tz = from_tz_column->get_data_at(i).to_string(); | 223 | 1 | auto to_tz = to_tz_column->get_data_at(i).to_string(); | 224 | 1 | execute_inner_loop(date_column, from_tz, to_tz, result_column, result_null_map, i); | 225 | 1 | } | 226 | 1 | } |
|
227 | | |
228 | | static std::tuple<int64_t, int64_t, bool> unix_timestamp_for_convert_tz( |
229 | 210 | const DateValueType& ts_value, const cctz::time_zone& from_tz) { |
230 | 210 | const auto civil_value = [&]() { |
231 | 210 | if constexpr (PType == TYPE_TIMESTAMP_NS) { |
232 | 6 | return ts_value.to_datetime(); |
233 | 204 | } else { |
234 | 204 | return ts_value; |
235 | 204 | } |
236 | 210 | }(); _ZZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE29unix_timestamp_for_convert_tzERKNS_11DateV2ValueINS_19DateTimeV2ValueTypeEEERKN4cctz9time_zoneEENKUlvE_clEv Line | Count | Source | 230 | 204 | const auto civil_value = [&]() { | 231 | | if constexpr (PType == TYPE_TIMESTAMP_NS) { | 232 | | return ts_value.to_datetime(); | 233 | 204 | } else { | 234 | 204 | return ts_value; | 235 | 204 | } | 236 | 204 | }(); |
_ZZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE29unix_timestamp_for_convert_tzERKNS_16TimeStampNsValueERKN4cctz9time_zoneEENKUlvE_clEv Line | Count | Source | 230 | 6 | const auto civil_value = [&]() { | 231 | 6 | if constexpr (PType == TYPE_TIMESTAMP_NS) { | 232 | 6 | return ts_value.to_datetime(); | 233 | | } else { | 234 | | return ts_value; | 235 | | } | 236 | 6 | }(); |
|
237 | 210 | cctz::civil_second civil_time(civil_value.year(), civil_value.month(), civil_value.day(), |
238 | 210 | civil_value.hour(), civil_value.minute(), |
239 | 210 | civil_value.second()); |
240 | 210 | const auto lookup = from_tz.lookup(civil_time); |
241 | 210 | const bool skipped = lookup.kind == cctz::time_zone::civil_lookup::SKIPPED; |
242 | 210 | const auto tp = skipped ? lookup.trans : lookup.pre; |
243 | | |
244 | | // Skipped civil times map to the transition instant. Do not keep the |
245 | | // input fractional part inside a local time interval that never existed. |
246 | 210 | return {tp.time_since_epoch().count(), skipped ? 0 : civil_value.microsecond(), skipped}; |
247 | 210 | } _ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE29unix_timestamp_for_convert_tzERKNS_11DateV2ValueINS_19DateTimeV2ValueTypeEEERKN4cctz9time_zoneE Line | Count | Source | 229 | 204 | const DateValueType& ts_value, const cctz::time_zone& from_tz) { | 230 | 204 | const auto civil_value = [&]() { | 231 | 204 | if constexpr (PType == TYPE_TIMESTAMP_NS) { | 232 | 204 | return ts_value.to_datetime(); | 233 | 204 | } else { | 234 | 204 | return ts_value; | 235 | 204 | } | 236 | 204 | }(); | 237 | 204 | cctz::civil_second civil_time(civil_value.year(), civil_value.month(), civil_value.day(), | 238 | 204 | civil_value.hour(), civil_value.minute(), | 239 | 204 | civil_value.second()); | 240 | 204 | const auto lookup = from_tz.lookup(civil_time); | 241 | 204 | const bool skipped = lookup.kind == cctz::time_zone::civil_lookup::SKIPPED; | 242 | 204 | const auto tp = skipped ? lookup.trans : lookup.pre; | 243 | | | 244 | | // Skipped civil times map to the transition instant. Do not keep the | 245 | | // input fractional part inside a local time interval that never existed. | 246 | 204 | return {tp.time_since_epoch().count(), skipped ? 0 : civil_value.microsecond(), skipped}; | 247 | 204 | } |
_ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE29unix_timestamp_for_convert_tzERKNS_16TimeStampNsValueERKN4cctz9time_zoneE Line | Count | Source | 229 | 6 | const DateValueType& ts_value, const cctz::time_zone& from_tz) { | 230 | 6 | const auto civil_value = [&]() { | 231 | 6 | if constexpr (PType == TYPE_TIMESTAMP_NS) { | 232 | 6 | return ts_value.to_datetime(); | 233 | 6 | } else { | 234 | 6 | return ts_value; | 235 | 6 | } | 236 | 6 | }(); | 237 | 6 | cctz::civil_second civil_time(civil_value.year(), civil_value.month(), civil_value.day(), | 238 | 6 | civil_value.hour(), civil_value.minute(), | 239 | 6 | civil_value.second()); | 240 | 6 | const auto lookup = from_tz.lookup(civil_time); | 241 | 6 | const bool skipped = lookup.kind == cctz::time_zone::civil_lookup::SKIPPED; | 242 | 6 | const auto tp = skipped ? lookup.trans : lookup.pre; | 243 | | | 244 | | // Skipped civil times map to the transition instant. Do not keep the | 245 | | // input fractional part inside a local time interval that never existed. | 246 | 6 | return {tp.time_since_epoch().count(), skipped ? 0 : civil_value.microsecond(), skipped}; | 247 | 6 | } |
|
248 | | |
249 | | static bool convert_value(const DateValueType& source, const cctz::time_zone& from_tz, |
250 | 210 | const cctz::time_zone& to_tz, DateValueType* result) { |
251 | 210 | const auto [seconds, microseconds, skipped] = |
252 | 210 | unix_timestamp_for_convert_tz(source, from_tz); |
253 | 210 | const std::pair<int64_t, int64_t> timestamp {seconds, microseconds}; |
254 | 210 | if constexpr (PType == TYPE_TIMESTAMP_NS) { |
255 | 6 | DateV2Value<DateTimeV2ValueType> converted; |
256 | 6 | converted.from_unixtime(timestamp, to_tz); |
257 | 6 | const uint16_t remainder = skipped ? 0 : source.nanosecond_remainder(); |
258 | 6 | return result->from_datetime(converted, remainder); |
259 | 204 | } else { |
260 | 204 | result->from_unixtime(timestamp, to_tz); |
261 | 204 | return result->is_valid_date(); |
262 | 204 | } |
263 | 210 | } _ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE13convert_valueERKNS_11DateV2ValueINS_19DateTimeV2ValueTypeEEERKN4cctz9time_zoneESB_PS5_ Line | Count | Source | 250 | 204 | const cctz::time_zone& to_tz, DateValueType* result) { | 251 | 204 | const auto [seconds, microseconds, skipped] = | 252 | 204 | unix_timestamp_for_convert_tz(source, from_tz); | 253 | 204 | const std::pair<int64_t, int64_t> timestamp {seconds, microseconds}; | 254 | | if constexpr (PType == TYPE_TIMESTAMP_NS) { | 255 | | DateV2Value<DateTimeV2ValueType> converted; | 256 | | converted.from_unixtime(timestamp, to_tz); | 257 | | const uint16_t remainder = skipped ? 0 : source.nanosecond_remainder(); | 258 | | return result->from_datetime(converted, remainder); | 259 | 204 | } else { | 260 | 204 | result->from_unixtime(timestamp, to_tz); | 261 | 204 | return result->is_valid_date(); | 262 | 204 | } | 263 | 204 | } |
_ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE13convert_valueERKNS_16TimeStampNsValueERKN4cctz9time_zoneES9_PS3_ Line | Count | Source | 250 | 6 | const cctz::time_zone& to_tz, DateValueType* result) { | 251 | 6 | const auto [seconds, microseconds, skipped] = | 252 | 6 | unix_timestamp_for_convert_tz(source, from_tz); | 253 | 6 | const std::pair<int64_t, int64_t> timestamp {seconds, microseconds}; | 254 | 6 | if constexpr (PType == TYPE_TIMESTAMP_NS) { | 255 | 6 | DateV2Value<DateTimeV2ValueType> converted; | 256 | 6 | converted.from_unixtime(timestamp, to_tz); | 257 | 6 | const uint16_t remainder = skipped ? 0 : source.nanosecond_remainder(); | 258 | 6 | return result->from_datetime(converted, remainder); | 259 | | } else { | 260 | | result->from_unixtime(timestamp, to_tz); | 261 | | return result->is_valid_date(); | 262 | | } | 263 | 6 | } |
|
264 | | |
265 | | static void execute_tz_const_with_state(ConvertTzState* convert_tz_state, |
266 | | const ColumnType* date_column, |
267 | | ColumnType* result_column, NullMap& result_null_map, |
268 | 56 | size_t input_rows_count) { |
269 | 56 | cctz::time_zone& from_tz = convert_tz_state->from_tz; |
270 | 56 | cctz::time_zone& to_tz = convert_tz_state->to_tz; |
271 | 56 | auto push_null = [&](size_t row) { |
272 | 0 | result_null_map[row] = true; |
273 | 0 | result_column->insert_default(); |
274 | 0 | }; Unexecuted instantiation: _ZZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE27execute_tz_const_with_stateEPNS_14ConvertTzStateEPKNS_12ColumnVectorILS1_26EEEPS6_RNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEmENKUlmE_clEm Unexecuted instantiation: _ZZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE27execute_tz_const_with_stateEPNS_14ConvertTzStateEPKNS_12ColumnVectorILS1_43EEEPS6_RNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEmENKUlmE_clEm |
275 | | // state isn't valid means there's NULL in timezone input. so return null rather than exception |
276 | 56 | if (!convert_tz_state->is_valid) [[unlikely]] { |
277 | | // If an invalid timezone is present, return null |
278 | 0 | for (size_t i = 0; i < input_rows_count; i++) { |
279 | 0 | push_null(i); |
280 | 0 | } |
281 | 0 | return; |
282 | 0 | } |
283 | 165 | for (size_t i = 0; i < input_rows_count; i++) { |
284 | 109 | if (result_null_map[i]) { |
285 | 2 | result_column->insert_default(); |
286 | 2 | continue; |
287 | 2 | } |
288 | | |
289 | 107 | DateValueType ts_value = date_column->get_element(i); |
290 | 107 | DateValueType ts_value2; |
291 | | |
292 | 107 | if (!convert_value(ts_value, from_tz, to_tz, &ts_value2)) [[unlikely]] { |
293 | 1 | throw_out_of_bound_convert_tz<DateValueType>(date_column->get_element(i), |
294 | 1 | from_tz.name(), to_tz.name()); |
295 | 1 | } |
296 | | |
297 | 107 | result_column->insert(Field::create_field<PType>(ts_value2)); |
298 | 107 | } |
299 | 56 | } _ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE27execute_tz_const_with_stateEPNS_14ConvertTzStateEPKNS_12ColumnVectorILS1_26EEEPS6_RNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEm Line | Count | Source | 268 | 51 | size_t input_rows_count) { | 269 | 51 | cctz::time_zone& from_tz = convert_tz_state->from_tz; | 270 | 51 | cctz::time_zone& to_tz = convert_tz_state->to_tz; | 271 | 51 | auto push_null = [&](size_t row) { | 272 | 51 | result_null_map[row] = true; | 273 | 51 | result_column->insert_default(); | 274 | 51 | }; | 275 | | // state isn't valid means there's NULL in timezone input. so return null rather than exception | 276 | 51 | if (!convert_tz_state->is_valid) [[unlikely]] { | 277 | | // If an invalid timezone is present, return null | 278 | 0 | for (size_t i = 0; i < input_rows_count; i++) { | 279 | 0 | push_null(i); | 280 | 0 | } | 281 | 0 | return; | 282 | 0 | } | 283 | 155 | for (size_t i = 0; i < input_rows_count; i++) { | 284 | 104 | if (result_null_map[i]) { | 285 | 2 | result_column->insert_default(); | 286 | 2 | continue; | 287 | 2 | } | 288 | | | 289 | 102 | DateValueType ts_value = date_column->get_element(i); | 290 | 102 | DateValueType ts_value2; | 291 | | | 292 | 102 | if (!convert_value(ts_value, from_tz, to_tz, &ts_value2)) [[unlikely]] { | 293 | 1 | throw_out_of_bound_convert_tz<DateValueType>(date_column->get_element(i), | 294 | 1 | from_tz.name(), to_tz.name()); | 295 | 1 | } | 296 | | | 297 | 102 | result_column->insert(Field::create_field<PType>(ts_value2)); | 298 | 102 | } | 299 | 51 | } |
_ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE27execute_tz_const_with_stateEPNS_14ConvertTzStateEPKNS_12ColumnVectorILS1_43EEEPS6_RNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEm Line | Count | Source | 268 | 5 | size_t input_rows_count) { | 269 | 5 | cctz::time_zone& from_tz = convert_tz_state->from_tz; | 270 | 5 | cctz::time_zone& to_tz = convert_tz_state->to_tz; | 271 | 5 | auto push_null = [&](size_t row) { | 272 | 5 | result_null_map[row] = true; | 273 | 5 | result_column->insert_default(); | 274 | 5 | }; | 275 | | // state isn't valid means there's NULL in timezone input. so return null rather than exception | 276 | 5 | if (!convert_tz_state->is_valid) [[unlikely]] { | 277 | | // If an invalid timezone is present, return null | 278 | 0 | for (size_t i = 0; i < input_rows_count; i++) { | 279 | 0 | push_null(i); | 280 | 0 | } | 281 | 0 | return; | 282 | 0 | } | 283 | 10 | for (size_t i = 0; i < input_rows_count; i++) { | 284 | 5 | if (result_null_map[i]) { | 285 | 0 | result_column->insert_default(); | 286 | 0 | continue; | 287 | 0 | } | 288 | | | 289 | 5 | DateValueType ts_value = date_column->get_element(i); | 290 | 5 | DateValueType ts_value2; | 291 | | | 292 | 5 | if (!convert_value(ts_value, from_tz, to_tz, &ts_value2)) [[unlikely]] { | 293 | 0 | throw_out_of_bound_convert_tz<DateValueType>(date_column->get_element(i), | 294 | 0 | from_tz.name(), to_tz.name()); | 295 | 0 | } | 296 | | | 297 | 5 | result_column->insert(Field::create_field<PType>(ts_value2)); | 298 | 5 | } | 299 | 5 | } |
|
300 | | |
301 | | static void execute_tz_const(FunctionContext* context, const ColumnType* date_column, |
302 | | const ColumnString* from_tz_column, |
303 | | const ColumnString* to_tz_column, ColumnType* result_column, |
304 | 0 | NullMap& result_null_map, size_t input_rows_count) { |
305 | 0 | auto from_tz = from_tz_column->get_data_at(0).to_string(); |
306 | 0 | auto to_tz = to_tz_column->get_data_at(0).to_string(); |
307 | 0 | cctz::time_zone from_zone, to_zone; |
308 | 0 | if (!TimezoneUtils::find_cctz_time_zone(from_tz, from_zone)) [[unlikely]] { |
309 | 0 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, |
310 | 0 | from_tz); |
311 | 0 | } |
312 | 0 | if (!TimezoneUtils::find_cctz_time_zone(to_tz, to_zone)) [[unlikely]] { |
313 | 0 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, |
314 | 0 | to_tz); |
315 | 0 | } |
316 | 0 | for (size_t i = 0; i < input_rows_count; i++) { |
317 | 0 | if (result_null_map[i]) { |
318 | 0 | result_column->insert_default(); |
319 | 0 | continue; |
320 | 0 | } |
321 | 0 | execute_inner_loop(date_column, from_tz, to_tz, result_column, result_null_map, i); |
322 | 0 | } |
323 | 0 | } Unexecuted instantiation: _ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE16execute_tz_constEPNS_15FunctionContextEPKNS_12ColumnVectorILS1_26EEEPKNS_9ColumnStrIjEESC_PS6_RNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEm Unexecuted instantiation: _ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE16execute_tz_constEPNS_15FunctionContextEPKNS_12ColumnVectorILS1_43EEEPKNS_9ColumnStrIjEESC_PS6_RNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEm |
324 | | |
325 | | static void execute_inner_loop(const ColumnType* date_column, const std::string& from_tz_name, |
326 | | const std::string& to_tz_name, ColumnType* result_column, |
327 | 103 | NullMap& result_null_map, const size_t index_now) { |
328 | 103 | DateValueType ts_value = date_column->get_element(index_now); |
329 | 103 | cctz::time_zone from_tz {}, to_tz {}; |
330 | 103 | DateValueType ts_value2; |
331 | | |
332 | 103 | if (!TimezoneUtils::find_cctz_time_zone(from_tz_name, from_tz)) [[unlikely]] { |
333 | 0 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, |
334 | 0 | from_tz_name); |
335 | 0 | } |
336 | 103 | if (!TimezoneUtils::find_cctz_time_zone(to_tz_name, to_tz)) [[unlikely]] { |
337 | 0 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, |
338 | 0 | to_tz_name); |
339 | 0 | } |
340 | | |
341 | 103 | if (!convert_value(ts_value, from_tz, to_tz, &ts_value2)) [[unlikely]] { |
342 | 0 | throw_out_of_bound_convert_tz<DateValueType>(date_column->get_element(index_now), |
343 | 0 | from_tz.name(), to_tz.name()); |
344 | 0 | } |
345 | | |
346 | 103 | result_column->insert(Field::create_field<PType>(ts_value2)); |
347 | 103 | } _ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE26EE18execute_inner_loopEPKNS_12ColumnVectorILS1_26EEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESE_PS4_RNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEm Line | Count | Source | 327 | 102 | NullMap& result_null_map, const size_t index_now) { | 328 | 102 | DateValueType ts_value = date_column->get_element(index_now); | 329 | 102 | cctz::time_zone from_tz {}, to_tz {}; | 330 | 102 | DateValueType ts_value2; | 331 | | | 332 | 102 | if (!TimezoneUtils::find_cctz_time_zone(from_tz_name, from_tz)) [[unlikely]] { | 333 | 0 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, | 334 | 0 | from_tz_name); | 335 | 0 | } | 336 | 102 | if (!TimezoneUtils::find_cctz_time_zone(to_tz_name, to_tz)) [[unlikely]] { | 337 | 0 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, | 338 | 0 | to_tz_name); | 339 | 0 | } | 340 | | | 341 | 102 | if (!convert_value(ts_value, from_tz, to_tz, &ts_value2)) [[unlikely]] { | 342 | 0 | throw_out_of_bound_convert_tz<DateValueType>(date_column->get_element(index_now), | 343 | 0 | from_tz.name(), to_tz.name()); | 344 | 0 | } | 345 | | | 346 | 102 | result_column->insert(Field::create_field<PType>(ts_value2)); | 347 | 102 | } |
_ZN5doris17FunctionConvertTZILNS_13PrimitiveTypeE43EE18execute_inner_loopEPKNS_12ColumnVectorILS1_43EEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESE_PS4_RNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEEm Line | Count | Source | 327 | 1 | NullMap& result_null_map, const size_t index_now) { | 328 | 1 | DateValueType ts_value = date_column->get_element(index_now); | 329 | 1 | cctz::time_zone from_tz {}, to_tz {}; | 330 | 1 | DateValueType ts_value2; | 331 | | | 332 | 1 | if (!TimezoneUtils::find_cctz_time_zone(from_tz_name, from_tz)) [[unlikely]] { | 333 | 0 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, | 334 | 0 | from_tz_name); | 335 | 0 | } | 336 | 1 | if (!TimezoneUtils::find_cctz_time_zone(to_tz_name, to_tz)) [[unlikely]] { | 337 | 0 | throw Exception(ErrorCode::INVALID_ARGUMENT, "Operation {} invalid timezone: {}", name, | 338 | 0 | to_tz_name); | 339 | 0 | } | 340 | | | 341 | 1 | if (!convert_value(ts_value, from_tz, to_tz, &ts_value2)) [[unlikely]] { | 342 | 0 | throw_out_of_bound_convert_tz<DateValueType>(date_column->get_element(index_now), | 343 | 0 | from_tz.name(), to_tz.name()); | 344 | 0 | } | 345 | | | 346 | 1 | result_column->insert(Field::create_field<PType>(ts_value2)); | 347 | 1 | } |
|
348 | | }; |
349 | | |
350 | 8 | void register_function_convert_tz(SimpleFunctionFactory& factory) { |
351 | 8 | factory.register_function<FunctionConvertTZ<TYPE_DATETIMEV2>>(); |
352 | 8 | factory.register_function<FunctionConvertTZ<TYPE_TIMESTAMP_NS>>(); |
353 | 8 | } |
354 | | |
355 | | } // namespace doris |