Coverage Report

Created: 2026-03-11 10:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/doris/be/src/runtime/runtime_predicate.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 <functional>
21
#include <memory>
22
#include <mutex>
23
#include <shared_mutex>
24
#include <string>
25
26
#include "common/status.h"
27
#include "core/arena.h"
28
#include "core/binary_cast.hpp"
29
#include "core/data_type/define_primitive_type.h"
30
#include "core/data_type/primitive_type.h"
31
#include "core/field.h"
32
#include "core/types.h"
33
#include "core/value/vdatetime_value.h"
34
#include "storage/olap_scan_common.h"
35
#include "storage/predicate/shared_predicate.h"
36
#include "storage/tablet/tablet_schema.h"
37
38
namespace doris {
39
class ColumnPredicate;
40
41
class RuntimePredicate {
42
public:
43
    RuntimePredicate(const TTopnFilterDesc& desc);
44
45
    Status init_target(int32_t target_node_id,
46
                       phmap::flat_hash_map<int, SlotDescriptor*> slot_id_to_slot_desc,
47
                       const int column_id);
48
49
0
    bool enable() const {
50
        // when sort node and scan node are not in the same fragment, predicate will be disabled
51
0
        std::shared_lock<std::shared_mutex> rlock(_rwlock);
52
0
        return _detected_source && _detected_target;
53
0
    }
54
55
0
    void set_detected_source() {
56
0
        std::unique_lock<std::shared_mutex> wlock(_rwlock);
57
0
        _orderby_extrem = Field(PrimitiveType::TYPE_NULL);
58
0
        _detected_source = true;
59
0
    }
60
61
0
    std::shared_ptr<ColumnPredicate> get_predicate(int32_t target_node_id) {
62
0
        std::shared_lock<std::shared_mutex> rlock(_rwlock);
63
0
        check_target_node_id(target_node_id);
64
0
        return _contexts.find(target_node_id)->second.predicate;
65
0
    }
66
67
    Status update(const Field& value);
68
69
0
    bool has_value() const {
70
0
        std::shared_lock<std::shared_mutex> rlock(_rwlock);
71
0
        return _has_value;
72
0
    }
73
74
0
    Field get_value() const {
75
0
        std::shared_lock<std::shared_mutex> rlock(_rwlock);
76
0
        return _orderby_extrem;
77
0
    }
78
79
0
    std::string get_col_name(int32_t target_node_id) const {
80
0
        check_target_node_id(target_node_id);
81
0
        return _contexts.find(target_node_id)->second.col_name;
82
0
    }
83
84
0
    bool is_asc() const { return _is_asc; }
85
86
0
    bool nulls_first() const { return _nulls_first; }
87
88
0
    bool target_is_slot(int32_t target_node_id) const {
89
0
        check_target_node_id(target_node_id);
90
0
        return _contexts.find(target_node_id)->second.target_is_slot();
91
0
    }
92
93
0
    const TExpr& get_texpr(int32_t target_node_id) const {
94
0
        check_target_node_id(target_node_id);
95
0
        return _contexts.find(target_node_id)->second.expr;
96
0
    }
97
98
private:
99
0
    void check_target_node_id(int32_t target_node_id) const {
100
0
        if (!_contexts.contains(target_node_id)) {
101
0
            std::string msg = "context target node ids: [";
102
0
            bool first = true;
103
0
            for (auto p : _contexts) {
104
0
                if (first) {
105
0
                    first = false;
106
0
                } else {
107
0
                    msg += ',';
108
0
                }
109
0
                msg += std::to_string(p.first);
110
0
            }
111
0
            msg += "], input target node is: " + std::to_string(target_node_id);
112
0
            DCHECK(false) << msg;
113
0
        }
114
0
    }
115
    struct TargetContext {
116
        TExpr expr;
117
        std::string col_name;
118
        DataTypePtr col_data_type;
119
        std::shared_ptr<ColumnPredicate> predicate;
120
121
0
        bool target_is_slot() const {
122
0
            return expr.nodes[0].node_type == TExprNodeType::SLOT_REF &&
123
0
                   expr.nodes[0].slot_ref.is_virtual_slot == false;
124
0
        }
125
    };
126
127
    bool _init(PrimitiveType type);
128
129
    mutable std::shared_mutex _rwlock;
130
131
    bool _nulls_first;
132
    bool _is_asc;
133
    std::map<int32_t, TargetContext> _contexts;
134
135
    Field _orderby_extrem {PrimitiveType::TYPE_NULL};
136
    std::function<std::shared_ptr<ColumnPredicate>(const int cid, const std::string& col_name,
137
                                                   const DataTypePtr& data_type, const Field& value,
138
                                                   bool opposite)>
139
            _pred_constructor;
140
    bool _detected_source = false;
141
    bool _detected_target = false;
142
    bool _has_value = false;
143
    PrimitiveType _type;
144
};
145
146
} // namespace doris