Coverage Report

Created: 2026-04-14 03:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/function_bitmap.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
// This file is copied from
18
// https://github.com/ClickHouse/ClickHouse/blob/master/src/Functions/FunctionBitmap.h
19
// and modified by Doris
20
21
#include <absl/strings/numbers.h>
22
#include <absl/strings/str_split.h>
23
#include <glog/logging.h>
24
#include <stdint.h>
25
#include <string.h>
26
27
#include <algorithm>
28
#include <boost/iterator/iterator_facade.hpp>
29
#include <functional>
30
#include <memory>
31
#include <ostream>
32
#include <string>
33
#include <utility>
34
#include <vector>
35
36
#include "common/compiler_util.h" // IWYU pragma: keep
37
#include "common/status.h"
38
#include "core/assert_cast.h"
39
#include "core/block/block.h"
40
#include "core/block/column_numbers.h"
41
#include "core/block/column_with_type_and_name.h"
42
#include "core/column/column.h"
43
#include "core/column/column_array.h"
44
#include "core/column/column_complex.h"
45
#include "core/column/column_const.h"
46
#include "core/column/column_nullable.h"
47
#include "core/column/column_string.h"
48
#include "core/column/column_vector.h"
49
#include "core/data_type/data_type.h"
50
#include "core/data_type/data_type_array.h"
51
#include "core/data_type/data_type_bitmap.h"
52
#include "core/data_type/data_type_nullable.h"
53
#include "core/data_type/data_type_number.h"
54
#include "core/data_type/data_type_string.h"
55
#include "core/field.h"
56
#include "core/types.h"
57
#include "core/value/bitmap_value.h"
58
#include "exec/common/stringop_substring.h"
59
#include "exec/common/util.hpp"
60
#include "exprs/aggregate/aggregate_function.h"
61
#include "exprs/function/function.h"
62
#include "exprs/function/function_always_not_nullable.h"
63
#include "exprs/function/function_bitmap_min_or_max.h"
64
#include "exprs/function/function_const.h"
65
#include "exprs/function/function_helpers.h"
66
#include "exprs/function/function_totype.h"
67
#include "exprs/function/simple_function_factory.h"
68
#include "util/hash/murmur_hash3.h"
69
#include "util/hash_util.hpp"
70
#include "util/string_parser.hpp"
71
#include "util/url_coding.h"
72
73
namespace doris {
74
class FunctionContext;
75
} // namespace doris
76
77
namespace doris {
78
79
struct BitmapEmpty {
80
    static constexpr auto name = "bitmap_empty";
81
    using ReturnColVec = ColumnBitmap;
82
4
    static DataTypePtr get_return_type() { return std::make_shared<DataTypeBitMap>(); }
83
4
    static auto init_value() { return BitmapValue {}; }
84
};
85
86
struct ToBitmap {
87
    static constexpr auto name = "to_bitmap";
88
    using ReturnType = DataTypeBitMap;
89
90
    template <typename ColumnType>
91
20
    static void vector(const ColumnType* col, MutableColumnPtr& col_res) {
92
20
        execute<ColumnType, false>(col, nullptr, col_res);
93
20
    }
Unexecuted instantiation: _ZN5doris8ToBitmap6vectorINS_9ColumnStrIjEEEEvPKT_RNS_3COWINS_7IColumnEE11mutable_ptrIS8_EE
_ZN5doris8ToBitmap6vectorINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEEvPKT_RNS_3COWINS_7IColumnEE11mutable_ptrIS9_EE
Line
Count
Source
91
20
    static void vector(const ColumnType* col, MutableColumnPtr& col_res) {
92
20
        execute<ColumnType, false>(col, nullptr, col_res);
93
20
    }
94
    template <typename ColumnType>
95
    static void vector_nullable(const ColumnType* col, const NullMap& nullmap,
96
0
                                MutableColumnPtr& col_res) {
97
0
        execute<ColumnType, true>(col, &nullmap, col_res);
98
0
    }
Unexecuted instantiation: _ZN5doris8ToBitmap15vector_nullableINS_9ColumnStrIjEEEEvPKT_RKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISF_EE
Unexecuted instantiation: _ZN5doris8ToBitmap15vector_nullableINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEEvPKT_RKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISG_EE
99
    template <typename ColumnType, bool arg_is_nullable>
100
20
    static void execute(const ColumnType* col, const NullMap* nullmap, MutableColumnPtr& col_res) {
101
20
        if constexpr (std::is_same_v<ColumnType, ColumnString>) {
102
0
            const ColumnString::Chars& data = col->get_chars();
103
0
            const ColumnString::Offsets& offsets = col->get_offsets();
104
105
0
            auto* res_column = reinterpret_cast<ColumnBitmap*>(col_res.get());
106
0
            auto& res_data = res_column->get_data();
107
0
            size_t size = offsets.size();
108
109
0
            for (size_t i = 0; i < size; ++i) {
110
0
                if (arg_is_nullable && ((*nullmap)[i])) {
111
0
                    continue;
112
0
                } else {
113
0
                    const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
114
0
                    int str_size = cast_set<int>(offsets[i] - offsets[i - 1]);
115
0
                    StringParser::ParseResult parse_result = StringParser::PARSE_SUCCESS;
116
0
                    uint64_t int_value = StringParser::string_to_unsigned_int<uint64_t>(
117
0
                            raw_str, str_size, &parse_result);
118
0
                    if (LIKELY(parse_result == StringParser::PARSE_SUCCESS)) {
119
0
                        res_data[i].add(int_value);
120
0
                    }
121
0
                }
122
0
            }
123
20
        } else if constexpr (std::is_same_v<ColumnType, ColumnInt64>) {
124
20
            auto* res_column = reinterpret_cast<ColumnBitmap*>(col_res.get());
125
20
            auto& res_data = res_column->get_data();
126
20
            size_t size = col->size();
127
128
40
            for (size_t i = 0; i < size; ++i) {
129
20
                if constexpr (arg_is_nullable) {
130
0
                    if ((*nullmap)[i]) {
131
0
                        continue;
132
0
                    }
133
0
                }
134
20
                if (auto value = col->get_data()[i]; value >= 0) {
135
20
                    res_data[i].add(value);
136
20
                }
137
20
            }
138
20
        }
139
20
    }
Unexecuted instantiation: _ZN5doris8ToBitmap7executeINS_9ColumnStrIjEELb1EEEvPKT_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISF_EE
Unexecuted instantiation: _ZN5doris8ToBitmap7executeINS_12ColumnVectorILNS_13PrimitiveTypeE6EEELb1EEEvPKT_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISG_EE
Unexecuted instantiation: _ZN5doris8ToBitmap7executeINS_9ColumnStrIjEELb0EEEvPKT_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISF_EE
_ZN5doris8ToBitmap7executeINS_12ColumnVectorILNS_13PrimitiveTypeE6EEELb0EEEvPKT_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISG_EE
Line
Count
Source
100
20
    static void execute(const ColumnType* col, const NullMap* nullmap, MutableColumnPtr& col_res) {
101
        if constexpr (std::is_same_v<ColumnType, ColumnString>) {
102
            const ColumnString::Chars& data = col->get_chars();
103
            const ColumnString::Offsets& offsets = col->get_offsets();
104
105
            auto* res_column = reinterpret_cast<ColumnBitmap*>(col_res.get());
106
            auto& res_data = res_column->get_data();
107
            size_t size = offsets.size();
108
109
            for (size_t i = 0; i < size; ++i) {
110
                if (arg_is_nullable && ((*nullmap)[i])) {
111
                    continue;
112
                } else {
113
                    const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
114
                    int str_size = cast_set<int>(offsets[i] - offsets[i - 1]);
115
                    StringParser::ParseResult parse_result = StringParser::PARSE_SUCCESS;
116
                    uint64_t int_value = StringParser::string_to_unsigned_int<uint64_t>(
117
                            raw_str, str_size, &parse_result);
118
                    if (LIKELY(parse_result == StringParser::PARSE_SUCCESS)) {
119
                        res_data[i].add(int_value);
120
                    }
121
                }
122
            }
123
20
        } else if constexpr (std::is_same_v<ColumnType, ColumnInt64>) {
124
20
            auto* res_column = reinterpret_cast<ColumnBitmap*>(col_res.get());
125
20
            auto& res_data = res_column->get_data();
126
20
            size_t size = col->size();
127
128
40
            for (size_t i = 0; i < size; ++i) {
129
                if constexpr (arg_is_nullable) {
130
                    if ((*nullmap)[i]) {
131
                        continue;
132
                    }
133
                }
134
20
                if (auto value = col->get_data()[i]; value >= 0) {
135
20
                    res_data[i].add(value);
136
20
                }
137
20
            }
138
20
        }
139
20
    }
140
};
141
142
struct ToBitmapWithCheck {
143
    static constexpr auto name = "to_bitmap_with_check";
144
    using ReturnType = DataTypeBitMap;
145
146
    template <typename ColumnType>
147
0
    static Status vector(const ColumnType* col, MutableColumnPtr& col_res) {
148
0
        return execute<ColumnType, false>(col, nullptr, col_res);
149
0
    }
Unexecuted instantiation: _ZN5doris17ToBitmapWithCheck6vectorINS_9ColumnStrIjEEEENS_6StatusEPKT_RNS_3COWINS_7IColumnEE11mutable_ptrIS9_EE
Unexecuted instantiation: _ZN5doris17ToBitmapWithCheck6vectorINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEENS_6StatusEPKT_RNS_3COWINS_7IColumnEE11mutable_ptrISA_EE
150
    template <typename ColumnType>
151
    static Status vector_nullable(const ColumnType* col, const NullMap& nullmap,
152
0
                                  MutableColumnPtr& col_res) {
153
0
        return execute<ColumnType, true>(col, &nullmap, col_res);
154
0
    }
Unexecuted instantiation: _ZN5doris17ToBitmapWithCheck15vector_nullableINS_9ColumnStrIjEEEENS_6StatusEPKT_RKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISG_EE
Unexecuted instantiation: _ZN5doris17ToBitmapWithCheck15vector_nullableINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEENS_6StatusEPKT_RKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISH_EE
155
    template <typename ColumnType, bool arg_is_nullable>
156
    static Status execute(const ColumnType* col, const NullMap* nullmap,
157
0
                          MutableColumnPtr& col_res) {
158
0
        if constexpr (std::is_same_v<ColumnType, ColumnString>) {
159
0
            const ColumnString::Chars& data = col->get_chars();
160
0
            const ColumnString::Offsets& offsets = col->get_offsets();
161
0
            auto* res_column = reinterpret_cast<ColumnBitmap*>(col_res.get());
162
0
            auto& res_data = res_column->get_data();
163
0
            size_t size = offsets.size();
164
165
0
            for (size_t i = 0; i < size; ++i) {
166
0
                if (arg_is_nullable && ((*nullmap)[i])) {
167
0
                    continue;
168
0
                } else {
169
0
                    const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
170
                    // The string lenght is less than 2G, so that cast the str size to int, not use size_t
171
0
                    int str_size = cast_set<int>(offsets[i] - offsets[i - 1]);
172
0
                    StringParser::ParseResult parse_result = StringParser::PARSE_SUCCESS;
173
0
                    uint64_t int_value = StringParser::string_to_unsigned_int<uint64_t>(
174
0
                            raw_str, str_size, &parse_result);
175
0
                    if (LIKELY(parse_result == StringParser::PARSE_SUCCESS)) {
176
0
                        res_data[i].add(int_value);
177
0
                    } else {
178
0
                        return Status::InvalidArgument(
179
0
                                "The input: {} is not valid, to_bitmap only support bigint value "
180
0
                                "from 0 to 18446744073709551615 currently, cannot create MV with "
181
0
                                "to_bitmap on column with negative values or cannot load negative "
182
0
                                "values to column with to_bitmap MV on it.",
183
0
                                std::string(raw_str, str_size));
184
0
                    }
185
0
                }
186
0
            }
187
0
        } else if constexpr (std::is_same_v<ColumnType, ColumnInt64>) {
188
0
            auto* res_column = reinterpret_cast<ColumnBitmap*>(col_res.get());
189
0
            auto& res_data = res_column->get_data();
190
0
            size_t size = col->size();
191
192
0
            for (size_t i = 0; i < size; ++i) {
193
0
                if (arg_is_nullable && ((*nullmap)[i])) {
194
0
                    continue;
195
0
                } else {
196
0
                    int64_t int_value = col->get_data()[i];
197
0
                    if (LIKELY(int_value >= 0)) {
198
0
                        res_data[i].add(int_value);
199
0
                    } else {
200
0
                        return Status::InvalidArgument(
201
0
                                "The input: {} is not valid, to_bitmap only support bigint value "
202
0
                                "from 0 to 18446744073709551615 currently, cannot create MV with "
203
0
                                "to_bitmap on column with negative values or cannot load negative "
204
0
                                "values to column with to_bitmap MV on it.",
205
0
                                int_value);
206
0
                    }
207
0
                }
208
0
            }
209
        } else {
210
            return Status::InvalidArgument("not support type");
211
        }
212
0
        return Status::OK();
213
0
    }
Unexecuted instantiation: _ZN5doris17ToBitmapWithCheck7executeINS_9ColumnStrIjEELb1EEENS_6StatusEPKT_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISG_EE
Unexecuted instantiation: _ZN5doris17ToBitmapWithCheck7executeINS_12ColumnVectorILNS_13PrimitiveTypeE6EEELb1EEENS_6StatusEPKT_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISH_EE
Unexecuted instantiation: _ZN5doris17ToBitmapWithCheck7executeINS_9ColumnStrIjEELb0EEENS_6StatusEPKT_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISG_EE
Unexecuted instantiation: _ZN5doris17ToBitmapWithCheck7executeINS_12ColumnVectorILNS_13PrimitiveTypeE6EEELb0EEENS_6StatusEPKT_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISH_EE
214
};
215
216
struct BitmapFromString {
217
    using ArgumentType = DataTypeString;
218
219
    static constexpr auto name = "bitmap_from_string";
220
221
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
222
                         std::vector<BitmapValue>& res, NullMap& null_map,
223
2
                         size_t input_rows_count) {
224
2
        res.reserve(input_rows_count);
225
2
        std::vector<uint64_t> bits;
226
2
        if (offsets.size() == 0 && input_rows_count == 1) {
227
            // For NULL constant
228
0
            res.emplace_back();
229
0
            null_map[0] = 1;
230
0
            return Status::OK();
231
0
        }
232
233
16
        auto split_and_parse = [&bits](const char* raw_str, size_t str_size) {
234
16
            bits.clear();
235
16
            auto res = absl::StrSplit(std::string_view {raw_str, str_size}, ",", absl::SkipEmpty());
236
16
            uint64_t value = 0;
237
38
            for (auto s : res) {
238
38
                if (!absl::SimpleAtoi(s, &value)) {
239
3
                    return false;
240
3
                }
241
35
                bits.push_back(value);
242
35
            }
243
13
            return true;
244
16
        };
245
246
        // split by comma
247
248
18
        for (size_t i = 0; i < input_rows_count; ++i) {
249
16
            const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
250
16
            int64_t str_size = offsets[i] - offsets[i - 1];
251
252
16
            if ((str_size > INT32_MAX) || !split_and_parse(raw_str, str_size)) {
253
3
                res.emplace_back();
254
3
                null_map[i] = 1;
255
3
                continue;
256
3
            }
257
13
            res.emplace_back(bits);
258
13
        }
259
2
        return Status::OK();
260
2
    }
261
};
262
263
struct NameBitmapFromBase64 {
264
    static constexpr auto name = "bitmap_from_base64";
265
};
266
struct BitmapFromBase64 {
267
    using ArgumentType = DataTypeString;
268
269
    static constexpr auto name = "bitmap_from_base64";
270
271
    static Status vector(const ColumnString::Chars& data, const ColumnString::Offsets& offsets,
272
                         std::vector<BitmapValue>& res, NullMap& null_map,
273
5
                         size_t input_rows_count) {
274
5
        res.reserve(input_rows_count);
275
5
        if (offsets.size() == 0 && input_rows_count == 1) {
276
            // For NULL constant
277
0
            res.emplace_back();
278
0
            null_map[0] = 1;
279
0
            return Status::OK();
280
0
        }
281
5
        std::string decode_buff;
282
5
        size_t last_decode_buff_len = 0;
283
5
        size_t curr_decode_buff_len = 0;
284
26
        for (size_t i = 0; i < input_rows_count; ++i) {
285
21
            const char* src_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
286
21
            size_t src_size = offsets[i] - offsets[i - 1];
287
21
            if (0 != src_size % 4) {
288
                // return Status::InvalidArgument(
289
                //         fmt::format("invalid base64: {}", std::string(src_str, src_size)));
290
0
                res.emplace_back();
291
0
                null_map[i] = 1;
292
0
                continue;
293
0
            }
294
21
            curr_decode_buff_len = src_size + 3;
295
21
            if (curr_decode_buff_len > last_decode_buff_len) {
296
11
                decode_buff.resize(curr_decode_buff_len);
297
11
                last_decode_buff_len = curr_decode_buff_len;
298
11
            }
299
21
            auto outlen = base64_decode(src_str, src_size, decode_buff.data());
300
21
            if (outlen < 0) {
301
0
                res.emplace_back();
302
0
                null_map[i] = 1;
303
21
            } else {
304
21
                BitmapValue bitmap_val;
305
21
                if (!bitmap_val.deserialize(decode_buff.data())) {
306
0
                    return Status::RuntimeError("bitmap_from_base64 decode failed: base64: {}",
307
0
                                                std::string(src_str, src_size));
308
0
                }
309
21
                res.emplace_back(std::move(bitmap_val));
310
21
            }
311
21
        }
312
5
        return Status::OK();
313
5
    }
314
};
315
struct BitmapFromArray {
316
    using ArgumentType = DataTypeArray;
317
    static constexpr auto name = "bitmap_from_array";
318
319
    template <typename ColumnType>
320
    static Status vector(const ColumnArray::Offsets64& offset_column_data,
321
                         const IColumn& nested_column, const NullMap& nested_null_map,
322
6
                         std::vector<BitmapValue>& res, NullMap& null_map) {
323
6
        const auto& nested_column_data = static_cast<const ColumnType&>(nested_column).get_data();
324
6
        auto size = offset_column_data.size();
325
6
        res.reserve(size);
326
6
        std::vector<uint64_t> bits;
327
12
        for (size_t i = 0; i < size; ++i) {
328
6
            auto curr_offset = offset_column_data[i];
329
6
            auto prev_offset = offset_column_data[i - 1];
330
42
            for (auto j = prev_offset; j < curr_offset; ++j) {
331
36
                auto data = nested_column_data[j];
332
                // invaild value
333
36
                if (UNLIKELY(data < 0) || UNLIKELY(nested_null_map[j])) {
334
0
                    res.emplace_back();
335
0
                    null_map[i] = 1;
336
0
                    break;
337
36
                } else {
338
36
                    bits.push_back(data);
339
36
                }
340
36
            }
341
            //input is valid value
342
6
            if (!null_map[i]) {
343
6
                res.emplace_back(bits);
344
6
            }
345
6
            bits.clear();
346
6
        }
347
6
        return Status::OK();
348
6
    }
Unexecuted instantiation: _ZN5doris15BitmapFromArray6vectorINS_12ColumnVectorILNS_13PrimitiveTypeE3EEEEENS_6StatusERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS_7IColumnERKNS6_IhLm4096ES9_Lm16ELm15EEERSt6vectorINS_11BitmapValueESaISK_EERSG_
Unexecuted instantiation: _ZN5doris15BitmapFromArray6vectorINS_12ColumnVectorILNS_13PrimitiveTypeE2EEEEENS_6StatusERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS_7IColumnERKNS6_IhLm4096ES9_Lm16ELm15EEERSt6vectorINS_11BitmapValueESaISK_EERSG_
Unexecuted instantiation: _ZN5doris15BitmapFromArray6vectorINS_12ColumnVectorILNS_13PrimitiveTypeE4EEEEENS_6StatusERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS_7IColumnERKNS6_IhLm4096ES9_Lm16ELm15EEERSt6vectorINS_11BitmapValueESaISK_EERSG_
_ZN5doris15BitmapFromArray6vectorINS_12ColumnVectorILNS_13PrimitiveTypeE5EEEEENS_6StatusERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS_7IColumnERKNS6_IhLm4096ES9_Lm16ELm15EEERSt6vectorINS_11BitmapValueESaISK_EERSG_
Line
Count
Source
322
6
                         std::vector<BitmapValue>& res, NullMap& null_map) {
323
6
        const auto& nested_column_data = static_cast<const ColumnType&>(nested_column).get_data();
324
6
        auto size = offset_column_data.size();
325
6
        res.reserve(size);
326
6
        std::vector<uint64_t> bits;
327
12
        for (size_t i = 0; i < size; ++i) {
328
6
            auto curr_offset = offset_column_data[i];
329
6
            auto prev_offset = offset_column_data[i - 1];
330
42
            for (auto j = prev_offset; j < curr_offset; ++j) {
331
36
                auto data = nested_column_data[j];
332
                // invaild value
333
36
                if (UNLIKELY(data < 0) || UNLIKELY(nested_null_map[j])) {
334
0
                    res.emplace_back();
335
0
                    null_map[i] = 1;
336
0
                    break;
337
36
                } else {
338
36
                    bits.push_back(data);
339
36
                }
340
36
            }
341
            //input is valid value
342
6
            if (!null_map[i]) {
343
6
                res.emplace_back(bits);
344
6
            }
345
6
            bits.clear();
346
6
        }
347
6
        return Status::OK();
348
6
    }
