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 | 5.17k | static FunctionPtr create() { return std::make_shared<FunctionMap>(); } |
70 | | |
71 | | /// Get function name. |
72 | 0 | String get_name() const override { return name; } |
73 | | |
74 | 5.16k | bool is_variadic() const override { return true; } |
75 | | |
76 | 10.3k | 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 | 5.16k | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
81 | 5.16k | DCHECK(arguments.size() % 2 == 0) |
82 | 0 | << "function: " << get_name() << ", arguments should not be even number"; |
83 | 5.16k | return std::make_shared<DataTypeMap>(make_nullable(arguments[0]), |
84 | 5.16k | make_nullable(arguments[1])); |
85 | 5.16k | } |
86 | | |
87 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
88 | 5.16k | uint32_t result, size_t input_rows_count) const override { |
89 | 5.16k | DCHECK(arguments.size() % 2 == 0) |
90 | 0 | << "function: " << get_name() << ", arguments should not be even number"; |
91 | | |
92 | 5.16k | size_t num_element = arguments.size(); |
93 | | |
94 | 5.16k | auto result_col = block.get_by_position(result).type->create_column(); |
95 | 5.16k | auto* map_column = assert_cast<ColumnMap*>(result_col.get()); |
96 | | |
97 | | // map keys column |
98 | 5.16k | auto& result_col_map_keys_data = map_column->get_keys(); |
99 | 5.16k | result_col_map_keys_data.reserve(input_rows_count * num_element / 2); |
100 | | // map values column |
101 | 5.16k | auto& result_col_map_vals_data = map_column->get_values(); |
102 | 5.16k | result_col_map_vals_data.reserve(input_rows_count * num_element / 2); |
103 | | // map offsets column |
104 | 5.16k | auto& result_col_map_offsets = map_column->get_offsets(); |
105 | 5.16k | result_col_map_offsets.resize(input_rows_count); |
106 | | |
107 | 5.16k | std::unique_ptr<bool[]> col_const = std::make_unique_for_overwrite<bool[]>(num_element); |
108 | 5.16k | std::vector<ColumnPtr> arg(num_element); |
109 | 16.1k | for (size_t i = 0; i < num_element; ++i) { |
110 | 10.9k | auto& col = block.get_by_position(arguments[i]).column; |
111 | 10.9k | std::tie(col, col_const[i]) = unpack_if_const(col); |
112 | 10.9k | bool is_nullable = i % 2 == 0 ? result_col_map_keys_data.is_nullable() |
113 | 10.9k | : result_col_map_vals_data.is_nullable(); |
114 | | // convert to nullable column |
115 | 10.9k | arg[i] = col; |
116 | 10.9k | if (is_nullable && !col->is_nullable()) { |
117 | 10.6k | arg[i] = ColumnNullable::create(col, ColumnUInt8::create(col->size(), 0)); |
118 | 10.6k | } |
119 | 10.9k | } |
120 | | |
121 | | // insert value into map |
122 | 5.16k | ColumnArray::Offset64 offset = 0; |
123 | 10.3k | for (size_t row = 0; row < input_rows_count; ++row) { |
124 | 10.6k | for (size_t i = 0; i < num_element; i += 2) { |
125 | 5.48k | result_col_map_keys_data.insert_from(*arg[i], index_check_const(row, col_const[i])); |
126 | 5.48k | result_col_map_vals_data.insert_from(*arg[i + 1], |
127 | 5.48k | index_check_const(row, col_const[i + 1])); |
128 | 5.48k | } |
129 | 5.16k | offset += num_element / 2; |
130 | 5.16k | result_col_map_offsets[row] = offset; |
131 | 5.16k | } |
132 | | |
133 | 5.16k | RETURN_IF_ERROR(map_column->deduplicate_keys()); |
134 | 5.16k | block.replace_by_position(result, std::move(result_col)); |
135 | 5.16k | return Status::OK(); |
136 | 5.16k | } |
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 | 127 | static FunctionPtr create() { return std::make_shared<FunctionMapContains>(); }_ZN5doris19FunctionMapContainsILb1ELb0EE6createEv Line | Count | Source | 143 | 69 | static FunctionPtr create() { return std::make_shared<FunctionMapContains>(); } |
_ZN5doris19FunctionMapContainsILb0ELb0EE6createEv Line | Count | Source | 143 | 58 | 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 | 111 | bool is_variadic() const override { return false; }_ZNK5doris19FunctionMapContainsILb1ELb0EE11is_variadicEv Line | Count | Source | 148 | 61 | bool is_variadic() const override { return false; } |
_ZNK5doris19FunctionMapContainsILb0ELb0EE11is_variadicEv Line | Count | Source | 148 | 50 | bool is_variadic() const override { return false; } |
|
149 | | |
150 | 109 | size_t get_number_of_arguments() const override { return 2; }_ZNK5doris19FunctionMapContainsILb1ELb0EE23get_number_of_argumentsEv Line | Count | Source | 150 | 60 | size_t get_number_of_arguments() const override { return 2; } |
_ZNK5doris19FunctionMapContainsILb0ELb0EE23get_number_of_argumentsEv Line | Count | Source | 150 | 49 | size_t get_number_of_arguments() const override { return 2; } |
|
151 | | |
152 | 715 | bool use_default_implementation_for_nulls() const override { |
153 | 715 | return FunctionArrayIndex<ArrayContainsAction> {}.use_default_implementation_for_nulls(); |
154 | 715 | } _ZNK5doris19FunctionMapContainsILb1ELb0EE36use_default_implementation_for_nullsEv Line | Count | Source | 152 | 398 | bool use_default_implementation_for_nulls() const override { | 153 | 398 | return FunctionArrayIndex<ArrayContainsAction> {}.use_default_implementation_for_nulls(); | 154 | 398 | } |
_ZNK5doris19FunctionMapContainsILb0ELb0EE36use_default_implementation_for_nullsEv Line | Count | Source | 152 | 317 | bool use_default_implementation_for_nulls() const override { | 153 | 317 | return FunctionArrayIndex<ArrayContainsAction> {}.use_default_implementation_for_nulls(); | 154 | 317 | } |
|
155 | | |
156 | 109 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
157 | 109 | DataTypePtr datatype = arguments[0]; |
158 | 109 | if (datatype->is_nullable()) { |
159 | 65 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); |
160 | 65 | } |
161 | 109 | 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 | 109 | } else { |
167 | 109 | if (arguments[0]->is_nullable()) { |
168 | 65 | return make_nullable(std::make_shared<DataTypeBool>()); |
169 | 65 | } else { |
170 | 44 | return std::make_shared<DataTypeBool>(); |
171 | 44 | } |
172 | 109 | } |
173 | 109 | } _ZNK5doris19FunctionMapContainsILb1ELb0EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS6_EE Line | Count | Source | 156 | 60 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { | 157 | 60 | DataTypePtr datatype = arguments[0]; | 158 | 60 | if (datatype->is_nullable()) { | 159 | 36 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); | 160 | 36 | } | 161 | 60 | 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 | 60 | } else { | 167 | 60 | if (arguments[0]->is_nullable()) { | 168 | 36 | return make_nullable(std::make_shared<DataTypeBool>()); | 169 | 36 | } else { | 170 | 24 | return std::make_shared<DataTypeBool>(); | 171 | 24 | } | 172 | 60 | } | 173 | 60 | } |
_ZNK5doris19FunctionMapContainsILb0ELb0EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS6_EE Line | Count | Source | 156 | 49 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { | 157 | 49 | DataTypePtr datatype = arguments[0]; | 158 | 49 | if (datatype->is_nullable()) { | 159 | 29 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); | 160 | 29 | } | 161 | 49 | 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 | 49 | } else { | 167 | 49 | if (arguments[0]->is_nullable()) { | 168 | 29 | return make_nullable(std::make_shared<DataTypeBool>()); | 169 | 29 | } else { | 170 | 20 | return std::make_shared<DataTypeBool>(); | 171 | 20 | } | 172 | 49 | } | 173 | 49 | } |
|
174 | | |
175 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
176 | 605 | uint32_t result, size_t input_rows_count) const override { |
177 | | // backup original argument 0 |
178 | 605 | auto orig_arg0 = block.get_by_position(arguments[0]); |
179 | 605 | auto left_column = |
180 | 605 | block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); |
181 | 605 | const ColumnMap* map_column = nullptr; |
182 | 605 | ColumnPtr nullmap_column = nullptr; |
183 | 605 | if (left_column->is_nullable()) { |
184 | 466 | auto nullable_column = reinterpret_cast<const ColumnNullable*>(left_column.get()); |
185 | 466 | map_column = check_and_get_column<ColumnMap>(nullable_column->get_nested_column()); |
186 | 466 | nullmap_column = nullable_column->get_null_map_column_ptr(); |
187 | 466 | } else { |
188 | 139 | map_column = check_and_get_column<ColumnMap>(*left_column.get()); |
189 | 139 | } |
190 | 605 | 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 | 605 | DataTypePtr datatype = block.get_by_position(arguments[0]).type; |
196 | 605 | if (datatype->is_nullable()) { |
197 | 465 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); |
198 | 465 | } |
199 | 605 | const auto datatype_map = static_cast<const DataTypeMap*>(datatype.get()); |
200 | 605 | if constexpr (is_key) { |
201 | 337 | const auto& array_column = map_column->get_keys_array_ptr(); |
202 | 337 | const auto datatype_array = |
203 | 337 | std::make_shared<DataTypeArray>(datatype_map->get_key_type()); |
204 | 337 | if (nullmap_column) { |
205 | 260 | block.get_by_position(arguments[0]) = { |
206 | 260 | ColumnNullable::create(array_column, nullmap_column), |
207 | 260 | make_nullable(datatype_array), |
208 | 260 | block.get_by_position(arguments[0]).name + ".keys"}; |
209 | 260 | } else { |
210 | 77 | block.get_by_position(arguments[0]) = { |
211 | 77 | array_column, datatype_array, |
212 | 77 | block.get_by_position(arguments[0]).name + ".keys"}; |
213 | 77 | } |
214 | 337 | } else { |
215 | 268 | const auto& array_column = map_column->get_values_array_ptr(); |
216 | 268 | const auto datatype_array = |
217 | 268 | std::make_shared<DataTypeArray>(datatype_map->get_value_type()); |
218 | 268 | if (nullmap_column) { |
219 | 206 | block.get_by_position(arguments[0]) = { |
220 | 206 | ColumnNullable::create(array_column, nullmap_column), |
221 | 206 | make_nullable(datatype_array), |
222 | 206 | block.get_by_position(arguments[0]).name + ".values"}; |
223 | 206 | } else { |
224 | 62 | block.get_by_position(arguments[0]) = { |
225 | 62 | array_column, datatype_array, |
226 | 62 | block.get_by_position(arguments[0]).name + ".values"}; |
227 | 62 | } |
228 | 268 | } |
229 | | |
230 | 605 | RETURN_IF_ERROR(FunctionArrayIndex<ArrayContainsAction> {}.execute_impl( |
231 | 605 | context, block, arguments, result, input_rows_count)); |
232 | | |
233 | | // restore original argument 0 |
234 | 605 | block.get_by_position(arguments[0]) = orig_arg0; |
235 | 605 | return Status::OK(); |
236 | 605 | } _ZNK5doris19FunctionMapContainsILb1ELb0EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Line | Count | Source | 176 | 337 | uint32_t result, size_t input_rows_count) const override { | 177 | | // backup original argument 0 | 178 | 337 | auto orig_arg0 = block.get_by_position(arguments[0]); | 179 | 337 | auto left_column = | 180 | 337 | block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); | 181 | 337 | const ColumnMap* map_column = nullptr; | 182 | 337 | ColumnPtr nullmap_column = nullptr; | 183 | 337 | if (left_column->is_nullable()) { | 184 | 260 | auto nullable_column = reinterpret_cast<const ColumnNullable*>(left_column.get()); | 185 | 260 | map_column = check_and_get_column<ColumnMap>(nullable_column->get_nested_column()); | 186 | 260 | nullmap_column = nullable_column->get_null_map_column_ptr(); | 187 | 260 | } else { | 188 | 77 | map_column = check_and_get_column<ColumnMap>(*left_column.get()); | 189 | 77 | } | 190 | 337 | 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 | 337 | DataTypePtr datatype = block.get_by_position(arguments[0]).type; | 196 | 337 | if (datatype->is_nullable()) { | 197 | 259 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); | 198 | 259 | } | 199 | 337 | const auto datatype_map = static_cast<const DataTypeMap*>(datatype.get()); | 200 | 337 | if constexpr (is_key) { | 201 | 337 | const auto& array_column = map_column->get_keys_array_ptr(); | 202 | 337 | const auto datatype_array = | 203 | 337 | std::make_shared<DataTypeArray>(datatype_map->get_key_type()); | 204 | 337 | if (nullmap_column) { | 205 | 260 | block.get_by_position(arguments[0]) = { | 206 | 260 | ColumnNullable::create(array_column, nullmap_column), | 207 | 260 | make_nullable(datatype_array), | 208 | 260 | block.get_by_position(arguments[0]).name + ".keys"}; | 209 | 260 | } else { | 210 | 77 | block.get_by_position(arguments[0]) = { | 211 | 77 | array_column, datatype_array, | 212 | 77 | block.get_by_position(arguments[0]).name + ".keys"}; | 213 | 77 | } | 214 | | } else { | 215 | | const auto& array_column = map_column->get_values_array_ptr(); | 216 | | const auto datatype_array = | 217 | | std::make_shared<DataTypeArray>(datatype_map->get_value_type()); | 218 | | if (nullmap_column) { | 219 | | block.get_by_position(arguments[0]) = { | 220 | | ColumnNullable::create(array_column, nullmap_column), | 221 | | make_nullable(datatype_array), | 222 | | block.get_by_position(arguments[0]).name + ".values"}; | 223 | | } else { | 224 | | block.get_by_position(arguments[0]) = { | 225 | | array_column, datatype_array, | 226 | | block.get_by_position(arguments[0]).name + ".values"}; | 227 | | } | 228 | | } | 229 | | | 230 | 337 | RETURN_IF_ERROR(FunctionArrayIndex<ArrayContainsAction> {}.execute_impl( | 231 | 337 | context, block, arguments, result, input_rows_count)); | 232 | | | 233 | | // restore original argument 0 | 234 | 337 | block.get_by_position(arguments[0]) = orig_arg0; | 235 | 337 | return Status::OK(); | 236 | 337 | } |
_ZNK5doris19FunctionMapContainsILb0ELb0EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Line | Count | Source | 176 | 268 | uint32_t result, size_t input_rows_count) const override { | 177 | | // backup original argument 0 | 178 | 268 | auto orig_arg0 = block.get_by_position(arguments[0]); | 179 | 268 | auto left_column = | 180 | 268 | block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); | 181 | 268 | const ColumnMap* map_column = nullptr; | 182 | 268 | ColumnPtr nullmap_column = nullptr; | 183 | 268 | if (left_column->is_nullable()) { | 184 | 206 | auto nullable_column = reinterpret_cast<const ColumnNullable*>(left_column.get()); | 185 | 206 | map_column = check_and_get_column<ColumnMap>(nullable_column->get_nested_column()); | 186 | 206 | nullmap_column = nullable_column->get_null_map_column_ptr(); | 187 | 206 | } else { | 188 | 62 | map_column = check_and_get_column<ColumnMap>(*left_column.get()); | 189 | 62 | } | 190 | 268 | 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 | 268 | DataTypePtr datatype = block.get_by_position(arguments[0]).type; | 196 | 268 | if (datatype->is_nullable()) { | 197 | 206 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); | 198 | 206 | } | 199 | 268 | const auto datatype_map = static_cast<const DataTypeMap*>(datatype.get()); | 200 | | if constexpr (is_key) { | 201 | | const auto& array_column = map_column->get_keys_array_ptr(); | 202 | | const auto datatype_array = | 203 | | std::make_shared<DataTypeArray>(datatype_map->get_key_type()); | 204 | | if (nullmap_column) { | 205 | | block.get_by_position(arguments[0]) = { | 206 | | ColumnNullable::create(array_column, nullmap_column), | 207 | | make_nullable(datatype_array), | 208 | | block.get_by_position(arguments[0]).name + ".keys"}; | 209 | | } else { | 210 | | block.get_by_position(arguments[0]) = { | 211 | | array_column, datatype_array, | 212 | | block.get_by_position(arguments[0]).name + ".keys"}; | 213 | | } | 214 | 268 | } else { | 215 | 268 | const auto& array_column = map_column->get_values_array_ptr(); | 216 | 268 | const auto datatype_array = | 217 | 268 | std::make_shared<DataTypeArray>(datatype_map->get_value_type()); | 218 | 268 | if (nullmap_column) { | 219 | 206 | block.get_by_position(arguments[0]) = { | 220 | 206 | ColumnNullable::create(array_column, nullmap_column), | 221 | 206 | make_nullable(datatype_array), | 222 | 206 | block.get_by_position(arguments[0]).name + ".values"}; | 223 | 206 | } else { | 224 | 62 | block.get_by_position(arguments[0]) = { | 225 | 62 | array_column, datatype_array, | 226 | 62 | block.get_by_position(arguments[0]).name + ".values"}; | 227 | 62 | } | 228 | 268 | } | 229 | | | 230 | 268 | RETURN_IF_ERROR(FunctionArrayIndex<ArrayContainsAction> {}.execute_impl( | 231 | 268 | context, block, arguments, result, input_rows_count)); | 232 | | | 233 | | // restore original argument 0 | 234 | 268 | block.get_by_position(arguments[0]) = orig_arg0; | 235 | 268 | return Status::OK(); | 236 | 268 | } |
|
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 | 276 | static FunctionPtr create() { return std::make_shared<FunctionMapKeysOrValues>(); }_ZN5doris23FunctionMapKeysOrValuesILb1EE6createEv Line | Count | Source | 243 | 108 | static FunctionPtr create() { return std::make_shared<FunctionMapKeysOrValues>(); } |
_ZN5doris23FunctionMapKeysOrValuesILb0EE6createEv Line | Count | Source | 243 | 168 | 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 | 260 | bool is_variadic() const override { return false; }_ZNK5doris23FunctionMapKeysOrValuesILb1EE11is_variadicEv Line | Count | Source | 248 | 100 | bool is_variadic() const override { return false; } |
_ZNK5doris23FunctionMapKeysOrValuesILb0EE11is_variadicEv Line | Count | Source | 248 | 160 | bool is_variadic() const override { return false; } |
|
249 | | |
250 | 258 | size_t get_number_of_arguments() const override { return 1; }_ZNK5doris23FunctionMapKeysOrValuesILb1EE23get_number_of_argumentsEv Line | Count | Source | 250 | 99 | size_t get_number_of_arguments() const override { return 1; } |
_ZNK5doris23FunctionMapKeysOrValuesILb0EE23get_number_of_argumentsEv Line | Count | Source | 250 | 159 | size_t get_number_of_arguments() const override { return 1; } |
|
251 | | |
252 | 258 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
253 | 258 | DataTypePtr datatype = arguments[0]; |
254 | 258 | if (datatype->is_nullable()) { |
255 | 0 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); |
256 | 0 | } |
257 | 258 | DCHECK(datatype->get_primitive_type() == TYPE_MAP) |
258 | 0 | << "first argument for function: " << name << " should be DataTypeMap"; |
259 | 258 | const auto datatype_map = static_cast<const DataTypeMap*>(datatype.get()); |
260 | 258 | if (is_key) { |
261 | 99 | return std::make_shared<DataTypeArray>(datatype_map->get_key_type()); |
262 | 159 | } else { |
263 | 159 | return std::make_shared<DataTypeArray>(datatype_map->get_value_type()); |
264 | 159 | } |
265 | 258 | } _ZNK5doris23FunctionMapKeysOrValuesILb1EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS6_EE Line | Count | Source | 252 | 99 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { | 253 | 99 | DataTypePtr datatype = arguments[0]; | 254 | 99 | if (datatype->is_nullable()) { | 255 | 0 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); | 256 | 0 | } | 257 | 99 | DCHECK(datatype->get_primitive_type() == TYPE_MAP) | 258 | 0 | << "first argument for function: " << name << " should be DataTypeMap"; | 259 | 99 | const auto datatype_map = static_cast<const DataTypeMap*>(datatype.get()); | 260 | 99 | if (is_key) { | 261 | 99 | return std::make_shared<DataTypeArray>(datatype_map->get_key_type()); | 262 | 99 | } else { | 263 | 0 | return std::make_shared<DataTypeArray>(datatype_map->get_value_type()); | 264 | 0 | } | 265 | 99 | } |
_ZNK5doris23FunctionMapKeysOrValuesILb0EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS6_EE Line | Count | Source | 252 | 159 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { | 253 | 159 | DataTypePtr datatype = arguments[0]; | 254 | 159 | if (datatype->is_nullable()) { | 255 | 0 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); | 256 | 0 | } | 257 | 159 | DCHECK(datatype->get_primitive_type() == TYPE_MAP) | 258 | 0 | << "first argument for function: " << name << " should be DataTypeMap"; | 259 | 159 | const auto datatype_map = static_cast<const DataTypeMap*>(datatype.get()); | 260 | 159 | if (is_key) { | 261 | 0 | return std::make_shared<DataTypeArray>(datatype_map->get_key_type()); | 262 | 159 | } else { | 263 | 159 | return std::make_shared<DataTypeArray>(datatype_map->get_value_type()); | 264 | 159 | } | 265 | 159 | } |
|
266 | | |
267 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
268 | 2.16k | uint32_t result, size_t input_rows_count) const override { |
269 | 2.16k | auto left_column = |
270 | 2.16k | block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); |
271 | 2.16k | const ColumnMap* map_column = nullptr; |
272 | 2.16k | 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 | 2.16k | } else { |
276 | 2.16k | map_column = check_and_get_column<ColumnMap>(*left_column.get()); |
277 | 2.16k | } |
278 | 2.16k | 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 | 2.16k | if constexpr (is_key) { |
284 | 584 | block.replace_by_position(result, map_column->get_keys_array_ptr()); |
285 | 1.57k | } else { |
286 | 1.57k | block.replace_by_position(result, map_column->get_values_array_ptr()); |
287 | 1.57k | } |
288 | | |
289 | 2.16k | return Status::OK(); |
290 | 2.16k | } _ZNK5doris23FunctionMapKeysOrValuesILb1EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Line | Count | Source | 268 | 584 | uint32_t result, size_t input_rows_count) const override { | 269 | 584 | auto left_column = | 270 | 584 | block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); | 271 | 584 | const ColumnMap* map_column = nullptr; | 272 | 584 | 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 | 584 | } else { | 276 | 584 | map_column = check_and_get_column<ColumnMap>(*left_column.get()); | 277 | 584 | } | 278 | 584 | 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 | 584 | if constexpr (is_key) { | 284 | 584 | block.replace_by_position(result, map_column->get_keys_array_ptr()); | 285 | | } else { | 286 | | block.replace_by_position(result, map_column->get_values_array_ptr()); | 287 | | } | 288 | | | 289 | 584 | return Status::OK(); | 290 | 584 | } |
_ZNK5doris23FunctionMapKeysOrValuesILb0EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm Line | Count | Source | 268 | 1.57k | uint32_t result, size_t input_rows_count) const override { | 269 | 1.57k | auto left_column = | 270 | 1.57k | block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); | 271 | 1.57k | const ColumnMap* map_column = nullptr; | 272 | 1.57k | 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 | 1.57k | } else { | 276 | 1.57k | map_column = check_and_get_column<ColumnMap>(*left_column.get()); | 277 | 1.57k | } | 278 | 1.57k | 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 | | if constexpr (is_key) { | 284 | | block.replace_by_position(result, map_column->get_keys_array_ptr()); | 285 | 1.57k | } else { | 286 | 1.57k | block.replace_by_position(result, map_column->get_values_array_ptr()); | 287 | 1.57k | } | 288 | | | 289 | 1.57k | return Status::OK(); | 290 | 1.57k | } |
|
291 | | }; |
292 | | |
293 | | class FunctionMapEntries : public IFunction { |
294 | | public: |
295 | | static constexpr auto name = "map_entries"; |
296 | 34 | static FunctionPtr create() { return std::make_shared<FunctionMapEntries>(); } |
297 | | |
298 | | /// Get function name. |
299 | 1 | String get_name() const override { return name; } |
300 | | |
301 | 26 | bool is_variadic() const override { return false; } |
302 | | |
303 | 25 | size_t get_number_of_arguments() const override { return 1; } |
304 | | |
305 | 25 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
306 | 25 | 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 | 25 | auto struct_type = std::make_shared<DataTypeStruct>( |
311 | 25 | DataTypes {make_nullable(datatype_map->get_key_type()), |
312 | 25 | make_nullable(datatype_map->get_value_type())}, |
313 | 25 | Strings {"key", "value"}); |
314 | | |
315 | | // Theoretically, the struct element will never be null, |
316 | | // but FE expects the array element to be nullable |
317 | 25 | return std::make_shared<DataTypeArray>(make_nullable(struct_type)); |
318 | 25 | } |
319 | | |
320 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
321 | 33 | uint32_t result, size_t input_rows_count) const override { |
322 | 33 | const auto* map_column = |
323 | 33 | assert_cast<const ColumnMap*>(block.get_by_position(arguments[0]).column.get()); |
324 | | |
325 | 33 | auto struct_column = ColumnStruct::create( |
326 | 33 | Columns {map_column->get_keys_ptr(), map_column->get_values_ptr()}); |
327 | | |
328 | | // all struct elements are not null |
329 | 33 | auto struct_null_map = ColumnUInt8::create(struct_column->size(), 0); |
330 | 33 | auto nullable_struct_column = |
331 | 33 | ColumnNullable::create(std::move(struct_column), std::move(struct_null_map)); |
332 | | |
333 | 33 | auto result_array_column = ColumnArray::create(std::move(nullable_struct_column), |
334 | 33 | map_column->get_offsets_ptr()); |
335 | | |
336 | 33 | block.replace_by_position(result, std::move(result_array_column)); |
337 | | |
338 | 33 | return Status::OK(); |
339 | 33 | } |
340 | | }; |
341 | | |
342 | | class FunctionStrToMap : public IFunction { |
343 | | public: |
344 | | static constexpr auto name = "str_to_map"; |
345 | 62 | static FunctionPtr create() { return std::make_shared<FunctionStrToMap>(); } |
346 | | |
347 | 1 | String get_name() const override { return name; } |
348 | | |
349 | 53 | size_t get_number_of_arguments() const override { return 3; } |
350 | | |
351 | 53 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
352 | 53 | return std::make_shared<DataTypeMap>(make_nullable(std::make_shared<DataTypeString>()), |
353 | 53 | make_nullable(std::make_shared<DataTypeString>())); |
354 | 53 | } |
355 | | |
356 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
357 | 170 | uint32_t result, size_t input_rows_count) const override { |
358 | 170 | DCHECK(arguments.size() == 3); |
359 | | |
360 | 170 | bool cols_const[2]; |
361 | 170 | ColumnPtr cols[2]; |
362 | 510 | for (size_t i = 0; i < 2; ++i) { |
363 | 340 | cols_const[i] = is_column_const(*block.get_by_position(arguments[i]).column); |
364 | 340 | } |
365 | | // convert to full column if necessary |
366 | 170 | default_preprocess_parameter_columns(cols, cols_const, {0, 1}, block, arguments); |
367 | 170 | const auto& [col3, col3_const] = |
368 | 170 | unpack_if_const(block.get_by_position(arguments[2]).column); |
369 | | |
370 | 170 | const auto& str_column = assert_cast<const ColumnString*>(cols[0].get()); |
371 | 170 | const auto& pair_delim_column = assert_cast<const ColumnString*>(cols[1].get()); |
372 | 170 | const auto& kv_delim_column = assert_cast<const ColumnString*>(col3.get()); |
373 | | |
374 | 170 | ColumnPtr result_col; |
375 | 170 | if (cols_const[0] && cols_const[1]) { |
376 | 10 | result_col = execute_vector<true, false>(input_rows_count, *str_column, |
377 | 10 | *pair_delim_column, *kv_delim_column); |
378 | 160 | } else if (col3_const) { |
379 | 30 | result_col = execute_vector<false, true>(input_rows_count, *str_column, |
380 | 30 | *pair_delim_column, *kv_delim_column); |
381 | 130 | } else { |
382 | 130 | result_col = execute_vector<false, false>(input_rows_count, *str_column, |
383 | 130 | *pair_delim_column, *kv_delim_column); |
384 | 130 | } |
385 | | |
386 | 170 | block.replace_by_position(result, std::move(result_col)); |
387 | | |
388 | 170 | return Status::OK(); |
389 | 170 | } |
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 | 170 | const ColumnString& kv_delim_col) { |
396 | | // map keys column |
397 | 170 | auto result_col_map_keys_data = |
398 | 170 | ColumnNullable::create(ColumnString::create(), ColumnUInt8::create()); |
399 | 170 | result_col_map_keys_data->reserve(input_rows_count); |
400 | | // map values column |
401 | 170 | auto result_col_map_vals_data = |
402 | 170 | ColumnNullable::create(ColumnString::create(), ColumnUInt8::create()); |
403 | 170 | result_col_map_vals_data->reserve(input_rows_count); |
404 | | // map offsets column |
405 | 170 | auto result_col_map_offsets = ColumnOffset64::create(); |
406 | 170 | result_col_map_offsets->reserve(input_rows_count); |
407 | | |
408 | 170 | std::vector<std::string_view> kvs; |
409 | 170 | std::string_view kv_delim; |
410 | 170 | if constexpr (is_str_and_pair_delim_const) { |
411 | 10 | auto str = str_col.get_data_at(0).to_string_view(); |
412 | 10 | auto pair_delim = pair_delim_col.get_data_at(0).to_string_view(); |
413 | 10 | kvs = split_pair_by_delim(str, pair_delim); |
414 | 10 | } |
415 | 170 | if constexpr (is_kv_delim_const) { |
416 | 30 | kv_delim = kv_delim_col.get_data_at(0).to_string_view(); |
417 | 30 | } |
418 | | |
419 | 405 | for (size_t i = 0; i < input_rows_count; ++i) { |
420 | 235 | if constexpr (!is_str_and_pair_delim_const) { |
421 | 220 | auto str = str_col.get_data_at(i).to_string_view(); |
422 | 220 | auto pair_delim = pair_delim_col.get_data_at(i).to_string_view(); |
423 | 220 | kvs = split_pair_by_delim(str, pair_delim); |
424 | 220 | } |
425 | 235 | if constexpr (!is_kv_delim_const) { |
426 | 190 | kv_delim = kv_delim_col.get_data_at(i).to_string_view(); |
427 | 190 | } |
428 | | |
429 | 1.47k | for (const auto& kv : kvs) { |
430 | 1.47k | auto kv_parts = split_kv_by_delim(kv, kv_delim); |
431 | 1.47k | if (kv_parts.size() == 2) { |
432 | 1.40k | result_col_map_keys_data->insert_data(kv_parts[0].data(), kv_parts[0].size()); |
433 | 1.40k | result_col_map_vals_data->insert_data(kv_parts[1].data(), kv_parts[1].size()); |
434 | 1.40k | } else { |
435 | 73 | result_col_map_keys_data->insert_data(kv.data(), kv.size()); |
436 | 73 | result_col_map_vals_data->insert_default(); |
437 | 73 | } |
438 | 1.47k | } |
439 | 235 | result_col_map_offsets->insert_value(result_col_map_keys_data->size()); |
440 | 235 | } |
441 | | |
442 | 170 | auto map_column = ColumnMap::create(std::move(result_col_map_keys_data), |
443 | 170 | std::move(result_col_map_vals_data), |
444 | 170 | std::move(result_col_map_offsets)); |
445 | | |
446 | | // `deduplicate_keys` always return ok |
447 | 170 | static_cast<void>(map_column->deduplicate_keys()); |
448 | 170 | return map_column; |
449 | 170 | } _ZN5doris16FunctionStrToMap14execute_vectorILb1ELb0EEENS_3COWINS_7IColumnEE13immutable_ptrIS3_EEmRKNS_9ColumnStrIjEESA_SA_ Line | Count | Source | 395 | 10 | const ColumnString& kv_delim_col) { | 396 | | // map keys column | 397 | 10 | auto result_col_map_keys_data = | 398 | 10 | ColumnNullable::create(ColumnString::create(), ColumnUInt8::create()); | 399 | 10 | result_col_map_keys_data->reserve(input_rows_count); | 400 | | // map values column | 401 | 10 | auto result_col_map_vals_data = | 402 | 10 | ColumnNullable::create(ColumnString::create(), ColumnUInt8::create()); | 403 | 10 | result_col_map_vals_data->reserve(input_rows_count); | 404 | | // map offsets column | 405 | 10 | auto result_col_map_offsets = ColumnOffset64::create(); | 406 | 10 | result_col_map_offsets->reserve(input_rows_count); | 407 | | | 408 | 10 | std::vector<std::string_view> kvs; | 409 | 10 | std::string_view kv_delim; | 410 | 10 | if constexpr (is_str_and_pair_delim_const) { | 411 | 10 | auto str = str_col.get_data_at(0).to_string_view(); | 412 | 10 | auto pair_delim = pair_delim_col.get_data_at(0).to_string_view(); | 413 | 10 | kvs = split_pair_by_delim(str, pair_delim); | 414 | 10 | } | 415 | | if constexpr (is_kv_delim_const) { | 416 | | kv_delim = kv_delim_col.get_data_at(0).to_string_view(); | 417 | | } | 418 | | | 419 | 25 | for (size_t i = 0; i < input_rows_count; ++i) { | 420 | | if constexpr (!is_str_and_pair_delim_const) { | 421 | | auto str = str_col.get_data_at(i).to_string_view(); | 422 | | auto pair_delim = pair_delim_col.get_data_at(i).to_string_view(); | 423 | | kvs = split_pair_by_delim(str, pair_delim); | 424 | | } | 425 | 15 | if constexpr (!is_kv_delim_const) { | 426 | 15 | kv_delim = kv_delim_col.get_data_at(i).to_string_view(); | 427 | 15 | } | 428 | | | 429 | 30 | for (const auto& kv : kvs) { | 430 | 30 | auto kv_parts = split_kv_by_delim(kv, kv_delim); | 431 | 30 | if (kv_parts.size() == 2) { | 432 | 2 | result_col_map_keys_data->insert_data(kv_parts[0].data(), kv_parts[0].size()); | 433 | 2 | result_col_map_vals_data->insert_data(kv_parts[1].data(), kv_parts[1].size()); | 434 | 28 | } else { | 435 | 28 | result_col_map_keys_data->insert_data(kv.data(), kv.size()); | 436 | 28 | result_col_map_vals_data->insert_default(); | 437 | 28 | } | 438 | 30 | } | 439 | 15 | result_col_map_offsets->insert_value(result_col_map_keys_data->size()); | 440 | 15 | } | 441 | | | 442 | 10 | auto map_column = ColumnMap::create(std::move(result_col_map_keys_data), | 443 | 10 | std::move(result_col_map_vals_data), | 444 | 10 | std::move(result_col_map_offsets)); | 445 | | | 446 | | // `deduplicate_keys` always return ok | 447 | 10 | static_cast<void>(map_column->deduplicate_keys()); | 448 | 10 | return map_column; | 449 | 10 | } |
_ZN5doris16FunctionStrToMap14execute_vectorILb0ELb1EEENS_3COWINS_7IColumnEE13immutable_ptrIS3_EEmRKNS_9ColumnStrIjEESA_SA_ Line | Count | Source | 395 | 30 | const ColumnString& kv_delim_col) { | 396 | | // map keys column | 397 | 30 | auto result_col_map_keys_data = | 398 | 30 | ColumnNullable::create(ColumnString::create(), ColumnUInt8::create()); | 399 | 30 | result_col_map_keys_data->reserve(input_rows_count); | 400 | | // map values column | 401 | 30 | auto result_col_map_vals_data = | 402 | 30 | ColumnNullable::create(ColumnString::create(), ColumnUInt8::create()); | 403 | 30 | result_col_map_vals_data->reserve(input_rows_count); | 404 | | // map offsets column | 405 | 30 | auto result_col_map_offsets = ColumnOffset64::create(); | 406 | 30 | result_col_map_offsets->reserve(input_rows_count); | 407 | | | 408 | 30 | std::vector<std::string_view> kvs; | 409 | 30 | std::string_view kv_delim; | 410 | | if constexpr (is_str_and_pair_delim_const) { | 411 | | auto str = str_col.get_data_at(0).to_string_view(); | 412 | | auto pair_delim = pair_delim_col.get_data_at(0).to_string_view(); | 413 | | kvs = split_pair_by_delim(str, pair_delim); | 414 | | } | 415 | 30 | if constexpr (is_kv_delim_const) { | 416 | 30 | kv_delim = kv_delim_col.get_data_at(0).to_string_view(); | 417 | 30 | } | 418 | | | 419 | 75 | for (size_t i = 0; i < input_rows_count; ++i) { | 420 | 45 | if constexpr (!is_str_and_pair_delim_const) { | 421 | 45 | auto str = str_col.get_data_at(i).to_string_view(); | 422 | 45 | auto pair_delim = pair_delim_col.get_data_at(i).to_string_view(); | 423 | 45 | kvs = split_pair_by_delim(str, pair_delim); | 424 | 45 | } | 425 | | if constexpr (!is_kv_delim_const) { | 426 | | kv_delim = kv_delim_col.get_data_at(i).to_string_view(); | 427 | | } | 428 | | | 429 | 61 | for (const auto& kv : kvs) { | 430 | 61 | auto kv_parts = split_kv_by_delim(kv, kv_delim); | 431 | 61 | if (kv_parts.size() == 2) { | 432 | 43 | result_col_map_keys_data->insert_data(kv_parts[0].data(), kv_parts[0].size()); | 433 | 43 | result_col_map_vals_data->insert_data(kv_parts[1].data(), kv_parts[1].size()); | 434 | 43 | } else { | 435 | 18 | result_col_map_keys_data->insert_data(kv.data(), kv.size()); | 436 | 18 | result_col_map_vals_data->insert_default(); | 437 | 18 | } | 438 | 61 | } | 439 | 45 | result_col_map_offsets->insert_value(result_col_map_keys_data->size()); | 440 | 45 | } | 441 | | | 442 | 30 | auto map_column = ColumnMap::create(std::move(result_col_map_keys_data), | 443 | 30 | std::move(result_col_map_vals_data), | 444 | 30 | std::move(result_col_map_offsets)); | 445 | | | 446 | | // `deduplicate_keys` always return ok | 447 | 30 | static_cast<void>(map_column->deduplicate_keys()); | 448 | 30 | return map_column; | 449 | 30 | } |
_ZN5doris16FunctionStrToMap14execute_vectorILb0ELb0EEENS_3COWINS_7IColumnEE13immutable_ptrIS3_EEmRKNS_9ColumnStrIjEESA_SA_ Line | Count | Source | 395 | 130 | const ColumnString& kv_delim_col) { | 396 | | // map keys column | 397 | 130 | auto result_col_map_keys_data = | 398 | 130 | ColumnNullable::create(ColumnString::create(), ColumnUInt8::create()); | 399 | 130 | result_col_map_keys_data->reserve(input_rows_count); | 400 | | // map values column | 401 | 130 | auto result_col_map_vals_data = | 402 | 130 | ColumnNullable::create(ColumnString::create(), ColumnUInt8::create()); | 403 | 130 | result_col_map_vals_data->reserve(input_rows_count); | 404 | | // map offsets column | 405 | 130 | auto result_col_map_offsets = ColumnOffset64::create(); | 406 | 130 | result_col_map_offsets->reserve(input_rows_count); | 407 | | | 408 | 130 | std::vector<std::string_view> kvs; | 409 | 130 | std::string_view kv_delim; | 410 | | if constexpr (is_str_and_pair_delim_const) { | 411 | | auto str = str_col.get_data_at(0).to_string_view(); | 412 | | auto pair_delim = pair_delim_col.get_data_at(0).to_string_view(); | 413 | | kvs = split_pair_by_delim(str, pair_delim); | 414 | | } | 415 | | if constexpr (is_kv_delim_const) { | 416 | | kv_delim = kv_delim_col.get_data_at(0).to_string_view(); | 417 | | } | 418 | | | 419 | 305 | for (size_t i = 0; i < input_rows_count; ++i) { | 420 | 175 | if constexpr (!is_str_and_pair_delim_const) { | 421 | 175 | auto str = str_col.get_data_at(i).to_string_view(); | 422 | 175 | auto pair_delim = pair_delim_col.get_data_at(i).to_string_view(); | 423 | 175 | kvs = split_pair_by_delim(str, pair_delim); | 424 | 175 | } | 425 | 175 | if constexpr (!is_kv_delim_const) { | 426 | 175 | kv_delim = kv_delim_col.get_data_at(i).to_string_view(); | 427 | 175 | } | 428 | | | 429 | 1.38k | for (const auto& kv : kvs) { | 430 | 1.38k | auto kv_parts = split_kv_by_delim(kv, kv_delim); | 431 | 1.38k | if (kv_parts.size() == 2) { | 432 | 1.35k | result_col_map_keys_data->insert_data(kv_parts[0].data(), kv_parts[0].size()); | 433 | 1.35k | result_col_map_vals_data->insert_data(kv_parts[1].data(), kv_parts[1].size()); | 434 | 1.35k | } else { | 435 | 27 | result_col_map_keys_data->insert_data(kv.data(), kv.size()); | 436 | 27 | result_col_map_vals_data->insert_default(); | 437 | 27 | } | 438 | 1.38k | } | 439 | 175 | result_col_map_offsets->insert_value(result_col_map_keys_data->size()); | 440 | 175 | } | 441 | | | 442 | 130 | auto map_column = ColumnMap::create(std::move(result_col_map_keys_data), | 443 | 130 | std::move(result_col_map_vals_data), | 444 | 130 | std::move(result_col_map_offsets)); | 445 | | | 446 | | // `deduplicate_keys` always return ok | 447 | 130 | static_cast<void>(map_column->deduplicate_keys()); | 448 | 130 | return map_column; | 449 | 130 | } |
|
450 | | |
451 | | static std::vector<std::string_view> split_pair_by_delim(const std::string_view& str, |
452 | 230 | const std::string_view& delim) { |
453 | 230 | if (str.empty()) { |
454 | 11 | return {str}; |
455 | 11 | } |
456 | 219 | 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 | 219 | std::vector<std::string_view> result; |
467 | 219 | size_t offset = 0; |
468 | 1.45k | while (offset < str.size()) { |
469 | 1.45k | auto pos = str.find(delim, offset); |
470 | 1.45k | if (pos == std::string::npos) { |
471 | 217 | result.push_back(str.substr(offset)); |
472 | 217 | break; |
473 | 217 | } |
474 | 1.23k | result.push_back(str.substr(offset, pos - offset)); |
475 | 1.23k | offset = pos + delim.size(); |
476 | 1.23k | } |
477 | 219 | return result; |
478 | 219 | } |
479 | | |
480 | | static std::vector<std::string_view> split_kv_by_delim(const std::string_view& str, |
481 | 1.47k | const std::string_view& delim) { |
482 | 1.47k | if (str.empty()) { |
483 | 15 | return {str}; |
484 | 15 | } |
485 | 1.46k | 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 | 1.46k | auto pos = str.find(delim); |
490 | 1.46k | if (pos == std::string::npos) { |
491 | 58 | return {str}; |
492 | 1.40k | } else { |
493 | 1.40k | return {str.substr(0, pos), str.substr(pos + delim.size())}; |
494 | 1.40k | } |
495 | 1.46k | } |
496 | | }; |
497 | | |
498 | | class FunctionMapContainsEntry : public IFunction { |
499 | | public: |
500 | | static constexpr auto name = "map_contains_entry"; |
501 | 401 | static FunctionPtr create() { return std::make_shared<FunctionMapContainsEntry>(); } |
502 | | |
503 | 1 | String get_name() const override { return name; } |
504 | 392 | size_t get_number_of_arguments() const override { return 3; } |
505 | 939 | bool use_default_implementation_for_nulls() const override { return false; } |
506 | | |
507 | 392 | DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { |
508 | 392 | DataTypePtr datatype = arguments[0]; |
509 | 392 | if (datatype->is_nullable()) { |
510 | 51 | datatype = assert_cast<const DataTypeNullable*>(datatype.get())->get_nested_type(); |
511 | 51 | } |
512 | 392 | DCHECK_EQ(datatype->get_primitive_type(), PrimitiveType::TYPE_MAP) |
513 | 0 | << "first argument for function: " << name << " should be DataTypeMap"; |
514 | | |
515 | 392 | if (arguments[0]->is_nullable()) { |
516 | 51 | return make_nullable(std::make_shared<DataTypeBool>()); |
517 | 341 | } else { |
518 | 341 | return std::make_shared<DataTypeBool>(); |
519 | 341 | } |
520 | 392 | } |
521 | | |
522 | | Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, |
523 | 547 | uint32_t result, size_t input_rows_count) const override { |
524 | 547 | return _execute_type_check_and_dispatch(block, arguments, result); |
525 | 547 | } |
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 | 1.09k | ColumnUInt8& result_matches) const { |
535 | 1.09k | auto& result_data = result_matches.get_data(); |
536 | 2.43k | for (size_t row = 0; row < map_offsets.size(); ++row) { |
537 | 1.33k | if (map_row_nullmap && map_row_nullmap[row]) { |
538 | 110 | continue; |
539 | 110 | } |
540 | 1.22k | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; |
541 | 1.22k | size_t map_end = map_offsets[row]; |
542 | | // const column always uses index 0 |
543 | 1.22k | size_t search_idx = search_is_const ? 0 : row; |
544 | 2.93k | for (size_t i = map_start; i < map_end; ++i) { |
545 | 1.70k | result_data[i] &= |
546 | 1.70k | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, |
547 | 1.70k | search_column, search_idx, search_nullmap) |
548 | 1.70k | ? 1 |
549 | 1.70k | : 0; |
550 | 1.70k | } |
551 | 1.22k | } |
552 | 1.09k | } _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE2EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRS4_ Line | Count | Source | 534 | 42 | ColumnUInt8& result_matches) const { | 535 | 42 | auto& result_data = result_matches.get_data(); | 536 | 84 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 42 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 2 | continue; | 539 | 2 | } | 540 | 40 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 40 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 40 | size_t search_idx = search_is_const ? 0 : row; | 544 | 80 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 40 | result_data[i] &= | 546 | 40 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 40 | search_column, search_idx, search_nullmap) | 548 | 40 | ? 1 | 549 | 40 | : 0; | 550 | 40 | } | 551 | 40 | } | 552 | 42 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE3EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Line | Count | Source | 534 | 47 | ColumnUInt8& result_matches) const { | 535 | 47 | auto& result_data = result_matches.get_data(); | 536 | 94 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 47 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 47 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 47 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 47 | size_t search_idx = search_is_const ? 0 : row; | 544 | 104 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 57 | result_data[i] &= | 546 | 57 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 57 | search_column, search_idx, search_nullmap) | 548 | 57 | ? 1 | 549 | 57 | : 0; | 550 | 57 | } | 551 | 47 | } | 552 | 47 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE4EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Line | Count | Source | 534 | 53 | ColumnUInt8& result_matches) const { | 535 | 53 | auto& result_data = result_matches.get_data(); | 536 | 106 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 53 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 53 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 53 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 53 | size_t search_idx = search_is_const ? 0 : row; | 544 | 120 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 67 | result_data[i] &= | 546 | 67 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 67 | search_column, search_idx, search_nullmap) | 548 | 67 | ? 1 | 549 | 67 | : 0; | 550 | 67 | } | 551 | 53 | } | 552 | 53 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE5EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Line | Count | Source | 534 | 232 | ColumnUInt8& result_matches) const { | 535 | 232 | auto& result_data = result_matches.get_data(); | 536 | 583 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 351 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 53 | continue; | 539 | 53 | } | 540 | 298 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 298 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 298 | size_t search_idx = search_is_const ? 0 : row; | 544 | 792 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 494 | result_data[i] &= | 546 | 494 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 494 | search_column, search_idx, search_nullmap) | 548 | 494 | ? 1 | 549 | 494 | : 0; | 550 | 494 | } | 551 | 298 | } | 552 | 232 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Line | Count | Source | 534 | 46 | ColumnUInt8& result_matches) const { | 535 | 46 | auto& result_data = result_matches.get_data(); | 536 | 92 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 46 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 46 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 46 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 46 | size_t search_idx = search_is_const ? 0 : row; | 544 | 104 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 58 | result_data[i] &= | 546 | 58 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 58 | search_column, search_idx, search_nullmap) | 548 | 58 | ? 1 | 549 | 58 | : 0; | 550 | 58 | } | 551 | 46 | } | 552 | 46 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE7EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Line | Count | Source | 534 | 34 | ColumnUInt8& result_matches) const { | 535 | 34 | auto& result_data = result_matches.get_data(); | 536 | 68 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 34 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 34 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 34 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 34 | size_t search_idx = search_is_const ? 0 : row; | 544 | 68 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 34 | result_data[i] &= | 546 | 34 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 34 | search_column, search_idx, search_nullmap) | 548 | 34 | ? 1 | 549 | 34 | : 0; | 550 | 34 | } | 551 | 34 | } | 552 | 34 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE8EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Line | Count | Source | 534 | 34 | ColumnUInt8& result_matches) const { | 535 | 34 | auto& result_data = result_matches.get_data(); | 536 | 68 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 34 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 34 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 34 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 34 | size_t search_idx = search_is_const ? 0 : row; | 544 | 68 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 34 | result_data[i] &= | 546 | 34 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 34 | search_column, search_idx, search_nullmap) | 548 | 34 | ? 1 | 549 | 34 | : 0; | 550 | 34 | } | 551 | 34 | } | 552 | 34 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE9EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Line | Count | Source | 534 | 34 | ColumnUInt8& result_matches) const { | 535 | 34 | auto& result_data = result_matches.get_data(); | 536 | 68 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 34 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 34 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 34 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 34 | size_t search_idx = search_is_const ? 0 : row; | 544 | 68 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 34 | result_data[i] &= | 546 | 34 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 34 | search_column, search_idx, search_nullmap) | 548 | 34 | ? 1 | 549 | 34 | : 0; | 550 | 34 | } | 551 | 34 | } | 552 | 34 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_13ColumnDecimalILNS_13PrimitiveTypeE28EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS_12ColumnVectorILS3_2EEE Line | Count | Source | 534 | 2 | ColumnUInt8& result_matches) const { | 535 | 2 | auto& result_data = result_matches.get_data(); | 536 | 4 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 2 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 2 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 2 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 2 | size_t search_idx = search_is_const ? 0 : row; | 544 | 4 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 2 | result_data[i] &= | 546 | 2 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 2 | search_column, search_idx, search_nullmap) | 548 | 2 | ? 1 | 549 | 2 | : 0; | 550 | 2 | } | 551 | 2 | } | 552 | 2 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_13ColumnDecimalILNS_13PrimitiveTypeE29EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS_12ColumnVectorILS3_2EEE Line | Count | Source | 534 | 2 | ColumnUInt8& result_matches) const { | 535 | 2 | auto& result_data = result_matches.get_data(); | 536 | 4 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 2 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 2 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 2 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 2 | size_t search_idx = search_is_const ? 0 : row; | 544 | 4 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 2 | result_data[i] &= | 546 | 2 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 2 | search_column, search_idx, search_nullmap) | 548 | 2 | ? 1 | 549 | 2 | : 0; | 550 | 2 | } | 551 | 2 | } | 552 | 2 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_13ColumnDecimalILNS_13PrimitiveTypeE20EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS_12ColumnVectorILS3_2EEE Line | Count | Source | 534 | 2 | ColumnUInt8& result_matches) const { | 535 | 2 | auto& result_data = result_matches.get_data(); | 536 | 4 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 2 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 2 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 2 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 2 | size_t search_idx = search_is_const ? 0 : row; | 544 | 4 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 2 | result_data[i] &= | 546 | 2 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 2 | search_column, search_idx, search_nullmap) | 548 | 2 | ? 1 | 549 | 2 | : 0; | 550 | 2 | } | 551 | 2 | } | 552 | 2 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_13ColumnDecimalILNS_13PrimitiveTypeE30EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS_12ColumnVectorILS3_2EEE Line | Count | Source | 534 | 2 | ColumnUInt8& result_matches) const { | 535 | 2 | auto& result_data = result_matches.get_data(); | 536 | 4 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 2 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 2 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 2 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 2 | size_t search_idx = search_is_const ? 0 : row; | 544 | 4 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 2 | result_data[i] &= | 546 | 2 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 2 | search_column, search_idx, search_nullmap) | 548 | 2 | ? 1 | 549 | 2 | : 0; | 550 | 2 | } | 551 | 2 | } | 552 | 2 | } |
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 _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE25EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Line | Count | Source | 534 | 76 | ColumnUInt8& result_matches) const { | 535 | 76 | auto& result_data = result_matches.get_data(); | 536 | 152 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 76 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 76 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 76 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 76 | size_t search_idx = search_is_const ? 0 : row; | 544 | 160 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 84 | result_data[i] &= | 546 | 84 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 84 | search_column, search_idx, search_nullmap) | 548 | 84 | ? 1 | 549 | 84 | : 0; | 550 | 84 | } | 551 | 76 | } | 552 | 76 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE26EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Line | Count | Source | 534 | 76 | ColumnUInt8& result_matches) const { | 535 | 76 | auto& result_data = result_matches.get_data(); | 536 | 152 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 76 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 76 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 76 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 76 | size_t search_idx = search_is_const ? 0 : row; | 544 | 160 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 84 | result_data[i] &= | 546 | 84 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 84 | search_column, search_idx, search_nullmap) | 548 | 84 | ? 1 | 549 | 84 | : 0; | 550 | 84 | } | 551 | 76 | } | 552 | 76 | } |
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 _ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE36EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Line | Count | Source | 534 | 34 | ColumnUInt8& result_matches) const { | 535 | 34 | auto& result_data = result_matches.get_data(); | 536 | 68 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 34 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 34 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 34 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 34 | size_t search_idx = search_is_const ? 0 : row; | 544 | 68 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 34 | result_data[i] &= | 546 | 34 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 34 | search_column, search_idx, search_nullmap) | 548 | 34 | ? 1 | 549 | 34 | : 0; | 550 | 34 | } | 551 | 34 | } | 552 | 34 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_12ColumnVectorILNS_13PrimitiveTypeE37EEEEEvRKNS_7IColumnEPKhS7_S9_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES9_bRNS2_ILS3_2EEE Line | Count | Source | 534 | 34 | ColumnUInt8& result_matches) const { | 535 | 34 | auto& result_data = result_matches.get_data(); | 536 | 68 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 34 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 0 | continue; | 539 | 0 | } | 540 | 34 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 34 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 34 | size_t search_idx = search_is_const ? 0 : row; | 544 | 68 | for (size_t i = map_start; i < map_end; ++i) { | 545 | 34 | result_data[i] &= | 546 | 34 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 34 | search_column, search_idx, search_nullmap) | 548 | 34 | ? 1 | 549 | 34 | : 0; | 550 | 34 | } | 551 | 34 | } | 552 | 34 | } |
_ZNK5doris24FunctionMapContainsEntry26_execute_column_comparisonINS_9ColumnStrIjEEEEvRKNS_7IColumnEPKhS6_S8_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES8_bRNS_12ColumnVectorILNS_13PrimitiveTypeE2EEE Line | Count | Source | 534 | 346 | ColumnUInt8& result_matches) const { | 535 | 346 | auto& result_data = result_matches.get_data(); | 536 | 811 | for (size_t row = 0; row < map_offsets.size(); ++row) { | 537 | 465 | if (map_row_nullmap && map_row_nullmap[row]) { | 538 | 55 | continue; | 539 | 55 | } | 540 | 410 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; | 541 | 410 | size_t map_end = map_offsets[row]; | 542 | | // const column always uses index 0 | 543 | 410 | size_t search_idx = search_is_const ? 0 : row; | 544 | 1.05k | for (size_t i = map_start; i < map_end; ++i) { | 545 | 644 | result_data[i] &= | 546 | 644 | compare_values<ColumnType>(map_entry_column, i, map_entry_nullmap, | 547 | 644 | search_column, search_idx, search_nullmap) | 548 | 644 | ? 1 | 549 | 644 | : 0; | 550 | 644 | } | 551 | 410 | } | 552 | 346 | } |
|
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 | 1.09k | ColumnUInt8& result_matches) const { |
561 | 1.09k | auto call = [&](const auto& type) -> bool { |
562 | 1.09k | using DispatchType = std::decay_t<decltype(type)>; |
563 | | |
564 | 1.09k | _execute_column_comparison<typename DispatchType::ColumnType>( |
565 | 1.09k | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, |
566 | 1.09k | map_row_nullmap, search_is_const, result_matches); |
567 | | |
568 | 1.09k | return true; |
569 | 1.09k | }; _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_2EEEEEbSJ_ Line | Count | Source | 561 | 42 | auto call = [&](const auto& type) -> bool { | 562 | 42 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 42 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 42 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 42 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 42 | return true; | 569 | 42 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_3EEEEEbSJ_ Line | Count | Source | 561 | 47 | auto call = [&](const auto& type) -> bool { | 562 | 47 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 47 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 47 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 47 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 47 | return true; | 569 | 47 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_4EEEEEbSJ_ Line | Count | Source | 561 | 53 | auto call = [&](const auto& type) -> bool { | 562 | 53 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 53 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 53 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 53 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 53 | return true; | 569 | 53 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_5EEEEEbSJ_ Line | Count | Source | 561 | 232 | auto call = [&](const auto& type) -> bool { | 562 | 232 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 232 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 232 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 232 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 232 | return true; | 569 | 232 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_6EEEEEbSJ_ Line | Count | Source | 561 | 46 | auto call = [&](const auto& type) -> bool { | 562 | 46 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 46 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 46 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 46 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 46 | return true; | 569 | 46 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_7EEEEEbSJ_ Line | Count | Source | 561 | 34 | auto call = [&](const auto& type) -> bool { | 562 | 34 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 34 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 34 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 34 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 34 | return true; | 569 | 34 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_8EEEEEbSJ_ Line | Count | Source | 561 | 34 | auto call = [&](const auto& type) -> bool { | 562 | 34 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 34 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 34 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 34 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 34 | return true; | 569 | 34 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_9EEEEEbSJ_ Line | Count | Source | 561 | 34 | auto call = [&](const auto& type) -> bool { | 562 | 34 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 34 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 34 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 34 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 34 | return true; | 569 | 34 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_28EEEEEbSJ_ Line | Count | Source | 561 | 2 | auto call = [&](const auto& type) -> bool { | 562 | 2 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 2 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 2 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 2 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 2 | return true; | 569 | 2 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_29EEEEEbSJ_ Line | Count | Source | 561 | 2 | auto call = [&](const auto& type) -> bool { | 562 | 2 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 2 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 2 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 2 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 2 | return true; | 569 | 2 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_20EEEEEbSJ_ Line | Count | Source | 561 | 2 | auto call = [&](const auto& type) -> bool { | 562 | 2 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 2 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 2 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 2 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 2 | return true; | 569 | 2 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_30EEEEEbSJ_ Line | Count | Source | 561 | 2 | auto call = [&](const auto& type) -> bool { | 562 | 2 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 2 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 2 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 2 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 2 | return true; | 569 | 2 | }; |
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_ _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_25EEEEEbSJ_ Line | Count | Source | 561 | 76 | auto call = [&](const auto& type) -> bool { | 562 | 76 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 76 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 76 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 76 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 76 | return true; | 569 | 76 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_26EEEEEbSJ_ Line | Count | Source | 561 | 76 | auto call = [&](const auto& type) -> bool { | 562 | 76 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 76 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 76 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 76 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 76 | return true; | 569 | 76 | }; |
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_ _ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_36EEEEEbSJ_ Line | Count | Source | 561 | 34 | auto call = [&](const auto& type) -> bool { | 562 | 34 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 34 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 34 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 34 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 34 | return true; | 569 | 34 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_37EEEEEbSJ_ Line | Count | Source | 561 | 34 | auto call = [&](const auto& type) -> bool { | 562 | 34 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 34 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 34 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 34 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 34 | return true; | 569 | 34 | }; |
_ZZNK5doris24FunctionMapContainsEntry27_dispatch_column_comparisonENS_13PrimitiveTypeERKNS_7IColumnEPKhS4_S6_RKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb0EEELm16ELm15EEES6_bRNS_12ColumnVectorILS1_2EEEENKUlRKT_E_clINS_16DispatchDataTypeILS1_23EEEEEbSJ_ Line | Count | Source | 561 | 346 | auto call = [&](const auto& type) -> bool { | 562 | 346 | using DispatchType = std::decay_t<decltype(type)>; | 563 | | | 564 | 346 | _execute_column_comparison<typename DispatchType::ColumnType>( | 565 | 346 | map_entry_column, map_entry_nullmap, search_column, search_nullmap, map_offsets, | 566 | 346 | map_row_nullmap, search_is_const, result_matches); | 567 | | | 568 | 346 | return true; | 569 | 346 | }; |
|
570 | | |
571 | 1.09k | 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 | 1.09k | } |
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 | 547 | bool value_is_const) const { |
583 | 547 | const auto& map_offsets = map_column->get_offsets(); |
584 | | |
585 | | // remove the nullable wrapper of map's key and value |
586 | 547 | const auto& map_keys_nullable = |
587 | 547 | reinterpret_cast<const ColumnNullable&>(map_column->get_keys()); |
588 | 547 | const IColumn* map_keys_column = &map_keys_nullable.get_nested_column(); |
589 | 547 | const auto& map_keys_nullmap = map_keys_nullable.get_null_map_column().get_data().data(); |
590 | | |
591 | 547 | const auto& map_values_nullable = |
592 | 547 | reinterpret_cast<const ColumnNullable&>(map_column->get_values()); |
593 | 547 | const IColumn* map_values_column = &map_values_nullable.get_nested_column(); |
594 | 547 | const auto& map_values_nullmap = |
595 | 547 | map_values_nullable.get_null_map_column().get_data().data(); |
596 | | |
597 | 547 | auto result_column = ColumnUInt8::create(map_offsets.size(), 0); |
598 | 547 | auto& result_data = result_column->get_data(); |
599 | | |
600 | 547 | const UInt8* map_row_nullmap = nullptr; |
601 | 547 | if (map_row_nullmap_col) { |
602 | 207 | map_row_nullmap = |
603 | 207 | assert_cast<const ColumnUInt8&>(*map_row_nullmap_col).get_data().data(); |
604 | 207 | } |
605 | | |
606 | 547 | auto matches = ColumnUInt8::create(map_keys_column->size(), 1); |
607 | | |
608 | | // matches &= key_compare |
609 | 547 | _dispatch_column_comparison(key_type, *map_keys_column, map_keys_nullmap, key_column, |
610 | 547 | key_nullmap, map_offsets, map_row_nullmap, key_is_const, |
611 | 547 | *matches); |
612 | | |
613 | | // matches &= value_compare |
614 | 547 | _dispatch_column_comparison(value_type, *map_values_column, map_values_nullmap, |
615 | 547 | value_column, value_nullmap, map_offsets, map_row_nullmap, |
616 | 547 | value_is_const, *matches); |
617 | | |
618 | | // aggregate results by map boundaries |
619 | 547 | auto& matches_data = matches->get_data(); |
620 | 1.21k | for (size_t row = 0; row < map_offsets.size(); ++row) { |
621 | 667 | if (map_row_nullmap && map_row_nullmap[row]) { |
622 | | // result is null for this row |
623 | 55 | continue; |
624 | 55 | } |
625 | | |
626 | 612 | size_t map_start = row == 0 ? 0 : map_offsets[row - 1]; |
627 | 612 | size_t map_end = map_offsets[row]; |
628 | | |
629 | 612 | bool found = false; |
630 | 1.09k | for (size_t i = map_start; i < map_end && !found; ++i) { |
631 | 820 | if (matches_data[i]) { |
632 | 340 | found = true; |
633 | 340 | break; |
634 | 340 | } |
635 | 820 | } |
636 | 612 | result_data[row] = found; |
637 | 612 | } |
638 | | |
639 | 547 | if (map_row_nullmap_col) { |
640 | 207 | return ColumnNullable::create(std::move(result_column), map_row_nullmap_col); |
641 | 207 | } |
642 | 340 | return result_column; |
643 | 547 | } |
644 | | |
645 | | // type comparability check and dispatch |
646 | | Status _execute_type_check_and_dispatch(Block& block, const ColumnNumbers& arguments, |
647 | 546 | uint32_t result) const { |
648 | | // get type information |
649 | 546 | auto map_type = remove_nullable(block.get_by_position(arguments[0]).type); |
650 | 546 | const auto* map_datatype = assert_cast<const DataTypeMap*>(map_type.get()); |
651 | 546 | auto map_key_type = remove_nullable(map_datatype->get_key_type()); |
652 | 546 | auto map_value_type = remove_nullable(map_datatype->get_value_type()); |
653 | 546 | auto search_key_type = remove_nullable(block.get_by_position(arguments[1]).type); |
654 | 546 | auto search_value_type = remove_nullable(block.get_by_position(arguments[2]).type); |
655 | | |
656 | 546 | PrimitiveType key_primitive_type = map_key_type->get_primitive_type(); |
657 | 546 | 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 | 546 | if (!is_equality_comparison_supported(key_primitive_type) || |
664 | 547 | !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 | 546 | auto map_column_ptr = |
678 | 546 | block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); |
679 | 546 | const ColumnMap* map_column = nullptr; |
680 | 546 | ColumnPtr map_row_nullmap_col = nullptr; |
681 | 546 | if (map_column_ptr->is_nullable()) { |
682 | 206 | const auto* nullable_column = |
683 | 206 | reinterpret_cast<const ColumnNullable*>(map_column_ptr.get()); |
684 | 206 | map_column = check_and_get_column<ColumnMap>(nullable_column->get_nested_column()); |
685 | 206 | map_row_nullmap_col = nullable_column->get_null_map_column_ptr(); |
686 | 340 | } else { |
687 | 340 | map_column = check_and_get_column<ColumnMap>(*map_column_ptr.get()); |
688 | 340 | } |
689 | 546 | 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 | 546 | const auto& [key_column_ptr, key_is_const] = |
696 | 546 | unpack_if_const(block.get_by_position(arguments[1]).column); |
697 | 546 | const auto& [value_column_ptr, value_is_const] = |
698 | 546 | unpack_if_const(block.get_by_position(arguments[2]).column); |
699 | | |
700 | 546 | const IColumn* key_column = nullptr; |
701 | 546 | const IColumn* value_column = nullptr; |
702 | 546 | const UInt8* key_nullmap = nullptr; |
703 | 546 | const UInt8* value_nullmap = nullptr; |
704 | | |
705 | 546 | if (key_column_ptr->is_nullable()) { |
706 | 42 | const auto* nullable_column = assert_cast<const ColumnNullable*>(key_column_ptr.get()); |
707 | 42 | key_column = &nullable_column->get_nested_column(); |
708 | 42 | key_nullmap = nullable_column->get_null_map_column().get_data().data(); |
709 | 504 | } else { |
710 | 504 | key_column = key_column_ptr.get(); |
711 | 504 | } |
712 | | |
713 | 546 | if (value_column_ptr->is_nullable()) { |
714 | 41 | const auto* nullable_column = |
715 | 41 | assert_cast<const ColumnNullable*>(value_column_ptr.get()); |
716 | 41 | value_column = &nullable_column->get_nested_column(); |
717 | 41 | value_nullmap = nullable_column->get_null_map_column().get_data().data(); |
718 | 505 | } else { |
719 | 505 | value_column = value_column_ptr.get(); |
720 | 505 | } |
721 | | |
722 | 546 | ColumnPtr return_column = |
723 | 546 | _execute_all_rows(map_column, map_row_nullmap_col, *key_column, key_nullmap, |
724 | 546 | *value_column, value_nullmap, key_primitive_type, |
725 | 546 | value_primitive_type, key_is_const, value_is_const); |
726 | | |
727 | 548 | if (return_column) { |
728 | 548 | block.replace_by_position(result, std::move(return_column)); |
729 | 548 | return Status::OK(); |
730 | 548 | } |
731 | | |
732 | 18.4E | return Status::RuntimeError( |
733 | 18.4E | "execute failed or unsupported types for function {}({}, {}, {})", get_name(), |
734 | 18.4E | block.get_by_position(arguments[0]).type->get_name(), |
735 | 18.4E | block.get_by_position(arguments[1]).type->get_name(), |
736 | 18.4E | block.get_by_position(arguments[2]).type->get_name()); |
737 | 546 | } |
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 | 1.70k | const UInt8* right_nullmap) const { |
744 | | // handle null values |
745 | 1.70k | bool left_is_null = left_nullmap && left_nullmap[left_idx]; |
746 | 1.70k | bool right_is_null = right_nullmap && right_nullmap[right_idx]; |
747 | | |
748 | 1.70k | if (left_is_null && right_is_null) { |
749 | 18 | return true; |
750 | 18 | } |
751 | 1.68k | if (left_is_null || right_is_null) { |
752 | 188 | return false; |
753 | 188 | } |
754 | | |
755 | | // use compare_at from typed column |
756 | 1.50k | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); |
757 | 1.50k | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); |
758 | 1.50k | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, |
759 | 1.50k | /*nan_direction_hint=*/1) == 0; |
760 | 1.68k | } _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE2EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 40 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 40 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 40 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 40 | if (left_is_null && right_is_null) { | 749 | 6 | return true; | 750 | 6 | } | 751 | 34 | if (left_is_null || right_is_null) { | 752 | 0 | return false; | 753 | 0 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 34 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 34 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 34 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 34 | /*nan_direction_hint=*/1) == 0; | 760 | 34 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE3EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 57 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 57 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 57 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 57 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 57 | if (left_is_null || right_is_null) { | 752 | 1 | return false; | 753 | 1 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 56 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 56 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 56 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 56 | /*nan_direction_hint=*/1) == 0; | 760 | 57 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE4EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 67 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 67 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 67 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 67 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 67 | if (left_is_null || right_is_null) { | 752 | 4 | return false; | 753 | 4 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 63 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 63 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 63 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 63 | /*nan_direction_hint=*/1) == 0; | 760 | 67 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE5EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 494 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 494 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 494 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 494 | if (left_is_null && right_is_null) { | 749 | 7 | return true; | 750 | 7 | } | 751 | 487 | if (left_is_null || right_is_null) { | 752 | 94 | return false; | 753 | 94 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 393 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 393 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 393 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 393 | /*nan_direction_hint=*/1) == 0; | 760 | 487 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 58 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 58 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 58 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 58 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 58 | if (left_is_null || right_is_null) { | 752 | 4 | return false; | 753 | 4 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 54 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 54 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 54 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 54 | /*nan_direction_hint=*/1) == 0; | 760 | 58 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE7EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 34 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 34 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 34 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 34 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 34 | if (left_is_null || right_is_null) { | 752 | 0 | return false; | 753 | 0 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 34 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 34 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 34 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 34 | /*nan_direction_hint=*/1) == 0; | 760 | 34 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE8EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 34 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 34 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 34 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 34 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 34 | if (left_is_null || right_is_null) { | 752 | 0 | return false; | 753 | 0 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 34 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 34 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 34 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 34 | /*nan_direction_hint=*/1) == 0; | 760 | 34 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE9EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 34 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 34 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 34 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 34 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 34 | if (left_is_null || right_is_null) { | 752 | 0 | return false; | 753 | 0 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 34 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 34 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 34 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 34 | /*nan_direction_hint=*/1) == 0; | 760 | 34 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_13ColumnDecimalILNS_13PrimitiveTypeE28EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 2 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 2 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 2 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 2 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 2 | if (left_is_null || right_is_null) { | 752 | 0 | return false; | 753 | 0 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 2 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 2 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 2 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 2 | /*nan_direction_hint=*/1) == 0; | 760 | 2 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_13ColumnDecimalILNS_13PrimitiveTypeE29EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 2 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 2 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 2 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 2 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 2 | if (left_is_null || right_is_null) { | 752 | 0 | return false; | 753 | 0 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 2 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 2 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 2 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 2 | /*nan_direction_hint=*/1) == 0; | 760 | 2 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_13ColumnDecimalILNS_13PrimitiveTypeE20EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 2 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 2 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 2 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 2 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 2 | if (left_is_null || right_is_null) { | 752 | 0 | return false; | 753 | 0 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 2 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 2 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 2 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 2 | /*nan_direction_hint=*/1) == 0; | 760 | 2 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_13ColumnDecimalILNS_13PrimitiveTypeE30EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 2 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 2 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 2 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 2 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 2 | if (left_is_null || right_is_null) { | 752 | 0 | return false; | 753 | 0 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 2 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 2 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 2 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 2 | /*nan_direction_hint=*/1) == 0; | 760 | 2 | } |
Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_13ColumnDecimalILNS_13PrimitiveTypeE35EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE11EEEEEbRKNS_7IColumnEmPKhS7_mS9_ _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE25EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 84 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 84 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 84 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 84 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 84 | if (left_is_null || right_is_null) { | 752 | 0 | return false; | 753 | 0 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 84 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 84 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 84 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 84 | /*nan_direction_hint=*/1) == 0; | 760 | 84 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE26EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 84 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 84 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 84 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 84 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 84 | if (left_is_null || right_is_null) { | 752 | 0 | return false; | 753 | 0 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 84 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 84 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 84 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 84 | /*nan_direction_hint=*/1) == 0; | 760 | 84 | } |
Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE12EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE27EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Unexecuted instantiation: _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE42EEEEEbRKNS_7IColumnEmPKhS7_mS9_ _ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE36EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 34 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 34 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 34 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 34 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 34 | if (left_is_null || right_is_null) { | 752 | 0 | return false; | 753 | 0 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 34 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 34 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 34 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 34 | /*nan_direction_hint=*/1) == 0; | 760 | 34 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_12ColumnVectorILNS_13PrimitiveTypeE37EEEEEbRKNS_7IColumnEmPKhS7_mS9_ Line | Count | Source | 743 | 34 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 34 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 34 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 34 | if (left_is_null && right_is_null) { | 749 | 0 | return true; | 750 | 0 | } | 751 | 34 | if (left_is_null || right_is_null) { | 752 | 0 | return false; | 753 | 0 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 34 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 34 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 34 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 34 | /*nan_direction_hint=*/1) == 0; | 760 | 34 | } |
_ZNK5doris24FunctionMapContainsEntry14compare_valuesINS_9ColumnStrIjEEEEbRKNS_7IColumnEmPKhS6_mS8_ Line | Count | Source | 743 | 644 | const UInt8* right_nullmap) const { | 744 | | // handle null values | 745 | 644 | bool left_is_null = left_nullmap && left_nullmap[left_idx]; | 746 | 644 | bool right_is_null = right_nullmap && right_nullmap[right_idx]; | 747 | | | 748 | 644 | if (left_is_null && right_is_null) { | 749 | 5 | return true; | 750 | 5 | } | 751 | 639 | if (left_is_null || right_is_null) { | 752 | 85 | return false; | 753 | 85 | } | 754 | | | 755 | | // use compare_at from typed column | 756 | 554 | const auto& typed_left_col = assert_cast<const ColumnType&>(left_col); | 757 | 554 | const auto& typed_right_col = assert_cast<const ColumnType&>(right_col); | 758 | 554 | return typed_left_col.compare_at(left_idx, right_idx, typed_right_col, | 759 | 554 | /*nan_direction_hint=*/1) == 0; | 760 | 639 | } |
|
761 | | |
762 | | // whether this function supports equality comparison for the given primitive type |
763 | 1.09k | bool is_equality_comparison_supported(PrimitiveType type) const { |
764 | 1.09k | return is_string_type(type) || is_number(type) || is_date_type(type) || |
765 | 1.09k | is_time_type(type) || is_ip(type); |
766 | 1.09k | } |
767 | | }; |
768 | | |
769 | | class FunctionDeduplicateMap : public IFunction { |
770 | | public: |
771 | | static constexpr auto name = "deduplicate_map"; |
772 | 10 | 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 | 8 | void register_function_map(SimpleFunctionFactory& factory) { |
796 | 8 | factory.register_function<FunctionMap>(); |
797 | 8 | factory.register_function<FunctionMapContains<true>>(); |
798 | 8 | factory.register_function<FunctionMapContains<false>>(); |
799 | 8 | factory.register_function<FunctionMapKeysOrValues<true>>(); |
800 | 8 | factory.register_function<FunctionMapKeysOrValues<false>>(); |
801 | 8 | factory.register_function<FunctionMapEntries>(); |
802 | 8 | factory.register_function<FunctionStrToMap>(); |
803 | 8 | factory.register_function<FunctionMapContainsEntry>(); |
804 | 8 | factory.register_function<FunctionDeduplicateMap>(); |
805 | 8 | } |
806 | | |
807 | | } // namespace doris |