Coverage Report

Created: 2026-07-12 06:41

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
0
    static DataTypePtr get_return_type() { return std::make_shared<DataTypeBitMap>(); }
83
0
    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
0
    static void vector(const ColumnType* col, MutableColumnPtr& col_res) {
92
0
        execute<ColumnType, false>(col, nullptr, col_res);
93
0
    }
Unexecuted instantiation: _ZN5doris8ToBitmap6vectorINS_9ColumnStrIjEEEEvPKT_RNS_3COWINS_7IColumnEE11mutable_ptrIS8_EE
Unexecuted instantiation: _ZN5doris8ToBitmap6vectorINS_12ColumnVectorILNS_13PrimitiveTypeE6EEEEEvPKT_RNS_3COWINS_7IColumnEE11mutable_ptrIS9_EE
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
0
    static void execute(const ColumnType* col, const NullMap* nullmap, MutableColumnPtr& col_res) {
101
0
        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
0
        } else if constexpr (std::is_same_v<ColumnType, ColumnInt64>) {
124
0
            auto* res_column = reinterpret_cast<ColumnBitmap*>(col_res.get());
125
0
            auto& res_data = res_column->get_data();
126
0
            size_t size = col->size();
127
128
0
            for (size_t i = 0; i < size; ++i) {
129
0
                if constexpr (arg_is_nullable) {
130
0
                    if ((*nullmap)[i]) {
131
0
                        continue;
132
0
                    }
133
0
                }
134
0
                if (auto value = col->get_data()[i]; value >= 0) {
135
0
                    res_data[i].add(value);
136
0
                }
137
0
            }
138
0
        }
139
0
    }
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
Unexecuted instantiation: _ZN5doris8ToBitmap7executeINS_12ColumnVectorILNS_13PrimitiveTypeE6EEELb0EEEvPKT_PKNS_8PODArrayIhLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERNS_3COWINS_7IColumnEE11mutable_ptrISG_EE
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
0
                         std::vector<BitmapValue>& res, NullMap& null_map) {
323
0
        const auto& nested_column_data = static_cast<const ColumnType&>(nested_column).get_data();
324
0
        auto size = offset_column_data.size();
325
0
        res.reserve(size);
326
0
        std::vector<uint64_t> bits;
327
0
        for (size_t i = 0; i < size; ++i) {
328
0
            auto curr_offset = offset_column_data[i];
329
0
            auto prev_offset = offset_column_data[i - 1];
330
0
            for (auto j = prev_offset; j < curr_offset; ++j) {
331
0
                auto data = nested_column_data[j];
332
                // invaild value
333
0
                if (UNLIKELY(data < 0) || UNLIKELY(nested_null_map[j])) {
334
0
                    res.emplace_back();
335
0
                    null_map[i] = 1;
336
0
                    break;
337
0
                } else {
338
0
                    bits.push_back(data);
339
0
                }
340
0
            }
341
            //input is valid value
342
0
            if (!null_map[i]) {
343
0
                res.emplace_back(bits);
344
0
            }
345
0
            bits.clear();
346
0
        }
347
0
        return Status::OK();
348
0
    }
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_
Unexecuted instantiation: _ZN5doris15BitmapFromArray6vectorINS_12ColumnVectorILNS_13PrimitiveTypeE5EEEEENS_6StatusERKNS_8PODArrayImLm4096ENS_9AllocatorILb0ELb0ELb0ENS_22DefaultMemoryAllocatorELb1EEELm16ELm15EEERKNS_7IColumnERKNS6_IhLm4096ES9_Lm16ELm15EEERSt6vectorINS_11BitmapValueESaISK_EERSG_
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
13
    static FunctionPtr create() { return std::make_shared<FunctionBitmapAlwaysNull>(); }
_ZN5doris24FunctionBitmapAlwaysNullINS_16BitmapFromStringEE6createEv
Line
Count
Source
358
4
    static FunctionPtr create() { return std::make_shared<FunctionBitmapAlwaysNull>(); }
_ZN5doris24FunctionBitmapAlwaysNullINS_16BitmapFromBase64EE6createEv
Line
Count
Source
358
7
    static FunctionPtr create() { return std::make_shared<FunctionBitmapAlwaysNull>(); }
_ZN5doris24FunctionBitmapAlwaysNullINS_15BitmapFromArrayEE6createEv
Line
Count
Source
358
2
    static FunctionPtr create() { return std::make_shared<FunctionBitmapAlwaysNull>(); }
359
360
7
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
361
7
        return make_nullable(std::make_shared<DataTypeBitMap>());
362
7
    }
_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
    }
Unexecuted instantiation: _ZNK5doris24FunctionBitmapAlwaysNullINS_15BitmapFromArrayEE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
363
364
7
    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; }
Unexecuted instantiation: _ZNK5doris24FunctionBitmapAlwaysNullINS_15BitmapFromArrayEE23get_number_of_argumentsEv
365
366
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
367
7
                        uint32_t result, size_t input_rows_count) const override {
368
7
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
369
7
        auto res_data_column = ColumnBitmap::create();
370
7
        auto& null_map = res_null_map->get_data();
371
7
        auto& res = res_data_column->get_data();
372
373
7
        ColumnPtr& argument_column = block.get_by_position(arguments[0]).column;
374
7
        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
0
            auto argument_type = remove_nullable(
381
0
                    assert_cast<const DataTypeArray&>(*block.get_by_position(arguments[0]).type)
382
0
                            .get_nested_type());
383
0
            const auto& array_column = static_cast<const ColumnArray&>(*argument_column);
384
0
            const auto& offset_column_data = array_column.get_offsets();
385
0
            const auto& nested_nullable_column =
386
0
                    static_cast<const ColumnNullable&>(array_column.get_data());
387
0
            const auto& nested_column = nested_nullable_column.get_nested_column();
388
0
            const auto& nested_null_map = nested_nullable_column.get_null_map_column().get_data();
389
390
0
            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
0
            case PrimitiveType::TYPE_INT:
404
0
                RETURN_IF_ERROR(Impl::template vector<ColumnInt32>(
405
0
                        offset_column_data, nested_column, nested_null_map, res, null_map));
406
0
                break;
407
0
            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
0
            }
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
7
        block.get_by_position(result).column =
422
7
                ColumnNullable::create(std::move(res_data_column), std::move(res_null_map));
423
7
        return Status::OK();
424
7
    }
_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
    }