Unexecuted instantiation: _ZN5doris15BitmapFromArray6vectorINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEENS_6StatusERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS_7IColumnERKNS6_IhLm4096ES9_Lm16ELm15EEERSt6vectorINS_11BitmapValueESaISK_EERSG_
349
};
350
351
template <typename Impl>
352
class FunctionBitmapAlwaysNull : public IFunction {
353
public:
354
    static constexpr auto name = Impl::name;
355
356
3
    String get_name() const override { return name; }
_ZNK5doris24FunctionBitmapAlwaysNullINS_16BitmapFromStringEE8get_nameB5cxx11Ev
Line
Count
Source
356
1
    String get_name() const override { return name; }
_ZNK5doris24FunctionBitmapAlwaysNullINS_16BitmapFromBase64EE8get_nameB5cxx11Ev
Line
Count
Source
356
1
    String get_name() const override { return name; }
_ZNK5doris24FunctionBitmapAlwaysNullINS_15BitmapFromArrayEE8get_nameB5cxx11Ev
Line
Count
Source
356
1
    String get_name() const override { return name; }
357
358
37
    static FunctionPtr create() { return std::make_shared<FunctionBitmapAlwaysNull>(); }
_ZN5doris24FunctionBitmapAlwaysNullINS_16BitmapFromStringEE6createEv
Line
Count
Source
358
10
    static FunctionPtr create() { return std::make_shared<FunctionBitmapAlwaysNull>(); }
_ZN5doris24FunctionBitmapAlwaysNullINS_16BitmapFromBase64EE6createEv
Line
Count
Source
358
13
    static FunctionPtr create() { return std::make_shared<FunctionBitmapAlwaysNull>(); }
_ZN5doris24FunctionBitmapAlwaysNullINS_15BitmapFromArrayEE6createEv
Line
Count
Source
358
14
    static FunctionPtr create() { return std::make_shared<FunctionBitmapAlwaysNull>(); }
359
360
13
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
361
13
        return make_nullable(std::make_shared<DataTypeBitMap>());
362
13
    }
