Coverage Report

Created: 2026-06-11 11:41

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