Unexecuted instantiation: _ZNK5doris24FunctionBitmapAlwaysNullINS_15BitmapFromArrayEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
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
2
    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 NameBitmapAndNotCount {
581
    static constexpr auto name = "bitmap_and_not_count";
582
};
583
584
template <typename LeftDataType, typename RightDataType>
585
struct BitmapAndNotCount {
586
    using ResultDataType = DataTypeInt64;
587
    using T0 = typename LeftDataType::FieldType;
588
    using T1 = typename RightDataType::FieldType;
589
    using TData = std::vector<BitmapValue>;
590
    using ResTData = typename ColumnInt64::Container::value_type;
591
592
3
    static void vector_vector(const TData& lvec, const TData& rvec, ResTData* res) {
593
3
        size_t size = lvec.size();
594
17
        for (size_t i = 0; i < size; ++i) {
595
14
            res[i] = lvec[i].andnot_cardinality(rvec[i]);
596
14
        }
597
3
    }
598
0
    static void scalar_vector(const BitmapValue& lval, const TData& rvec, ResTData* res) {
599
0
        size_t size = rvec.size();
600
0
        for (size_t i = 0; i < size; ++i) {
601
0
            res[i] = lval.andnot_cardinality(rvec[i]);
602
0
        }
603
0
    }
604
0
    static void vector_scalar(const TData& lvec, const BitmapValue& rval, ResTData* res) {
605
0
        size_t size = lvec.size();
606
0
        for (size_t i = 0; i < size; ++i) {
607
0
            res[i] = lvec[i].andnot_cardinality(rval);
608
0
        }
609
0
    }
610
};
611
612
20
void update_bitmap_op_count(int64_t* __restrict count, const NullMap& null_map) {
613
20
    static constexpr int64_t flags[2] = {-1, 0};
614
20
    size_t size = null_map.size();
615
20
    auto* __restrict null_map_data = null_map.data();
616
112
    for (size_t i = 0; i < size; ++i) {
617
92
        count[i] &= flags[null_map_data[i]];
618
92
    }
619
20
}
620
621
// for bitmap_and_count, bitmap_xor_count and bitmap_and_not_count,
622
// result is 0 for rows that if any column is null value
623
ColumnPtr handle_bitmap_op_count_null_value(ColumnPtr& src, const Block& block,
624
                                            const ColumnNumbers& args, uint32_t result,
625
9
                                            size_t input_rows_count) {
626
9
    MutableColumnPtr mutable_src = IColumn::mutate(std::move(src));
627
9
    auto* src_not_nullable_mutable = mutable_src.get();
628
9
    if (auto* nullable = check_and_get_column<ColumnNullable>(*mutable_src)) {
629
6
        src_not_nullable_mutable = &nullable->get_nested_column();
630
6
    }
631
9
    auto* __restrict count_data =
632
9
            assert_cast<ColumnInt64*>(src_not_nullable_mutable)->get_data().data();
633
634
20
    for (const auto& arg : args) {
635
20
        const ColumnWithTypeAndName& elem = block.get_by_position(arg);
636
20
        if (!elem.type->is_nullable()) {
637
0
            continue;
638
0
        }
639
640
20
        bool is_const = is_column_const(*elem.column);
641
        /// Const Nullable that are NULL.
642
20
        if (is_const && assert_cast<const ColumnConst*>(elem.column.get())->only_null()) {
643
0
            return block.get_by_position(result).type->create_column_const(
644
0
                    input_rows_count, Field::create_field<TYPE_BIGINT>(0));
645
0
        }
646
20
        if (is_const) {
647
0
            continue;
648
0
        }
649
650
20
        if (const auto* nullable_column = assert_cast<const ColumnNullable*>(elem.column.get())) {
651
20
            const ColumnPtr& null_map_column = nullable_column->get_null_map_column_ptr();
652
20
            const NullMap& src_null_map =
653
20
                    assert_cast<const ColumnUInt8&>(*null_map_column).get_data();
654
655
20
            update_bitmap_op_count(count_data, src_null_map);
656
20
        }
657
20
    }
658
659
9
    return mutable_src;
660
9
}
661
662
Status execute_bitmap_op_count_null_to_zero(
663
        FunctionContext* context, Block& block, const ColumnNumbers& arguments, uint32_t result,
664
        size_t input_rows_count,
665
        const std::function<Status(FunctionContext*, Block&, const ColumnNumbers&, size_t, size_t)>&
666
9
                exec_impl_func) {
667
9
    if (have_null_column(block, arguments)) {
668
9
        auto [temporary_block, new_args, new_result] =
669
9
                create_block_with_nested_columns(block, arguments, result);
670
9
        RETURN_IF_ERROR(exec_impl_func(context, temporary_block, new_args, new_result,
671
9
                                       temporary_block.rows()));
672
9
        block.get_by_position(result).column = handle_bitmap_op_count_null_value(
673
9
                temporary_block.get_by_position(new_result).column, block, arguments, result,
674
9
                input_rows_count);
675
9
    } else {
676
0
        return exec_impl_func(context, block, arguments, result, input_rows_count);
677
0
    }
678
9
    return Status::OK();
679
9
}
680
681
template <typename FunctionName, bool NewVersion = false>
682
class FunctionBitmapAndNotCount : public IFunction {
683
public:
684
    using LeftDataType = DataTypeBitMap;
685
    using RightDataType = DataTypeBitMap;
686
    using ResultDataType = typename BitmapAndNotCount<LeftDataType, RightDataType>::ResultDataType;
687
688
    static constexpr auto name = NewVersion ? "bitmap_and_not_count_v2" : FunctionName::name;
689
10
    static FunctionPtr create() { return std::make_shared<FunctionBitmapAndNotCount>(); }
_ZN5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb0EE6createEv
Line
Count
Source
689
5
    static FunctionPtr create() { return std::make_shared<FunctionBitmapAndNotCount>(); }
_ZN5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb1EE6createEv
Line
Count
Source
689
5
    static FunctionPtr create() { return std::make_shared<FunctionBitmapAndNotCount>(); }
690
3
    String get_name() const override { return name; }
_ZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb0EE8get_nameB5cxx11Ev
Line
Count
Source
690
1
    String get_name() const override { return name; }
_ZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb1EE8get_nameB5cxx11Ev
Line
Count
Source
690
2
    String get_name() const override { return name; }
691
6
    size_t get_number_of_arguments() const override { return 2; }
_ZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb0EE23get_number_of_argumentsEv
Line
Count
Source
691
3
    size_t get_number_of_arguments() const override { return 2; }
_ZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb1EE23get_number_of_argumentsEv
Line
Count
Source
691
3
    size_t get_number_of_arguments() const override { return 2; }
692
6
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
693
6
        if constexpr (NewVersion) {
694
3
            return std::make_shared<ResultDataType>();
695
3
        } else {
696
3
            bool return_nullable = false;
697
            // result is nullable only when any columns is nullable for bitmap_and_not_count
698
3
            for (size_t i = 0; i < arguments.size(); ++i) {
699
3
                if (arguments[i]->is_nullable()) {
700
3
                    return_nullable = true;
701
3
                    break;
702
3
                }
703
3
            }
704
3
            auto result_type = std::make_shared<ResultDataType>();
705
3
            return return_nullable ? make_nullable(result_type) : result_type;
706
3
        }
707
6
    }
_ZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb0EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
692
3
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
693
        if constexpr (NewVersion) {
694
            return std::make_shared<ResultDataType>();
695
3
        } else {
696
3
            bool return_nullable = false;
697
            // result is nullable only when any columns is nullable for bitmap_and_not_count
698
3
            for (size_t i = 0; i < arguments.size(); ++i) {
699
3
                if (arguments[i]->is_nullable()) {
700
3
                    return_nullable = true;
701
3
                    break;
702
3
                }
703
3
            }
704
3
            auto result_type = std::make_shared<ResultDataType>();
705
3
            return return_nullable ? make_nullable(result_type) : result_type;
706
3
        }
707
3
    }
_ZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb1EE20get_return_type_implERKSt6vectorISt10shared_ptrIKNS_9IDataTypeEESaIS7_EE
Line
Count
Source
692
3
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
693
3
        if constexpr (NewVersion) {
694
3
            return std::make_shared<ResultDataType>();
695
        } else {
696
            bool return_nullable = false;
697
            // result is nullable only when any columns is nullable for bitmap_and_not_count
698
            for (size_t i = 0; i < arguments.size(); ++i) {
699
                if (arguments[i]->is_nullable()) {
700
                    return_nullable = true;
701
                    break;
702
                }
703
            }
704
            auto result_type = std::make_shared<ResultDataType>();
705
            return return_nullable ? make_nullable(result_type) : result_type;
706
        }
707
3
    }
708
709
9
    bool use_default_implementation_for_nulls() const override {
710
        // for bitmap_and_not_count, result is always not null, and if the bitmap op result is null,
711
        // the count is 0
712
9
        return false;
713
9
    }
_ZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb0EE36use_default_implementation_for_nullsEv
Line
Count
Source
709
5
    bool use_default_implementation_for_nulls() const override {
710
        // for bitmap_and_not_count, result is always not null, and if the bitmap op result is null,
711
        // the count is 0
712
5
        return false;
713
5
    }
_ZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb1EE36use_default_implementation_for_nullsEv
Line
Count
Source
709
4
    bool use_default_implementation_for_nulls() const override {
710
        // for bitmap_and_not_count, result is always not null, and if the bitmap op result is null,
711
        // the count is 0
712
4
        return false;
713
4
    }
714
715
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
716
3
                        uint32_t result, size_t input_rows_count) const override {
717
3
        DCHECK_EQ(arguments.size(), 2);
718
3
        auto impl_func = [&](FunctionContext* context, Block& block, const ColumnNumbers& arguments,
719
3
                             uint32_t result, size_t input_rows_count) {
720
3
            return execute_impl_internal(context, block, arguments, result, input_rows_count);
721
3
        };
_ZZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb0EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlS4_S6_SB_jmE_clES4_S6_SB_jm
Line
Count
Source
719
2
                             uint32_t result, size_t input_rows_count) {
720
2
            return execute_impl_internal(context, block, arguments, result, input_rows_count);
721
2
        };
_ZZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb1EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjmENKUlS4_S6_SB_jmE_clES4_S6_SB_jm
Line
Count
Source
719
1
                             uint32_t result, size_t input_rows_count) {
720
1
            return execute_impl_internal(context, block, arguments, result, input_rows_count);
721
1
        };
722
3
        return execute_bitmap_op_count_null_to_zero(context, block, arguments, result,
723
3
                                                    input_rows_count, impl_func);
724
3
    }
_ZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb0EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
716
2
                        uint32_t result, size_t input_rows_count) const override {
717
        DCHECK_EQ(arguments.size(), 2);
718
2
        auto impl_func = [&](FunctionContext* context, Block& block, const ColumnNumbers& arguments,
719
2
                             uint32_t result, size_t input_rows_count) {
720
2
            return execute_impl_internal(context, block, arguments, result, input_rows_count);
721
2
        };
722
2
        return execute_bitmap_op_count_null_to_zero(context, block, arguments, result,
723
2
                                                    input_rows_count, impl_func);
724
2
    }
_ZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb1EE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
716
1
                        uint32_t result, size_t input_rows_count) const override {
717
        DCHECK_EQ(arguments.size(), 2);
718
1
        auto impl_func = [&](FunctionContext* context, Block& block, const ColumnNumbers& arguments,
719
1
                             uint32_t result, size_t input_rows_count) {
720
1
            return execute_impl_internal(context, block, arguments, result, input_rows_count);
721
1
        };
722
1
        return execute_bitmap_op_count_null_to_zero(context, block, arguments, result,
723
1
                                                    input_rows_count, impl_func);
724
1
    }