_ZNK5doris24FunctionBitmapAlwaysNullINS_16BitmapFromStringEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
360
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
361
2
        return make_nullable(std::make_shared<DataTypeBitMap>());
362
2
    }
_ZNK5doris24FunctionBitmapAlwaysNullINS_16BitmapFromBase64EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
360
5
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
361
5
        return make_nullable(std::make_shared<DataTypeBitMap>());
362
5
    }
_ZNK5doris24FunctionBitmapAlwaysNullINS_15BitmapFromArrayEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
360
6
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
361
6
        return make_nullable(std::make_shared<DataTypeBitMap>());
362
6
    }
363
364
13
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris24FunctionBitmapAlwaysNullINS_16BitmapFromStringEE23get_number_of_argumentsEv
Line
Count
Source
364
2
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris24FunctionBitmapAlwaysNullINS_16BitmapFromBase64EE23get_number_of_argumentsEv
Line
Count
Source
364
5
    size_t get_number_of_arguments() const override { return 1; }
_ZNK5doris24FunctionBitmapAlwaysNullINS_15BitmapFromArrayEE23get_number_of_argumentsEv
Line
Count
Source
364
6
    size_t get_number_of_arguments() const override { return 1; }
365
366
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
367
13
                        uint32_t result, size_t input_rows_count) const override {
368
13
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
369
13
        auto res_data_column = ColumnBitmap::create();
370
13
        auto& null_map = res_null_map->get_data();
371
13
        auto& res = res_data_column->get_data();
372
373
13
        ColumnPtr& argument_column = block.get_by_position(arguments[0]).column;
374
13
        if constexpr (std::is_same_v<typename Impl::ArgumentType, DataTypeString>) {
375
7
            const auto& str_column = static_cast<const ColumnString&>(*argument_column);
376
7
            const ColumnString::Chars& data = str_column.get_chars();
377
7
            const ColumnString::Offsets& offsets = str_column.get_offsets();
378
7
            RETURN_IF_ERROR(Impl::vector(data, offsets, res, null_map, input_rows_count));
379
7
        } else if constexpr (std::is_same_v<typename Impl::ArgumentType, DataTypeArray>) {
380
6
            auto argument_type = remove_nullable(
381
6
                    assert_cast<const DataTypeArray&>(*block.get_by_position(arguments[0]).type)
382
6
                            .get_nested_type());
383
6
            const auto& array_column = static_cast<const ColumnArray&>(*argument_column);
384
6
            const auto& offset_column_data = array_column.get_offsets();
385
6
            const auto& nested_nullable_column =
386
6
                    static_cast<const ColumnNullable&>(array_column.get_data());
387
6
            const auto& nested_column = nested_nullable_column.get_nested_column();
388
6
            const auto& nested_null_map = nested_nullable_column.get_null_map_column().get_data();
389
390
6
            switch (argument_type->get_primitive_type()) {
391
0
            case PrimitiveType::TYPE_TINYINT:
392
0
                RETURN_IF_ERROR(Impl::template vector<ColumnInt8>(offset_column_data, nested_column,
393
0
                                                                  nested_null_map, res, null_map));
394
0
                break;
395
0
            case PrimitiveType::TYPE_BOOLEAN:
396
0
                RETURN_IF_ERROR(Impl::template vector<ColumnUInt8>(
397
0
                        offset_column_data, nested_column, nested_null_map, res, null_map));
398
0
                break;
399
0
            case PrimitiveType::TYPE_SMALLINT:
400
0
                RETURN_IF_ERROR(Impl::template vector<ColumnInt16>(
401
0
                        offset_column_data, nested_column, nested_null_map, res, null_map));
402
0
                break;
403
6
            case PrimitiveType::TYPE_INT:
404
6
                RETURN_IF_ERROR(Impl::template vector<ColumnInt32>(
405
6
                        offset_column_data, nested_column, nested_null_map, res, null_map));
406
6
                break;
407
6
            case PrimitiveType::TYPE_BIGINT:
408
0
                RETURN_IF_ERROR(Impl::template vector<ColumnInt64>(
409
0
                        offset_column_data, nested_column, nested_null_map, res, null_map));
410
0
                break;
411
0
            default:
412
0
                return Status::RuntimeError("Illegal column {} of argument of function {}",
413
0
                                            block.get_by_position(arguments[0]).column->get_name(),
414
0
                                            get_name());
415
6
            }
416
        } else {
417
            return Status::RuntimeError("Illegal column {} of argument of function {}",
418
                                        block.get_by_position(arguments[0]).column->get_name(),
419
                                        get_name());
420
        }
421
13
        block.get_by_position(result).column =
422
13
                ColumnNullable::create(std::move(res_data_column), std::move(res_null_map));
423
13
        return Status::OK();
424
13
    }
_ZNK5doris24FunctionBitmapAlwaysNullINS_16BitmapFromStringEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
367
2
                        uint32_t result, size_t input_rows_count) const override {
368
2
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
369
2
        auto res_data_column = ColumnBitmap::create();
370
2
        auto& null_map = res_null_map->get_data();
371
2
        auto& res = res_data_column->get_data();
372
373
2
        ColumnPtr& argument_column = block.get_by_position(arguments[0]).column;
374
2
        if constexpr (std::is_same_v<typename Impl::ArgumentType, DataTypeString>) {
375
2
            const auto& str_column = static_cast<const ColumnString&>(*argument_column);
376
2
            const ColumnString::Chars& data = str_column.get_chars();
377
2
            const ColumnString::Offsets& offsets = str_column.get_offsets();
378
2
            RETURN_IF_ERROR(Impl::vector(data, offsets, res, null_map, input_rows_count));
379
        } else if constexpr (std::is_same_v<typename Impl::ArgumentType, DataTypeArray>) {
380
            auto argument_type = remove_nullable(
381
                    assert_cast<const DataTypeArray&>(*block.get_by_position(arguments[0]).type)
382
                            .get_nested_type());
383
            const auto& array_column = static_cast<const ColumnArray&>(*argument_column);
384
            const auto& offset_column_data = array_column.get_offsets();
385
            const auto& nested_nullable_column =
386
                    static_cast<const ColumnNullable&>(array_column.get_data());
387
            const auto& nested_column = nested_nullable_column.get_nested_column();
388
            const auto& nested_null_map = nested_nullable_column.get_null_map_column().get_data();
389
390
            switch (argument_type->get_primitive_type()) {
391
            case PrimitiveType::TYPE_TINYINT:
392
                RETURN_IF_ERROR(Impl::template vector<ColumnInt8>(offset_column_data, nested_column,
393
                                                                  nested_null_map, res, null_map));
394
                break;
395
            case PrimitiveType::TYPE_BOOLEAN:
396
                RETURN_IF_ERROR(Impl::template vector<ColumnUInt8>(
397
                        offset_column_data, nested_column, nested_null_map, res, null_map));
398
                break;
399
            case PrimitiveType::TYPE_SMALLINT:
400
                RETURN_IF_ERROR(Impl::template vector<ColumnInt16>(
401
                        offset_column_data, nested_column, nested_null_map, res, null_map));
402
                break;
403
            case PrimitiveType::TYPE_INT:
404
                RETURN_IF_ERROR(Impl::template vector<ColumnInt32>(
405
                        offset_column_data, nested_column, nested_null_map, res, null_map));
406
                break;
407
            case PrimitiveType::TYPE_BIGINT:
408
                RETURN_IF_ERROR(Impl::template vector<ColumnInt64>(
409
                        offset_column_data, nested_column, nested_null_map, res, null_map));
410
                break;
411
            default:
412
                return Status::RuntimeError("Illegal column {} of argument of function {}",
413
                                            block.get_by_position(arguments[0]).column->get_name(),
414
                                            get_name());
415
            }
416
        } else {
417
            return Status::RuntimeError("Illegal column {} of argument of function {}",
418
                                        block.get_by_position(arguments[0]).column->get_name(),
419
                                        get_name());
420
        }
421
2
        block.get_by_position(result).column =
422
2
                ColumnNullable::create(std::move(res_data_column), std::move(res_null_map));
423
2
        return Status::OK();
424
2
    }
