Coverage Report

Created: 2026-10-20 19:14

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
54
    static bool is_normalizer_only(const std::map<std::string, std::string>& properties) {
32
54
        const auto normalizer = properties.find(INVERTED_INDEX_NORMALIZER_NAME_KEY);
33
54
        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
54
        return !properties.contains(INVERTED_INDEX_PARSER_PHRASE_SUPPORT_KEY) &&
36
54
               normalizer != properties.end() && boost::iequals(normalizer->second, "lowercase") &&
37
54
               (analyzer == properties.end() || analyzer->second.empty()) &&
38
54
               get_parser_string_from_properties(properties) == INVERTED_INDEX_PARSER_NONE;
39
54
    }
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
    // MATCH filters score analyzed phrase indexes and single-term normalizers.
107
    static bool is_need_similarity_score(InvertedIndexQueryType query_type,
108
                                         const TabletIndex* index_meta);
109
110
    static bool is_need_similarity_score(TExprOpcode::type query_type,
111
                                         const TabletIndex* index_meta);
112
};
113
114
} // namespace doris::segment_v2