Coverage Report

Created: 2026-07-07 22:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/exec/operator/materialization_opertor.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 <stdint.h>
21
22
#include <map>
23
#include <string>
24
#include <unordered_map>
25
26
#include "common/status.h"
27
#include "exec/operator/operator.h"
28
29
namespace doris {
30
class RuntimeState;
31
32
class MaterializationOperator;
33
34
struct FetchRpcStruct {
35
    std::shared_ptr<PBackendService_Stub> stub;
36
    std::unique_ptr<brpc::Controller> cntl;
37
    PMultiGetRequestV2 request;
38
    PMultiGetResponseV2 response;
39
    std::string backend_address;
40
};
41
42
struct MaterializationSharedState {
43
public:
44
5
    MaterializationSharedState() = default;
45
46
    Status init_multi_requests(const TMaterializationNode& tnode, RuntimeState* state);
47
    Status create_muiltget_result(const Columns& columns, bool eos);
48
49
    Status merge_multi_response(RuntimeProfile* profile);
50
    void get_block(Block* block);
51
52
private:
53
    void _update_profile_info(int64_t backend_id, RuntimeProfile* response_profile);
54
    void _update_topn_lazy_materialization_profile(RuntimeProfile* profile);
55
56
    struct TopNLazyMaterializationBackendStats {
57
        std::string backend;
58
        int64_t rows_read = 0;
59
        int64_t segments_read = 0;
60
        int64_t local_io_count = 0;
61
        int64_t local_io_bytes = 0;
62
        int64_t remote_io_count = 0;
63
        int64_t remote_io_bytes = 0;
64
        int64_t skip_cache_io_count = 0;
65
        int64_t write_cache_bytes = 0;
66
        int64_t local_io_time = 0;
67
        int64_t remote_io_time = 0;
68
        int64_t write_cache_io_time = 0;
69
    };
70
71
public:
72
    bool rpc_struct_inited = false;
73
74
    bool eos = false;
75
    // empty materialization sink block not need to merge block
76
    bool need_merge_block = true;
77
    Block origin_block;
78
    // The rowid column of the origin block. should be replaced by the column of the result block.
79
    std::vector<int> rowid_locs;
80
    std::vector<MutableBlock> response_blocks;
81
    std::map<int64_t, FetchRpcStruct> rpc_struct_map;
82
    // Register each line in which block to ensure the order of the result.
83
    // Zero means NULL value.
84
    std::vector<std::vector<int64_t>> block_order_results;
85
    // backend id => <rpc profile info string key, rpc profile info string value>.
86
    std::map<int64_t, std::map<std::string, fmt::memory_buffer>> backend_profile_info_string;
87
88
    // Store the maximum number of rows processed by a single backend in the current batch
89
    uint32_t _max_rows_per_backend = 0;
90
    // Store the number of rows processed by each backend
91
    std::unordered_map<int64_t, uint32_t> _backend_rows_count; // backend_id => rows_count
92
93
private:
94
    // backend id => accumulated TopN phase-2 profile stats.
95
    std::map<int64_t, TopNLazyMaterializationBackendStats> _topn_lazy_materialization_backend_stats;
96
};
97
98
class MaterializationLocalState final : public PipelineXLocalState<FakeSharedState> {
99
public:
100
    using Parent = MaterializationOperator;
101
    using Base = PipelineXLocalState<FakeSharedState>;
102
103
    ENABLE_FACTORY_CREATOR(MaterializationLocalState);
104
0
    MaterializationLocalState(RuntimeState* state, OperatorXBase* parent) : Base(state, parent) {};
105
106
0
    Status init(RuntimeState* state, LocalStateInfo& info) override {
107
0
        RETURN_IF_ERROR(Base::init(state, info));
108
0
        _max_rpc_timer = ADD_TIMER_WITH_LEVEL(custom_profile(), "MaxRpcTime", 2);
109
0
        _merge_response_timer = ADD_TIMER_WITH_LEVEL(custom_profile(), "MergeResponseTime", 2);
110
0
        _max_rows_per_backend_counter =
111
0
                ADD_COUNTER_WITH_LEVEL(custom_profile(), "MaxRowsPerBackend", TUnit::UNIT, 2);
112
0
        return Status::OK();
113
0
    }
114
115
private:
116
    friend class MaterializationOperator;
117
    template <typename LocalStateType>
118
    friend class StatefulOperatorX;
119
120
    std::unique_ptr<Block> _child_block = Block::create_unique();
121
    bool _child_eos = false;
122
    MaterializationSharedState _materialization_state;
123
    RuntimeProfile::Counter* _max_rpc_timer = nullptr;
124
    RuntimeProfile::Counter* _merge_response_timer = nullptr;
125
    RuntimeProfile::Counter* _max_rows_per_backend_counter = nullptr;
126
};
127
128
class MaterializationOperator final : public StatefulOperatorX<MaterializationLocalState> {
129
public:
130
    using Base = StatefulOperatorX<MaterializationLocalState>;
131
    MaterializationOperator(ObjectPool* pool, const TPlanNode& tnode, int operator_id,
132
                            const DescriptorTbl& descs)
133
0
            : Base(pool, tnode, operator_id, descs) {}
134
135
    Status init(const TPlanNode& tnode, RuntimeState* state) override;
136
137
    Status prepare(RuntimeState* state) override;
138
139
0
    bool is_blockable(RuntimeState* state) const override { return true; }
140
    bool need_more_input_data(RuntimeState* state) const override;
141
    Status pull(RuntimeState* state, Block* output_block, bool* eos) const override;
142
    Status push(RuntimeState* state, Block* input_block, bool eos) const override;
143
144
private:
145
    friend class MaterializationLocalState;
146
147
    // Materialized slot by this node. The i-th result expr list refers to a slot of RowId
148
    TMaterializationNode _materialization_node;
149
    VExprContextSPtrs _rowid_exprs;
150
};
151
152
} // namespace doris