_ZNK5doris24FunctionBitmapAlwaysNullINS_16BitmapFromBase64EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
367
5
                        uint32_t result, size_t input_rows_count) const override {
368
5
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
369
5
        auto res_data_column = ColumnBitmap::create();
370
5
        auto& null_map = res_null_map->get_data();
371
5
        auto& res = res_data_column->get_data();
372
373
5
        ColumnPtr& argument_column = block.get_by_position(arguments[0]).column;
374
5
        if constexpr (std::is_same_v<typename Impl::ArgumentType, DataTypeString>) {
375
5
            const auto& str_column = static_cast<const ColumnString&>(*argument_column);
376
5
            const ColumnString::Chars& data = str_column.get_chars();
377
5
            const ColumnString::Offsets& offsets = str_column.get_offsets();
378
5
            RETURN_IF_ERROR(Impl::vector(data, offsets, res, null_map, input_rows_count));
379
        } else if constexpr (std::is_same_v<typename Impl::ArgumentType, DataTypeArray>) {
380
            auto argument_type = remove_nullable(
381
                    assert_cast<const DataTypeArray&>(*block.get_by_position(arguments[0]).type)
382
                            .get_nested_type());
383
            const auto& array_column = static_cast<const ColumnArray&>(*argument_column);
384
            const auto& offset_column_data = array_column.get_offsets();
385
            const auto& nested_nullable_column =
386
                    static_cast<const ColumnNullable&>(array_column.get_data());
387
            const auto& nested_column = nested_nullable_column.get_nested_column();
388
            const auto& nested_null_map = nested_nullable_column.get_null_map_column().get_data();
389
390
            switch (argument_type->get_primitive_type()) {
391
            case PrimitiveType::TYPE_TINYINT:
392
                RETURN_IF_ERROR(Impl::template vector<ColumnInt8>(offset_column_data, nested_column,
393
                                                                  nested_null_map, res, null_map));
394
                break;
395
            case PrimitiveType::TYPE_BOOLEAN:
396
                RETURN_IF_ERROR(Impl::template vector<ColumnUInt8>(
397
                        offset_column_data, nested_column, nested_null_map, res, null_map));
398
                break;
399
            case PrimitiveType::TYPE_SMALLINT:
400
                RETURN_IF_ERROR(Impl::template vector<ColumnInt16>(
401
                        offset_column_data, nested_column, nested_null_map, res, null_map));
402
                break;
403
            case PrimitiveType::TYPE_INT:
404
                RETURN_IF_ERROR(Impl::template vector<ColumnInt32>(
405
                        offset_column_data, nested_column, nested_null_map, res, null_map));
406
                break;
407
            case PrimitiveType::TYPE_BIGINT:
408
                RETURN_IF_ERROR(Impl::template vector<ColumnInt64>(
409
                        offset_column_data, nested_column, nested_null_map, res, null_map));
410
                break;
411
            default:
412
                return Status::RuntimeError("Illegal column {} of argument of function {}",
413
                                            block.get_by_position(arguments[0]).column->get_name(),
414
                                            get_name());
415
            }
416
        } else {
417
            return Status::RuntimeError("Illegal column {} of argument of function {}",
418
                                        block.get_by_position(arguments[0]).column->get_name(),
419
                                        get_name());
420
        }
421
5
        block.get_by_position(result).column =
422
5
                ColumnNullable::create(std::move(res_data_column), std::move(res_null_map));
423
5
        return Status::OK();
424
5
    }
_ZNK5doris24FunctionBitmapAlwaysNullINS_15BitmapFromArrayEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
367
6
                        uint32_t result, size_t input_rows_count) const override {
368
6
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
369
6
        auto res_data_column = ColumnBitmap::create();
370
6
        auto& null_map = res_null_map->get_data();
371
6
        auto& res = res_data_column->get_data();
372
373
6
        ColumnPtr& argument_column = block.get_by_position(arguments[0]).column;
374
        if constexpr (std::is_same_v<typename Impl::ArgumentType, DataTypeString>) {
375
            const auto& str_column = static_cast<const ColumnString&>(*argument_column);
376
            const ColumnString::Chars& data = str_column.get_chars();
377
            const ColumnString::Offsets& offsets = str_column.get_offsets();
378
            RETURN_IF_ERROR(Impl::vector(data, offsets, res, null_map, input_rows_count));
379
6
        } else if constexpr (std::is_same_v<typename Impl::ArgumentType, DataTypeArray>) {
380
6
            auto argument_type = remove_nullable(
381
6
                    assert_cast<const DataTypeArray&>(*block.get_by_position(arguments[0]).type)
382
6
                            .get_nested_type());
383
6
            const auto& array_column = static_cast<const ColumnArray&>(*argument_column);
384
6
            const auto& offset_column_data = array_column.get_offsets();
385
6
            const auto& nested_nullable_column =
386
6
                    static_cast<const ColumnNullable&>(array_column.get_data());
387
6
            const auto& nested_column = nested_nullable_column.get_nested_column();
388
6
            const auto& nested_null_map = nested_nullable_column.get_null_map_column().get_data();
389
390
6
            switch (argument_type->get_primitive_type()) {
391
0
            case PrimitiveType::TYPE_TINYINT:
392
0
                RETURN_IF_ERROR(Impl::template vector<ColumnInt8>(offset_column_data, nested_column,
393
0
                                                                  nested_null_map, res, null_map));
394
0
                break;
395
0
            case PrimitiveType::TYPE_BOOLEAN:
396
0
                RETURN_IF_ERROR(Impl::template vector<ColumnUInt8>(
397
0
                        offset_column_data, nested_column, nested_null_map, res, null_map));
398
0
                break;
399
0
            case PrimitiveType::TYPE_SMALLINT:
400
0
                RETURN_IF_ERROR(Impl::template vector<ColumnInt16>(
401
0
                        offset_column_data, nested_column, nested_null_map, res, null_map));
402
0
                break;
403
6
            case PrimitiveType::TYPE_INT:
404
6
                RETURN_IF_ERROR(Impl::template vector<ColumnInt32>(
405
6
                        offset_column_data, nested_column, nested_null_map, res, null_map));
406
6
                break;
407
6
            case PrimitiveType::TYPE_BIGINT:
408
0
                RETURN_IF_ERROR(Impl::template vector<ColumnInt64>(
409
0
                        offset_column_data, nested_column, nested_null_map, res, null_map));
410
0
                break;
411
0
            default:
412
0
                return Status::RuntimeError("Illegal column {} of argument of function {}",
413
0
                                            block.get_by_position(arguments[0]).column->get_name(),
414
0
                                            get_name());
415
6
            }
416
        } else {
417
            return Status::RuntimeError("Illegal column {} of argument of function {}",
418
                                        block.get_by_position(arguments[0]).column->get_name(),
419
                                        get_name());
420
        }
421
6
        block.get_by_position(result).column =
422
6
                ColumnNullable::create(std::move(res_data_column), std::move(res_null_map));
423
6
        return Status::OK();
424
6
    }
425
};
426
427
template <int HashBits>
428
struct BitmapHashName {};
429
430
template <>
431
struct BitmapHashName<32> {
432
    static constexpr auto name = "bitmap_hash";
433
};
434
435
template <>
436
struct BitmapHashName<64> {
437
    static constexpr auto name = "bitmap_hash64";
438
};
439
440
template <int HashBits>
441
struct BitmapHash {
442
    static constexpr auto name = BitmapHashName<HashBits>::name;
443
444
    using ReturnType = DataTypeBitMap;
445
446
    template <typename ColumnType>
447
0
    static void vector(const ColumnType* col, MutableColumnPtr& col_res) {
448
0
        if constexpr (std::is_same_v<ColumnType, ColumnString>) {
449
0
            const ColumnString::Chars& data = col->get_chars();
450
0
            const ColumnString::Offsets& offsets = col->get_offsets();
451
0
            auto* res_column = reinterpret_cast<ColumnBitmap*>(col_res.get());
452
0
            auto& res_data = res_column->get_data();
453
0
            size_t size = offsets.size();
454
455
0
            for (size_t i = 0; i < size; ++i) {
456
0
                const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
457
0
                size_t str_size = offsets[i] - offsets[i - 1];
458
0
                if constexpr (HashBits == 32) {
459
0
                    uint32_t hash_value =
460
0
                            HashUtil::murmur_hash3_32(raw_str, str_size, HashUtil::MURMUR3_32_SEED);
461
0
                    res_data[i].add(hash_value);
462
0
                } else {
463
0
                    uint64_t hash_value = 0;
464
0
                    murmur_hash3_x64_64(raw_str, str_size, 0, &hash_value);
465
0
                    res_data[i].add(hash_value);
466
0
                }
467
0
            }
468
0
        }
469
0
    }
Unexecuted instantiation: _ZN5doris10BitmapHashILi32EE6vectorINS_9ColumnStrIjEEEEvPKT_RNS_3COWINS_7IColumnEE11mutable_ptrIS9_EE
Unexecuted instantiation: _ZN5doris10BitmapHashILi32EE6vectorINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEEvPKT_RNS_3COWINS_7IColumnEE11mutable_ptrISA_EE
Unexecuted instantiation: _ZN5doris10BitmapHashILi64EE6vectorINS_9ColumnStrIjEEEEvPKT_RNS_3COWINS_7IColumnEE11mutable_ptrIS9_EE
Unexecuted instantiation: _ZN5doris10BitmapHashILi64EE6vectorINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEEvPKT_RNS_3COWINS_7IColumnEE11mutable_ptrISA_EE
470
471
    template <typename ColumnType>
472
    static void vector_nullable(const ColumnType* col, const NullMap& nullmap,
473
0
                                MutableColumnPtr& col_res) {
474
0
        if constexpr (std::is_same_v<ColumnType, ColumnString>) {
475
0
            const ColumnString::Chars& data = col->get_chars();
476
0
            const ColumnString::Offsets& offsets = col->get_offsets();
477
0
            auto* res_column = reinterpret_cast<ColumnBitmap*>(col_res.get());
478
0
            auto& res_data = res_column->get_data();
479
0
            size_t size = offsets.size();
480
481
0
            for (size_t i = 0; i < size; ++i) {
482
0
                if (nullmap[i]) {
483
0
                    continue;
484
0
                } else {
485
0
                    const char* raw_str = reinterpret_cast<const char*>(&data[offsets[i - 1]]);
486
0
                    size_t str_size = offsets[i] - offsets[i - 1];
487
0
                    if constexpr (HashBits == 32) {
488
0
                        uint32_t hash_value = HashUtil::murmur_hash3_32(raw_str, str_size,
489
0
                                                                        HashUtil::MURMUR3_32_SEED);
490
0
                        res_data[i].add(hash_value);
491
0
                    } else {
492
0
                        uint64_t hash_value = 0;
493
0
                        murmur_hash3_x64_64(raw_str, str_size, 0, &hash_value);
494
0
                        res_data[i].add(hash_value);
495
0
                    }
496
0
                }
497
0
            }
498
0
        }
499
0
    }
Unexecuted instantiation: _ZN5doris10BitmapHashILi32EE15vector_nullableINS_9ColumnStrIjEEEEvPKT_RKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISG_EE
Unexecuted instantiation: _ZN5doris10BitmapHashILi32EE15vector_nullableINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEEvPKT_RKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISH_EE
Unexecuted instantiation: _ZN5doris10BitmapHashILi64EE15vector_nullableINS_9ColumnStrIjEEEEvPKT_RKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISG_EE
Unexecuted instantiation: _ZN5doris10BitmapHashILi64EE15vector_nullableINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEEvPKT_RKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISH_EE
500
};
501
502
class FunctionBitmapCount : public IFunction {
503
public:
504
    static constexpr auto name = "bitmap_count";
505
506
1
    String get_name() const override { return name; }
507
508
8
    static FunctionPtr create() { return std::make_shared<FunctionBitmapCount>(); }
509
510
0
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
511
0
        return std::make_shared<DataTypeInt64>();
512
0
    }