725
726
    Status execute_impl_internal(FunctionContext* context, Block& block,
727
                                 const ColumnNumbers& arguments, uint32_t result,
728
3
                                 size_t input_rows_count) const {
729
3
        using ColVecResult = ColumnVector<ResultDataType::PType>;
730
731
3
        typename ColVecResult::MutablePtr col_res = ColVecResult::create();
732
3
        auto& vec_res = col_res->get_data();
733
3
        vec_res.resize(block.rows());
734
735
3
        const auto& left = block.get_by_position(arguments[0]);
736
3
        auto lcol = left.column;
737
3
        const auto& right = block.get_by_position(arguments[1]);
738
3
        auto rcol = right.column;
739
740
3
        if (is_column_const(*left.column)) {
741
0
            BitmapAndNotCount<LeftDataType, RightDataType>::scalar_vector(
742
0
                    assert_cast<const ColumnBitmap&>(
743
0
                            assert_cast<const ColumnConst*>(lcol.get())->get_data_column())
744
0
                            .get_data()[0],
745
0
                    assert_cast<const ColumnBitmap*>(rcol.get())->get_data(), vec_res.data());
746
3
        } else if (is_column_const(*right.column)) {
747
0
            BitmapAndNotCount<LeftDataType, RightDataType>::vector_scalar(
748
0
                    assert_cast<const ColumnBitmap*>(lcol.get())->get_data(),
749
0
                    assert_cast<const ColumnBitmap&>(
750
0
                            assert_cast<const ColumnConst*>(rcol.get())->get_data_column())
751
0
                            .get_data()[0],
752
0
                    vec_res.data());
753
3
        } else {
754
3
            BitmapAndNotCount<LeftDataType, RightDataType>::vector_vector(
755
3
                    assert_cast<const ColumnBitmap*>(lcol.get())->get_data(),
756
3
                    assert_cast<const ColumnBitmap*>(rcol.get())->get_data(), vec_res.data());
757
3
        }
758
759
3
        auto& result_info = block.get_by_position(result);
760
3
        if (result_info.type->is_nullable()) {
761
2
            block.replace_by_position(
762
2
                    result, ColumnNullable::create(std::move(col_res),
763
2
                                                   ColumnUInt8::create(input_rows_count, 0)));
764
2
        } else {
765
1
            block.replace_by_position(result, std::move(col_res));
766
1
        }
767
3
        return Status::OK();
768
3
    }
_ZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb0EE21execute_impl_internalEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
728
2
                                 size_t input_rows_count) const {
729
2
        using ColVecResult = ColumnVector<ResultDataType::PType>;
730
731
2
        typename ColVecResult::MutablePtr col_res = ColVecResult::create();
732
2
        auto& vec_res = col_res->get_data();
733
2
        vec_res.resize(block.rows());
734
735
2
        const auto& left = block.get_by_position(arguments[0]);
736
2
        auto lcol = left.column;
737
2
        const auto& right = block.get_by_position(arguments[1]);
738
2
        auto rcol = right.column;
739
740
2
        if (is_column_const(*left.column)) {
741
0
            BitmapAndNotCount<LeftDataType, RightDataType>::scalar_vector(
742
0
                    assert_cast<const ColumnBitmap&>(
743
0
                            assert_cast<const ColumnConst*>(lcol.get())->get_data_column())
744
0
                            .get_data()[0],
745
0
                    assert_cast<const ColumnBitmap*>(rcol.get())->get_data(), vec_res.data());
746
2
        } else if (is_column_const(*right.column)) {
747
0
            BitmapAndNotCount<LeftDataType, RightDataType>::vector_scalar(
748
0
                    assert_cast<const ColumnBitmap*>(lcol.get())->get_data(),
749
0
                    assert_cast<const ColumnBitmap&>(
750
0
                            assert_cast<const ColumnConst*>(rcol.get())->get_data_column())
751
0
                            .get_data()[0],
752
0
                    vec_res.data());
753
2
        } else {
754
2
            BitmapAndNotCount<LeftDataType, RightDataType>::vector_vector(
755
2
                    assert_cast<const ColumnBitmap*>(lcol.get())->get_data(),
756
2
                    assert_cast<const ColumnBitmap*>(rcol.get())->get_data(), vec_res.data());
757
2
        }
758
759
2
        auto& result_info = block.get_by_position(result);
760
2
        if (result_info.type->is_nullable()) {
761
2
            block.replace_by_position(
762
2
                    result, ColumnNullable::create(std::move(col_res),
763
2
                                                   ColumnUInt8::create(input_rows_count, 0)));
764
2
        } else {
765
0
            block.replace_by_position(result, std::move(col_res));
766
0
        }
767
2
        return Status::OK();
768
2
    }
_ZNK5doris25FunctionBitmapAndNotCountINS_21NameBitmapAndNotCountELb1EE21execute_impl_internalEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Line
Count
Source
728
1
                                 size_t input_rows_count) const {
729
1
        using ColVecResult = ColumnVector<ResultDataType::PType>;
730
731
1
        typename ColVecResult::MutablePtr col_res = ColVecResult::create();
732
1
        auto& vec_res = col_res->get_data();
733
1
        vec_res.resize(block.rows());
734
735
1
        const auto& left = block.get_by_position(arguments[0]);
736
1
        auto lcol = left.column;
737
1
        const auto& right = block.get_by_position(arguments[1]);
738
1
        auto rcol = right.column;
739
740
1
        if (is_column_const(*left.column)) {
741
0
            BitmapAndNotCount<LeftDataType, RightDataType>::scalar_vector(
742
0
                    assert_cast<const ColumnBitmap&>(
743
0
                            assert_cast<const ColumnConst*>(lcol.get())->get_data_column())
744
0
                            .get_data()[0],
745
0
                    assert_cast<const ColumnBitmap*>(rcol.get())->get_data(), vec_res.data());
746
1
        } else if (is_column_const(*right.column)) {
747
0
            BitmapAndNotCount<LeftDataType, RightDataType>::vector_scalar(
748
0
                    assert_cast<const ColumnBitmap*>(lcol.get())->get_data(),
749
0
                    assert_cast<const ColumnBitmap&>(
750
0
                            assert_cast<const ColumnConst*>(rcol.get())->get_data_column())
751
0
                            .get_data()[0],
752
0
                    vec_res.data());
753
1
        } else {
754
1
            BitmapAndNotCount<LeftDataType, RightDataType>::vector_vector(
755
1
                    assert_cast<const ColumnBitmap*>(lcol.get())->get_data(),
756
1
                    assert_cast<const ColumnBitmap*>(rcol.get())->get_data(), vec_res.data());
757
1
        }
758
759
1
        auto& result_info = block.get_by_position(result);
760
1
        if (result_info.type->is_nullable()) {
761
0
            block.replace_by_position(
762
0
                    result, ColumnNullable::create(std::move(col_res),
763
0
                                                   ColumnUInt8::create(input_rows_count, 0)));
764
1
        } else {
765
1
            block.replace_by_position(result, std::move(col_res));
766
1
        }
767
1
        return Status::OK();
768
1
    }
