be/src/exprs/function/functions_logical.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 | | // This file is copied from |
18 | | // https://github.com/ClickHouse/ClickHouse/blob/master/src/Functions/FunctionsLogical.cpp |
19 | | // and modified by Doris |
20 | | |
21 | | #include "exprs/function/functions_logical.h" |
22 | | |
23 | | #include <glog/logging.h> |
24 | | |
25 | | #include <algorithm> |
26 | | #include <ranges> |
27 | | #include <utility> |
28 | | |
29 | | #include "common/compiler_util.h" // IWYU pragma: keep |
30 | | #include "common/status.h" |
31 | | #include "core/assert_cast.h" |
32 | | #include "core/block/block.h" |
33 | | #include "core/block/column_with_type_and_name.h" |
34 | | #include "core/column/column.h" |
35 | | #include "core/column/column_const.h" |
36 | | #include "core/column/column_nullable.h" |
37 | | #include "core/column/column_vector.h" |
38 | | #include "core/data_type/data_type_nullable.h" |
39 | | #include "core/data_type/data_type_number.h" |
40 | | #include "core/string_ref.h" |
41 | | #include "exprs/aggregate/aggregate_function.h" |
42 | | #include "exprs/function/simple_function_factory.h" |
43 | | |
44 | | namespace doris { |
45 | | class FunctionContext; |
46 | | } // namespace doris |
47 | | |
48 | | namespace doris { |
49 | | |
50 | | namespace { |
51 | | using namespace FunctionsLogicalDetail; |
52 | | |
53 | | template <class Op> |
54 | 0 | void vector_const(const IColumn* left, const ColumnConst* right, IColumn* res, size_t rows) { |
55 | 0 | const auto* __restrict l_datas = assert_cast<const ColumnUInt8*>(left)->get_data().data(); |
56 | 0 | auto r_data = (uint8_t)right->get_bool(0); |
57 | 0 | auto* __restrict res_datas = assert_cast<ColumnUInt8*>(res)->get_data().data(); |
58 | |
|
59 | 0 | for (size_t i = 0; i < rows; ++i) { |
60 | 0 | res_datas[i] = Op::apply(l_datas[i], r_data); |
61 | 0 | } |
62 | 0 | } Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_112vector_constINS_22FunctionsLogicalDetail7AndImplEEEvPKNS_7IColumnEPKNS_11ColumnConstEPS4_m Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_112vector_constINS_22FunctionsLogicalDetail6OrImplEEEvPKNS_7IColumnEPKNS_11ColumnConstEPS4_m Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_112vector_constINS_22FunctionsLogicalDetail7XorImplEEEvPKNS_7IColumnEPKNS_11ColumnConstEPS4_m |
63 | | |
64 | | template <class Op> |
65 | 1 | void vector_vector(const IColumn* left, const IColumn* right, IColumn* res, size_t rows) { |
66 | 1 | const auto* __restrict l_datas = assert_cast<const ColumnUInt8*>(left)->get_data().data(); |
67 | 1 | const auto* __restrict r_datas = assert_cast<const ColumnUInt8*>(right)->get_data().data(); |
68 | 1 | auto* __restrict res_datas = assert_cast<ColumnUInt8*>(res)->get_data().data(); |
69 | | |
70 | 10 | for (size_t i = 0; i < rows; ++i) { |
71 | 9 | res_datas[i] = Op::apply(l_datas[i], r_datas[i]); |
72 | 9 | } |
73 | 1 | } Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_113vector_vectorINS_22FunctionsLogicalDetail7AndImplEEEvPKNS_7IColumnES6_PS4_m Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_113vector_vectorINS_22FunctionsLogicalDetail6OrImplEEEvPKNS_7IColumnES6_PS4_m functions_logical.cpp:_ZN5doris12_GLOBAL__N_113vector_vectorINS_22FunctionsLogicalDetail7XorImplEEEvPKNS_7IColumnES6_PS4_m Line | Count | Source | 65 | 1 | void vector_vector(const IColumn* left, const IColumn* right, IColumn* res, size_t rows) { | 66 | 1 | const auto* __restrict l_datas = assert_cast<const ColumnUInt8*>(left)->get_data().data(); | 67 | 1 | const auto* __restrict r_datas = assert_cast<const ColumnUInt8*>(right)->get_data().data(); | 68 | 1 | auto* __restrict res_datas = assert_cast<ColumnUInt8*>(res)->get_data().data(); | 69 | | | 70 | 10 | for (size_t i = 0; i < rows; ++i) { | 71 | 9 | res_datas[i] = Op::apply(l_datas[i], r_datas[i]); | 72 | 9 | } | 73 | 1 | } |
|
74 | | |
75 | 0 | std::pair<const IColumn*, ColumnPtr> get_nested_and_null_column(const IColumn* column) { |
76 | 0 | auto null_column = check_and_get_column<const ColumnNullable>(column); |
77 | 0 | if (null_column) { |
78 | 0 | return {null_column->get_nested_column_ptr().get(), null_column->get_null_map_column_ptr()}; |
79 | 0 | } else { |
80 | 0 | return {column, ColumnUInt8::create(column->size(), 0)}; |
81 | 0 | } |
82 | 0 | } |
83 | | |
84 | | template <class Op> |
85 | | void vector_const_null(const IColumn* left, const ColumnConst* right, IColumn* res, IColumn* nulls, |
86 | 0 | size_t rows) { |
87 | 0 | auto [data_column, null_column_ptr] = get_nested_and_null_column(left); |
88 | 0 | const auto* __restrict l_datas = |
89 | 0 | assert_cast<const ColumnUInt8*>(data_column)->get_data().data(); |
90 | 0 | const auto* __restrict l_nulls = |
91 | 0 | assert_cast<const ColumnUInt8*>(null_column_ptr.get())->get_data().data(); |
92 | |
|
93 | 0 | auto* __restrict res_datas = assert_cast<ColumnUInt8*>(res)->get_data().data(); |
94 | 0 | auto* __restrict res_nulls = assert_cast<ColumnUInt8*>(nulls)->get_data().data(); |
95 | |
|
96 | 0 | auto r_data_ptr = right->get_data_at(0); |
97 | |
|
98 | 0 | if (r_data_ptr.data == nullptr) { |
99 | 0 | for (size_t i = 0; i < rows; ++i) { |
100 | 0 | res_nulls[i] = Op::apply_null(l_datas[i], l_nulls[i], 1, true); |
101 | 0 | res_datas[i] = Op::apply(l_datas[i], 1); |
102 | 0 | } |
103 | 0 | } else { |
104 | 0 | UInt8 r_data = *(UInt8*)r_data_ptr.data; |
105 | 0 | for (size_t i = 0; i < rows; ++i) { |
106 | 0 | res_nulls[i] = Op::apply_null(l_datas[i], l_nulls[i], r_data, false); |
107 | 0 | res_datas[i] = Op::apply(l_datas[i], r_data); |
108 | 0 | } |
109 | 0 | } |
110 | 0 | } Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_117vector_const_nullINS_22FunctionsLogicalDetail7AndImplEEEvPKNS_7IColumnEPKNS_11ColumnConstEPS4_SA_m Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_117vector_const_nullINS_22FunctionsLogicalDetail6OrImplEEEvPKNS_7IColumnEPKNS_11ColumnConstEPS4_SA_m |
111 | | |
112 | | template <class Op> |
113 | | void vector_vector_null(const IColumn* left, const IColumn* right, IColumn* res, IColumn* nulls, |
114 | 0 | size_t rows) { |
115 | 0 | auto [l_datas_ptr, l_nulls_ptr] = get_nested_and_null_column(left); |
116 | 0 | auto [r_datas_ptr, r_nulls_ptr] = get_nested_and_null_column(right); |
117 | |
|
118 | 0 | const auto* __restrict l_datas = |
119 | 0 | assert_cast<const ColumnUInt8*>(l_datas_ptr)->get_data().data(); |
120 | 0 | const auto* __restrict r_datas = |
121 | 0 | assert_cast<const ColumnUInt8*>(r_datas_ptr)->get_data().data(); |
122 | 0 | const auto* __restrict l_nulls = |
123 | 0 | assert_cast<const ColumnUInt8*>(l_nulls_ptr.get())->get_data().data(); |
124 | 0 | const auto* __restrict r_nulls = |
125 | 0 | assert_cast<const ColumnUInt8*>(r_nulls_ptr.get())->get_data().data(); |
126 | |
|
127 | 0 | auto* __restrict res_datas = assert_cast<ColumnUInt8*>(res)->get_data().data(); |
128 | 0 | auto* __restrict res_nulls = assert_cast<ColumnUInt8*>(nulls)->get_data().data(); |
129 | |
|
130 | 0 | for (size_t i = 0; i < rows; ++i) { |
131 | 0 | res_nulls[i] = Op::apply_null(l_datas[i], l_nulls[i], r_datas[i], r_nulls[i]); |
132 | 0 | res_datas[i] = Op::apply(l_datas[i], r_datas[i]); |
133 | 0 | } |
134 | 0 | } Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_118vector_vector_nullINS_22FunctionsLogicalDetail7AndImplEEEvPKNS_7IColumnES6_PS4_S7_m Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_118vector_vector_nullINS_22FunctionsLogicalDetail6OrImplEEEvPKNS_7IColumnES6_PS4_S7_m |
135 | | |
136 | | template <class Op> |
137 | | void basic_execute_impl(ColumnRawPtrs arguments, ColumnWithTypeAndName& result_info, |
138 | 1 | size_t input_rows_count) { |
139 | 1 | auto col_res = ColumnUInt8::create(input_rows_count); |
140 | 1 | if (auto l = check_and_get_column<ColumnConst>(arguments[0])) { |
141 | 0 | vector_const<Op>(arguments[1], l, col_res.get(), input_rows_count); |
142 | 1 | } else if (auto r = check_and_get_column<ColumnConst>(arguments[1])) { |
143 | 0 | vector_const<Op>(arguments[0], r, col_res.get(), input_rows_count); |
144 | 1 | } else { |
145 | 1 | vector_vector<Op>(arguments[0], arguments[1], col_res.get(), input_rows_count); |
146 | 1 | } |
147 | 1 | result_info.column = std::move(col_res); |
148 | 1 | } Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_118basic_execute_implINS_22FunctionsLogicalDetail7AndImplEEEvSt6vectorIPKNS_7IColumnESaIS7_EERNS_21ColumnWithTypeAndNameEm Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_118basic_execute_implINS_22FunctionsLogicalDetail6OrImplEEEvSt6vectorIPKNS_7IColumnESaIS7_EERNS_21ColumnWithTypeAndNameEm functions_logical.cpp:_ZN5doris12_GLOBAL__N_118basic_execute_implINS_22FunctionsLogicalDetail7XorImplEEEvSt6vectorIPKNS_7IColumnESaIS7_EERNS_21ColumnWithTypeAndNameEm Line | Count | Source | 138 | 1 | size_t input_rows_count) { | 139 | 1 | auto col_res = ColumnUInt8::create(input_rows_count); | 140 | 1 | if (auto l = check_and_get_column<ColumnConst>(arguments[0])) { | 141 | 0 | vector_const<Op>(arguments[1], l, col_res.get(), input_rows_count); | 142 | 1 | } else if (auto r = check_and_get_column<ColumnConst>(arguments[1])) { | 143 | 0 | vector_const<Op>(arguments[0], r, col_res.get(), input_rows_count); | 144 | 1 | } else { | 145 | 1 | vector_vector<Op>(arguments[0], arguments[1], col_res.get(), input_rows_count); | 146 | 1 | } | 147 | 1 | result_info.column = std::move(col_res); | 148 | 1 | } |
|
149 | | |
150 | | template <class Op> |
151 | | void null_execute_impl(ColumnRawPtrs arguments, ColumnWithTypeAndName& result_info, |
152 | 0 | size_t input_rows_count) { |
153 | 0 | auto col_nulls = ColumnUInt8::create(input_rows_count); |
154 | 0 | auto col_res = ColumnUInt8::create(input_rows_count); |
155 | 0 | if (auto l = check_and_get_column<ColumnConst>(arguments[0])) { |
156 | 0 | vector_const_null<Op>(arguments[1], l, col_res.get(), col_nulls.get(), input_rows_count); |
157 | 0 | } else if (auto r = check_and_get_column<ColumnConst>(arguments[1])) { |
158 | 0 | vector_const_null<Op>(arguments[0], r, col_res.get(), col_nulls.get(), input_rows_count); |
159 | 0 | } else { |
160 | 0 | vector_vector_null<Op>(arguments[0], arguments[1], col_res.get(), col_nulls.get(), |
161 | 0 | input_rows_count); |
162 | 0 | } |
163 | 0 | result_info.column = ColumnNullable::create(std::move(col_res), std::move(col_nulls)); |
164 | 0 | } Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_117null_execute_implINS_22FunctionsLogicalDetail7AndImplEEEvSt6vectorIPKNS_7IColumnESaIS7_EERNS_21ColumnWithTypeAndNameEm Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_117null_execute_implINS_22FunctionsLogicalDetail6OrImplEEEvSt6vectorIPKNS_7IColumnESaIS7_EERNS_21ColumnWithTypeAndNameEm |
165 | | |
166 | | } // namespace |
167 | | |
168 | 1.21k | bool is_native_number(PrimitiveType type) { |
169 | 1.21k | return (is_int_or_bool(type) && type != TYPE_LARGEINT) || is_float_or_double(type); |
170 | 1.21k | } |
171 | | |
172 | | template <typename Impl, typename Name> |
173 | | DataTypePtr FunctionAnyArityLogical<Impl, Name>::get_return_type_impl( |
174 | 531 | const DataTypes& arguments) const { |
175 | 531 | if (arguments.size() < 2) { |
176 | 0 | throw doris::Exception( |
177 | 0 | ErrorCode::INVALID_ARGUMENT, |
178 | 0 | "Number of arguments for function \"{}\" should be at least 2: passed {}", |
179 | 0 | get_name(), arguments.size()); |
180 | 0 | } |
181 | | |
182 | 531 | bool has_nullable_arguments = false; |
183 | 1.59k | for (size_t i = 0; i < arguments.size(); ++i) { |
184 | 1.06k | const auto& arg_type = arguments[i]; |
185 | | |
186 | 1.06k | if (!has_nullable_arguments) { |
187 | 669 | has_nullable_arguments = arg_type->is_nullable(); |
188 | 669 | if (has_nullable_arguments && !Impl::special_implementation_for_nulls()) { |
189 | 0 | LOG(WARNING) << fmt::format( |
190 | 0 | "Logical error: Unexpected type of argument for function \"{}\" argument " |
191 | 0 | "{} is of type {}", |
192 | 0 | get_name(), i + 1, arg_type->get_name()); |
193 | 0 | } |
194 | 669 | } |
195 | | |
196 | 1.06k | auto arg_primitive_type = arg_type->get_primitive_type(); |
197 | 1.06k | if (!(is_native_number(arg_primitive_type) || |
198 | 1.06k | (Impl::special_implementation_for_nulls() && is_native_number(arg_primitive_type)))) { |
199 | 0 | throw doris::Exception(ErrorCode::INVALID_ARGUMENT, |
200 | 0 | "Illegal type ({}) of {} argument of function {}", |
201 | 0 | arg_type->get_name(), i + 1, get_name()); |
202 | 0 | } |
203 | 1.06k | } |
204 | | |
205 | 531 | auto result_type = std::make_shared<DataTypeUInt8>(); |
206 | 531 | return has_nullable_arguments ? make_nullable(result_type) : result_type; |
207 | 531 | } _ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_7AndImplENS_7NameAndEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE Line | Count | Source | 174 | 144 | const DataTypes& arguments) const { | 175 | 144 | if (arguments.size() < 2) { | 176 | 0 | throw doris::Exception( | 177 | 0 | ErrorCode::INVALID_ARGUMENT, | 178 | 0 | "Number of arguments for function \"{}\" should be at least 2: passed {}", | 179 | 0 | get_name(), arguments.size()); | 180 | 0 | } | 181 | | | 182 | 144 | bool has_nullable_arguments = false; | 183 | 432 | for (size_t i = 0; i < arguments.size(); ++i) { | 184 | 288 | const auto& arg_type = arguments[i]; | 185 | | | 186 | 288 | if (!has_nullable_arguments) { | 187 | 225 | has_nullable_arguments = arg_type->is_nullable(); | 188 | 225 | if (has_nullable_arguments && !Impl::special_implementation_for_nulls()) { | 189 | 0 | LOG(WARNING) << fmt::format( | 190 | 0 | "Logical error: Unexpected type of argument for function \"{}\" argument " | 191 | 0 | "{} is of type {}", | 192 | 0 | get_name(), i + 1, arg_type->get_name()); | 193 | 0 | } | 194 | 225 | } | 195 | | | 196 | 288 | auto arg_primitive_type = arg_type->get_primitive_type(); | 197 | 288 | if (!(is_native_number(arg_primitive_type) || | 198 | 288 | (Impl::special_implementation_for_nulls() && is_native_number(arg_primitive_type)))) { | 199 | 0 | throw doris::Exception(ErrorCode::INVALID_ARGUMENT, | 200 | 0 | "Illegal type ({}) of {} argument of function {}", | 201 | 0 | arg_type->get_name(), i + 1, get_name()); | 202 | 0 | } | 203 | 288 | } | 204 | | | 205 | 144 | auto result_type = std::make_shared<DataTypeUInt8>(); | 206 | 144 | return has_nullable_arguments ? make_nullable(result_type) : result_type; | 207 | 144 | } |
_ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_6OrImplENS_6NameOrEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE Line | Count | Source | 174 | 386 | const DataTypes& arguments) const { | 175 | 386 | if (arguments.size() < 2) { | 176 | 0 | throw doris::Exception( | 177 | 0 | ErrorCode::INVALID_ARGUMENT, | 178 | 0 | "Number of arguments for function \"{}\" should be at least 2: passed {}", | 179 | 0 | get_name(), arguments.size()); | 180 | 0 | } | 181 | | | 182 | 386 | bool has_nullable_arguments = false; | 183 | 1.15k | for (size_t i = 0; i < arguments.size(); ++i) { | 184 | 772 | const auto& arg_type = arguments[i]; | 185 | | | 186 | 772 | if (!has_nullable_arguments) { | 187 | 442 | has_nullable_arguments = arg_type->is_nullable(); | 188 | 442 | if (has_nullable_arguments && !Impl::special_implementation_for_nulls()) { | 189 | 0 | LOG(WARNING) << fmt::format( | 190 | 0 | "Logical error: Unexpected type of argument for function \"{}\" argument " | 191 | 0 | "{} is of type {}", | 192 | 0 | get_name(), i + 1, arg_type->get_name()); | 193 | 0 | } | 194 | 442 | } | 195 | | | 196 | 772 | auto arg_primitive_type = arg_type->get_primitive_type(); | 197 | 772 | if (!(is_native_number(arg_primitive_type) || | 198 | 772 | (Impl::special_implementation_for_nulls() && is_native_number(arg_primitive_type)))) { | 199 | 0 | throw doris::Exception(ErrorCode::INVALID_ARGUMENT, | 200 | 0 | "Illegal type ({}) of {} argument of function {}", | 201 | 0 | arg_type->get_name(), i + 1, get_name()); | 202 | 0 | } | 203 | 772 | } | 204 | | | 205 | 386 | auto result_type = std::make_shared<DataTypeUInt8>(); | 206 | 386 | return has_nullable_arguments ? make_nullable(result_type) : result_type; | 207 | 386 | } |
_ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_7XorImplENS_7NameXorEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE Line | Count | Source | 174 | 1 | const DataTypes& arguments) const { | 175 | 1 | if (arguments.size() < 2) { | 176 | 0 | throw doris::Exception( | 177 | 0 | ErrorCode::INVALID_ARGUMENT, | 178 | 0 | "Number of arguments for function \"{}\" should be at least 2: passed {}", | 179 | 0 | get_name(), arguments.size()); | 180 | 0 | } | 181 | | | 182 | 1 | bool has_nullable_arguments = false; | 183 | 3 | for (size_t i = 0; i < arguments.size(); ++i) { | 184 | 2 | const auto& arg_type = arguments[i]; | 185 | | | 186 | 2 | if (!has_nullable_arguments) { | 187 | 2 | has_nullable_arguments = arg_type->is_nullable(); | 188 | 2 | if (has_nullable_arguments && !Impl::special_implementation_for_nulls()) { | 189 | 0 | LOG(WARNING) << fmt::format( | 190 | 0 | "Logical error: Unexpected type of argument for function \"{}\" argument " | 191 | 0 | "{} is of type {}", | 192 | 0 | get_name(), i + 1, arg_type->get_name()); | 193 | 0 | } | 194 | 2 | } | 195 | | | 196 | 2 | auto arg_primitive_type = arg_type->get_primitive_type(); | 197 | 2 | if (!(is_native_number(arg_primitive_type) || | 198 | 2 | (Impl::special_implementation_for_nulls() && is_native_number(arg_primitive_type)))) { | 199 | 0 | throw doris::Exception(ErrorCode::INVALID_ARGUMENT, | 200 | 0 | "Illegal type ({}) of {} argument of function {}", | 201 | 0 | arg_type->get_name(), i + 1, get_name()); | 202 | 0 | } | 203 | 2 | } | 204 | | | 205 | 1 | auto result_type = std::make_shared<DataTypeUInt8>(); | 206 | 1 | return has_nullable_arguments ? make_nullable(result_type) : result_type; | 207 | 1 | } |
|
208 | | |
209 | | template <typename Impl, typename Name> |
210 | | Status FunctionAnyArityLogical<Impl, Name>::execute_impl(FunctionContext* context, Block& block, |
211 | | const ColumnNumbers& arguments, |
212 | | uint32_t result_index, |
213 | 1 | size_t input_rows_count) const { |
214 | 1 | ColumnRawPtrs args_in; |
215 | 1 | for (const auto arg_index : arguments) |
216 | 2 | args_in.push_back(block.get_by_position(arg_index).column.get()); |
217 | | |
218 | 1 | auto& result_info = block.get_by_position(result_index); |
219 | 1 | if constexpr (Impl::special_implementation_for_nulls()) { |
220 | 0 | if (result_info.type->is_nullable()) { |
221 | 0 | null_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); |
222 | 0 | } else { |
223 | 0 | basic_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); |
224 | 0 | } |
225 | 1 | } else { |
226 | 1 | DCHECK(std::ranges::all_of(args_in, [](const auto& arg) { return !arg->is_nullable(); })); |
227 | 1 | basic_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); |
228 | 1 | } |
229 | 1 | return Status::OK(); |
230 | 1 | } Unexecuted instantiation: _ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_7AndImplENS_7NameAndEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Unexecuted instantiation: _ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_6OrImplENS_6NameOrEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm _ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_7XorImplENS_7NameXorEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Line | Count | Source | 213 | 1 | size_t input_rows_count) const { | 214 | 1 | ColumnRawPtrs args_in; | 215 | 1 | for (const auto arg_index : arguments) | 216 | 2 | args_in.push_back(block.get_by_position(arg_index).column.get()); | 217 | | | 218 | 1 | auto& result_info = block.get_by_position(result_index); | 219 | | if constexpr (Impl::special_implementation_for_nulls()) { | 220 | | if (result_info.type->is_nullable()) { | 221 | | null_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); | 222 | | } else { | 223 | | basic_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); | 224 | | } | 225 | 1 | } else { | 226 | | DCHECK(std::ranges::all_of(args_in, [](const auto& arg) { return !arg->is_nullable(); })); | 227 | 1 | basic_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); | 228 | 1 | } | 229 | 1 | return Status::OK(); | 230 | 1 | } |
|
231 | | |
232 | | template <PrimitiveType A, typename Op> |
233 | | struct UnaryOperationImpl { |
234 | | using ArrayA = typename ColumnVector<A>::Container; |
235 | | using ArrayC = typename ColumnVector<Op::ResultType>::Container; |
236 | | |
237 | 331 | static void NO_INLINE vector(const ArrayA& a, ArrayC& c) { |
238 | 482k | std::transform(a.cbegin(), a.cend(), c.begin(), [](const auto x) { return Op::apply(x); }); |
239 | 331 | } |
240 | | }; |
241 | | |
242 | | template <template <PrimitiveType> class Impl, typename Name> |
243 | | DataTypePtr FunctionUnaryLogical<Impl, Name>::get_return_type_impl( |
244 | 152 | const DataTypes& arguments) const { |
245 | 152 | if (!is_native_number(arguments[0]->get_primitive_type())) { |
246 | 0 | throw doris::Exception(ErrorCode::INVALID_ARGUMENT, |
247 | 0 | "Illegal type ({}) of argument of function {}", |
248 | 0 | arguments[0]->get_name(), get_name()); |
249 | 0 | } |
250 | | |
251 | 152 | return std::make_shared<DataTypeUInt8>(); |
252 | 152 | } |
253 | | |
254 | | template <template <PrimitiveType> class Impl, PrimitiveType T> |
255 | 329 | bool functionUnaryExecuteType(Block& block, const ColumnNumbers& arguments, size_t result) { |
256 | 329 | if (auto col = check_and_get_column<ColumnVector<T>>( |
257 | 331 | block.get_by_position(arguments[0]).column.get())) { |
258 | 331 | auto col_res = ColumnUInt8::create(); |
259 | | |
260 | 331 | typename ColumnUInt8::Container& vec_res = col_res->get_data(); |
261 | 331 | vec_res.resize(col->get_data().size()); |
262 | 331 | UnaryOperationImpl<T, Impl<T>>::vector(col->get_data(), vec_res); |
263 | | |
264 | 331 | block.replace_by_position(result, std::move(col_res)); |
265 | 331 | return true; |
266 | 331 | } |
267 | | |
268 | 18.4E | return false; |
269 | 329 | } |
270 | | |
271 | | template <template <PrimitiveType> class Impl, typename Name> |
272 | | Status FunctionUnaryLogical<Impl, Name>::execute_impl(FunctionContext* context, Block& block, |
273 | | const ColumnNumbers& arguments, |
274 | | uint32_t result, |
275 | 329 | size_t /*input_rows_count*/) const { |
276 | 329 | if (!functionUnaryExecuteType<Impl, TYPE_BOOLEAN>(block, arguments, result)) { |
277 | 0 | throw doris::Exception(ErrorCode::INVALID_ARGUMENT, |
278 | 0 | "Illegal column {} of argument of function {}", |
279 | 0 | block.get_by_position(arguments[0]).column->get_name(), get_name()); |
280 | 0 | } |
281 | | |
282 | 329 | return Status::OK(); |
283 | 329 | } |
284 | | |
285 | 8 | void register_function_logical(SimpleFunctionFactory& instance) { |
286 | 8 | instance.register_function<FunctionAnd>(); |
287 | 8 | instance.register_function<FunctionOr>(); |
288 | 8 | instance.register_function<FunctionNot>(); |
289 | 8 | instance.register_function<FunctionXor>(); |
290 | 8 | } |
291 | | |
292 | | } // namespace doris |