Coverage Report

Created: 2026-06-17 19:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/predicate/like_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/like_column_predicate.h"
19
20
#include "core/column/column_string.h"
21
#include "core/data_type/define_primitive_type.h"
22
#include "core/string_ref.h"
23
#include "exprs/function/like.h"
24
#include "exprs/function_context.h"
25
26
namespace doris {
27
28
LikeColumnPredicate::LikeColumnPredicate(bool opposite, uint32_t column_id, std::string col_name,
29
                                         doris::FunctionContext* fn_ctx, doris::StringRef val)
30
0
        : ColumnPredicate(column_id, col_name, TYPE_STRING, opposite), pattern(val) {
31
0
    _state = reinterpret_cast<StateType*>(
32
0
            fn_ctx->get_function_state(doris::FunctionContext::THREAD_LOCAL));
33
0
    THROW_IF_ERROR(_state->search_state.clone(_like_state));
34
0
}
35
36
0
void LikeColumnPredicate::evaluate_vec(const IColumn& column, uint16_t size, bool* flags) const {
37
0
    _evaluate_vec<false>(column, size, flags);
38
0
}
39
40
void LikeColumnPredicate::evaluate_and_vec(const IColumn& column, uint16_t size,
41
0
                                           bool* flags) const {
42
0
    _evaluate_vec<true>(column, size, flags);
43
0
}
44
45
uint16_t LikeColumnPredicate::_evaluate_inner(const IColumn& column, uint16_t* sel,
46
0
                                              uint16_t size) const {
47
0
    uint16_t new_size = 0;
48
0
    if (is_column_nullable(column)) {
49
0
        auto* nullable_col = assert_cast<const ColumnNullable*>(&column);
50
0
        auto& null_map_data = nullable_col->get_null_map_column().get_data();
51
0
        auto& nested_col = nullable_col->get_nested_column();
52
0
        if (nested_col.is_column_dictionary()) {
53
0
            auto* nested_col_ptr = assert_cast<const ColumnDictI32*>(&nested_col);
54
0
            auto& data_array = nested_col_ptr->get_data();
55
0
            const auto& dict_res = _find_code_from_dictionary_column(*nested_col_ptr);
56
0
            if (!nullable_col->has_null()) {
57
0
                for (uint16_t i = 0; i != size; i++) {
58
0
                    uint16_t idx = sel[i];
59
0
                    sel[new_size] = idx;
60
0
                    unsigned char flag = dict_res[data_array[idx]];
61
0
                    new_size += _opposite ^ flag;
62
0
                }
63
0
            } else {
64
0
                for (uint16_t i = 0; i != size; i++) {
65
0
                    uint16_t idx = sel[i];
66
0
                    sel[new_size] = idx;
67
0
                    if (null_map_data[idx]) {
68
0
                        new_size += _opposite;
69
0
                        continue;
70
0
                    }
71
0
                    unsigned char flag = dict_res[data_array[idx]];
72
0
                    new_size += _opposite ^ flag;
73
0
                }
74
0
            }
75
0
        } else {
76
0
            auto* str_col = assert_cast<const ColumnString*>(&nested_col);
77
0
            if (!nullable_col->has_null()) {
78
0
                ColumnUInt8::Container res(size, 0);
79
0
                for (uint16_t i = 0; i != size; i++) {
80
0
                    uint16_t idx = sel[i];
81
0
                    sel[new_size] = idx;
82
0
                    unsigned char flag = 0;
83
0
                    THROW_IF_ERROR((_state->scalar_function)(
84
0
                            &_like_state, str_col->get_data_at(idx), pattern, &flag));
85
0
                    new_size += _opposite ^ flag;
86
0
                }
87
0
            } else {
88
0
                for (uint16_t i = 0; i != size; i++) {
89
0
                    uint16_t idx = sel[i];
90
0
                    sel[new_size] = idx;
91
0
                    if (null_map_data[idx]) {
92
0
                        new_size += _opposite;
93
0
                        continue;
94
0
                    }
95
96
0
                    StringRef cell_value = str_col->get_data_at(idx);
97
0
                    unsigned char flag = 0;
98
0
                    THROW_IF_ERROR((_state->scalar_function)(
99
0
                            &_like_state, StringRef(cell_value.data, cell_value.size), pattern,
100
0
                            &flag));
101
0
                    new_size += _opposite ^ flag;
102
0
                }
103
0
            }
104
0
        }
105
0
    } else {
106
0
        if (column.is_column_dictionary()) {
107
0
            auto* nested_col_ptr = assert_cast<const ColumnDictI32*>(&column);
108
0
            const auto& dict_res = _find_code_from_dictionary_column(*nested_col_ptr);
109
0
            auto& data_array = nested_col_ptr->get_data();
110
0
            for (uint16_t i = 0; i != size; i++) {
111
0
                uint16_t idx = sel[i];
112
0
                sel[new_size] = idx;
113
0
                unsigned char flag = dict_res[data_array[idx]];
114
0
                new_size += _opposite ^ flag;
115
0
            }
116
0
        } else {
117
0
            const auto* str_col = assert_cast<const ColumnString*>(&column);
118
119
0
            ColumnUInt8::Container res(size, 0);
120
0
            for (uint16_t i = 0; i != size; i++) {
121
0
                uint16_t idx = sel[i];
122
0
                sel[new_size] = idx;
123
0
                unsigned char flag = 0;
124
0
                THROW_IF_ERROR((_state->scalar_function)(&_like_state, str_col->get_data_at(idx),
125
0
                                                         pattern, &flag));
126
0
                new_size += _opposite ^ flag;
127
0
            }
128
0
        }
129
0
    }
130
0
    return new_size;
131
0
}
132
133
} //namespace doris