769
};
770
771
struct NameBitmapContains {
772
    static constexpr auto name = "bitmap_contains";
773
};
774
775
template <typename LeftDataType, typename RightDataType>
776
struct BitmapContains {
777
    using ResultDataType = DataTypeUInt8;
778
    using T0 = typename LeftDataType::FieldType;
779
    using T1 = typename RightDataType::FieldType;
780
    using LTData = std::vector<BitmapValue>;
781
    using RTData = typename ColumnVector<RightDataType::PType>::Container;
782
    using ResTData = typename ColumnUInt8::Container;
783
784
0
    static void vector_vector(const LTData& lvec, const RTData& rvec, ResTData& res) {
785
0
        size_t size = lvec.size();
786
0
        for (size_t i = 0; i < size; ++i) {
787
0
            res[i] = lvec[i].contains(rvec[i]);
788
0
        }
789
0
    }
790
0
    static void vector_scalar(const LTData& lvec, const T1& rval, ResTData& res) {
791
0
        size_t size = lvec.size();
792
0
        for (size_t i = 0; i < size; ++i) {
793
0
            res[i] = lvec[i].contains(rval);
794
0
        }
795
0
    }
796
0
    static void scalar_vector(const BitmapValue& lval, const RTData& rvec, ResTData& res) {
797
0
        size_t size = rvec.size();
798
0
        for (size_t i = 0; i < size; ++i) {
799
0
            res[i] = lval.contains(rvec[i]);
800
0
        }
801
0
    }
802
};
803
804
struct NameBitmapRemove {
805
    static constexpr auto name = "bitmap_remove";
806
};
807
808
template <typename LeftDataType, typename RightDataType>
809
struct BitmapRemove {
810
    using ResultDataType = DataTypeBitMap;
811
    using T0 = typename LeftDataType::FieldType;
812
    using T1 = typename RightDataType::FieldType;
813
    using LTData = std::vector<BitmapValue>;
814
    using RTData = typename ColumnVector<RightDataType::PType>::Container;
815
    using ResTData = std::vector<BitmapValue>;
816
817
1
    static void vector_vector(const LTData& lvec, const RTData& rvec, ResTData& res) {
818
1
        size_t size = lvec.size();
819
4
        for (size_t i = 0; i < size; ++i) {
820
3
            res[i] = lvec[i];
821
3
            res[i].remove(rvec[i]);
822
3
        }
823
1
    }
824
0
    static void vector_scalar(const LTData& lvec, const T1& rval, ResTData& res) {
825
0
        size_t size = lvec.size();
826
0
        for (size_t i = 0; i < size; ++i) {
827
0
            res[i] = lvec[i];
828
0
            res[i].remove(rval);
829
0
        }
830
0
    }
831
0
    static void scalar_vector(const BitmapValue& lval, const RTData& rvec, ResTData& res) {
832
0
        size_t size = rvec.size();
833
0
        for (size_t i = 0; i < size; ++i) {
834
0
            res[i] = lval;
835
0
            res[i].remove(rvec[i]);
836
0
        }
837
0
    }
838
};
839
840
struct NameBitmapHasAny {
841
    static constexpr auto name = "bitmap_has_any";
842
};
843
844
template <typename LeftDataType, typename RightDataType>
845
struct BitmapHasAny {
846
    using ResultDataType = DataTypeUInt8;
847
    using T0 = typename LeftDataType::FieldType;
848
    using T1 = typename RightDataType::FieldType;
849
    using TData = std::vector<BitmapValue>;
850
    using ResTData = typename ColumnUInt8::Container;
851
852
0
    static void vector_vector(const TData& lvec, const TData& rvec, ResTData& res) {
853
0
        size_t size = lvec.size();
854
0
        for (size_t i = 0; i < size; ++i) {
855
0
            auto bitmap = lvec[i];
856
0
            bitmap &= rvec[i];
857
0
            res[i] = bitmap.cardinality() != 0;
858
0
        }
859
0
    }
860
0
    static void vector_scalar(const TData& lvec, const BitmapValue& rval, ResTData& res) {
861
0
        size_t size = lvec.size();
862
0
        for (size_t i = 0; i < size; ++i) {
863
0
            auto bitmap = lvec[i];
864
0
            bitmap &= rval;
865
0
            res[i] = bitmap.cardinality() != 0;
866
0
        }
867
0
    }
868
0
    static void scalar_vector(const BitmapValue& lval, const TData& rvec, ResTData& res) {
869
0
        size_t size = rvec.size();
870
0
        for (size_t i = 0; i < size; ++i) {
871
0
            auto bitmap = lval;
872
0
            bitmap &= rvec[i];
873
0
            res[i] = bitmap.cardinality() != 0;
874
0
        }
875
0
    }
876
};
877
878
struct NameBitmapHasAll {
879
    static constexpr auto name = "bitmap_has_all";
880
};
881
882
template <typename LeftDataType, typename RightDataType>
883
struct BitmapHasAll {
884
    using ResultDataType = DataTypeUInt8;
885
    using T0 = typename LeftDataType::FieldType;
886
    using T1 = typename RightDataType::FieldType;
887
    using TData = std::vector<BitmapValue>;
888
    using ResTData = typename ColumnUInt8::Container;
889
890
1
    static void vector_vector(const TData& lvec, const TData& rvec, ResTData& res) {
891
1
        size_t size = lvec.size();
892
6
        for (size_t i = 0; i < size; ++i) {
893
5
            uint64_t lhs_cardinality = lvec[i].cardinality();
894
5
            auto bitmap = lvec[i];
895
5
            bitmap |= rvec[i];
896
5
            res[i] = bitmap.cardinality() == lhs_cardinality;
897
5
        }
898
1
    }
899
0
    static void vector_scalar(const TData& lvec, const BitmapValue& rval, ResTData& res) {
900
0
        size_t size = lvec.size();
901
0
        for (size_t i = 0; i < size; ++i) {
902
0
            uint64_t lhs_cardinality = lvec[i].cardinality();
903
0
            auto bitmap = lvec[i];
904
0
            bitmap |= rval;
905
0
            res[i] = bitmap.cardinality() == lhs_cardinality;
906
0
        }
907
0
    }
908
0
    static void scalar_vector(const BitmapValue& lval, const TData& rvec, ResTData& res) {
909
0
        size_t size = rvec.size();
910
0
        uint64_t lhs_cardinality = lval.cardinality();
911
0
        for (size_t i = 0; i < size; ++i) {
912
0
            auto bitmap = lval;
913
0
            bitmap |= rvec[i];
914
0
            res[i] = bitmap.cardinality() == lhs_cardinality;
915
0
        }
916
0
    }
917
};
918
919
struct NameBitmapToString {
920
    static constexpr auto name = "bitmap_to_string";
921
};
922
923
struct BitmapToString {
924
    using ReturnType = DataTypeString;
925
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_BITMAP;
926
    using Type = DataTypeBitMap::FieldType;
927
    using ReturnColumnType = ColumnString;
928
    using Chars = ColumnString::Chars;
929
    using Offsets = ColumnString::Offsets;
930
931
1
    static Status vector(const std::vector<BitmapValue>& data, Chars& chars, Offsets& offsets) {
932
1
        size_t size = data.size();
933
1
        offsets.resize(size);
934
1
        chars.reserve(size);
935
5
        for (size_t i = 0; i < size; ++i) {
936
4
            StringOP::push_value_string(data[i].to_string(), i, chars, offsets);
937
4
        }
938
1
        return Status::OK();
939
1
    }
940
};
941
942
struct NameBitmapToBase64 {
943
    static constexpr auto name = "bitmap_to_base64";
944
};
945
946
struct BitmapToBase64 {
947
    using ReturnType = DataTypeString;
948
    static constexpr auto PrimitiveTypeImpl = PrimitiveType::TYPE_BITMAP;
949
    using Type = DataTypeBitMap::FieldType;
950
    using ReturnColumnType = ColumnString;
951
    using Chars = ColumnString::Chars;
952
    using Offsets = ColumnString::Offsets;
953
954
    // ColumnString not support 64bit, only 32bit, so that the max size is 4G
955
4
    static Status vector(const std::vector<BitmapValue>& data, Chars& chars, Offsets& offsets) {
956
4
        size_t size = data.size();
957
4
        offsets.resize(size);
958
4
        size_t output_char_size = 0;
959
23
        for (size_t i = 0; i < size; ++i) {
960
19
            const BitmapValue& bitmap_val = data[i];
961
19
            auto ser_size = bitmap_val.getSizeInBytes();
962
19
            output_char_size += (int)(4.0 * ceil((double)ser_size / 3.0));
963
19
        }
964
4
        ColumnString::check_chars_length(output_char_size, size);
965
4
        chars.resize(output_char_size);
966
4
        auto chars_data = chars.data();
967
968
4
        size_t cur_ser_size = 0;
969
4
        size_t last_ser_size = 0;
970
4
        std::string ser_buff;
971
4
        size_t encoded_offset = 0;
972
23
        for (size_t i = 0; i < size; ++i) {
973
19
            const BitmapValue& bitmap_val = data[i];
974
19
            cur_ser_size = bitmap_val.getSizeInBytes();
975
19
            if (cur_ser_size > last_ser_size) {
976
9
                last_ser_size = cur_ser_size;
977
9
                ser_buff.resize(cur_ser_size);
978
9
            }
979
19
            bitmap_val.write_to(ser_buff.data());
980
981
19
            auto outlen = base64_encode((const unsigned char*)ser_buff.data(), cur_ser_size,
982
19
                                        chars_data + encoded_offset);
983
19
            DCHECK(outlen > 0);
984
985
19
            encoded_offset += (int)(4.0 * ceil((double)cur_ser_size / 3.0));
986
19
            offsets[i] = cast_set<UInt32>(encoded_offset);
987
19
        }
988
4
        return Status::OK();
989
4
    }
990
};
991
992
struct SubBitmap {
993
    static constexpr auto name = "sub_bitmap";
994
    using TData1 = std::vector<BitmapValue>;
995
    using TData2 = typename ColumnInt64::Container;
996
997
    static void vector3(const TData1& bitmap_data, const TData2& offset_data,
998
                        const TData2& limit_data, NullMap& null_map, size_t input_rows_count,
999
0
                        TData1& res) {
1000
0
        for (int i = 0; i < input_rows_count; ++i) {
1001
0
            if (null_map[i]) {
1002
0
                continue;
1003
0
            }
1004
0
            if (limit_data[i] <= 0) {
1005
0
                null_map[i] = 1;
1006
0
                continue;
1007
0
            }
1008
0
            if (bitmap_data[i].offset_limit(offset_data[i], limit_data[i], &res[i]) == 0) {
1009
0
                null_map[i] = 1;
1010
0
            }
1011
0
        }
1012
0
    }
1013
    static void vector_scalars(const TData1& bitmap_data, const Int64& offset_data,
1014
                               const Int64& limit_data, NullMap& null_map, size_t input_rows_count,
1015
0
                               TData1& res) {
1016
0
        for (int i = 0; i < input_rows_count; ++i) {
1017
0
            if (null_map[i]) {
1018
0
                continue;
1019
0
            }
1020
0
            if (limit_data <= 0) {
1021
0
                null_map[i] = 1;
1022
0
                continue;
1023
0
            }
1024
0
            if (bitmap_data[i].offset_limit(offset_data, limit_data, &res[i]) == 0) {
1025
0
                null_map[i] = 1;
1026
0
            }
1027
0
        }
1028
0
    }
1029
};
1030
1031
struct BitmapSubsetLimit {
1032
    static constexpr auto name = "bitmap_subset_limit";
1033
    using TData1 = std::vector<BitmapValue>;
1034
    using TData2 = typename ColumnInt64::Container;
1035
1036
    static void vector3(const TData1& bitmap_data, const TData2& offset_data,
1037
                        const TData2& limit_data, NullMap& null_map, size_t input_rows_count,
1038
0
                        TData1& res) {
1039
0
        for (int i = 0; i < input_rows_count; ++i) {
1040
0
            if (null_map[i]) {
1041
0
                continue;
1042
0
            }
1043
0
            if (offset_data[i] < 0 || limit_data[i] < 0) {
1044
0
                null_map[i] = 1;
1045
0
                continue;
1046
0
            }
1047
0
            bitmap_data[i].sub_limit(offset_data[i], limit_data[i], &res[i]);
1048
0
        }
1049
0
    }
1050
    static void vector_scalars(const TData1& bitmap_data, const Int64& offset_data,
1051
                               const Int64& limit_data, NullMap& null_map, size_t input_rows_count,
1052
0
                               TData1& res) {
1053
0
        for (int i = 0; i < input_rows_count; ++i) {
1054
0
            if (null_map[i]) {
1055
0
                continue;
1056
0
            }
1057
0
            if (offset_data < 0 || limit_data < 0) {
1058
0
                null_map[i] = 1;
1059
0
                continue;
1060
0
            }
1061
0
            bitmap_data[i].sub_limit(offset_data, limit_data, &res[i]);
1062
0
        }
1063
0
    }
1064
};
1065
1066
struct BitmapSubsetInRange {
1067
    static constexpr auto name = "bitmap_subset_in_range";
1068
    using TData1 = std::vector<BitmapValue>;
1069
    using TData2 = typename ColumnInt64::Container;
1070
1071
    static void vector3(const TData1& bitmap_data, const TData2& range_start,
1072
                        const TData2& range_end, NullMap& null_map, size_t input_rows_count,
1073
0
                        TData1& res) {
1074
0
        for (int i = 0; i < input_rows_count; ++i) {
1075
0
            if (null_map[i]) {
1076
0
                continue;
1077
0
            }
1078
0
            if (range_start[i] >= range_end[i] || range_start[i] < 0 || range_end[i] < 0) {
1079
0
                null_map[i] = 1;
1080
0
                continue;
1081
0
            }
1082
0
            bitmap_data[i].sub_range(range_start[i], range_end[i], &res[i]);
1083
0
        }
1084
0
    }
1085
    static void vector_scalars(const TData1& bitmap_data, const Int64& range_start,
1086
                               const Int64& range_end, NullMap& null_map, size_t input_rows_count,
1087
0
                               TData1& res) {
1088
0
        for (int i = 0; i < input_rows_count; ++i) {
1089
0
            if (null_map[i]) {
1090
0
                continue;
1091
0
            }
1092
0
            if (range_start >= range_end || range_start < 0 || range_end < 0) {
1093
0
                null_map[i] = 1;
1094
0
                continue;
1095
0
            }
1096
0
            bitmap_data[i].sub_range(range_start, range_end, &res[i]);
1097
0
        }
1098
0
    }
1099
};
1100
1101
template <typename Impl>
1102
class FunctionBitmapSubs : public IFunction {
1103
public:
1104
    static constexpr auto name = Impl::name;
1105
3
    String get_name() const override { return name; }
_ZNK5doris18FunctionBitmapSubsINS_9SubBitmapEE8get_nameB5cxx11Ev
Line
Count
Source
1105
1
    String get_name() const override { return name; }
_ZNK5doris18FunctionBitmapSubsINS_17BitmapSubsetLimitEE8get_nameB5cxx11Ev
Line
Count
Source
1105
1
    String get_name() const override { return name; }
_ZNK5doris18FunctionBitmapSubsINS_19BitmapSubsetInRangeEE8get_nameB5cxx11Ev
Line
Count
Source
1105
1
    String get_name() const override { return name; }
1106
1107
6
    static FunctionPtr create() { return std::make_shared<FunctionBitmapSubs>(); }
_ZN5doris18FunctionBitmapSubsINS_9SubBitmapEE6createEv
Line
Count
Source
1107
2
    static FunctionPtr create() { return std::make_shared<FunctionBitmapSubs>(); }
_ZN5doris18FunctionBitmapSubsINS_17BitmapSubsetLimitEE6createEv
Line
Count
Source
1107
2
    static FunctionPtr create() { return std::make_shared<FunctionBitmapSubs>(); }
_ZN5doris18FunctionBitmapSubsINS_19BitmapSubsetInRangeEE6createEv
Line
Count
Source
1107
2
    static FunctionPtr create() { return std::make_shared<FunctionBitmapSubs>(); }
1108
1109
0
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1110
0
        return make_nullable(std::make_shared<DataTypeBitMap>());
1111
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
1112
1113
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
1114
1115
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
1116
0
                        uint32_t result, size_t input_rows_count) const override {
1117
0
        DCHECK_EQ(arguments.size(), 3);
1118
0
        auto res_null_map = ColumnUInt8::create(input_rows_count, 0);
1119
0
        auto res_data_column = ColumnBitmap::create(input_rows_count);
1120
1121
0
        bool col_const[3];
1122
0
        ColumnPtr argument_columns[3];
1123
0
        for (int i = 0; i < 3; ++i) {
1124
0
            col_const[i] = is_column_const(*block.get_by_position(arguments[i]).column);
1125
0
        }
1126
0
        argument_columns[0] = col_const[0] ? static_cast<const ColumnConst&>(
1127
0
                                                     *block.get_by_position(arguments[0]).column)
1128
0
                                                     .convert_to_full_column()
1129
0
                                           : block.get_by_position(arguments[0]).column;
1130
1131
0
        default_preprocess_parameter_columns(argument_columns, col_const, {1, 2}, block, arguments);
1132
1133
0
        auto bitmap_column = assert_cast<const ColumnBitmap*>(argument_columns[0].get());
1134
0
        auto offset_column = assert_cast<const ColumnInt64*>(argument_columns[1].get());
1135
0
        auto limit_column = assert_cast<const ColumnInt64*>(argument_columns[2].get());
1136
1137
0
        if (col_const[1] && col_const[2]) {
1138
0
            Impl::vector_scalars(bitmap_column->get_data(), offset_column->get_element(0),
1139
0
                                 limit_column->get_element(0), res_null_map->get_data(),
1140
0
                                 input_rows_count, res_data_column->get_data());
1141
0
        } else {
1142
0
            Impl::vector3(bitmap_column->get_data(), offset_column->get_data(),
1143
0
                          limit_column->get_data(), res_null_map->get_data(), input_rows_count,
1144
0
                          res_data_column->get_data());
1145
0
        }
1146
1147
0
        block.get_by_position(result).column =
1148
0
                ColumnNullable::create(std::move(res_data_column), std::move(res_null_map));
1149
0
        return Status::OK();
1150
0
    }