513
514
0
    size_t get_number_of_arguments() const override { return 1; }
515
516
0
    bool use_default_implementation_for_nulls() const override { return false; }
517
518
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
519
0
                        uint32_t result, size_t input_rows_count) const override {
520
0
        auto res_data_column = ColumnInt64::create();
521
0
        auto& res = res_data_column->get_data();
522
0
        auto data_null_map = ColumnUInt8::create(input_rows_count, 0);
523
0
        auto& null_map = data_null_map->get_data();
524
525
0
        auto column = block.get_by_position(arguments[0]).column;
526
0
        if (auto* nullable = check_and_get_column<const ColumnNullable>(*column)) {
527
0
            VectorizedUtils::update_null_map(null_map, nullable->get_null_map_data());
528
0
            column = nullable->get_nested_column_ptr();
529
0
        }
530
0
        auto str_col = assert_cast<const ColumnBitmap*>(column.get());
531
0
        const auto& col_data = str_col->get_data();
532
533
0
        res.reserve(input_rows_count);
534
0
        for (size_t i = 0; i < input_rows_count; ++i) {
535
0
            if (null_map[i]) {
536
0
                res.push_back(0);
537
0
                continue;
538
0
            }
539
0
            res.push_back(col_data[i].cardinality());
540
0
        }
541
0
        block.replace_by_position(result, std::move(res_data_column));
542
0
        return Status::OK();
543
0
    }
544
};
545
546
struct NameBitmapNot {
547
    static constexpr auto name = "bitmap_not";
548
};
549
550
template <typename LeftDataType, typename RightDataType>
551
struct BitmapNot {
552
    using ResultDataType = DataTypeBitMap;
553
    using T0 = typename LeftDataType::FieldType;
554
    using T1 = typename RightDataType::FieldType;
555
    using TData = std::vector<BitmapValue>;
556
557
0
    static void vector_vector(const TData& lvec, const TData& rvec, TData& res) {
558
0
        size_t size = lvec.size();
559
0
        for (size_t i = 0; i < size; ++i) {
560
0
            res[i] = lvec[i];
561
0
            res[i] -= rvec[i];
562
0
        }
563
0
    }
564
0
    static void vector_scalar(const TData& lvec, const BitmapValue& rval, TData& res) {
565
0
        size_t size = lvec.size();
566
0
        for (size_t i = 0; i < size; ++i) {
567
0
            res[i] = lvec[i];
568
0
            res[i] -= rval;
569
0
        }
570
0
    }
571
0
    static void scalar_vector(const BitmapValue& lval, const TData& rvec, TData& res) {
572
0
        size_t size = rvec.size();
573
0
        for (size_t i = 0; i < size; ++i) {
574
0
            res[i] = lval;
575
0
            res[i] -= rvec[i];
576
0
        }
577
0
    }
578
};
579
580
struct NameBitmapAndNot {
581
    static constexpr auto name = "bitmap_and_not";
582
};
583
584
template <typename LeftDataType, typename RightDataType>
585
struct BitmapAndNot {
586
    using ResultDataType = DataTypeBitMap;
587
    using T0 = typename LeftDataType::FieldType;
588
    using T1 = typename RightDataType::FieldType;
589
    using TData = std::vector<BitmapValue>;
590
591
0
    static void vector_vector(const TData& lvec, const TData& rvec, TData& res) {
592
0
        size_t size = lvec.size();
593
0
        BitmapValue mid_data;
594
0
        for (size_t i = 0; i < size; ++i) {
595
0
            mid_data = lvec[i];
596
0
            mid_data &= rvec[i];
597
0
            res[i] = lvec[i];
598
0
            res[i] -= mid_data;
599
0
            mid_data.reset();
600
0
        }
601
0
    }
602
0
    static void vector_scalar(const TData& lvec, const BitmapValue& rval, TData& res) {
603
0
        size_t size = lvec.size();
604
0
        BitmapValue mid_data;
605
0
        for (size_t i = 0; i < size; ++i) {
606
0
            mid_data = lvec[i];
607
0
            mid_data &= rval;
608
0
            res[i] = lvec[i];
609
0
            res[i] -= mid_data;
610
0
            mid_data.reset();
611
0
        }
612
0
    }
613
0
    static void scalar_vector(const BitmapValue& lval, const TData& rvec, TData& res) {
614
0
        size_t size = rvec.size();
615
0
        BitmapValue mid_data;
616
0
        for (size_t i = 0; i < size; ++i) {
617
0
            mid_data = lval;
618
0
            mid_data &= rvec[i];
619
0
            res[i] = lval;
620
0
            res[i] -= mid_data;
621
0
            mid_data.reset();
622
0
        }
623
0
    }
624
};
625
626
struct NameBitmapAndNotCount {
627
    static constexpr auto name = "bitmap_and_not_count";
628
};
629
630
template <typename LeftDataType, typename RightDataType>
631
struct BitmapAndNotCount {
632
    using ResultDataType = DataTypeInt64;
633
    using T0 = typename LeftDataType::FieldType;
634
    using T1 = typename RightDataType::FieldType;
635
    using TData = std::vector<BitmapValue>;
636
    using ResTData = typename ColumnInt64::Container::value_type;
637
638
2
    static void vector_vector(const TData& lvec, const TData& rvec, ResTData* res) {
639
2
        size_t size = lvec.size();
640
2
        BitmapValue mid_data;
641
10
        for (size_t i = 0; i < size; ++i) {
642
8
            mid_data = lvec[i];
643
8
            mid_data &= rvec[i];
644
8
            res[i] = lvec[i].andnot_cardinality(mid_data);
645
8
            mid_data.reset();
646
8
        }
647
2
    }
648
0
    static void scalar_vector(const BitmapValue& lval, const TData& rvec, ResTData* res) {
649
0
        size_t size = rvec.size();
650
0
        BitmapValue mid_data;
651
0
        for (size_t i = 0; i < size; ++i) {
652
0
            mid_data = lval;
653
0
            mid_data &= rvec[i];
654
0
            res[i] = lval.andnot_cardinality(mid_data);
655
0
            mid_data.reset();
656
0
        }
657
0
    }
658
0
    static void vector_scalar(const TData& lvec, const BitmapValue& rval, ResTData* res) {
659
0
        size_t size = lvec.size();
660
0
        BitmapValue mid_data;
661
0
        for (size_t i = 0; i < size; ++i) {
662
0
            mid_data = lvec[i];
663
0
            mid_data &= rval;
664
0
            res[i] = lvec[i].andnot_cardinality(mid_data);
665
0
            mid_data.reset();
666
0
        }
667
0
    }
668
};
669
670
14
void update_bitmap_op_count(int64_t* __restrict count, const NullMap& null_map) {
671
14
    static constexpr int64_t flags[2] = {-1, 0};
672
14
    size_t size = null_map.size();
673
14
    auto* __restrict null_map_data = null_map.data();
674
66
    for (size_t i = 0; i < size; ++i) {
675
52
        count[i] &= flags[null_map_data[i]];
676
52
    }
677
14
}
678
679
// for bitmap_and_count, bitmap_xor_count and bitmap_and_not_count,
680
// result is 0 for rows that if any column is null value
681
ColumnPtr handle_bitmap_op_count_null_value(ColumnPtr& src, const Block& block,
682
                                            const ColumnNumbers& args, uint32_t result,
683
6
                                            size_t input_rows_count) {
684
6
    auto* nullable = assert_cast<const ColumnNullable*>(src.get());
685
6
    ColumnPtr src_not_nullable = nullable->get_nested_column_ptr();
686
6
    MutableColumnPtr src_not_nullable_mutable = (*std::move(src_not_nullable)).assume_mutable();
687
6
    auto* __restrict count_data =
688
6
            assert_cast<ColumnInt64*>(src_not_nullable_mutable.get())->get_data().data();
689
690
14
    for (const auto& arg : args) {
691
14
        const ColumnWithTypeAndName& elem = block.get_by_position(arg);
692
14
        if (!elem.type->is_nullable()) {
693
0
            continue;
694
0
        }
695
696
14
        bool is_const = is_column_const(*elem.column);
697
        /// Const Nullable that are NULL.
698
14
        if (is_const && assert_cast<const ColumnConst*>(elem.column.get())->only_null()) {
699
0
            return block.get_by_position(result).type->create_column_const(
700
0
                    input_rows_count, Field::create_field<TYPE_BIGINT>(0));
701
0
        }
702
14
        if (is_const) {
703
0
            continue;
704
0
        }
705
706
14
        if (const auto* nullable_column = assert_cast<const ColumnNullable*>(elem.column.get())) {
707
14
            const ColumnPtr& null_map_column = nullable_column->get_null_map_column_ptr();
708
14
            const NullMap& src_null_map =
709
14
                    assert_cast<const ColumnUInt8&>(*null_map_column).get_data();
710
711
14
            update_bitmap_op_count(count_data, src_null_map);
712
14
        }
713
14
    }
714
715
6
    return src;
716
6
}
717
718
Status execute_bitmap_op_count_null_to_zero(
719
        FunctionContext* context, Block& block, const ColumnNumbers& arguments, uint32_t result,
720
        size_t input_rows_count,
721
        const std::function<Status(FunctionContext*, Block&, const ColumnNumbers&, size_t, size_t)>&
722
6
                exec_impl_func) {
723
6
    if (have_null_column(block, arguments)) {
724
6
        auto [temporary_block, new_args, new_result] =
725
6
                create_block_with_nested_columns(block, arguments, result);
726
6
        RETURN_IF_ERROR(exec_impl_func(context, temporary_block, new_args, new_result,
727
6
                                       temporary_block.rows()));
728
6
        block.get_by_position(result).column = handle_bitmap_op_count_null_value(
729
6
                temporary_block.get_by_position(new_result).column, block, arguments, result,
730
6
                input_rows_count);
731
6
    } else {
732
0
        return exec_impl_func(context, block, arguments, result, input_rows_count);
733
0
    }
734
6
    return Status::OK();
735
6
}
736
737
template <typename FunctionName>
738
class FunctionBitmapAndNotCount : public IFunction {
739
public:
740
    using LeftDataType = DataTypeBitMap;
741
    using RightDataType = DataTypeBitMap;
742
    using ResultDataType = typename BitmapAndNotCount<LeftDataType, RightDataType>::ResultDataType;
743
744
    static constexpr auto name = FunctionName::name;
745
10
    static FunctionPtr create() { return std::make_shared<FunctionBitmapAndNotCount>(); }
746
1
    String get_name() const override { return name; }
747
2
    size_t get_number_of_arguments() const override { return 2; }
748
2
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
749
2
        bool return_nullable = false;
750
        // result is nullable only when any columns is nullable for bitmap_and_not_count
751
2
        for (size_t i = 0; i < arguments.size(); ++i) {
752
2
            if (arguments[i]->is_nullable()) {
753
2
                return_nullable = true;
754
2
                break;
755
2
            }
756
2
        }
757
2
        auto result_type = std::make_shared<ResultDataType>();
758
2
        return return_nullable ? make_nullable(result_type) : result_type;
759
2
    }
