be/src/exprs/function/function_map.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 <glog/logging.h> |
19 | | #include <stddef.h> |
20 | | |
21 | | #include <algorithm> |
22 | | #include <boost/iterator/iterator_facade.hpp> |
23 | | #include <memory> |
24 | | #include <ostream> |
25 | | #include <string> |
26 | | #include <string_view> |
27 | | #include <tuple> |
28 | | #include <utility> |
29 | | |
30 | | #include "common/status.h" |
31 | | #include "core/assert_cast.h" |
32 | | #include "core/block/block.h" |
33 | | #include "core/block/column_numbers.h" |
34 | | #include "core/block/column_with_type_and_name.h" |
35 | | #include "core/call_on_type_index.h" |
36 | | #include "core/column/column.h" |
37 | | #include "core/column/column_array.h" |
38 | | #include "core/column/column_const.h" |
39 | | #include "core/column/column_map.h" |
40 | | #include "core/column/column_nullable.h" |
41 | | #include "core/column/column_vector.h" |
42 | | #include "core/data_type/data_type.h" |
43 | | #include "core/data_type/data_type_array.h" |
44 | | #include "core/data_type/data_type_map.h" |
45 | | #include "core/data_type/data_type_nullable.h" |
46 | | #include "core/data_type/data_type_number.h" |
47 | | #include "core/data_type/data_type_string.h" |
48 | | #include "core/data_type/data_type_struct.h" |
49 | | #include "core/data_type/primitive_type.h" |
50 | | #include "core/typeid_cast.h" |
51 | | #include "core/types.h" |
52 | | #include "exprs/aggregate/aggregate_function.h" |
53 | | #include "exprs/function/array/function_array_index.h" |
54 | | #include "exprs/function/function.h" |
55 | | #include "exprs/function/simple_function_factory.h" |
56 | | #include "util/simd/vstring_function.h" |
57 | | |
58 | | namespace doris { |
59 | | class FunctionContext; |
60 | | } // namespace doris |
61 | | |
62 | | namespace doris { |
63 | | |
64 | | // construct a map |
65 | | // map(key1, value2, key2, value2) -> {key1: value2, key2: value2} |
66 | | class FunctionMap : public IFunction { |
67 | | public: |
68 | | static constexpr auto name = "map"; |
69 | 2 | static FunctionPtr create() { return std::make_shared<FunctionMap>(); } |
70 | | |
71 | | /// Get function name. |
72 | 0 | String get_name() const override { return name; } |
73 | | |
74 | 1 | bool is_variadic() const override { return true; } |
75 | | |
76 | 0 | bool use_default_implementation_for_nulls() const override { return false; } |
77 | | |
78 | 0 | size_t get_number_of_arguments() const override { return 0; } |
79 | | |
80 | 0 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
81 | 0 | DCHECK(arguments.size() % 2 == 0) |
82 | 0 | << "function: " << get_name() << ", arguments should not be even number"; |
83 | 0 | return std::make_shared<DataTypeMap>(make_nullable(arguments[0]), |
84 | 0 | make_nullable(arguments[1])); |
85 | 0 | } |
86 | | |
87 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
88 | 0 | uint32_t result, size_t input_rows_count) const override { |
89 | 0 | DCHECK(arguments.size() % 2 == 0) |
90 | 0 | << "function: " << get_name() << ", arguments should not be even number"; |
91 | |
|
92 | 0 | size_t num_element = arguments.size(); |
93 | |
|
94 | 0 | auto result_col = block.get_by_position(result).type->create_column(); |
95 | 0 | auto* map_column = assert_cast<ColumnMap*>(result_col.get()); |
96 | | |
97 | | // map keys column |
98 | 0 | auto& result_col_map_keys_data = map_column->get_keys(); |
99 | 0 | result_col_map_keys_data.reserve(input_rows_count * num_element / 2); |
100 | | // map values column |
101 | 0 | auto& result_col_map_vals_data = map_column->get_values(); |
102 | 0 | result_col_map_vals_data.reserve(input_rows_count * num_element / 2); |
103 | | // map offsets column |
104 | 0 | auto& result_col_map_offsets = map_column->get_offsets(); |
105 | 0 | result_col_map_offsets.resize(input_rows_count); |
106 | |
|
107 | 0 | std::unique_ptr<bool[]> col_const = std::make_unique_for_overwrite<bool[]>(num_element); |
108 | 0 | std::vector<ColumnPtr> arg(num_element); |
109 | 0 | for (size_t i = 0; i < num_element; ++i) { |
110 | 0 | auto& col = block.get_by_position(arguments[i]).column; |
111 | 0 | std::tie(col, col_const[i]) = unpack_if_const(col); |
112 | 0 | bool is_nullable = i % 2 == 0 ? result_col_map_keys_data.is_nullable() |
113 | 0 | : result_col_map_vals_data.is_nullable(); |
114 | | // convert to nullable column |
115 | 0 | arg[i] = col; |
116 | 0 | if (is_nullable && !col->is_nullable()) { |
117 | 0 | arg[i] = ColumnNullable::create(col, ColumnUInt8::create(col->size(), 0)); |
118 | 0 | } |
119 | 0 | } |
120 | | |
121 | | // insert value into map |
122 | 0 | ColumnArray::Offset64 offset = 0; |
123 | 0 | for (size_t row = 0; row < input_rows_count; ++row) { |
124 | 0 | for (size_t i = 0; i < num_element; i += 2) { |
125 | 0 | result_col_map_keys_data.insert_from(*arg[i], index_check_const(row, col_const[i])); |
126 | 0 | result_col_map_vals_data.insert_from(*arg[i + 1], |
127 | 0 | index_check_const(row, col_const[i + 1])); |
128 | 0 | } |
129 | 0 | offset += num_element / 2; |
130 | 0 | result_col_map_offsets[row] = offset; |
131 | 0 | } |
132 | |
|
133 | 0 | RETURN_IF_ERROR(map_column->deduplicate_keys()); |
134 | 0 | block.replace_by_position(result, std::move(result_col)); |
135 | 0 | return Status::OK(); |
136 | 0 | } |
137 | | }; |
138 | | |
139 | | template <bool is_key, bool OldVersion = false> |
140 | | class FunctionMapContains : public IFunction { |
141 | | public: |
142 | | static constexpr auto name = is_key ? "map_contains_key" : "map_contains_value"; |
143 | 4 | static FunctionPtr create() { return std::make_shared<FunctionMapContains>(); }_ZN5doris19FunctionMapContainsILb1ELb0EE6createEv Line | Count | Source | 143 | 2 | static FunctionPtr create() { return std::make_shared<FunctionMapContains>(); } |
_ZN5doris19FunctionMapContainsILb0ELb0EE6createEv Line | Count | Source | 143 | 2 | static FunctionPtr create() { return std::make_shared<FunctionMapContains>(); } |
|
144 | | |
145 | | /// Get function name. |
146 | 2 | String get_name() const override { return name; }_ZNK5doris19FunctionMapContainsILb1ELb0EE8get_nameB5cxx11Ev Line | Count | Source | 146 | 1 | String get_name() const override { return name; } |
_ZNK5doris19FunctionMapContainsILb0ELb0EE8get_nameB5cxx11Ev Line | Count | Source | 146 | 1 | String get_name() const override { return name; } |
|
147 | | |
148 | 2 | bool is_variadic() const override { return false; }_ZNK5doris19FunctionMapContainsILb1ELb0EE11is_variadicEv Line | Count | Source | 148 | 1 | bool is_variadic() const override { return false; } |
_ZNK5doris19FunctionMapContainsILb0ELb0EE11is_variadicEv Line | Count | Source | 148 | 1 | bool is_variadic() const override { return false; } |
|
149 | | |
150 | 0 | size_t get_number_of_arguments() const override { return 2; }Unexecuted instantiation: _ZNK5doris19FunctionMapContainsILb1ELb0EE23get_number_of_argumentsEv Unexecuted instantiation: _ZNK5doris19FunctionMapContainsILb0ELb0EE23get_number_of_argumentsEv |
151 | | |
152 | 0 | bool use_default_implementation_for_nulls() const override { |
153 | 0 | return FunctionArrayIndex<ArrayContainsAction> {}.use_default_implementation_for_nulls(); |
154 | 0 | } Unexecuted instantiation: _ZNK5doris19FunctionMapContainsILb1ELb0EE36use_default_implementation_for_nullsEv Unexecuted instantiation: _ZNK5doris19FunctionMapContainsILb0ELb0EE36use_default_implementation_for_nullsEv |
155 | | |
156 | 0 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
157 | 0 | DataTypePtr datatype = arguments[0]; |
158 | 0 | if (datatype->is_nullable()) { |
159 | 0 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); |
160 | 0 | } |
161 | 0 | DCHECK(datatype->get_primitive_type() == TYPE_MAP) |
162 | 0 | << "first argument for function: " << name << " should be DataTypeMap"; |
163 | |
|
164 | | if constexpr (OldVersion) { |
165 | | return make_nullable(std::make_shared<DataTypeBool>()); |
166 | 0 | } else { |
167 | 0 | if (arguments[0]->is_nullable()) { |
168 | 0 | return make_nullable(std::make_shared<DataTypeBool>()); |
169 | 0 | } else { |
170 | 0 | return std::make_shared<DataTypeBool>(); |
171 | 0 | } |
172 | 0 | } |
173 | 0 | } Unexecuted instantiation: _ZNK5doris19FunctionMapContainsILb1ELb0EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS6_EE Unexecuted instantiation: _ZNK5doris19FunctionMapContainsILb0ELb0EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS6_EE |
174 | | |
175 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
176 | 0 | uint32_t result, size_t input_rows_count) const override { |
177 | | // backup original argument 0 |
178 | 0 | auto orig_arg0 = block.get_by_position(arguments[0]); |
179 | 0 | auto left_column = |
180 | 0 | block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); |
181 | 0 | const ColumnMap* map_column = nullptr; |
182 | 0 | ColumnPtr nullmap_column = nullptr; |
183 | 0 | if (left_column->is_nullable()) { |
184 | 0 | auto nullable_column = reinterpret_cast<const ColumnNullable*>(left_column.get()); |
185 | 0 | map_column = check_and_get_column<ColumnMap>(nullable_column->get_nested_column()); |
186 | 0 | nullmap_column = nullable_column->get_null_map_column_ptr(); |
187 | 0 | } else { |
188 | 0 | map_column = check_and_get_column<ColumnMap>(*left_column.get()); |
189 | 0 | } |
190 | 0 | if (!map_column) { |
191 | 0 | return Status::RuntimeError("unsupported types for function {}({})", get_name(), |
192 | 0 | block.get_by_position(arguments[0]).type->get_name()); |
193 | 0 | } |
194 | | |
195 | 0 | DataTypePtr datatype = block.get_by_position(arguments[0]).type; |
196 | 0 | if (datatype->is_nullable()) { |
197 | 0 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); |
198 | 0 | } |
199 | 0 | const auto datatype_map = static_cast<const DataTypeMap*>(datatype.get()); |
200 | 0 | if constexpr (is_key) { |
201 | 0 | const auto& array_column = map_column->get_keys_array_ptr(); |
202 | 0 | const auto datatype_array = |
203 | 0 | std::make_shared<DataTypeArray>(datatype_map->get_key_type()); |
204 | 0 | if (nullmap_column) { |
205 | 0 | block.get_by_position(arguments[0]) = { |
206 | 0 | ColumnNullable::create(array_column, nullmap_column), |
207 | 0 | make_nullable(datatype_array), |
208 | 0 | block.get_by_position(arguments[0]).name + ".keys"}; |
209 | 0 | } else { |
210 | 0 | block.get_by_position(arguments[0]) = { |
211 | 0 | array_column, datatype_array, |
212 | 0 | block.get_by_position(arguments[0]).name + ".keys"}; |
213 | 0 | } |
214 | 0 | } else { |
215 | 0 | const auto& array_column = map_column->get_values_array_ptr(); |
216 | 0 | const auto datatype_array = |
217 | 0 | std::make_shared<DataTypeArray>(datatype_map->get_value_type()); |
218 | 0 | if (nullmap_column) { |
219 | 0 | block.get_by_position(arguments[0]) = { |
220 | 0 | ColumnNullable::create(array_column, nullmap_column), |
221 | 0 | make_nullable(datatype_array), |
222 | 0 | block.get_by_position(arguments[0]).name + ".values"}; |
223 | 0 | } else { |
224 | 0 | block.get_by_position(arguments[0]) = { |
225 | 0 | array_column, datatype_array, |
226 | 0 | block.get_by_position(arguments[0]).name + ".values"}; |
227 | 0 | } |
228 | 0 | } |
229 | |
|
230 | 0 | RETURN_IF_ERROR(FunctionArrayIndex<ArrayContainsAction> {}.execute_impl( |
231 | 0 | context, block, arguments, result, input_rows_count)); |
232 | | |
233 | | // restore original argument 0 |
234 | 0 | block.get_by_position(arguments[0]) = orig_arg0; |
235 | 0 | return Status::OK(); |
236 | 0 | } Unexecuted instantiation: _ZNK5doris19FunctionMapContainsILb1ELb0EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Unexecuted instantiation: _ZNK5doris19FunctionMapContainsILb0ELb0EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm |
237 | | }; |
238 | | |
239 | | template <bool is_key> |
240 | | class FunctionMapKeysOrValues : public IFunction { |
241 | | public: |
242 | | static constexpr auto name = is_key ? "map_keys" : "map_values"; |
243 | 4 | static FunctionPtr create() { return std::make_shared<FunctionMapKeysOrValues>(); }_ZN5doris23FunctionMapKeysOrValuesILb1EE6createEv Line | Count | Source | 243 | 2 | static FunctionPtr create() { return std::make_shared<FunctionMapKeysOrValues>(); } |
_ZN5doris23FunctionMapKeysOrValuesILb0EE6createEv Line | Count | Source | 243 | 2 | static FunctionPtr create() { return std::make_shared<FunctionMapKeysOrValues>(); } |
|
244 | | |
245 | | /// Get function name. |
246 | 2 | String get_name() const override { return name; }_ZNK5doris23FunctionMapKeysOrValuesILb1EE8get_nameB5cxx11Ev Line | Count | Source | 246 | 1 | String get_name() const override { return name; } |
_ZNK5doris23FunctionMapKeysOrValuesILb0EE8get_nameB5cxx11Ev Line | Count | Source | 246 | 1 | String get_name() const override { return name; } |
|
247 | | |
248 | 2 | bool is_variadic() const override { return false; }_ZNK5doris23FunctionMapKeysOrValuesILb1EE11is_variadicEv Line | Count | Source | 248 | 1 | bool is_variadic() const override { return false; } |
_ZNK5doris23FunctionMapKeysOrValuesILb0EE11is_variadicEv Line | Count | Source | 248 | 1 | bool is_variadic() const override { return false; } |
|
249 | | |
250 | 0 | size_t get_number_of_arguments() const override { return 1; }Unexecuted instantiation: _ZNK5doris23FunctionMapKeysOrValuesILb1EE23get_number_of_argumentsEv Unexecuted instantiation: _ZNK5doris23FunctionMapKeysOrValuesILb0EE23get_number_of_argumentsEv |
251 | | |
252 | 0 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
253 | 0 | DataTypePtr datatype = arguments[0]; |
254 | 0 | if (datatype->is_nullable()) { |
255 | 0 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); |
256 | 0 | } |
257 | 0 | DCHECK(datatype->get_primitive_type() == TYPE_MAP) |
258 | 0 | << "first argument for function: " << name << " should be DataTypeMap"; |
259 | 0 | const auto datatype_map = static_cast<const DataTypeMap*>(datatype.get()); |
260 | 0 | if (is_key) { |
261 | 0 | return std::make_shared<DataTypeArray>(datatype_map->get_key_type()); |
262 | 0 | } else { |
263 | 0 | return std::make_shared<DataTypeArray>(datatype_map->get_value_type()); |
264 | 0 | } |
265 | 0 | } Unexecuted instantiation: _ZNK5doris23FunctionMapKeysOrValuesILb1EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS6_EE Unexecuted instantiation: _ZNK5doris23FunctionMapKeysOrValuesILb0EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS6_EE |
266 | | |
267 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
268 | 0 | uint32_t result, size_t input_rows_count) const override { |
269 | 0 | auto left_column = |
270 | 0 | block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); |
271 | 0 | const ColumnMap* map_column = nullptr; |
272 | 0 | if (left_column->is_nullable()) { |
273 | 0 | auto nullable_column = reinterpret_cast<const ColumnNullable*>(left_column.get()); |
274 | 0 | map_column = check_and_get_column<ColumnMap>(nullable_column->get_nested_column()); |
275 | 0 | } else { |
276 | 0 | map_column = check_and_get_column<ColumnMap>(*left_column.get()); |
277 | 0 | } |
278 | 0 | if (!map_column) { |
279 | 0 | return Status::RuntimeError("unsupported types for function {}({})", get_name(), |
280 | 0 | block.get_by_position(arguments[0]).type->get_name()); |
281 | 0 | } |
282 | | |
283 | 0 | if constexpr (is_key) { |
284 | 0 | block.replace_by_position(result, map_column->get_keys_array_ptr()); |
285 | 0 | } else { |
286 | 0 | block.replace_by_position(result, map_column->get_values_array_ptr()); |
287 | 0 | } |
288 | |
|
289 | 0 | return Status::OK(); |
290 | 0 | } Unexecuted instantiation: _ZNK5doris23FunctionMapKeysOrValuesILb1EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Unexecuted instantiation: _ZNK5doris23FunctionMapKeysOrValuesILb0EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm |
291 | | }; |
292 | | |
293 | | class FunctionMapEntries : public IFunction { |
294 | | public: |
295 | | static constexpr auto name = "map_entries"; |
296 | 2 | static FunctionPtr create() { return std::make_shared<FunctionMapEntries>(); } |
297 | | |
298 | | /// Get function name. |
299 | 1 | String get_name() const override { return name; } |
300 | | |
301 | 1 | bool is_variadic() const override { return false; } |
302 | | |
303 | 0 | size_t get_number_of_arguments() const override { return 1; } |
304 | | |
305 | 0 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
306 | 0 | const auto* const datatype_map = assert_cast<const DataTypeMap*>(arguments[0].get()); |
307 | | |
308 | | // Create struct type with named fields "key" and "value" |
309 | | // key and value are always nullable |
310 | 0 | auto struct_type = std::make_shared<DataTypeStruct>( |
311 | 0 | DataTypes {make_nullable(datatype_map->get_key_type()), |
312 | 0 | make_nullable(datatype_map->get_value_type())}, |
313 | 0 | Strings {"key", "value"}); |
314 | | |
315 | | // Theoretically, the struct element will never be null, |
316 | | // but FE expects the array element to be nullable |
317 | 0 | return std::make_shared<DataTypeArray>(make_nullable(struct_type)); |
318 | 0 | } |
319 | | |
320 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
321 | 0 | uint32_t result, size_t input_rows_count) const override { |
322 | 0 | const auto* map_column = |
323 | 0 | assert_cast<const ColumnMap*>(block.get_by_position(arguments[0]).column.get()); |
324 | |
|
325 | 0 | auto struct_column = ColumnStruct::create( |
326 | 0 | Columns {map_column->get_keys_ptr(), map_column->get_values_ptr()}); |
327 | | |
328 | | // all struct elements are not null |
329 | 0 | auto struct_null_map = ColumnUInt8::create(struct_column->size(), 0); |
330 | 0 | auto nullable_struct_column = |
331 | 0 | ColumnNullable::create(std::move(struct_column), std::move(struct_null_map)); |
332 | |
|
333 | 0 | auto result_array_column = ColumnArray::create(std::move(nullable_struct_column), |
334 | 0 | map_column->get_offsets_ptr()); |
335 | |
|
336 | 0 | block.replace_by_position(result, std::move(result_array_column)); |
337 | |
|
338 | 0 | return Status::OK(); |
339 | 0 | } |
340 | | }; |
341 | | |
342 | | class FunctionStrToMap : public IFunction { |
343 | | public: |
344 | | static constexpr auto name = "str_to_map"; |
345 | 2 | static FunctionPtr create() { return std::make_shared<FunctionStrToMap>(); } |
346 | | |
347 | 1 | String get_name() const override { return name; } |
348 | | |
349 | 0 | size_t get_number_of_arguments() const override { return 3; } |
350 | | |
351 | 0 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
352 | 0 | return std::make_shared<DataTypeMap>(make_nullable(std::make_shared<DataTypeString>()), |
353 | 0 | make_nullable(std::make_shared<DataTypeString>())); |
354 | 0 | } |
355 | | |
356 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
357 | 0 | uint32_t result, size_t input_rows_count) const override { |
358 | 0 | DCHECK(arguments.size() == 3); |
359 | |
|
360 | 0 | bool cols_const[2]; |
361 | 0 | ColumnPtr cols[2]; |
362 | 0 | for (size_t i = 0; i < 2; ++i) { |
363 | 0 | cols_const[i] = is_column_const(*block.get_by_position(arguments[i]).column); |
364 | 0 | } |
365 | | // convert to full column if necessary |
366 | 0 | default_preprocess_parameter_columns(cols, cols_const, {0, 1}, block, arguments); |
367 | 0 | const auto& [col3, col3_const] = |
368 | 0 | unpack_if_const(block.get_by_position(arguments[2]).column); |
369 | |
|
370 | 0 | const auto& str_column = assert_cast<const ColumnString*>(cols[0].get()); |
371 | 0 | const auto& pair_delim_column = assert_cast<const ColumnString*>(cols[1].get()); |
372 | 0 | const auto& kv_delim_column = assert_cast<const ColumnString*>(col3.get()); |
373 | |
|
374 | 0 | ColumnPtr result_col; |
375 | 0 | if (cols_const[0] && cols_const[1]) { |
376 | 0 | result_col = execute_vector<true, false>(input_rows_count, *str_column, |
377 | 0 | *pair_delim_column, *kv_delim_column); |
378 | 0 | } else if (col3_const) { |
379 | 0 | result_col = execute_vector<false, true>(input_rows_count, *str_column, |
380 | 0 | *pair_delim_column, *kv_delim_column); |
381 | 0 | } else { |
382 | 0 | result_col = execute_vector<false, false>(input_rows_count, *str_column, |
383 | 0 | *pair_delim_column, *kv_delim_column); |
384 | 0 | } |
385 | |
|
386 | 0 | block.replace_by_position(result, std::move(result_col)); |
387 | |
|
388 | 0 | return Status::OK(); |
389 | 0 | } |
390 | | |
391 | | private: |
392 | | template <bool is_str_and_pair_delim_const, bool is_kv_delim_const> |
393 | | static ColumnPtr execute_vector(const size_t input_rows_count, const ColumnString& str_col, |
394 | | const ColumnString& pair_delim_col, |
395 | 0 | const ColumnString& kv_delim_col) { |
396 | | // map keys column |
397 | 0 | auto result_col_map_keys_data = |
398 | 0 | ColumnNullable::create(ColumnString::create(), ColumnUInt8::create()); |
399 | 0 | result_col_map_keys_data->reserve(input_rows_count); |
400 | | // map values column |
401 | 0 | auto result_col_map_vals_data = |
402 | 0 | ColumnNullable::create(ColumnString::create(), ColumnUInt8::create()); |
403 | 0 | result_col_map_vals_data->reserve(input_rows_count); |
404 | | // map offsets column |
405 | 0 | auto result_col_map_offsets = ColumnOffset64::create(); |
406 | 0 | result_col_map_offsets->reserve(input_rows_count); |
407 | |
|
408 | 0 | std::vector<std::string_view> kvs; |
409 | 0 | std::string_view kv_delim; |
410 | 0 | if constexpr (is_str_and_pair_delim_const) { |
411 | 0 | auto str = str_col.get_data_at(0).to_string_view(); |
412 | 0 | auto pair_delim = pair_delim_col.get_data_at(0).to_string_view(); |
413 | 0 | kvs = split_pair_by_delim(str, pair_delim); |
414 | 0 | } |
415 | 0 | if constexpr (is_kv_delim_const) { |
416 | 0 | kv_delim = kv_delim_col.get_data_at(0).to_string_view(); |
417 | 0 | } |
418 | |
|
419 | 0 | for (size_t i = 0; i < input_rows_count; ++i) { |
420 | 0 | if constexpr (!is_str_and_pair_delim_const) { |
421 | 0 | auto str = str_col.get_data_at(i).to_string_view(); |
422 | 0 | auto pair_delim = pair_delim_col.get_data_at(i).to_string_view(); |
423 | 0 | kvs = split_pair_by_delim(str, pair_delim); |
424 | 0 | } |
425 | 0 | if constexpr (!is_kv_delim_const) { |
426 | 0 | kv_delim = kv_delim_col.get_data_at(i).to_string_view(); |
427 | 0 | } |
428 | |
|
429 | 0 | for (const auto& kv : kvs) { |
430 | 0 | auto kv_parts = split_kv_by_delim(kv, kv_delim); |
431 | 0 | if (kv_parts.size() == 2) { |
432 | 0 | result_col_map_keys_data->insert_data(kv_parts[0].data(), kv_parts[0].size()); |
433 | 0 | result_col_map_vals_data->insert_data(kv_parts[1].data(), kv_parts[1].size()); |
434 | 0 | } else { |
435 | 0 | result_col_map_keys_data->insert_data(kv.data(), kv.size()); |
436 | 0 | result_col_map_vals_data->insert_default(); |
437 | 0 | } |
438 | 0 | } |
439 | 0 | result_col_map_offsets->insert_value(result_col_map_keys_data->size()); |
440 | 0 | } |
441 | |
|
442 | 0 | auto map_column = ColumnMap::create(std::move(result_col_map_keys_data), |
443 | 0 | std::move(result_col_map_vals_data), |
444 | 0 | std::move(result_col_map_offsets)); |
445 | | |
446 | | // `deduplicate_keys` always return ok |
447 | 0 | static_cast<void>(map_column->deduplicate_keys()); |
448 | 0 | return map_column; |
449 | 0 | } Unexecuted instantiation: _ZN5doris16FunctionStrToMap14execute_vectorILb1ELb0EEENS_3COWINS_7IColumnEE13immutable_ptrIS3_EEmRKNS_9ColumnStrIjEESA_SA_ Unexecuted instantiation: _ZN5doris16FunctionStrToMap14execute_vectorILb0ELb1EEENS_3COWINS_7IColumnEE13immutable_ptrIS3_EEmRKNS_9ColumnStrIjEESA_SA_ Unexecuted instantiation: _ZN5doris16FunctionStrToMap14execute_vectorILb0ELb0EEENS_3COWINS_7IColumnEE13immutable_ptrIS3_EEmRKNS_9ColumnStrIjEESA_SA_ |
450 | | |
451 | | static std::vector<std::string_view> split_pair_by_delim(const std::string_view& str, |
452 | 0 | const std::string_view& delim) { |
453 | 0 | if (str.empty()) { |
454 | 0 | return {str}; |
455 | 0 | } |
456 | 0 | if (delim.empty()) { |
457 | 0 | std::vector<std::string_view> result; |
458 | 0 | size_t offset = 0; |
459 | 0 | while (offset < str.size()) { |
460 | 0 | auto len = get_utf8_byte_length(str[offset]); |
461 | 0 | result.push_back(str.substr(offset, len)); |
462 | 0 | offset += len; |
463 | 0 | } |
464 | 0 | return result; |
465 | 0 | } |
466 | 0 | std::vector<std::string_view> result; |
467 | 0 | size_t offset = 0; |
468 | 0 | while (offset < str.size()) { |
469 | 0 | auto pos = str.find(delim, offset); |
470 | 0 | if (pos == std::string::npos) { |
471 | 0 | result.push_back(str.substr(offset)); |
472 | 0 | break; |
473 | 0 | } |
474 | 0 | result.push_back(str.substr(offset, pos - offset)); |
475 | 0 | offset = pos + delim.size(); |
476 | 0 | } |
477 | 0 | return result; |
478 | 0 | } |
479 | | |
480 | | static std::vector<std::string_view> split_kv_by_delim(const std::string_view& str, |
481 | 0 | const std::string_view& delim) { |
482 | 0 | if (str.empty()) { |
483 | 0 | return {str}; |
484 | 0 | } |
485 | 0 | if (delim.empty()) { |
486 | 0 | auto len = get_utf8_byte_length(str[0]); |
487 | 0 | return {str.substr(0, len), str.substr(len)}; |
488 | 0 | } |
489 | 0 | auto pos = str.find(delim); |
490 | 0 | if (pos == std::string::npos) { |
491 | 0 | return {str}; |
492 | 0 | } else { |
493 | 0 | return {str.substr(0, pos), str.substr(pos + delim.size())}; |
494 | 0 | } |
495 | 0 | } |
496 | | }; |
497 | | |
498 | | class FunctionMapContainsEntry : public IFunction { |
499 | | public: |
500 | | static constexpr auto name = "map_contains_entry"; |
501 | 2 | static FunctionPtr create() { return std::make_shared<FunctionMapContainsEntry>(); } |
502 | | |
503 | 1 | String get_name() const override { return name; } |
504 | 0 | size_t get_number_of_arguments() const override { return 3; } |
505 | 0 | bool use_default_implementation_for_nulls() const override { return false; } |
506 | | |
507 | 0 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
508 | 0 | DataTypePtr datatype = arguments[0]; |
509 | 0 | if (datatype->is_nullable()) { |
510 | 0 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); |
511 | 0 | } |
512 | 0 | DCHECK_EQ(datatype->get_primitive_type(), PrimitiveType::TYPE_MAP) |
513 | 0 | << "first argument for function: " << name << " should be DataTypeMap"; |
514 | |
|
515 | 0 | if (arguments[0]->is_nullable()) { |
516 | 0 | return make_nullable(std::make_shared<DataTypeBool>()); |
517 | 0 | } else { |
518 | 0 | return std::make_shared<DataTypeBool>(); |
519 | 0 | } |
520 | 0 | } |
521 | | |
522 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
523 | 0 | uint32_t result, size_t input_rows_count) const override { |
524 | 0 | return _execute_type_check_and_dispatch(block, arguments, result); |
525 | 0 | } |
526 | | |
527 | | private: |
528 | | // assume result_matches is initialized to all 1s |
529 | | template <typename ColumnType> |
530 | | void _execute_column_comparison(const IColumn& map_entry_column, const UInt8* map_entry_nullmap, |
531 | | const IColumn& search_column, const UInt8* search_nullmap, |
532 | | const ColumnArray::Offsets64& map_offsets, |
533 | | const UInt8* map_row_nullmap, bool search_is_const, |
534 | 0 | ColumnUInt8& result_matches) const { |
535 | 0 | auto& result_data = result_matches.get_data(); |
536 | 0 | for (size_t row = 0; row < map_offsets.size(); ++row) { |
537 | 0 | if (map_row_nullmap && map_row_nullmap[row]) { |
538 | 0 | continue; |
539 | 0 | } |
540 | 0 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; |
541 | 0 | size_t map_end = map_offsets[row]; |
542 | | // const column always uses index 0 |
543 | 0 | size_t search_idx = search_is_const ? 0 : row; |
544 | 0 | for (size_t i = map_start; i < map_end; ++i) { |
545 | 0 | result_data[i] &= |
546 | 0 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, |
547 | 0 | search_column, search_idx, search_nullmap) |
548 | 0 | ? 1 |
549 | 0 | : 0; |
550 | 0 | } |
551 | 0 | } |
552 | 0 | } Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE2EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRS4_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE3EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE4EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE5EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE7EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE8EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE9EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_13ColumnDecimalILNS_13PrimitiveTypeE28EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS_12ColumnVectorILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_13ColumnDecimalILNS_13PrimitiveTypeE29EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS_12ColumnVectorILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_13ColumnDecimalILNS_13PrimitiveTypeE20EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS_12ColumnVectorILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_13ColumnDecimalILNS_13PrimitiveTypeE30EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS_12ColumnVectorILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_13ColumnDecimalILNS_13PrimitiveTypeE35EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS_12ColumnVectorILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE11EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE25EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE26EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE12EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE27EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE42EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE36EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE37EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_9ColumnStrIjEEEEvRKNS_7IColumnEPKhS6_S8_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES8_bRNS_12ColumnVectorILNS_13PrimitiveTypeE2EEE |
553 | | |
554 | | // dispatch column comparison by type, map_entry_column is the column of map's key or value, search_column is the column of search key or value |
555 | | void _dispatch_column_comparison(PrimitiveType type, const IColumn& map_entry_column, |
556 | | const UInt8* map_entry_nullmap, const IColumn& search_column, |
557 | | const UInt8* search_nullmap, |
558 | | const ColumnArray::Offsets64& map_offsets, |
559 | | const UInt8* map_row_nullmap, bool search_is_const, |
560 | 0 | ColumnUInt8& result_matches) const { |
561 | 0 | auto call = [&](const auto& type) -> bool { |
562 | 0 | using DispatchType = std::decay_t<decltype(type)>; |
563 | |
|
564 | 0 | _execute_column_comparison<typename DispatchType::ColumnType>( |
565 | 0 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, |
566 | 0 | map_row_nullmap, search_is_const, result_matches); |
567 | |
|
568 | 0 | return true; |
569 | 0 | }; Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_2EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_3EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_4EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_5EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_6EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_7EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_8EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_9EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_28EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_29EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_20EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_30EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_35EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_11EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_25EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_26EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_12EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_27EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_42EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_36EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_37EEEEEbSJ_ Unexecuted instantiation: _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_23EEEEEbSJ_ |
570 | |
|
571 | 0 | if (!dispatch_switch_all(type, call)) { |
572 | 0 | throw doris::Exception(ErrorCode::INTERNAL_ERROR, "not support type {}", |
573 | 0 | type_to_string(type)); |
574 | 0 | } |
575 | 0 | } |
576 | | |
577 | | // main loop function |
578 | | ColumnPtr _execute_all_rows(const ColumnMap* map_column, const ColumnPtr& map_row_nullmap_col, |
579 | | const IColumn& key_column, const UInt8* key_nullmap, |
580 | | const IColumn& value_column, const UInt8* value_nullmap, |
581 | | PrimitiveType key_type, PrimitiveType value_type, bool key_is_const, |
582 | 0 | bool value_is_const) const { |
583 | 0 | const auto& map_offsets = map_column->get_offsets(); |
584 | | |
585 | | // remove the nullable wrapper of map's key and value |
586 | 0 | const auto& map_keys_nullable = |
587 | 0 | reinterpret_cast<const ColumnNullable&>(map_column->get_keys()); |
588 | 0 | const IColumn* map_keys_column = &map_keys_nullable.get_nested_column(); |
589 | 0 | const auto& map_keys_nullmap = map_keys_nullable.get_null_map_column().get_data().data(); |
590 | |
|
591 | 0 | const auto& map_values_nullable = |
592 | 0 | reinterpret_cast<const ColumnNullable&>(map_column->get_values()); |
593 | 0 | const IColumn* map_values_column = &map_values_nullable.get_nested_column(); |
594 | 0 | const auto& map_values_nullmap = |
595 | 0 | map_values_nullable.get_null_map_column().get_data().data(); |
596 | |
|
597 | 0 | auto result_column = ColumnUInt8::create(map_offsets.size(), 0); |
598 | 0 | auto& result_data = result_column->get_data(); |
599 | |
|
600 | 0 | const UInt8* map_row_nullmap = nullptr; |
601 | 0 | if (map_row_nullmap_col) { |
602 | 0 | map_row_nullmap = |
603 | 0 | assert_cast<const ColumnUInt8&>(*map_row_nullmap_col).get_data().data(); |
604 | 0 | } |
605 | |
|
606 | 0 | auto matches = ColumnUInt8::create(map_keys_column->size(), 1); |
607 | | |
608 | | // matches &= key_compare |
609 | 0 | _dispatch_column_comparison(key_type, *map_keys_column, map_keys_nullmap, key_column, |
610 | 0 | key_nullmap, map_offsets, map_row_nullmap, key_is_const, |
611 | 0 | *matches); |
612 | | |
613 | | // matches &= value_compare |
614 | 0 | _dispatch_column_comparison(value_type, *map_values_column, map_values_nullmap, |
615 | 0 | value_column, value_nullmap, map_offsets, map_row_nullmap, |
616 | 0 | value_is_const, *matches); |
617 | | |
618 | | // aggregate results by map boundaries |
619 | 0 | auto& matches_data = matches->get_data(); |
620 | 0 | for (size_t row = 0; row < map_offsets.size(); ++row) { |
621 | 0 | if (map_row_nullmap && map_row_nullmap[row]) { |
622 | | // result is null for this row |
623 | 0 | continue; |
624 | 0 | } |
625 | | |
626 | 0 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; |
627 | 0 | size_t map_end = map_offsets[row]; |
628 | |
|
629 | 0 | bool found = false; |
630 | 0 | for (size_t i = map_start; i < map_end && !found; ++i) { |
631 | 0 | if (matches_data[i]) { |
632 | 0 | found = true; |
633 | 0 | break; |
634 | 0 | } |
635 | 0 | } |
636 | 0 | result_data[row] = found; |
637 | 0 | } |
638 | |
|
639 | 0 | if (map_row_nullmap_col) { |
640 | 0 | return ColumnNullable::create(std::move(result_column), map_row_nullmap_col); |
641 | 0 | } |
642 | 0 | return result_column; |
643 | 0 | } |
644 | | |
645 | | // type comparability check and dispatch |
646 | | Status _execute_type_check_and_dispatch(Block& block, const ColumnNumbers& arguments, |
647 | 0 | uint32_t result) const { |
648 | | // get type information |
649 | 0 | auto map_type = remove_nullable(block.get_by_position(arguments[0]).type); |
650 | 0 | const auto* map_datatype = assert_cast<const DataTypeMap*>(map_type.get()); |
651 | 0 | auto map_key_type = remove_nullable(map_datatype->get_key_type()); |
652 | 0 | auto map_value_type = remove_nullable(map_datatype->get_value_type()); |
653 | 0 | auto search_key_type = remove_nullable(block.get_by_position(arguments[1]).type); |
654 | 0 | auto search_value_type = remove_nullable(block.get_by_position(arguments[2]).type); |
655 | |
|
656 | 0 | PrimitiveType key_primitive_type = map_key_type->get_primitive_type(); |
657 | 0 | PrimitiveType value_primitive_type = map_value_type->get_primitive_type(); |
658 | | |
659 | | // FE should ensure the column types are the same, |
660 | | // but primitive type may be different (eg. TYPE_STRING and TYPE_VARCHAR both use ColumnString) |
661 | | |
662 | | // check whether this function supports equality comparison for the types |
663 | 0 | if (!is_equality_comparison_supported(key_primitive_type) || |
664 | 0 | !is_equality_comparison_supported(value_primitive_type)) { |
665 | 0 | return Status::RuntimeError( |
666 | 0 | "Trying to do equality comparison on unsupported types for function {}. " |
667 | 0 | "Map key type: {}, search key type: {}. " |
668 | 0 | "Map value type: {}, search value type: {}. " |
669 | 0 | "Key primitive type: {}, value primitive type: {}.", |
670 | 0 | get_name(), map_key_type->get_name(), search_key_type->get_name(), |
671 | 0 | map_value_type->get_name(), search_value_type->get_name(), |
672 | 0 | type_to_string(key_primitive_type), type_to_string(value_primitive_type)); |
673 | 0 | } |
674 | | |
675 | | // type check passed, extract columns and execute |
676 | | // extract map column |
677 | 0 | auto map_column_ptr = |
678 | 0 | block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); |
679 | 0 | const ColumnMap* map_column = nullptr; |
680 | 0 | ColumnPtr map_row_nullmap_col = nullptr; |
681 | 0 | if (map_column_ptr->is_nullable()) { |
682 | 0 | const auto* nullable_column = |
683 | 0 | reinterpret_cast<const ColumnNullable*>(map_column_ptr.get()); |
684 | 0 | map_column = check_and_get_column<ColumnMap>(nullable_column->get_nested_column()); |
685 | 0 | map_row_nullmap_col = nullable_column->get_null_map_column_ptr(); |
686 | 0 | } else { |
687 | 0 | map_column = check_and_get_column<ColumnMap>(*map_column_ptr.get()); |
688 | 0 | } |
689 | 0 | if (!map_column) { |
690 | 0 | return Status::RuntimeError("unsupported types for function {}({})", get_name(), |
691 | 0 | block.get_by_position(arguments[0]).type->get_name()); |
692 | 0 | } |
693 | | |
694 | | // extract (search) key and value columns |
695 | 0 | const auto& [key_column_ptr, key_is_const] = |
696 | 0 | unpack_if_const(block.get_by_position(arguments[1]).column); |
697 | 0 | const auto& [value_column_ptr, value_is_const] = |
698 | 0 | unpack_if_const(block.get_by_position(arguments[2]).column); |
699 | |
|
700 | 0 | const IColumn* key_column = nullptr; |
701 | 0 | const IColumn* value_column = nullptr; |
702 | 0 | const UInt8* key_nullmap = nullptr; |
703 | 0 | const UInt8* value_nullmap = nullptr; |
704 | |
|
705 | 0 | if (key_column_ptr->is_nullable()) { |
706 | 0 | const auto* nullable_column = assert_cast<const ColumnNullable*>(key_column_ptr.get()); |
707 | 0 | key_column = &nullable_column->get_nested_column(); |
708 | 0 | key_nullmap = nullable_column->get_null_map_column().get_data().data(); |
709 | 0 | } else { |
710 | 0 | key_column = key_column_ptr.get(); |
711 | 0 | } |
712 | |
|
713 | 0 | if (value_column_ptr->is_nullable()) { |
714 | 0 | const auto* nullable_column = |
715 | 0 | assert_cast<const ColumnNullable*>(value_column_ptr.get()); |
716 | 0 | value_column = &nullable_column->get_nested_column(); |
717 | 0 | value_nullmap = nullable_column->get_null_map_column().get_data().data(); |
718 | 0 | } else { |
719 | 0 | value_column = value_column_ptr.get(); |
720 | 0 | } |
721 | |
|
722 | 0 | ColumnPtr return_column = |
723 | 0 | _execute_all_rows(map_column, map_row_nullmap_col, *key_column, key_nullmap, |
724 | 0 | *value_column, value_nullmap, key_primitive_type, |
725 | 0 | value_primitive_type, key_is_const, value_is_const); |
726 | |
|
727 | 0 | if (return_column) { |
728 | 0 | block.replace_by_position(result, std::move(return_column)); |
729 | 0 | return Status::OK(); |
730 | 0 | } |
731 | | |
732 | 0 | return Status::RuntimeError( |
733 | 0 | "execute failed or unsupported types for function {}({}, {}, {})", get_name(), |
734 | 0 | block.get_by_position(arguments[0]).type->get_name(), |
735 | 0 | block.get_by_position(arguments[1]).type->get_name(), |
736 | 0 | block.get_by_position(arguments[2]).type->get_name()); |
737 | 0 | } |
738 | | |
739 | | // generic type-specialized comparison function |
740 | | template <typename ColumnType> |
741 | | bool compare_values(const IColumn& left_col, size_t left_idx, const UInt8* left_nullmap, |
742 | | const IColumn& right_col, size_t right_idx, |
743 | 0 | const UInt8* right_nullmap) const { |
744 | | // handle null values |
745 | 0 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; |
746 | 0 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; |
747 | |
|
748 | 0 | if (left_is_null && right_is_null) { |
749 | 0 | return true; |
750 | 0 | } |
751 | 0 | if (left_is_null || right_is_null) { |
752 | 0 | return false; |
753 | 0 | } |
754 | | |
755 | | // use compare_at from typed column |
756 | 0 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); |
757 | 0 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); |
758 | 0 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, |
759 | 0 | /*nan_direction_hint=*/1) == 0; |
760 | 0 | } Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE2EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE3EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE4EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE5EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE7EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE8EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE9EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_13ColumnDecimalILNS_13PrimitiveTypeE28EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_13ColumnDecimalILNS_13PrimitiveTypeE29EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_13ColumnDecimalILNS_13PrimitiveTypeE20EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_13ColumnDecimalILNS_13PrimitiveTypeE30EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_13ColumnDecimalILNS_13PrimitiveTypeE35EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE11EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE25EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE26EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE12EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE27EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE42EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE36EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE37EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_9ColumnStrIjEEEEbRKNS_7IColumnEmPKhS6_mS8_ |
761 | | |
762 | | // whether this function supports equality comparison for the given primitive type |
763 | 0 | bool is_equality_comparison_supported(PrimitiveType type) const { |
764 | 0 | return is_string_type(type) || is_number(type) || is_date_type(type) || |
765 | 0 | is_time_type(type) || is_ip(type); |
766 | 0 | } |
767 | | }; |
768 | | |
769 | | class FunctionDeduplicateMap : public IFunction { |
770 | | public: |
771 | | static constexpr auto name = "deduplicate_map"; |
772 | 3 | static FunctionPtr create() { return std::make_shared<FunctionDeduplicateMap>(); } |
773 | | |
774 | 1 | String get_name() const override { return name; } |
775 | 1 | size_t get_number_of_arguments() const override { return 1; } |
776 | 2 | bool use_default_implementation_for_nulls() const override { return true; } |
777 | | |
778 | 1 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
779 | 1 | return arguments[0]; |
780 | 1 | } |
781 | | |
782 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
783 | 1 | uint32_t result, size_t input_rows_count) const override { |
784 | 1 | DCHECK_EQ(arguments.size(), 1); |
785 | 1 | auto col_ptr = block.get_by_position(arguments[0]).column->clone_resized(input_rows_count); |
786 | 1 | auto& col_map = assert_cast<ColumnMap&>(*col_ptr); |
787 | 1 | RETURN_IF_ERROR(col_map.deduplicate_keys()); |
788 | 1 | block.replace_by_position(result, std::move(col_ptr)); |
789 | 1 | return Status::OK(); |
790 | 1 | } |
791 | | |
792 | | private: |
793 | | }; |
794 | | |
795 | 1 | void register_function_map(SimpleFunctionFactory& factory) { |
796 | 1 | factory.register_function<FunctionMap>(); |
797 | 1 | factory.register_function<FunctionMapContains<true>>(); |
798 | 1 | factory.register_function<FunctionMapContains<false>>(); |
799 | 1 | factory.register_function<FunctionMapKeysOrValues<true>>(); |
800 | 1 | factory.register_function<FunctionMapKeysOrValues<false>>(); |
801 | 1 | factory.register_function<FunctionMapEntries>(); |
802 | 1 | factory.register_function<FunctionStrToMap>(); |
803 | 1 | factory.register_function<FunctionMapContainsEntry>(); |
804 | 1 | factory.register_function<FunctionDeduplicateMap>(); |
805 | 1 | } |
806 | | |
807 | | } // namespace doris |