Unexecuted instantiation: _ZNK5doris18FunctionBitmapSubsINS_9SubBitmapEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris18FunctionBitmapSubsINS_17BitmapSubsetLimitEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
Unexecuted instantiation: _ZNK5doris18FunctionBitmapSubsINS_19BitmapSubsetInRangeEE12execute_implEPNS_15FunctionContextERNS_5BlockERKSt6vectorIjSaIjEEjm
1151
};
1152
1153
class FunctionBitmapToArray : public IFunction {
1154
public:
1155
    static constexpr auto name = "bitmap_to_array";
1156
1157
1
    String get_name() const override { return name; }
1158
1159
2
    static FunctionPtr create() { return std::make_shared<FunctionBitmapToArray>(); }
1160
1161
0
    DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
1162
0
        auto nested_type = make_nullable(std::make_shared<DataTypeInt64>());
1163
0
        return std::make_shared<DataTypeArray>(nested_type);
1164
0
    }
1165
1166
0
    size_t get_number_of_arguments() const override { return 1; }
1167
1168
    Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
1169
0
                        uint32_t result, size_t input_rows_count) const override {
1170
0
        auto return_nested_type = make_nullable(std::make_shared<DataTypeInt64>());
1171
0
        auto dest_array_column_ptr = ColumnArray::create(return_nested_type->create_column(),
1172
0
                                                         ColumnArray::ColumnOffsets::create());
1173
1174
0
        IColumn* dest_nested_column = &dest_array_column_ptr->get_data();
1175
0
        ColumnNullable* dest_nested_nullable_col =
1176
0
                reinterpret_cast<ColumnNullable*>(dest_nested_column);
1177
0
        dest_nested_column = dest_nested_nullable_col->get_nested_column_ptr().get();
1178
0
        auto& dest_nested_null_map = dest_nested_nullable_col->get_null_map_column().get_data();
1179
1180
0
        auto& arg_col = block.get_by_position(arguments[0]).column;
1181
0
        auto bitmap_col = assert_cast<const ColumnBitmap*>(arg_col.get());
1182
0
        const auto& bitmap_col_data = bitmap_col->get_data();
1183
0
        auto& nested_column_data = assert_cast<ColumnInt64*>(dest_nested_column)->get_data();
1184
0
        auto& dest_offsets = dest_array_column_ptr->get_offsets();
1185
0
        dest_offsets.reserve(input_rows_count);
1186
1187
0
        for (int i = 0; i < input_rows_count; ++i) {
1188
0
            bitmap_col_data[i].to_array(nested_column_data);
1189
0
            dest_nested_null_map.resize_fill(nested_column_data.size(), 0);
1190
0
            dest_offsets.push_back(nested_column_data.size());
1191
0
        }
1192
1193
0
        block.replace_by_position(result, std::move(dest_array_column_ptr));
1194
0
        return Status::OK();
1195
0
    }
