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 | 0 | void vector_vector(const IColumn* left, const IColumn* right, IColumn* res, size_t rows) { |
66 | 0 | const auto* __restrict l_datas = assert_cast<const ColumnUInt8*>(left)->get_data().data(); |
67 | 0 | const auto* __restrict r_datas = assert_cast<const ColumnUInt8*>(right)->get_data().data(); |
68 | 0 | auto* __restrict res_datas = assert_cast<ColumnUInt8*>(res)->get_data().data(); |
69 | |
|
70 | 0 | for (size_t i = 0; i < rows; ++i) { |
71 | 0 | res_datas[i] = Op::apply(l_datas[i], r_datas[i]); |
72 | 0 | } |
73 | 0 | } 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 Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_113vector_vectorINS_22FunctionsLogicalDetail7XorImplEEEvPKNS_7IColumnES6_PS4_m |
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 | 0 | size_t input_rows_count) { |
139 | 0 | auto col_res = ColumnUInt8::create(input_rows_count); |
140 | 0 | if (auto l = check_and_get_column<ColumnConst>(arguments[0])) { |
141 | 0 | vector_const<Op>(arguments[1], l.get(), col_res.get(), input_rows_count); |
142 | 0 | } else if (auto r = check_and_get_column<ColumnConst>(arguments[1])) { |
143 | 0 | vector_const<Op>(arguments[0], r.get(), col_res.get(), input_rows_count); |
144 | 0 | } else { |
145 | 0 | vector_vector<Op>(arguments[0], arguments[1], col_res.get(), input_rows_count); |
146 | 0 | } |
147 | 0 | result_info.column = std::move(col_res); |
148 | 0 | } 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 Unexecuted instantiation: functions_logical.cpp:_ZN5doris12_GLOBAL__N_118basic_execute_implINS_22FunctionsLogicalDetail7XorImplEEEvSt6vectorIPKNS_7IColumnESaIS7_EERNS_21ColumnWithTypeAndNameEm |
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.get(), col_res.get(), col_nulls.get(), |
157 | 0 | input_rows_count); |
158 | 0 | } else if (auto r = check_and_get_column<ColumnConst>(arguments[1])) { |
159 | 0 | vector_const_null<Op>(arguments[0], r.get(), col_res.get(), col_nulls.get(), |
160 | 0 | input_rows_count); |
161 | 0 | } else { |
162 | 0 | vector_vector_null<Op>(arguments[0], arguments[1], col_res.get(), col_nulls.get(), |
163 | 0 | input_rows_count); |
164 | 0 | } |
165 | 0 | result_info.column = ColumnNullable::create(std::move(col_res), std::move(col_nulls)); |
166 | 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 |
167 | | |
168 | | } // namespace |
169 | | |
170 | 34 | bool is_native_number(PrimitiveType type) { |
171 | 34 | return (is_int_or_bool(type) && type != TYPE_LARGEINT) || is_float_or_double(type); |
172 | 34 | } |
173 | | |
174 | | template <typename Impl, typename Name> |
175 | | DataTypePtr FunctionAnyArityLogical<Impl, Name>::get_return_type_impl( |
176 | 17 | const DataTypes& arguments) const { |
177 | 17 | if (arguments.size() < 2) { |
178 | 0 | throw doris::Exception( |
179 | 0 | ErrorCode::INVALID_ARGUMENT, |
180 | 0 | "Number of arguments for function \"{}\" should be at least 2: passed {}", |
181 | 0 | get_name(), arguments.size()); |
182 | 0 | } |
183 | | |
184 | 17 | bool has_nullable_arguments = false; |
185 | 51 | for (size_t i = 0; i < arguments.size(); ++i) { |
186 | 34 | const auto& arg_type = arguments[i]; |
187 | | |
188 | 34 | if (!has_nullable_arguments) { |
189 | 19 | has_nullable_arguments = arg_type->is_nullable(); |
190 | 19 | if (has_nullable_arguments && !Impl::special_implementation_for_nulls()) { |
191 | 0 | LOG(WARNING) << fmt::format( |
192 | 0 | "Logical error: Unexpected type of argument for function \"{}\" argument " |
193 | 0 | "{} is of type {}", |
194 | 0 | get_name(), i + 1, arg_type->get_name()); |
195 | 0 | } |
196 | 19 | } |
197 | | |
198 | 34 | auto arg_primitive_type = arg_type->get_primitive_type(); |
199 | 34 | if (!(is_native_number(arg_primitive_type) || |
200 | 34 | (Impl::special_implementation_for_nulls() && is_native_number(arg_primitive_type)))) { |
201 | 0 | throw doris::Exception(ErrorCode::INVALID_ARGUMENT, |
202 | 0 | "Illegal type ({}) of {} argument of function {}", |
203 | 0 | arg_type->get_name(), i + 1, get_name()); |
204 | 0 | } |
205 | 34 | } |
206 | | |
207 | 17 | auto result_type = std::make_shared<DataTypeUInt8>(); |
208 | 17 | return has_nullable_arguments ? make_nullable(result_type) : result_type; |
209 | 17 | } _ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_7AndImplENS_7NameAndEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE Line | Count | Source | 176 | 8 | const DataTypes& arguments) const { | 177 | 8 | if (arguments.size() < 2) { | 178 | 0 | throw doris::Exception( | 179 | 0 | ErrorCode::INVALID_ARGUMENT, | 180 | 0 | "Number of arguments for function \"{}\" should be at least 2: passed {}", | 181 | 0 | get_name(), arguments.size()); | 182 | 0 | } | 183 | | | 184 | 8 | bool has_nullable_arguments = false; | 185 | 24 | for (size_t i = 0; i < arguments.size(); ++i) { | 186 | 16 | const auto& arg_type = arguments[i]; | 187 | | | 188 | 16 | if (!has_nullable_arguments) { | 189 | 8 | has_nullable_arguments = arg_type->is_nullable(); | 190 | 8 | if (has_nullable_arguments && !Impl::special_implementation_for_nulls()) { | 191 | 0 | LOG(WARNING) << fmt::format( | 192 | 0 | "Logical error: Unexpected type of argument for function \"{}\" argument " | 193 | 0 | "{} is of type {}", | 194 | 0 | get_name(), i + 1, arg_type->get_name()); | 195 | 0 | } | 196 | 8 | } | 197 | | | 198 | 16 | auto arg_primitive_type = arg_type->get_primitive_type(); | 199 | 16 | if (!(is_native_number(arg_primitive_type) || | 200 | 16 | (Impl::special_implementation_for_nulls() && is_native_number(arg_primitive_type)))) { | 201 | 0 | throw doris::Exception(ErrorCode::INVALID_ARGUMENT, | 202 | 0 | "Illegal type ({}) of {} argument of function {}", | 203 | 0 | arg_type->get_name(), i + 1, get_name()); | 204 | 0 | } | 205 | 16 | } | 206 | | | 207 | 8 | auto result_type = std::make_shared<DataTypeUInt8>(); | 208 | 8 | return has_nullable_arguments ? make_nullable(result_type) : result_type; | 209 | 8 | } |
_ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_6OrImplENS_6NameOrEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE Line | Count | Source | 176 | 9 | const DataTypes& arguments) const { | 177 | 9 | if (arguments.size() < 2) { | 178 | 0 | throw doris::Exception( | 179 | 0 | ErrorCode::INVALID_ARGUMENT, | 180 | 0 | "Number of arguments for function \"{}\" should be at least 2: passed {}", | 181 | 0 | get_name(), arguments.size()); | 182 | 0 | } | 183 | | | 184 | 9 | bool has_nullable_arguments = false; | 185 | 27 | for (size_t i = 0; i < arguments.size(); ++i) { | 186 | 18 | const auto& arg_type = arguments[i]; | 187 | | | 188 | 18 | if (!has_nullable_arguments) { | 189 | 11 | has_nullable_arguments = arg_type->is_nullable(); | 190 | 11 | if (has_nullable_arguments && !Impl::special_implementation_for_nulls()) { | 191 | 0 | LOG(WARNING) << fmt::format( | 192 | 0 | "Logical error: Unexpected type of argument for function \"{}\" argument " | 193 | 0 | "{} is of type {}", | 194 | 0 | get_name(), i + 1, arg_type->get_name()); | 195 | 0 | } | 196 | 11 | } | 197 | | | 198 | 18 | auto arg_primitive_type = arg_type->get_primitive_type(); | 199 | 18 | if (!(is_native_number(arg_primitive_type) || | 200 | 18 | (Impl::special_implementation_for_nulls() && is_native_number(arg_primitive_type)))) { | 201 | 0 | throw doris::Exception(ErrorCode::INVALID_ARGUMENT, | 202 | 0 | "Illegal type ({}) of {} argument of function {}", | 203 | 0 | arg_type->get_name(), i + 1, get_name()); | 204 | 0 | } | 205 | 18 | } | 206 | | | 207 | 9 | auto result_type = std::make_shared<DataTypeUInt8>(); | 208 | 9 | return has_nullable_arguments ? make_nullable(result_type) : result_type; | 209 | 9 | } |
Unexecuted instantiation: _ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_7XorImplENS_7NameXorEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE |
210 | | |
211 | | template <typename Impl, typename Name> |
212 | | Status FunctionAnyArityLogical<Impl, Name>::execute_impl(FunctionContext* context, Block& block, |
213 | | const ColumnNumbers& arguments, |
214 | | uint32_t result_index, |
215 | 0 | size_t input_rows_count) const { |
216 | 0 | ColumnRawPtrs args_in; |
217 | 0 | for (const auto arg_index : arguments) |
218 | 0 | args_in.push_back(block.get_by_position(arg_index).column.get()); |
219 | |
|
220 | 0 | auto& result_info = block.get_by_position(result_index); |
221 | 0 | if constexpr (Impl::special_implementation_for_nulls()) { |
222 | 0 | if (result_info.type->is_nullable()) { |
223 | 0 | null_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); |
224 | 0 | } else { |
225 | 0 | basic_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); |
226 | 0 | } |
227 | 0 | } else { |
228 | 0 | DCHECK(std::ranges::all_of(args_in, [](const auto& arg) { return !arg->is_nullable(); })); |
229 | 0 | basic_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); |
230 | 0 | } |
231 | 0 | return Status::OK(); |
232 | 0 | } Unexecuted instantiation: _ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_7AndImplENS_7NameAndEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Unexecuted instantiation: _ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_6OrImplENS_6NameOrEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Unexecuted instantiation: _ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_7XorImplENS_7NameXorEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm |
233 | | |
234 | | template <PrimitiveType A, typename Op> |
235 | | struct UnaryOperationImpl { |
236 | | using ArrayA = typename ColumnVector<A>::Container; |
237 | | using ArrayC = typename ColumnVector<Op::ResultType>::Container; |
238 | | |
239 | 0 | static void NO_INLINE vector(const ArrayA& a, ArrayC& c) { |
240 | 0 | std::transform(a.cbegin(), a.cend(), c.begin(), [](const auto x) { return Op::apply(x); }); |
241 | 0 | } |
242 | | }; |
243 | | |
244 | | template <template <PrimitiveType> class Impl, typename Name> |
245 | | DataTypePtr FunctionUnaryLogical<Impl, Name>::get_return_type_impl( |
246 | 0 | const DataTypes& arguments) const { |
247 | 0 | if (!is_native_number(arguments[0]->get_primitive_type())) { |
248 | 0 | throw doris::Exception(ErrorCode::INVALID_ARGUMENT, |
249 | 0 | "Illegal type ({}) of argument of function {}", |
250 | 0 | arguments[0]->get_name(), get_name()); |
251 | 0 | } |
252 | | |
253 | 0 | return std::make_shared<DataTypeUInt8>(); |
254 | 0 | } |
255 | | |
256 | | template <template <PrimitiveType> class Impl, PrimitiveType T> |
257 | 0 | bool functionUnaryExecuteType(Block& block, const ColumnNumbers& arguments, size_t result) { |
258 | 0 | if (auto col = check_and_get_column<ColumnVector<T>>( |
259 | 0 | block.get_by_position(arguments[0]).column.get())) { |
260 | 0 | auto col_res = ColumnUInt8::create(); |
261 | |
|
262 | 0 | typename ColumnUInt8::Container& vec_res = col_res->get_data(); |
263 | 0 | vec_res.resize(col->get_data().size()); |
264 | 0 | UnaryOperationImpl<T, Impl<T>>::vector(col->get_data(), vec_res); |
265 | |
|
266 | 0 | block.replace_by_position(result, std::move(col_res)); |
267 | 0 | return true; |
268 | 0 | } |
269 | | |
270 | 0 | return false; |
271 | 0 | } |
272 | | |
273 | | template <template <PrimitiveType> class Impl, typename Name> |
274 | | Status FunctionUnaryLogical<Impl, Name>::execute_impl(FunctionContext* context, Block& block, |
275 | | const ColumnNumbers& arguments, |
276 | | uint32_t result, |
277 | 0 | size_t /*input_rows_count*/) const { |
278 | 0 | if (!functionUnaryExecuteType<Impl, TYPE_BOOLEAN>(block, arguments, result)) { |
279 | 0 | throw doris::Exception(ErrorCode::INVALID_ARGUMENT, |
280 | 0 | "Illegal column {} of argument of function {}", |
281 | 0 | block.get_by_position(arguments[0]).column->get_name(), get_name()); |
282 | 0 | } |
283 | | |
284 | 0 | return Status::OK(); |
285 | 0 | } |
286 | | |
287 | 1 | void register_function_logical(SimpleFunctionFactory& instance) { |
288 | 1 | instance.register_function<FunctionAnd>(); |
289 | 1 | instance.register_function<FunctionOr>(); |
290 | 1 | instance.register_function<FunctionNot>(); |
291 | 1 | instance.register_function<FunctionXor>(); |
292 | 1 | } |
293 | | |
294 | | } // namespace doris |