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 | 31 | std::pair<const IColumn*, ColumnPtr> get_nested_and_null_column(const IColumn* column) { |
76 | 31 | auto null_column = check_and_get_column<const ColumnNullable>(column); |
77 | 31 | if (null_column) { |
78 | 11 | return {null_column->get_nested_column_ptr().get(), null_column->get_null_map_column_ptr()}; |
79 | 20 | } else { |
80 | 20 | return {column, ColumnUInt8::create(column->size(), 0)}; |
81 | 20 | } |
82 | 31 | } |
83 | | |
84 | | template <class Op> |
85 | | void vector_const_null(const IColumn* left, const ColumnConst* right, IColumn* res, IColumn* nulls, |
86 | 17 | size_t rows) { |
87 | 17 | auto [data_column, null_column_ptr] = get_nested_and_null_column(left); |
88 | 17 | const auto* __restrict l_datas = |
89 | 17 | assert_cast<const ColumnUInt8*>(data_column)->get_data().data(); |
90 | 17 | const auto* __restrict l_nulls = |
91 | 17 | assert_cast<const ColumnUInt8*>(null_column_ptr.get())->get_data().data(); |
92 | | |
93 | 17 | auto* __restrict res_datas = assert_cast<ColumnUInt8*>(res)->get_data().data(); |
94 | 17 | auto* __restrict res_nulls = assert_cast<ColumnUInt8*>(nulls)->get_data().data(); |
95 | | |
96 | 17 | auto r_data_ptr = right->get_data_at(0); |
97 | | |
98 | 17 | if (r_data_ptr.data == nullptr) { |
99 | 41 | for (size_t i = 0; i < rows; ++i) { |
100 | 24 | res_nulls[i] = Op::apply_null(l_datas[i], l_nulls[i], 1, true); |
101 | 24 | res_datas[i] = Op::apply(l_datas[i], 1); |
102 | 24 | } |
103 | 17 | } 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 | 17 | } functions_logical.cpp:_ZN5doris12_GLOBAL__N_117vector_const_nullINS_22FunctionsLogicalDetail7AndImplEEEvPKNS_7IColumnEPKNS_11ColumnConstEPS4_SA_m Line | Count | Source | 86 | 14 | size_t rows) { | 87 | 14 | auto [data_column, null_column_ptr] = get_nested_and_null_column(left); | 88 | 14 | const auto* __restrict l_datas = | 89 | 14 | assert_cast<const ColumnUInt8*>(data_column)->get_data().data(); | 90 | 14 | const auto* __restrict l_nulls = | 91 | 14 | assert_cast<const ColumnUInt8*>(null_column_ptr.get())->get_data().data(); | 92 | | | 93 | 14 | auto* __restrict res_datas = assert_cast<ColumnUInt8*>(res)->get_data().data(); | 94 | 14 | auto* __restrict res_nulls = assert_cast<ColumnUInt8*>(nulls)->get_data().data(); | 95 | | | 96 | 14 | auto r_data_ptr = right->get_data_at(0); | 97 | | | 98 | 14 | if (r_data_ptr.data == nullptr) { | 99 | 29 | for (size_t i = 0; i < rows; ++i) { | 100 | 15 | res_nulls[i] = Op::apply_null(l_datas[i], l_nulls[i], 1, true); | 101 | 15 | res_datas[i] = Op::apply(l_datas[i], 1); | 102 | 15 | } | 103 | 14 | } 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 | 14 | } |
functions_logical.cpp:_ZN5doris12_GLOBAL__N_117vector_const_nullINS_22FunctionsLogicalDetail6OrImplEEEvPKNS_7IColumnEPKNS_11ColumnConstEPS4_SA_m Line | Count | Source | 86 | 3 | size_t rows) { | 87 | 3 | auto [data_column, null_column_ptr] = get_nested_and_null_column(left); | 88 | 3 | const auto* __restrict l_datas = | 89 | 3 | assert_cast<const ColumnUInt8*>(data_column)->get_data().data(); | 90 | 3 | const auto* __restrict l_nulls = | 91 | 3 | assert_cast<const ColumnUInt8*>(null_column_ptr.get())->get_data().data(); | 92 | | | 93 | 3 | auto* __restrict res_datas = assert_cast<ColumnUInt8*>(res)->get_data().data(); | 94 | 3 | auto* __restrict res_nulls = assert_cast<ColumnUInt8*>(nulls)->get_data().data(); | 95 | | | 96 | 3 | auto r_data_ptr = right->get_data_at(0); | 97 | | | 98 | 3 | if (r_data_ptr.data == nullptr) { | 99 | 12 | for (size_t i = 0; i < rows; ++i) { | 100 | 9 | res_nulls[i] = Op::apply_null(l_datas[i], l_nulls[i], 1, true); | 101 | 9 | res_datas[i] = Op::apply(l_datas[i], 1); | 102 | 9 | } | 103 | 3 | } 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 | 3 | } |
|
111 | | |
112 | | template <class Op> |
113 | | void vector_vector_null(const IColumn* left, const IColumn* right, IColumn* res, IColumn* nulls, |
114 | 7 | size_t rows) { |
115 | 7 | auto [l_datas_ptr, l_nulls_ptr] = get_nested_and_null_column(left); |
116 | 7 | auto [r_datas_ptr, r_nulls_ptr] = get_nested_and_null_column(right); |
117 | | |
118 | 7 | const auto* __restrict l_datas = |
119 | 7 | assert_cast<const ColumnUInt8*>(l_datas_ptr)->get_data().data(); |
120 | 7 | const auto* __restrict r_datas = |
121 | 7 | assert_cast<const ColumnUInt8*>(r_datas_ptr)->get_data().data(); |
122 | 7 | const auto* __restrict l_nulls = |
123 | 7 | assert_cast<const ColumnUInt8*>(l_nulls_ptr.get())->get_data().data(); |
124 | 7 | const auto* __restrict r_nulls = |
125 | 7 | assert_cast<const ColumnUInt8*>(r_nulls_ptr.get())->get_data().data(); |
126 | | |
127 | 7 | auto* __restrict res_datas = assert_cast<ColumnUInt8*>(res)->get_data().data(); |
128 | 7 | auto* __restrict res_nulls = assert_cast<ColumnUInt8*>(nulls)->get_data().data(); |
129 | | |
130 | 14 | for (size_t i = 0; i < rows; ++i) { |
131 | 7 | res_nulls[i] = Op::apply_null(l_datas[i], l_nulls[i], r_datas[i], r_nulls[i]); |
132 | 7 | res_datas[i] = Op::apply(l_datas[i], r_datas[i]); |
133 | 7 | } |
134 | 7 | } functions_logical.cpp:_ZN5doris12_GLOBAL__N_118vector_vector_nullINS_22FunctionsLogicalDetail7AndImplEEEvPKNS_7IColumnES6_PS4_S7_m Line | Count | Source | 114 | 2 | size_t rows) { | 115 | 2 | auto [l_datas_ptr, l_nulls_ptr] = get_nested_and_null_column(left); | 116 | 2 | auto [r_datas_ptr, r_nulls_ptr] = get_nested_and_null_column(right); | 117 | | | 118 | 2 | const auto* __restrict l_datas = | 119 | 2 | assert_cast<const ColumnUInt8*>(l_datas_ptr)->get_data().data(); | 120 | 2 | const auto* __restrict r_datas = | 121 | 2 | assert_cast<const ColumnUInt8*>(r_datas_ptr)->get_data().data(); | 122 | 2 | const auto* __restrict l_nulls = | 123 | 2 | assert_cast<const ColumnUInt8*>(l_nulls_ptr.get())->get_data().data(); | 124 | 2 | const auto* __restrict r_nulls = | 125 | 2 | assert_cast<const ColumnUInt8*>(r_nulls_ptr.get())->get_data().data(); | 126 | | | 127 | 2 | auto* __restrict res_datas = assert_cast<ColumnUInt8*>(res)->get_data().data(); | 128 | 2 | auto* __restrict res_nulls = assert_cast<ColumnUInt8*>(nulls)->get_data().data(); | 129 | | | 130 | 4 | for (size_t i = 0; i < rows; ++i) { | 131 | 2 | res_nulls[i] = Op::apply_null(l_datas[i], l_nulls[i], r_datas[i], r_nulls[i]); | 132 | 2 | res_datas[i] = Op::apply(l_datas[i], r_datas[i]); | 133 | 2 | } | 134 | 2 | } |
functions_logical.cpp:_ZN5doris12_GLOBAL__N_118vector_vector_nullINS_22FunctionsLogicalDetail6OrImplEEEvPKNS_7IColumnES6_PS4_S7_m Line | Count | Source | 114 | 5 | size_t rows) { | 115 | 5 | auto [l_datas_ptr, l_nulls_ptr] = get_nested_and_null_column(left); | 116 | 5 | auto [r_datas_ptr, r_nulls_ptr] = get_nested_and_null_column(right); | 117 | | | 118 | 5 | const auto* __restrict l_datas = | 119 | 5 | assert_cast<const ColumnUInt8*>(l_datas_ptr)->get_data().data(); | 120 | 5 | const auto* __restrict r_datas = | 121 | 5 | assert_cast<const ColumnUInt8*>(r_datas_ptr)->get_data().data(); | 122 | 5 | const auto* __restrict l_nulls = | 123 | 5 | assert_cast<const ColumnUInt8*>(l_nulls_ptr.get())->get_data().data(); | 124 | 5 | const auto* __restrict r_nulls = | 125 | 5 | assert_cast<const ColumnUInt8*>(r_nulls_ptr.get())->get_data().data(); | 126 | | | 127 | 5 | auto* __restrict res_datas = assert_cast<ColumnUInt8*>(res)->get_data().data(); | 128 | 5 | auto* __restrict res_nulls = assert_cast<ColumnUInt8*>(nulls)->get_data().data(); | 129 | | | 130 | 10 | for (size_t i = 0; i < rows; ++i) { | 131 | 5 | res_nulls[i] = Op::apply_null(l_datas[i], l_nulls[i], r_datas[i], r_nulls[i]); | 132 | 5 | res_datas[i] = Op::apply(l_datas[i], r_datas[i]); | 133 | 5 | } | 134 | 5 | } |
|
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 | 24 | size_t input_rows_count) { |
153 | 24 | auto col_nulls = ColumnUInt8::create(input_rows_count); |
154 | 24 | auto col_res = ColumnUInt8::create(input_rows_count); |
155 | 24 | 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 | 24 | } else if (auto r = check_and_get_column<ColumnConst>(arguments[1])) { |
158 | 17 | vector_const_null<Op>(arguments[0], r, col_res.get(), col_nulls.get(), input_rows_count); |
159 | 17 | } else { |
160 | 7 | vector_vector_null<Op>(arguments[0], arguments[1], col_res.get(), col_nulls.get(), |
161 | 7 | input_rows_count); |
162 | 7 | } |
163 | 24 | result_info.column = ColumnNullable::create(std::move(col_res), std::move(col_nulls)); |
164 | 24 | } functions_logical.cpp:_ZN5doris12_GLOBAL__N_117null_execute_implINS_22FunctionsLogicalDetail7AndImplEEEvSt6vectorIPKNS_7IColumnESaIS7_EERNS_21ColumnWithTypeAndNameEm Line | Count | Source | 152 | 16 | size_t input_rows_count) { | 153 | 16 | auto col_nulls = ColumnUInt8::create(input_rows_count); | 154 | 16 | auto col_res = ColumnUInt8::create(input_rows_count); | 155 | 16 | 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 | 16 | } else if (auto r = check_and_get_column<ColumnConst>(arguments[1])) { | 158 | 14 | vector_const_null<Op>(arguments[0], r, col_res.get(), col_nulls.get(), input_rows_count); | 159 | 14 | } else { | 160 | 2 | vector_vector_null<Op>(arguments[0], arguments[1], col_res.get(), col_nulls.get(), | 161 | 2 | input_rows_count); | 162 | 2 | } | 163 | 16 | result_info.column = ColumnNullable::create(std::move(col_res), std::move(col_nulls)); | 164 | 16 | } |
functions_logical.cpp:_ZN5doris12_GLOBAL__N_117null_execute_implINS_22FunctionsLogicalDetail6OrImplEEEvSt6vectorIPKNS_7IColumnESaIS7_EERNS_21ColumnWithTypeAndNameEm Line | Count | Source | 152 | 8 | size_t input_rows_count) { | 153 | 8 | auto col_nulls = ColumnUInt8::create(input_rows_count); | 154 | 8 | auto col_res = ColumnUInt8::create(input_rows_count); | 155 | 8 | 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 | 8 | } else if (auto r = check_and_get_column<ColumnConst>(arguments[1])) { | 158 | 3 | vector_const_null<Op>(arguments[0], r, col_res.get(), col_nulls.get(), input_rows_count); | 159 | 5 | } else { | 160 | 5 | vector_vector_null<Op>(arguments[0], arguments[1], col_res.get(), col_nulls.get(), | 161 | 5 | input_rows_count); | 162 | 5 | } | 163 | 8 | result_info.column = ColumnNullable::create(std::move(col_res), std::move(col_nulls)); | 164 | 8 | } |
|
165 | | |
166 | | } // namespace |
167 | | |
168 | 6.55k | bool is_native_number(PrimitiveType type) { |
169 | 6.55k | return (is_int_or_bool(type) && type != TYPE_LARGEINT) || is_float_or_double(type); |
170 | 6.55k | } |
171 | | |
172 | | template <typename Impl, typename Name> |
173 | | DataTypePtr FunctionAnyArityLogical<Impl, Name>::get_return_type_impl( |
174 | 2.97k | const DataTypes& arguments) const { |
175 | 2.97k | 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 | 2.97k | bool has_nullable_arguments = false; |
183 | 8.91k | for (size_t i = 0; i < arguments.size(); ++i) { |
184 | 5.94k | const auto& arg_type = arguments[i]; |
185 | | |
186 | 5.94k | if (!has_nullable_arguments) { |
187 | 3.83k | has_nullable_arguments = arg_type->is_nullable(); |
188 | 3.83k | 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 | 3.83k | } |
195 | | |
196 | 5.94k | auto arg_primitive_type = arg_type->get_primitive_type(); |
197 | 5.94k | if (!(is_native_number(arg_primitive_type) || |
198 | 5.94k | (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 | 5.94k | } |
204 | | |
205 | 2.97k | auto result_type = std::make_shared<DataTypeUInt8>(); |
206 | 2.97k | return has_nullable_arguments ? make_nullable(result_type) : result_type; |
207 | 2.97k | } _ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_7AndImplENS_7NameAndEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE Line | Count | Source | 174 | 1.14k | const DataTypes& arguments) const { | 175 | 1.14k | 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.14k | bool has_nullable_arguments = false; | 183 | 3.42k | for (size_t i = 0; i < arguments.size(); ++i) { | 184 | 2.28k | const auto& arg_type = arguments[i]; | 185 | | | 186 | 2.28k | if (!has_nullable_arguments) { | 187 | 1.72k | has_nullable_arguments = arg_type->is_nullable(); | 188 | 1.72k | 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 | 1.72k | } | 195 | | | 196 | 2.28k | auto arg_primitive_type = arg_type->get_primitive_type(); | 197 | 2.28k | if (!(is_native_number(arg_primitive_type) || | 198 | 2.28k | (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.28k | } | 204 | | | 205 | 1.14k | auto result_type = std::make_shared<DataTypeUInt8>(); | 206 | 1.14k | return has_nullable_arguments ? make_nullable(result_type) : result_type; | 207 | 1.14k | } |
_ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_6OrImplENS_6NameOrEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS9_EE Line | Count | Source | 174 | 1.82k | const DataTypes& arguments) const { | 175 | 1.82k | 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.82k | bool has_nullable_arguments = false; | 183 | 5.48k | for (size_t i = 0; i < arguments.size(); ++i) { | 184 | 3.65k | const auto& arg_type = arguments[i]; | 185 | | | 186 | 3.65k | if (!has_nullable_arguments) { | 187 | 2.11k | has_nullable_arguments = arg_type->is_nullable(); | 188 | 2.11k | 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.11k | } | 195 | | | 196 | 3.65k | auto arg_primitive_type = arg_type->get_primitive_type(); | 197 | 3.65k | if (!(is_native_number(arg_primitive_type) || | 198 | 3.65k | (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 | 3.65k | } | 204 | | | 205 | 1.82k | auto result_type = std::make_shared<DataTypeUInt8>(); | 206 | 1.82k | return has_nullable_arguments ? make_nullable(result_type) : result_type; | 207 | 1.82k | } |
_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 | 25 | size_t input_rows_count) const { |
214 | 25 | ColumnRawPtrs args_in; |
215 | 25 | for (const auto arg_index : arguments) |
216 | 50 | args_in.push_back(block.get_by_position(arg_index).column.get()); |
217 | | |
218 | 25 | auto& result_info = block.get_by_position(result_index); |
219 | 25 | if constexpr (Impl::special_implementation_for_nulls()) { |
220 | 24 | if (result_info.type->is_nullable()) { |
221 | 24 | null_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); |
222 | 24 | } else { |
223 | 0 | basic_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); |
224 | 0 | } |
225 | 24 | } 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 | 25 | return Status::OK(); |
230 | 25 | } _ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_7AndImplENS_7NameAndEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Line | Count | Source | 213 | 16 | size_t input_rows_count) const { | 214 | 16 | ColumnRawPtrs args_in; | 215 | 16 | for (const auto arg_index : arguments) | 216 | 32 | args_in.push_back(block.get_by_position(arg_index).column.get()); | 217 | | | 218 | 16 | auto& result_info = block.get_by_position(result_index); | 219 | 16 | if constexpr (Impl::special_implementation_for_nulls()) { | 220 | 16 | if (result_info.type->is_nullable()) { | 221 | 16 | null_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); | 222 | 16 | } else { | 223 | 0 | basic_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); | 224 | 0 | } | 225 | | } else { | 226 | | DCHECK(std::ranges::all_of(args_in, [](const auto& arg) { return !arg->is_nullable(); })); | 227 | | basic_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); | 228 | | } | 229 | 16 | return Status::OK(); | 230 | 16 | } |
_ZNK5doris22FunctionsLogicalDetail23FunctionAnyArityLogicalINS0_6OrImplENS_6NameOrEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Line | Count | Source | 213 | 8 | size_t input_rows_count) const { | 214 | 8 | ColumnRawPtrs args_in; | 215 | 8 | for (const auto arg_index : arguments) | 216 | 16 | args_in.push_back(block.get_by_position(arg_index).column.get()); | 217 | | | 218 | 8 | auto& result_info = block.get_by_position(result_index); | 219 | 8 | if constexpr (Impl::special_implementation_for_nulls()) { | 220 | 8 | if (result_info.type->is_nullable()) { | 221 | 8 | null_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); | 222 | 8 | } else { | 223 | 0 | basic_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); | 224 | 0 | } | 225 | | } else { | 226 | | DCHECK(std::ranges::all_of(args_in, [](const auto& arg) { return !arg->is_nullable(); })); | 227 | | basic_execute_impl<Impl>(std::move(args_in), result_info, input_rows_count); | 228 | | } | 229 | 8 | return Status::OK(); | 230 | 8 | } |
_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 | 1.01k | static void NO_INLINE vector(const ArrayA& a, ArrayC& c) { |
238 | 799k | std::transform(a.cbegin(), a.cend(), c.begin(), [](const auto x) { return Op::apply(x); }); |
239 | 1.01k | } |
240 | | }; |
241 | | |
242 | | template <template <PrimitiveType> class Impl, typename Name> |
243 | | DataTypePtr FunctionUnaryLogical<Impl, Name>::get_return_type_impl( |
244 | 615 | const DataTypes& arguments) const { |
245 | 615 | 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 | 615 | return std::make_shared<DataTypeUInt8>(); |
252 | 615 | } |
253 | | |
254 | | template <template <PrimitiveType> class Impl, PrimitiveType T> |
255 | 1.01k | bool functionUnaryExecuteType(Block& block, const ColumnNumbers& arguments, size_t result) { |
256 | 1.01k | if (auto col = check_and_get_column<ColumnVector<T>>( |
257 | 1.01k | block.get_by_position(arguments[0]).column.get())) { |
258 | 1.01k | auto col_res = ColumnUInt8::create(); |
259 | | |
260 | 1.01k | typename ColumnUInt8::Container& vec_res = col_res->get_data(); |
261 | 1.01k | vec_res.resize(col->get_data().size()); |
262 | 1.01k | UnaryOperationImpl<T, Impl<T>>::vector(col->get_data(), vec_res); |
263 | | |
264 | 1.01k | block.replace_by_position(result, std::move(col_res)); |
265 | 1.01k | return true; |
266 | 1.01k | } |
267 | | |
268 | 1 | return false; |
269 | 1.01k | } |
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 | 1.01k | size_t /*input_rows_count*/) const { |
276 | 1.01k | 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 | 1.01k | return Status::OK(); |
283 | 1.01k | } |
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 |