1196
};
1197
1198
using FunctionBitmapEmpty = FunctionConst<BitmapEmpty, false>;
1199
using FunctionToBitmap = FunctionAlwaysNotNullable<ToBitmap>;
1200
using FunctionToBitmapWithCheck = FunctionAlwaysNotNullable<ToBitmapWithCheck, true>;
1201
1202
using FunctionBitmapFromString = FunctionBitmapAlwaysNull<BitmapFromString>;
1203
using FunctionBitmapFromArray = FunctionBitmapAlwaysNull<BitmapFromArray>;
1204
using FunctionBitmapHash = FunctionAlwaysNotNullable<BitmapHash<32>>;
1205
using FunctionBitmapHash64 = FunctionAlwaysNotNullable<BitmapHash<64>>;
1206
1207
using FunctionBitmapMin = FunctionBitmapSingle<FunctionBitmapMinImpl>;
1208
using FunctionBitmapMax = FunctionBitmapSingle<FunctionBitmapMaxImpl>;
1209
1210
using FunctionBitmapToString = FunctionUnaryToType<BitmapToString, NameBitmapToString>;
1211
using FunctionBitmapToBase64 = FunctionUnaryToType<BitmapToBase64, NameBitmapToBase64>;
1212
using FunctionBitmapFromBase64 = FunctionBitmapAlwaysNull<BitmapFromBase64>;
1213
using FunctionBitmapNot =
1214
        FunctionBinaryToType<DataTypeBitMap, DataTypeBitMap, BitmapNot, NameBitmapNot>;
