Coverage Report

Created: 2026-03-14 20:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/predicate/block_column_predicate.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "storage/predicate/block_column_predicate.h"
19
20
#include <string.h>
21
22
namespace roaring {
23
class Roaring;
24
} // namespace roaring
25
26
namespace doris {
27
namespace segment_v2 {
28
class InvertedIndexIterator;
29
} // namespace segment_v2
30
31
uint16_t SingleColumnBlockPredicate::evaluate(MutableColumns& block, uint16_t* sel,
32
4.20k
                                              uint16_t selected_size) const {
33
4.20k
    auto column_id = _predicate->column_id();
34
4.20k
    auto& column = block[column_id];
35
4.20k
    return _predicate->evaluate(*column, sel, selected_size);
36
4.20k
}
37
38
void SingleColumnBlockPredicate::evaluate_and(MutableColumns& block, uint16_t* sel,
39
4
                                              uint16_t selected_size, bool* flags) const {
40
4
    auto column_id = _predicate->column_id();
41
4
    auto& column = block[column_id];
42
4
    _predicate->evaluate_and(*column, sel, selected_size, flags);
43
4
}
44
45
582
bool SingleColumnBlockPredicate::evaluate_and(const segment_v2::ZoneMap& zone_map) const {
46
582
    return _predicate->evaluate_and(zone_map);
47
582
}
48
49
10
bool SingleColumnBlockPredicate::evaluate_and(const segment_v2::BloomFilter* bf) const {
50
10
    return _predicate->evaluate_and(bf);
51
10
}
52
53
bool SingleColumnBlockPredicate::evaluate_and(const StringRef* dict_words,
54
0
                                              const size_t dict_num) const {
55
0
    return _predicate->evaluate_and(dict_words, dict_num);
56
0
}
57
58
void SingleColumnBlockPredicate::evaluate_or(MutableColumns& block, uint16_t* sel,
59
6
                                             uint16_t selected_size, bool* flags) const {
60
6
    auto column_id = _predicate->column_id();
61
6
    auto& column = block[column_id];
62
6
    _predicate->evaluate_or(*column, sel, selected_size, flags);
63
6
}
64
65
void SingleColumnBlockPredicate::evaluate_vec(MutableColumns& block, uint16_t size,
66
0
                                              bool* flags) const {
67
0
    auto column_id = _predicate->column_id();
68
0
    auto& column = block[column_id];
69
70
    // Dictionary column should do something to initial.
71
0
    if (PredicateTypeTraits::is_range(_predicate->type())) {
72
0
        column->convert_dict_codes_if_necessary();
73
0
    } else if (PredicateTypeTraits::is_bloom_filter(_predicate->type())) {
74
0
        column->initialize_hash_values_for_runtime_filter();
75
0
    }
76
77
0
    _predicate->evaluate_vec(*column, size, flags);
78
0
}
79
80
uint16_t OrBlockColumnPredicate::evaluate(MutableColumns& block, uint16_t* sel,
81
4
                                          uint16_t selected_size) const {
82
4
    if (num_of_column_predicate() == 1) {
83
0
        return _block_column_predicate_vec[0]->evaluate(block, sel, selected_size);
84
4
    } else {
85
4
        if (!selected_size) {
86
0
            return 0;
87
0
        }
88
4
        std::vector<uint8_t> ret_flags(selected_size, 0);
89
12
        for (int i = 0; i < num_of_column_predicate(); ++i) {
90
8
            _block_column_predicate_vec[i]->evaluate_or(block, sel, selected_size,
91
8
                                                        (bool*)ret_flags.data());
92
8
        }
93
94
4
        uint16_t new_size = 0;
95
38
        for (int i = 0; i < selected_size; ++i) {
96
34
            if (ret_flags[i]) {
97
23
                sel[new_size++] = sel[i];
98
23
            }
99
34
        }
100
4
        return new_size;
101
4
    }
102
4
}
103
104
void OrBlockColumnPredicate::evaluate_or(MutableColumns& block, uint16_t* sel,
105
0
                                         uint16_t selected_size, bool* flags) const {
106
0
    for (auto& block_column_predicate : _block_column_predicate_vec) {
107
0
        block_column_predicate->evaluate_or(block, sel, selected_size, flags);
108
0
    }
109
0
}
110
111
void OrBlockColumnPredicate::evaluate_and(MutableColumns& block, uint16_t* sel,
112
0
                                          uint16_t selected_size, bool* flags) const {
113
0
    if (num_of_column_predicate() == 1) {
114
0
        _block_column_predicate_vec[0]->evaluate_and(block, sel, selected_size, flags);
115
0
    } else {
116
0
        std::vector<uint8_t> ret_flags(selected_size, 0);
117
0
        for (int i = 0; i < num_of_column_predicate(); ++i) {
118
0
            _block_column_predicate_vec[i]->evaluate_or(block, sel, selected_size,
119
0
                                                        (bool*)ret_flags.data());
120
0
        }
121
122
0
        for (int i = 0; i < selected_size; ++i) {
123
0
            flags[i] &= ret_flags[i];
124
0
        }
125
0
    }
126
0
}
127
128
bool OrBlockColumnPredicate::evaluate_and(ParquetPredicate::CachedPageIndexStat* statistic,
129
0
                                          RowRanges* row_ranges) const {
130
0
    if (num_of_column_predicate() >= 1) {
131
0
        _block_column_predicate_vec[0]->evaluate_and(statistic, row_ranges);
132
0
        for (int i = 1; i < num_of_column_predicate(); ++i) {
133
0
            RowRanges tmp_row_ranges;
134
0
            _block_column_predicate_vec[i]->evaluate_and(statistic, &tmp_row_ranges);
135
0
            RowRanges::ranges_union(*row_ranges, tmp_row_ranges, row_ranges);
136
0
        }
137
0
    }
138
0
    return row_ranges->count() != 0;
139
0
}
140
141
bool AndBlockColumnPredicate::evaluate_and(ParquetPredicate::CachedPageIndexStat* statistic,
142
0
                                           RowRanges* row_ranges) const {
143
0
    if (num_of_column_predicate() >= 1) {
144
0
        for (int i = 0; i < num_of_column_predicate(); ++i) {
145
0
            RowRanges tmp_row_ranges;
146
0
            if (!_block_column_predicate_vec[i]->evaluate_and(statistic, &tmp_row_ranges)) {
147
0
                return false;
148
0
            }
149
150
0
            if (i == 0) {
151
0
                *row_ranges = tmp_row_ranges;
152
0
            } else {
153
0
                RowRanges::ranges_intersection(*row_ranges, tmp_row_ranges, row_ranges);
154
0
            }
155
0
        }
156
0
    }
157
0
    return true;
158
0
}
159
160
uint16_t AndBlockColumnPredicate::evaluate(MutableColumns& block, uint16_t* sel,
161
4.20k
                                           uint16_t selected_size) const {
162
4.20k
    for (auto& block_column_predicate : _block_column_predicate_vec) {
163
4.20k
        selected_size = block_column_predicate->evaluate(block, sel, selected_size);
164
4.20k
    }
165
4.20k
    return selected_size;
166
4.20k
}
167
168
void AndBlockColumnPredicate::evaluate_and(MutableColumns& block, uint16_t* sel,
169
0
                                           uint16_t selected_size, bool* flags) const {
170
0
    for (auto& block_column_predicate : _block_column_predicate_vec) {
171
0
        block_column_predicate->evaluate_and(block, sel, selected_size, flags);
172
0
    }
173
0
}
174
175
0
bool AndBlockColumnPredicate::evaluate_and(const segment_v2::ZoneMap& zone_map) const {
176
0
    for (auto& block_column_predicate : _block_column_predicate_vec) {
177
0
        if (!block_column_predicate->evaluate_and(zone_map)) {
178
0
            return false;
179
0
        }
180
0
    }
181
0
    return true;
182
0
}
183
184
0
bool AndBlockColumnPredicate::evaluate_and(const segment_v2::BloomFilter* bf) const {
185
0
    for (auto& block_column_predicate : _block_column_predicate_vec) {
186
0
        if (!block_column_predicate->evaluate_and(bf)) {
187
0
            return false;
188
0
        }
189
0
    }
190
0
    return true;
191
0
}
192
193
bool AndBlockColumnPredicate::evaluate_and(const StringRef* dict_words,
194
0
                                           const size_t dict_num) const {
195
0
    for (auto& predicate : _block_column_predicate_vec) {
196
0
        if (!predicate->evaluate_and(dict_words, dict_num)) {
197
0
            return false;
198
0
        }
199
0
    }
200
0
    return true;
201
0
}
202
203
void AndBlockColumnPredicate::evaluate_or(MutableColumns& block, uint16_t* sel,
204
2
                                          uint16_t selected_size, bool* flags) const {
205
2
    if (num_of_column_predicate() == 1) {
206
0
        _block_column_predicate_vec[0]->evaluate_or(block, sel, selected_size, flags);
207
2
    } else {
208
2
        std::vector<uint8_t> new_flags(selected_size, 1);
209
4
        for (const auto& block_column_predicate : _block_column_predicate_vec) {
210
4
            block_column_predicate->evaluate_and(block, sel, selected_size,
211
4
                                                 (bool*)new_flags.data());
212
4
        }
213
214
16
        for (uint16_t i = 0; i < selected_size; i++) {
215
14
            flags[i] |= new_flags[i];
216
14
        }
217
2
    }
218
2
}
219
220
// todo(wb) Can the 'and' of multiple bitmaps be vectorized?
221
void AndBlockColumnPredicate::evaluate_vec(MutableColumns& block, uint16_t size,
222
0
                                           bool* flags) const {
223
0
    if (num_of_column_predicate() == 1) {
224
0
        _block_column_predicate_vec[0]->evaluate_vec(block, size, flags);
225
0
    } else {
226
0
        std::vector<uint8_t> new_flags(size);
227
228
0
        bool initialized = false;
229
0
        for (const auto& block_column_predicate : _block_column_predicate_vec) {
230
0
            if (initialized) {
231
0
                block_column_predicate->evaluate_vec(block, size, (bool*)new_flags.data());
232
0
                for (uint16_t j = 0; j < size; j++) {
233
0
                    flags[j] &= new_flags[j];
234
0
                }
235
0
            } else {
236
0
                block_column_predicate->evaluate_vec(block, size, flags);
237
0
                initialized = true;
238
0
            }
239
0
        }
240
0
    }
241
0
}
242
243
Status AndBlockColumnPredicate::evaluate(const std::string& column_name,
244
                                         InvertedIndexIterator* iterator, uint32_t num_rows,
245
0
                                         roaring::Roaring* bitmap) const {
246
0
    return Status::Error<ErrorCode::INVERTED_INDEX_NOT_IMPLEMENTED>(
247
0
            "Not Implemented evaluate with inverted index, please check the predicate");
248
0
}
249
250
} // namespace doris