760
761
4
    bool use_default_implementation_for_nulls() const override {
762
        // for bitmap_and_not_count, result is always not null, and if the bitmap op result is null,
763
        // the count is 0
764
4
        return false;
765
4
    }
766
767
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
768
2
                        uint32_t result, size_t input_rows_count) const override {
769
2
        DCHECK_EQ(arguments.size(), 2);
770
2
        auto impl_func = [&](FunctionContext* context, Block& block, const ColumnNumbers& arguments,
771
2
                             uint32_t result, size_t input_rows_count) {
772
2
            return execute_impl_internal(context, block, arguments, result, input_rows_count);
773
2
        };
774
2
        return execute_bitmap_op_count_null_to_zero(context, block, arguments, result,
775
2
                                                    input_rows_count, impl_func);
776
2
    }
777
778
    Status execute_impl_internal(FunctionContext* context, Block& block,
779
                                 const ColumnNumbers& arguments, uint32_t result,
780
2
                                 size_t input_rows_count) const {
781
2
        using ColVecResult = ColumnVector<ResultDataType::PType>;
782
783
2
        typename ColVecResult::MutablePtr col_res = ColVecResult::create();
784
2
        auto& vec_res = col_res->get_data();
785
2
        vec_res.resize(block.rows());
786
787
2
        const auto& left = block.get_by_position(arguments[0]);
788
2
        auto lcol = left.column;
789
2
        const auto& right = block.get_by_position(arguments[1]);
790
2
        auto rcol = right.column;
791
792
2
        if (is_column_const(*left.column)) {
793
0
            BitmapAndNotCount<LeftDataType, RightDataType>::scalar_vector(
794
0
                    assert_cast<const ColumnBitmap&>(
795
0
                            assert_cast<const ColumnConst*>(lcol.get())->get_data_column())
796
0
                            .get_data()[0],
797
0
                    assert_cast<const ColumnBitmap*>(rcol.get())->get_data(), vec_res.data());
798
2
        } else if (is_column_const(*right.column)) {
799
0
            BitmapAndNotCount<LeftDataType, RightDataType>::vector_scalar(
800
0
                    assert_cast<const ColumnBitmap*>(lcol.get())->get_data(),
801
0
                    assert_cast<const ColumnBitmap&>(
802
0
                            assert_cast<const ColumnConst*>(rcol.get())->get_data_column())
803
0
                            .get_data()[0],
804
0
                    vec_res.data());
805
2
        } else {
806
2
            BitmapAndNotCount<LeftDataType, RightDataType>::vector_vector(
807
2
                    assert_cast<const ColumnBitmap*>(lcol.get())->get_data(),
808
2
                    assert_cast<const ColumnBitmap*>(rcol.get())->get_data(), vec_res.data());
809
2
        }
810
811
2
        auto& result_info = block.get_by_position(result);
812
2
        if (result_info.type->is_nullable()) {
813
2
            block.replace_by_position(
814
2
                    result, ColumnNullable::create(std::move(col_res),
815
2
                                                   ColumnUInt8::create(input_rows_count, 0)));
816
2
        } else {
817
0
            block.replace_by_position(result, std::move(col_res));
818
0
        }
819
2
        return Status::OK();
820
2
    }
