Coverage Report

Created: 2026-10-19 11:41

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/index/index_reader_helper.h
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
#pragma once
19
20
#include <boost/algorithm/string/predicate.hpp>
21
#include <map>
22
#include <string>
23
24
#include "storage/index/index_iterator.h"
25
#include "storage/index/inverted/inverted_index_reader.h"
26
27
namespace doris::segment_v2 {
28
29
class IndexReaderHelper {
30
public:
31
39
    static bool is_normalizer_only(const std::map<std::string, std::string>& properties) {
32
39
        const auto normalizer = properties.find(INVERTED_INDEX_NORMALIZER_NAME_KEY);
33
39
        const auto analyzer = properties.find(INVERTED_INDEX_ANALYZER_NAME_KEY);
34
        // A custom normalizer can split a value into multiple terms that need positions.
35
39
        return !properties.contains(INVERTED_INDEX_PARSER_PHRASE_SUPPORT_KEY) &&
36
39
               normalizer != properties.end() && boost::iequals(normalizer->second, "lowercase") &&
37
39
               (analyzer == properties.end() || analyzer->second.empty()) &&
38
39
               get_parser_string_from_properties(properties) == INVERTED_INDEX_PARSER_NONE;
39
39
    }
40
41
25
    static bool is_fulltext_index(const IndexReaderPtr& reader) {
42
25
        if (reader == nullptr || reader->index_type() != IndexType::INVERTED) {
43
4
            return false;
44
4
        }
45
46
21
        auto inverted_index_reader = std::static_pointer_cast<InvertedIndexReader>(reader);
47
21
        return inverted_index_reader->type() == InvertedIndexReaderType::FULLTEXT;
48
25
    }
49
50
14
    static bool is_string_index(const IndexReaderPtr& reader) {
51
14
        if (reader == nullptr || reader->index_type() != IndexType::INVERTED) {
52
2
            return false;
53
2
        }
54
55
12
        auto inverted_index_reader = std::static_pointer_cast<InvertedIndexReader>(reader);
56
12
        return inverted_index_reader->type() == InvertedIndexReaderType::STRING_TYPE;
57
14
    }
58
59
15
    static bool is_bkd_index(const IndexReaderPtr& reader) {
60
15
        if (reader == nullptr || reader->index_type() != IndexType::INVERTED) {
61
3
            return false;
62
3
        }
63
64
12
        auto inverted_index_reader = std::static_pointer_cast<InvertedIndexReader>(reader);
65
12
        return inverted_index_reader->type() == InvertedIndexReaderType::BKD;
66
15
    }
67
68
53
    static bool is_support_phrase(const IndexReaderPtr& reader) {
69
53
        if (reader == nullptr || reader->index_type() != IndexType::INVERTED) {
70
4
            return false;
71
4
        }
72
73
49
        auto inverted_index_reader = std::static_pointer_cast<InvertedIndexReader>(reader);
74
49
        const auto& properties = inverted_index_reader->get_index_properties();
75
49
        return get_parser_phrase_support_string_from_properties(properties) ==
76
49
                       INVERTED_INDEX_PARSER_PHRASE_SUPPORT_YES ||
77
49
               is_normalizer_only(properties);
78
53
    }
79
80
    // only string type or bkd index reader can be used for equal
81
9
    static bool has_string_or_bkd_index(const IndexIterator* iter) {
82
9
        if (iter == nullptr) {
83
0
            return false;
84
0
        }
85
86
9
        return iter->get_reader(InvertedIndexReaderType::STRING_TYPE) != nullptr ||
87
9
               iter->get_reader(InvertedIndexReaderType::BKD) != nullptr;
88
9
    }
89
90
8
    static bool has_bkd_index(const IndexIterator* iter) {
91
8
        if (iter == nullptr) {
92
0
            return false;
93
0
        }
94
95
8
        return iter->get_reader(InvertedIndexReaderType::BKD) != nullptr;
96
8
    }
97
98
0
    static bool has_string_index(const IndexIterator* iter) {
99
0
        if (iter == nullptr) {
100
0
            return false;
101
0
        }
102
0
103
0
        return iter->get_reader(InvertedIndexReaderType::STRING_TYPE) != nullptr;
104
0
    }
105
106
    static bool is_need_similarity_score(InvertedIndexQueryType query_type,
107
20
                                         const TabletIndex* index_meta) {
108
20
        if (query_type == InvertedIndexQueryType::MATCH_ANY_QUERY ||
109
20
            query_type == InvertedIndexQueryType::MATCH_ALL_QUERY ||
110
20
            query_type == InvertedIndexQueryType::MATCH_PHRASE_QUERY ||
111
20
            query_type == InvertedIndexQueryType::MATCH_PHRASE_PREFIX_QUERY) {
112
18
            const auto& properties = index_meta->properties();
113
18
            if (get_parser_phrase_support_string_from_properties(properties) ==
114
18
                        INVERTED_INDEX_PARSER_PHRASE_SUPPORT_YES ||
115
18
                is_normalizer_only(properties)) {
116
17
                return true;
117
17
            }
118
18
        }
119
3
        return false;
120
20
    }
121
122
    static bool is_need_similarity_score(TExprOpcode::type query_type,
123
42
                                         const TabletIndex* index_meta) {
124
42
        if (query_type == TExprOpcode::MATCH_ANY || query_type == TExprOpcode::MATCH_ALL ||
125
42
            query_type == TExprOpcode::MATCH_PHRASE ||
126
42
            query_type == TExprOpcode::MATCH_PHRASE_PREFIX) {
127
40
            const auto& properties = index_meta->properties();
128
40
            if (get_parser_phrase_support_string_from_properties(properties) ==
129
40
                        INVERTED_INDEX_PARSER_PHRASE_SUPPORT_YES ||
130
40
                is_normalizer_only(properties)) {
131
39
                return true;
132
39
            }
133
40
        }
134
3
        return false;
135
42
    }
136
};
137
138
} // namespace doris::segment_v2