1215
using FunctionBitmapContains =
1216
        FunctionBinaryToType<DataTypeBitMap, DataTypeInt64, BitmapContains, NameBitmapContains>;
1217
using FunctionBitmapRemove =
1218
        FunctionBinaryToType<DataTypeBitMap, DataTypeInt64, BitmapRemove, NameBitmapRemove>;
1219
1220
using FunctionBitmapHasAny =
1221
        FunctionBinaryToType<DataTypeBitMap, DataTypeBitMap, BitmapHasAny, NameBitmapHasAny>;
1222
using FunctionBitmapHasAll =
1223
        FunctionBinaryToType<DataTypeBitMap, DataTypeBitMap, BitmapHasAll, NameBitmapHasAll>;
1224
using FunctionSubBitmap = FunctionBitmapSubs<SubBitmap>;
1225
using FunctionBitmapSubsetLimit = FunctionBitmapSubs<BitmapSubsetLimit>;
1226
using FunctionBitmapSubsetInRange = FunctionBitmapSubs<BitmapSubsetInRange>;
1227
1228
1
void register_function_bitmap(SimpleFunctionFactory& factory) {
1229
1
    factory.register_function<FunctionBitmapEmpty>();
1230
1
    factory.register_function<FunctionToBitmap>();
1231
1
    factory.register_function<FunctionToBitmapWithCheck>();
1232
1
    factory.register_function<FunctionBitmapFromString>();
1233
1
    factory.register_function<FunctionBitmapToBase64>();
1234
1
    factory.register_function<FunctionBitmapFromBase64>();
1235
1
    factory.register_function<FunctionBitmapFromArray>();
1236
1
    factory.register_function<FunctionBitmapHash>();
1237
1
    factory.register_function<FunctionBitmapHash64>();
1238
1
    factory.register_function<FunctionBitmapCount>();
1239
1
    factory.register_function<FunctionBitmapMin>();
1240
1
    factory.register_function<FunctionBitmapMax>();
1241
1
    factory.register_function<FunctionBitmapToString>();
1242
1
    factory.register_function<FunctionBitmapNot>();
1243
1
    factory.register_alias(NameBitmapNot::name, "bitmap_and_not");
1244
1
    factory.register_alias(NameBitmapNot::name, "bitmap_andnot");
1245
1
    factory.register_function<FunctionBitmapAndNotCount<NameBitmapAndNotCount>>();
1246
1
    factory.register_function<FunctionBitmapAndNotCount<NameBitmapAndNotCount, true>>();
1247
1
    factory.register_alias(NameBitmapAndNotCount::name, "bitmap_andnot_count");
1248
1
    factory.register_function<FunctionBitmapContains>();
1249
1
    factory.register_function<FunctionBitmapRemove>();
1250
1
    factory.register_function<FunctionBitmapHasAny>();
1251
1
    factory.register_function<FunctionBitmapHasAll>();
1252
1
    factory.register_function<FunctionSubBitmap>();
1253
1
    factory.register_function<FunctionBitmapSubsetLimit>();
1254
1
    factory.register_function<FunctionBitmapSubsetInRange>();
1255
1
    factory.register_function<FunctionBitmapToArray>();
1256
1
}
1257
1258
} // namespace doris