821
};
822
823
struct NameBitmapContains {
824
    static constexpr auto name = "bitmap_contains";
825
};
826
827
template <typename LeftDataType, typename RightDataType>
828
struct BitmapContains {
829
    using ResultDataType = DataTypeUInt8;
830
    using T0 = typename LeftDataType::FieldType;
831
    using T1 = typename RightDataType::FieldType;
832
    using LTData = std::vector<BitmapValue>;
833
    using RTData = typename ColumnVector<RightDataType::PType>::Container;
834
    using ResTData = typename ColumnUInt8::Container;
835
836
0
    static void vector_vector(const LTData& lvec, const RTData& rvec, ResTData& res) {
837
0
        size_t size = lvec.size();
838
0
        for (size_t i = 0; i < size; ++i) {
839
0
            res[i] = lvec[i].contains(rvec[i]);
840
0
        }
841
0
    }
842
0
    static void vector_scalar(const LTData& lvec, const T1& rval, ResTData& res) {
843
0
        size_t size = lvec.size();
844
0
        for (size_t i = 0; i < size; ++i) {
845
0
            res[i] = lvec[i].contains(rval);
846
0
        }
847
0
    }
848
0
    static void scalar_vector(const BitmapValue& lval, const RTData& rvec, ResTData& res) {
849
0
        size_t size = rvec.size();
850
0
        for (size_t i = 0; i < size; ++i) {
851
0
            res[i] = lval.contains(rvec[i]);
852
0
        }
853
0
    }
854
};
855
856
struct NameBitmapRemove {
857
    static constexpr auto name = "bitmap_remove";
858
};
859
860
template <typename LeftDataType, typename RightDataType>
861
struct BitmapRemove {
862
    using ResultDataType = DataTypeBitMap;
863
    using T0 = typename LeftDataType::FieldType;
864
    using T1 = typename RightDataType::FieldType;
865
    using LTData = std::vector<BitmapValue>;
866
    using RTData = typename ColumnVector<RightDataType::PType>::Container;
867
    using ResTData = std::vector<BitmapValue>;
868
869
1
    static void vector_vector(const LTData& lvec, const RTData& rvec, ResTData& res) {
870
1
        size_t size = lvec.size();
871
4
        for (size_t i = 0; i < size; ++i) {
872
3
            res[i] = lvec[i];
873
3
            res[i].remove(rvec[i]);
874
3
        }
875
1
    }
876
0
    static void vector_scalar(const LTData& lvec, const T1& rval, ResTData& res) {
877
0
        size_t size = lvec.size();
878
0
        for (size_t i = 0; i < size; ++i) {
879
0
            res[i] = lvec[i];
880
0
            res[i].remove(rval);
881
0
        }
882
0
    }
883
0
    static void scalar_vector(const BitmapValue& lval, const RTData& rvec, ResTData& res) {
884
0
        size_t size = rvec.size();
885
0
        for (size_t i = 0; i < size; ++i) {
886
0
            res[i] = lval;
887
0
            res[i].remove(rvec[i]);
888
0
        }
889
0
    }
890
};
891
892
struct NameBitmapHasAny {
893
    static constexpr auto name = "bitmap_has_any";
894
};
895
896
template <typename LeftDataType, typename RightDataType>
897
struct BitmapHasAny {
898
    using ResultDataType = DataTypeUInt8;
899
    using T0 = typename LeftDataType::FieldType;
900
    using T1 = typename RightDataType::FieldType;
901
    using TData = std::vector<BitmapValue>;
902
    using ResTData = typename ColumnUInt8::Container;
903
904
0
    static void vector_vector(const TData& lvec, const TData& rvec, ResTData& res) {
905
0
        size_t size = lvec.size();
906
0
        for (size_t i = 0; i < size; ++i) {
907
0
            auto bitmap = lvec[i];
908
0
            bitmap &= rvec[i];
909
0
            res[i] = bitmap.cardinality() != 0;
910
0
        }
911
0
    }
912
0
    static void vector_scalar(const TData& lvec, const BitmapValue& rval, ResTData& res) {
913
0
        size_t size = lvec.size();
914
0
        for (size_t i = 0; i < size; ++i) {
915
0
            auto bitmap = lvec[i];
916
0
            bitmap &= rval;
917
0
            res[i] = bitmap.cardinality() != 0;
918
0
        }
919
0
    }
920
0
    static void scalar_vector(const BitmapValue& lval, const TData& rvec, ResTData& res) {
921
0
        size_t size = rvec.size();
922
0
        for (size_t i = 0; i < size; ++i) {
923
0
            auto bitmap = lval;
924
0
            bitmap &= rvec[i];
925
0
            res[i] = bitmap.cardinality() != 0;
926
0
        }
927
0
    }
928
};
929
930
struct NameBitmapHasAll {
931
    static constexpr auto name = "bitmap_has_all";
932
};
933
934
template <typename LeftDataType, typename RightDataType>
935
struct BitmapHasAll {
936
    using ResultDataType = DataTypeUInt8;
937
    using T0 = typename LeftDataType::FieldType;
938
    using T1 = typename RightDataType::FieldType;
939
    using TData = std::vector<BitmapValue>;
940
    using ResTData = typename ColumnUInt8::Container;
941
942
1
    static void vector_vector(const TData& lvec, const TData& rvec, ResTData& res) {
943
1
        size_t size = lvec.size();
944
6
        for (size_t i = 0; i < size; ++i) {
945
5
            uint64_t lhs_cardinality = lvec[i].cardinality();
946
5
            auto bitmap = lvec[i];
947
5
            bitmap |= rvec[i];
948
5
            res[i] = bitmap.cardinality() == lhs_cardinality;
949
5
        }
950
1
    }
951
0
    static void vector_scalar(const TData& lvec, const BitmapValue& rval, ResTData& res) {
952
0
        size_t size = lvec.size();
953
0
        for (size_t i = 0; i < size; ++i) {
954
0
            uint64_t lhs_cardinality = lvec[i].cardinality();
955
0
            auto bitmap = lvec[i];
956
0
            bitmap |= rval;
957
0
            res[i] = bitmap.cardinality() == lhs_cardinality;
958
0
        }
959
0
    }
960
0
    static void scalar_vector(const BitmapValue& lval, const TData& rvec, ResTData& res) {
961
0
        size_t size = rvec.size();
962
0
        uint64_t lhs_cardinality = lval.cardinality();
963
0
        for (size_t i = 0; i < size; ++i) {
964
0
            auto bitmap = lval;
965
0
            bitmap |= rvec[i];
966
0
            res[i] = bitmap.cardinality() == lhs_cardinality;
967
0
        }
968
0
    }
969
};
970
971
struct NameBitmapToString {
972
    static constexpr auto name = "bitmap_to_string";
973
};
974
975
struct BitmapToString {
976
    using ReturnType = DataTypeString;
977
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_BITMAP;
978
    using Type = DataTypeBitMap::FieldType;
979
    using ReturnColumnType = ColumnString;
980
    using Chars = ColumnString::Chars;
981
    using Offsets = ColumnString::Offsets;
982
983
1
    static Status vector(const std::vector<BitmapValue>& data, Chars& chars, Offsets& offsets) {
984
1
        size_t size = data.size();
985
1
        offsets.resize(size);
986
1
        chars.reserve(size);
987
5
        for (size_t i = 0; i < size; ++i) {
988
4
            StringOP::push_value_string(data[i].to_string(), i, chars, offsets);
989
4
        }
990
1
        return Status::OK();
991
1
    }
992
};
993
994
struct NameBitmapToBase64 {
995
    static constexpr auto name = "bitmap_to_base64";
996
};
997
998
struct BitmapToBase64 {
999
    using ReturnType = DataTypeString;
1000
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_BITMAP;
1001
    using Type = DataTypeBitMap::FieldType;
1002
    using ReturnColumnType = ColumnString;
1003
    using Chars = ColumnString::Chars;
1004
    using Offsets = ColumnString::Offsets;
1005
1006
    // ColumnString not support 64bit, only 32bit, so that the max size is 4G
1007
4
    static Status vector(const std::vector<BitmapValue>& data, Chars& chars, Offsets& offsets) {
1008
4
        size_t size = data.size();
1009
4
        offsets.resize(size);
1010
4
        size_t output_char_size = 0;
1011
23
        for (size_t i = 0; i < size; ++i) {
1012
19
            const BitmapValue& bitmap_val = data[i];
1013
19
            auto ser_size = bitmap_val.getSizeInBytes();
1014
19
            output_char_size += (int)(4.0 * ceil((double)ser_size / 3.0));
1015
19
        }
1016
4
        ColumnString::check_chars_length(output_char_size, size);
1017
4
        chars.resize(output_char_size);
1018
4
        auto chars_data = chars.data();
1019
1020
4
        size_t cur_ser_size = 0;
1021
4
        size_t last_ser_size = 0;
1022
4
        std::string ser_buff;
1023
4
        size_t encoded_offset = 0;
1024
23
        for (size_t i = 0; i < size; ++i) {
1025
19
            const BitmapValue& bitmap_val = data[i];
1026
19
            cur_ser_size = bitmap_val.getSizeInBytes();
1027
19
            if (cur_ser_size > last_ser_size) {
1028
9
                last_ser_size = cur_ser_size;
1029
9
                ser_buff.resize(cur_ser_size);
1030
9
            }
1031
19
            bitmap_val.write_to(ser_buff.data());
1032
1033
19
            auto outlen = base64_encode((const unsigned char*)ser_buff.data(), cur_ser_size,
1034
19
                                        chars_data + encoded_offset);
1035
19
            DCHECK(outlen > 0);
1036
1037
19
            encoded_offset += (int)(4.0 * ceil((double)cur_ser_size / 3.0));
1038
19
            offsets[i] = cast_set<UInt32>(encoded_offset);
1039
19
        }
1040
4
        return Status::OK();
1041
4
    }
1042
};
1043
1044
struct SubBitmap {
1045
    static constexpr auto name = "sub_bitmap";
1046
    using TData1 = std::vector<BitmapValue>;
1047
    using TData2 = typename ColumnInt64::Container;
1048
1049
    static void vector3(const TData1& bitmap_data, const TData2& offset_data,
1050
                        const TData2& limit_data, NullMap& null_map, size_t input_rows_count,
1051
0
                        TData1& res) {
1052
0
        for (int i = 0; i < input_rows_count; ++i) {
1053
0
            if (null_map[i]) {
1054
0
                continue;
1055
0
            }
1056
0
            if (limit_data[i] <= 0) {
1057
0
                null_map[i] = 1;
1058
0
                continue;
1059
0
            }
1060
0
            if (bitmap_data[i].offset_limit(offset_data[i], limit_data[i], &res[i]) == 0) {
1061
0
                null_map[i] = 1;
1062
0
            }
1063
0
        }
1064
0
    }
1065
    static void vector_scalars(const TData1& bitmap_data, const Int64& offset_data,
1066
                               const Int64& limit_data, NullMap& null_map, size_t input_rows_count,
1067
0
                               TData1& res) {
1068
0
        for (int i = 0; i < input_rows_count; ++i) {
1069
0
            if (null_map[i]) {
1070
0
                continue;
1071
0
            }
1072
0
            if (limit_data <= 0) {
1073
0
                null_map[i] = 1;
1074
0
                continue;
1075
0
            }
1076
0
            if (bitmap_data[i].offset_limit(offset_data, limit_data, &res[i]) == 0) {
1077
0
                null_map[i] = 1;
1078
0
            }
1079
0
        }
1080
0
    }
1081
};
1082
1083
struct BitmapSubsetLimit {
1084
    static constexpr auto name = "bitmap_subset_limit";
1085
    using TData1 = std::vector<BitmapValue>;
1086
    using TData2 = typename ColumnInt64::Container;
1087
1088
    static void vector3(const TData1& bitmap_data, const TData2& offset_data,
1089
                        const TData2& limit_data, NullMap& null_map, size_t input_rows_count,
1090
0
                        TData1& res) {
1091
0
        for (int i = 0; i < input_rows_count; ++i) {
1092
0
            if (null_map[i]) {
1093
0
                continue;
1094
0
            }
1095
0
            if (offset_data[i] < 0 || limit_data[i] < 0) {
1096
0
                null_map[i] = 1;
1097
0
                continue;
1098
0
            }
1099
0
            bitmap_data[i].sub_limit(offset_data[i], limit_data[i], &res[i]);
1100
0
        }
1101
0
    }
1102
    static void vector_scalars(const TData1& bitmap_data, const Int64& offset_data,
1103
                               const Int64& limit_data, NullMap& null_map, size_t input_rows_count,
1104
0
                               TData1& res) {
1105
0
        for (int i = 0; i < input_rows_count; ++i) {
1106
0
            if (null_map[i]) {
1107
0
                continue;
1108
0
            }
1109
0
            if (offset_data < 0 || limit_data < 0) {
1110
0
                null_map[i] = 1;
1111
0
                continue;
1112
0
            }
1113
0
            bitmap_data[i].sub_limit(offset_data, limit_data, &res[i]);
1114
0
        }
1115
0
    }
1116
};
1117
1118
struct BitmapSubsetInRange {
1119
    static constexpr auto name = "bitmap_subset_in_range";
1120
    using TData1 = std::vector<BitmapValue>;
1121
    using TData2 = typename ColumnInt64::Container;
1122
1123
    static void vector3(const TData1& bitmap_data, const TData2& range_start,
1124
                        const TData2& range_end, NullMap& null_map, size_t input_rows_count,
1125
0
                        TData1& res) {
1126
0
        for (int i = 0; i < input_rows_count; ++i) {
1127
0
            if (null_map[i]) {
1128
0
                continue;
1129
0
            }
1130
0
            if (range_start[i] >= range_end[i] || range_start[i] < 0 || range_end[i] < 0) {
1131
0
                null_map[i] = 1;
1132
0
                continue;
1133
0
            }
1134
0
            bitmap_data[i].sub_range(range_start[i], range_end[i], &res[i]);
1135
0
        }
1136
0
    }
1137
    static void vector_scalars(const TData1& bitmap_data, const Int64& range_start,
1138
                               const Int64& range_end, NullMap& null_map, size_t input_rows_count,
1139
0
                               TData1& res) {
1140
0
        for (int i = 0; i < input_rows_count; ++i) {
1141
0
            if (null_map[i]) {
1142
0
                continue;
1143
0
            }
1144
0
            if (range_start >= range_end || range_start < 0 || range_end < 0) {
1145
0
                null_map[i] = 1;
1146
0
                continue;
1147
0
            }
1148
0
            bitmap_data[i].sub_range(range_start, range_end, &res[i]);
1149
0
        }
1150
0
    }
1151
};
1152
1153
template <typename Impl>
1154
class FunctionBitmapSubs : public IFunction {
1155
public:
1156
    static constexpr auto name = Impl::name;
1157
3
    String get_name() const override { return name; }
_ZNK5doris18FunctionBitmapSubsINS_9SubBitmapEE8get_nameB5cxx11Ev
Line
Count
Source
1157
1
    String get_name() const override { return name; }
_ZNK5doris18FunctionBitmapSubsINS_17BitmapSubsetLimitEE8get_nameB5cxx11Ev
Line
Count
Source
1157
1
    String get_name() const override { return name; }
_ZNK5doris18FunctionBitmapSubsINS_19BitmapSubsetInRangeEE8get_nameB5cxx11Ev
Line
Count
Source
1157
1
    String get_name() const override { return name; }
1158
1159
24
    static FunctionPtr create() { return std::make_shared<FunctionBitmapSubs>(); }
_ZN5doris18FunctionBitmapSubsINS_9SubBitmapEE6createEv
Line
Count
Source
1159
8
    static FunctionPtr create() { return std::make_shared<FunctionBitmapSubs>(); }
_ZN5doris18FunctionBitmapSubsINS_17BitmapSubsetLimitEE6createEv
Line
Count
Source
1159
8
    static FunctionPtr create() { return std::make_shared<FunctionBitmapSubs>(); }
_ZN5doris18FunctionBitmapSubsINS_19BitmapSubsetInRangeEE6createEv
Line
Count
Source
1159
8
    static FunctionPtr create() { return std::make_shared<FunctionBitmapSubs>(); }
1160
1161
0
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1162
0
        return make_nullable(std::make_shared<DataTypeBitMap>());
1163
0
    }
