Coverage Report

Created: 2026-10-16 23:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exprs/function/search/search_lowering.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
#pragma once
21
22
#include <gen_cpp/Exprs_types.h>
23
24
#include <cstdint>
25
#include <string>
26
#include <vector>
27
28
#include "common/status.h"
29
#include "storage/index/inverted/common/inverted_index_query_type.h"
30
#include "storage/index/inverted/query/logical/node.h"
31
32
namespace doris::index_query::logical {
33
34
// What lowering needs to know about the index a field resolves to.
35
struct FieldProps {
36
    // False when the field has no usable index in this segment.
37
    bool bound = false;
38
    // A scalar index: only TERM and EXACT apply, as a comparison.
39
    bool direct_index = false;
40
    // The index tokenizes values, so clause values are analyzed.
41
    bool analyzed = false;
42
    std::string binding;
43
};
44
45
class FieldCatalog {
46
public:
47
158
    virtual ~FieldCatalog() = default;
48
49
    // `query_type` is the reader-selection hint the clause implies (see
50
    // search_clause_query_type). An unbound field returns OK with bound=false.
51
    virtual Status resolve(const std::string& field, segment_v2::InvertedIndexQueryType query_type,
52
                           FieldProps* out) = 0;
53
54
    // Tokenizes `value` with the analyzer of the index `props` resolved to.
55
    virtual Status analyze(const FieldProps& props, const std::string& value,
56
                           std::vector<Token>* out) = 0;
57
58
    // Normalizes `value` as the analyzed index `props` resolved to normalizes its terms, without
59
    // splitting it.
60
    virtual Status normalize(const FieldProps& props, const std::string& value,
61
                             std::string* out) = 0;
62
};
63
64
struct LoweringOptions {
65
    std::string default_operator = "or";
66
    // The DSL-level threshold for multi-token TERM values; -1 when unset.
67
    int32_t minimum_should_match = -1;
68
};
69
70
// The reader-selection hint for a leaf clause type. TERM, WILDCARD, PREFIX and
71
// REGEXP prefer a tokenized index; EXACT prefers an untokenized one.
72
segment_v2::InvertedIndexQueryType search_clause_query_type(const std::string& clause_type);
73
74
// Lowers `clause` and its children. NESTED must be handled by the caller.
75
Status lower_search_clause(const TSearchClause& clause, const LoweringOptions& options,
76
                           FieldCatalog& catalog, NodePtr* out);
77
78
} // namespace doris::index_query::logical