Unexecuted instantiation: _ZNK5doris18FunctionBitmapSubsINS_9SubBitmapEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Unexecuted instantiation: _ZNK5doris18FunctionBitmapSubsINS_17BitmapSubsetLimitEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Unexecuted instantiation: _ZNK5doris18FunctionBitmapSubsINS_19BitmapSubsetInRangeEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
1164
1165
0
    size_t get_number_of_arguments() const override { return 3; }
Unexecuted instantiation: _ZNK5doris18FunctionBitmapSubsINS_9SubBitmapEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris18FunctionBitmapSubsINS_17BitmapSubsetLimitEE23get_number_of_argumentsEv
Unexecuted instantiation: _ZNK5doris18FunctionBitmapSubsINS_19BitmapSubsetInRangeEE23get_number_of_argumentsEv
1166
1167
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
1168
0
                        uint32_t result, size_t input_rows_count) const override {
1169
0
        DCHECK_EQ(arguments.size(), 3);
1170
0
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
1171
0
        auto res_data_column = ColumnBitmap::create(input_rows_count);
1172
1173
0
        bool col_const[3];
1174
0
        ColumnPtr argument_columns[3];
1175
0
        for (int i = 0; i < 3; ++i) {
1176
0
            col_const[i] = is_column_const(*block.get_by_position(arguments[i]).column);
1177
0
        }
1178
0
        argument_columns[0] = col_const[0] ? static_cast<const ColumnConst&>(
1179
0
                                                     *block.get_by_position(arguments[0]).column)
1180
0
                                                     .convert_to_full_column()
1181
0
                                           : block.get_by_position(arguments[0]).column;
1182
1183
0
        default_preprocess_parameter_columns(argument_columns, col_const, {1, 2}, block, arguments);
1184
1185
0
        auto bitmap_column = assert_cast<const ColumnBitmap*>(argument_columns[0].get());
1186
0
        auto offset_column = assert_cast<const ColumnInt64*>(argument_columns[1].get());
1187
0
        auto limit_column = assert_cast<const ColumnInt64*>(argument_columns[2].get());
1188
1189
0
        if (col_const[1] && col_const[2]) {
1190
0
            Impl::vector_scalars(bitmap_column->get_data(), offset_column->get_element(0),
1191
0
                                 limit_column->get_element(0), res_null_map->get_data(),
1192
0
                                 input_rows_count, res_data_column->get_data());
1193
0
        } else {
1194
0
            Impl::vector3(bitmap_column->get_data(), offset_column->get_data(),
1195
0
                          limit_column->get_data(), res_null_map->get_data(), input_rows_count,
1196
0
                          res_data_column->get_data());
1197
0
        }
1198
1199
0
        block.get_by_position(result).column =
1200
0
                ColumnNullable::create(std::move(res_data_column), std::move(res_null_map));
1201
0
        return Status::OK();
1202
0
    }
Unexecuted instantiation: _ZNK5doris18FunctionBitmapSubsINS_9SubBitmapEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris18FunctionBitmapSubsINS_17BitmapSubsetLimitEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris18FunctionBitmapSubsINS_19BitmapSubsetInRangeEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
1203
};
1204
1205
class FunctionBitmapToArray : public IFunction {
1206
public:
1207
    static constexpr auto name = "bitmap_to_array";
1208
1209
1
    String get_name() const override { return name; }
1210
1211
8
    static FunctionPtr create() { return std::make_shared<FunctionBitmapToArray>(); }
1212
1213
0
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1214
0
        auto nested_type = make_nullable(std::make_shared<DataTypeInt64>());
1215
0
        return std::make_shared<DataTypeArray>(nested_type);
1216
0
    }
1217
1218
0
    size_t get_number_of_arguments() const override { return 1; }
1219
1220
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
1221
0
                        uint32_t result, size_t input_rows_count) const override {
1222
0
        auto return_nested_type = make_nullable(std::make_shared<DataTypeInt64>());
1223
0
        auto dest_array_column_ptr = ColumnArray::create(return_nested_type->create_column(),
1224
0
                                                         ColumnArray::ColumnOffsets::create());
1225
1226
0
        IColumn* dest_nested_column = &dest_array_column_ptr->get_data();
1227
0
        ColumnNullable* dest_nested_nullable_col =
1228
0
                reinterpret_cast<ColumnNullable*>(dest_nested_column);
1229
0
        dest_nested_column = dest_nested_nullable_col->get_nested_column_ptr().get();
1230
0
        auto& dest_nested_null_map = dest_nested_nullable_col->get_null_map_column().get_data();
1231
1232
0
        auto& arg_col = block.get_by_position(arguments[0]).column;
1233
0
        auto bitmap_col = assert_cast<const ColumnBitmap*>(arg_col.get());
1234
0
        const auto& bitmap_col_data = bitmap_col->get_data();
1235
0
        auto& nested_column_data = assert_cast<ColumnInt64*>(dest_nested_column)->get_data();
1236
0
        auto& dest_offsets = dest_array_column_ptr->get_offsets();
1237
0
        dest_offsets.reserve(input_rows_count);
1238
1239
0
        for (int i = 0; i < input_rows_count; ++i) {
1240
0
            bitmap_col_data[i].to_array(nested_column_data);
1241
0
            dest_nested_null_map.resize_fill(nested_column_data.size(), 0);
1242
0
            dest_offsets.push_back(nested_column_data.size());
1243
0
        }
1244
1245
0
        block.replace_by_position(result, std::move(dest_array_column_ptr));
1246
0
        return Status::OK();
1247
0
    }
1248
};
1249
1250
using FunctionBitmapEmpty = FunctionConst<BitmapEmpty, false>;
1251
using FunctionToBitmap = FunctionAlwaysNotNullable<ToBitmap>;
1252
using FunctionToBitmapWithCheck = FunctionAlwaysNotNullable<ToBitmapWithCheck, true>;
1253
1254
using FunctionBitmapFromString = FunctionBitmapAlwaysNull<BitmapFromString>;
1255
using FunctionBitmapFromArray = FunctionBitmapAlwaysNull<BitmapFromArray>;
1256
using FunctionBitmapHash = FunctionAlwaysNotNullable<BitmapHash<32>>;
1257
using FunctionBitmapHash64 = FunctionAlwaysNotNullable<BitmapHash<64>>;
1258
1259
using FunctionBitmapMin = FunctionBitmapSingle<FunctionBitmapMinImpl>;
1260
using FunctionBitmapMax = FunctionBitmapSingle<FunctionBitmapMaxImpl>;
1261
1262
using FunctionBitmapToString = FunctionUnaryToType<BitmapToString, NameBitmapToString>;
1263
using FunctionBitmapToBase64 = FunctionUnaryToType<BitmapToBase64, NameBitmapToBase64>;
1264
using FunctionBitmapFromBase64 = FunctionBitmapAlwaysNull<BitmapFromBase64>;
1265
using FunctionBitmapNot =
1266
        FunctionBinaryToType<DataTypeBitMap, DataTypeBitMap, BitmapNot, NameBitmapNot>;
1267
using FunctionBitmapAndNot =
1268
        FunctionBinaryToType<DataTypeBitMap, DataTypeBitMap, BitmapAndNot, NameBitmapAndNot>;
1269
using FunctionBitmapContains =
1270
        FunctionBinaryToType<DataTypeBitMap, DataTypeInt64, BitmapContains, NameBitmapContains>;
1271
using FunctionBitmapRemove =
1272
        FunctionBinaryToType<DataTypeBitMap, DataTypeInt64, BitmapRemove, NameBitmapRemove>;
1273
1274
using FunctionBitmapHasAny =
1275
        FunctionBinaryToType<DataTypeBitMap, DataTypeBitMap, BitmapHasAny, NameBitmapHasAny>;
1276
using FunctionBitmapHasAll =
1277
        FunctionBinaryToType<DataTypeBitMap, DataTypeBitMap, BitmapHasAll, NameBitmapHasAll>;
1278
using FunctionSubBitmap = FunctionBitmapSubs<SubBitmap>;
1279
using FunctionBitmapSubsetLimit = FunctionBitmapSubs<BitmapSubsetLimit>;
1280
using FunctionBitmapSubsetInRange = FunctionBitmapSubs<BitmapSubsetInRange>;
1281
1282
7
void register_function_bitmap(SimpleFunctionFactory& factory) {
1283
7
    factory.register_function<FunctionBitmapEmpty>();
1284
7
    factory.register_function<FunctionToBitmap>();
1285
7
    factory.register_function<FunctionToBitmapWithCheck>();
1286
7
    factory.register_function<FunctionBitmapFromString>();
1287
7
    factory.register_function<FunctionBitmapToBase64>();
1288
7
    factory.register_function<FunctionBitmapFromBase64>();
1289
7
    factory.register_function<FunctionBitmapFromArray>();
1290
7
    factory.register_function<FunctionBitmapHash>();
1291
7
    factory.register_function<FunctionBitmapHash64>();
1292
7
    factory.register_function<FunctionBitmapCount>();
1293
7
    factory.register_function<FunctionBitmapMin>();
1294
7
    factory.register_function<FunctionBitmapMax>();
1295
7
    factory.register_function<FunctionBitmapToString>();
1296
7
    factory.register_function<FunctionBitmapNot>();
1297
7
    factory.register_function<FunctionBitmapAndNot>();
1298
7
    factory.register_alias(NameBitmapAndNot::name, "bitmap_andnot");
1299
7
    factory.register_function<FunctionBitmapAndNotCount<NameBitmapAndNotCount>>();
1300
7
    factory.register_alias(NameBitmapAndNotCount::name, "bitmap_andnot_count");
1301
7
    factory.register_function<FunctionBitmapContains>();
1302
7
    factory.register_function<FunctionBitmapRemove>();
1303
7
    factory.register_function<FunctionBitmapHasAny>();
1304
7
    factory.register_function<FunctionBitmapHasAll>();
1305
7
    factory.register_function<FunctionSubBitmap>();
1306
7
    factory.register_function<FunctionBitmapSubsetLimit>();
1307
7
    factory.register_function<FunctionBitmapSubsetInRange>();
1308
7
    factory.register_function<FunctionBitmapToArray>();
1309
7
}
1310
1311
} // namespace doris