Coverage Report

Created: 2026-04-14 17:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/format/parquet/vparquet_page_reader.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 <gen_cpp/parquet_types.h>
21
#include <stdint.h>
22
23
#include <memory>
24
#include <string>
25
26
#include "common/cast_set.h"
27
#include "common/config.h"
28
#include "common/status.h"
29
#include "format/parquet/parquet_common.h"
30
#include "storage/cache/page_cache.h"
31
#include "util/block_compression.h"
32
namespace doris {
33
class BlockCompressionCodec;
34
35
namespace io {
36
class BufferedStreamReader;
37
struct IOContext;
38
} // namespace io
39
40
} // namespace doris
41
42
namespace doris {
43
namespace io {
44
class BufferedStreamReader;
45
struct IOContext;
46
} // namespace io
47
struct Slice;
48
} // namespace doris
49
50
namespace doris {
51
/**
52
 * Use to deserialize parquet page header, and get the page data in iterator interface.
53
 */
54
55
// Session-level options for parquet page reading/caching.
56
struct ParquetPageReadContext {
57
    bool enable_parquet_file_page_cache = true;
58
42
    ParquetPageReadContext() = default;
59
    ParquetPageReadContext(bool enable_parquet_file_page_cache)
60
114
            : enable_parquet_file_page_cache(enable_parquet_file_page_cache) {}
61
};
62
63
inline bool should_cache_decompressed(const tparquet::PageHeader* header,
64
190
                                      const tparquet::ColumnMetaData& metadata) {
65
190
    if (header->compressed_page_size <= 0) return true;
66
186
    if (metadata.codec == tparquet::CompressionCodec::UNCOMPRESSED) return true;
67
179
    if (header->uncompressed_page_size == 0) return true;
68
69
171
    double ratio = static_cast<double>(header->uncompressed_page_size) /
70
171
                   static_cast<double>(header->compressed_page_size);
71
171
    return ratio <= config::parquet_page_cache_decompress_threshold;
72
179
}
73
74
class ParquetPageCacheKeyBuilder {
75
public:
76
    void init(const std::string& path, int64_t mtime);
77
259
    StoragePageCache::CacheKey make_key(uint64_t end_offset, int64_t offset) const {
78
259
        return StoragePageCache::CacheKey(_file_key_prefix, end_offset, offset);
79
259
    }
80
81
private:
82
    std::string _file_key_prefix;
83
};
84
85
template <bool IN_COLLECTION, bool OFFSET_INDEX>
86
class PageReader {
87
public:
88
    struct PageStatistics {
89
        int64_t decode_header_time = 0;
90
        int64_t skip_page_header_num = 0;
91
        int64_t parse_page_header_num = 0;
92
        int64_t read_page_header_time = 0;
93
        int64_t page_cache_hit_counter = 0;
94
        int64_t page_cache_missing_counter = 0;
95
        int64_t page_cache_compressed_hit_counter = 0;
96
        int64_t page_cache_decompressed_hit_counter = 0;
97
        int64_t page_cache_write_counter = 0;
98
        int64_t page_cache_compressed_write_counter = 0;
99
        int64_t page_cache_decompressed_write_counter = 0;
100
        int64_t page_read_counter = 0;
101
    };
102
103
    PageReader(io::BufferedStreamReader* reader, io::IOContext* io_ctx, uint64_t offset,
104
               uint64_t length, size_t total_rows, const tparquet::ColumnMetaData& metadata,
105
               const ParquetPageReadContext& page_read_ctx,
106
               const tparquet::OffsetIndex* offset_index = nullptr);
107
167
    ~PageReader() = default;
_ZN5doris10PageReaderILb0ELb0EED2Ev
Line
Count
Source
107
165
    ~PageReader() = default;
Unexecuted instantiation: _ZN5doris10PageReaderILb1ELb1EED2Ev
_ZN5doris10PageReaderILb1ELb0EED2Ev
Line
Count
Source
107
2
    ~PageReader() = default;
Unexecuted instantiation: _ZN5doris10PageReaderILb0ELb1EED2Ev
108
109
0
    bool has_next_page() const {
110
0
        if constexpr (OFFSET_INDEX) {
111
0
            return _page_index + 1 != _offset_index->page_locations.size();
112
0
        } else {
113
            // Deprecated
114
            // Parquet file may not be standardized,
115
            // _end_offset may exceed the actual data area.
116
            // ColumnChunkReader::has_next_page() use the number of parsed values for judgment
117
            // ref:https://github.com/duckdb/duckdb/issues/10829
118
            // [[deprecated]]
119
0
            LOG(FATAL) << "has_next_page should not be called when no offset index";
120
0
            return _offset < _end_offset;
121
0
        }
122
0
    }
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb1EE13has_next_pageEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb1EE13has_next_pageEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb0EE13has_next_pageEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb0EE13has_next_pageEv
123
124
    Status parse_page_header();
125
126
34
    Status next_page() {
127
34
        _page_statistics.skip_page_header_num += _state == INITIALIZED;
128
34
        if constexpr (OFFSET_INDEX) {
129
0
            _page_index++;
130
0
            _start_row = _offset_index->page_locations[_page_index].first_row_index;
131
0
            if (_page_index + 1 < _offset_index->page_locations.size()) {
132
0
                _end_row = _offset_index->page_locations[_page_index + 1].first_row_index;
133
0
            } else {
134
0
                _end_row = _total_rows;
135
0
            }
136
0
            int64_t next_page_offset = _offset_index->page_locations[_page_index].offset;
137
0
            _offset = next_page_offset;
138
0
            _next_header_offset = next_page_offset;
139
0
            _state = INITIALIZED;
140
34
        } else {
141
34
            if (UNLIKELY(_offset == _start_offset)) {
142
0
                return Status::Corruption("should parse first page.");
143
0
            }
144
145
34
            if (is_header_v2()) {
146
0
                _start_row += _cur_page_header.data_page_header_v2.num_rows;
147
34
            } else if constexpr (!IN_COLLECTION) {
148
34
                _start_row += _cur_page_header.data_page_header.num_values;
149
34
            }
150
151
34
            _offset = _next_header_offset;
152
34
            _state = INITIALIZED;
153
34
        }
154
155
0
        return Status::OK();
156
34
    }
Unexecuted instantiation: _ZN5doris10PageReaderILb1ELb1EE9next_pageEv
Unexecuted instantiation: _ZN5doris10PageReaderILb1ELb0EE9next_pageEv
Unexecuted instantiation: _ZN5doris10PageReaderILb0ELb1EE9next_pageEv
_ZN5doris10PageReaderILb0ELb0EE9next_pageEv
Line
Count
Source
126
34
    Status next_page() {
127
34
        _page_statistics.skip_page_header_num += _state == INITIALIZED;
128
        if constexpr (OFFSET_INDEX) {
129
            _page_index++;
130
            _start_row = _offset_index->page_locations[_page_index].first_row_index;
131
            if (_page_index + 1 < _offset_index->page_locations.size()) {
132
                _end_row = _offset_index->page_locations[_page_index + 1].first_row_index;
133
            } else {
134
                _end_row = _total_rows;
135
            }
136
            int64_t next_page_offset = _offset_index->page_locations[_page_index].offset;
137
            _offset = next_page_offset;
138
            _next_header_offset = next_page_offset;
139
            _state = INITIALIZED;
140
34
        } else {
141
34
            if (UNLIKELY(_offset == _start_offset)) {
142
0
                return Status::Corruption("should parse first page.");
143
0
            }
144
145
34
            if (is_header_v2()) {
146
0
                _start_row += _cur_page_header.data_page_header_v2.num_rows;
147
34
            } else if constexpr (!IN_COLLECTION) {
148
34
                _start_row += _cur_page_header.data_page_header.num_values;
149
34
            }
150
151
34
            _offset = _next_header_offset;
152
34
            _state = INITIALIZED;
153
34
        }
154
155
0
        return Status::OK();
156
34
    }
157
158
34
    Status dict_next_page() {
159
34
        if constexpr (OFFSET_INDEX) {
160
0
            _state = INITIALIZED;
161
0
            return Status::OK();
162
34
        } else {
163
34
            return next_page();
164
34
        }
165
34
    }
Unexecuted instantiation: _ZN5doris10PageReaderILb1ELb1EE14dict_next_pageEv
Unexecuted instantiation: _ZN5doris10PageReaderILb1ELb0EE14dict_next_pageEv
Unexecuted instantiation: _ZN5doris10PageReaderILb0ELb1EE14dict_next_pageEv
_ZN5doris10PageReaderILb0ELb0EE14dict_next_pageEv
Line
Count
Source
158
34
    Status dict_next_page() {
159
        if constexpr (OFFSET_INDEX) {
160
            _state = INITIALIZED;
161
            return Status::OK();
162
34
        } else {
163
34
            return next_page();
164
34
        }
165
34
    }
166
167
559
    Status get_page_header(const tparquet::PageHeader** page_header) {
168
559
        if (UNLIKELY(_state != HEADER_PARSED)) {
169
0
            return Status::InternalError("Page header not parsed");
170
0
        }
171
559
        *page_header = &_cur_page_header;
172
559
        return Status::OK();
173
559
    }
Unexecuted instantiation: _ZN5doris10PageReaderILb1ELb1EE15get_page_headerEPPKN8tparquet10PageHeaderE
_ZN5doris10PageReaderILb1ELb0EE15get_page_headerEPPKN8tparquet10PageHeaderE
Line
Count
Source
167
6
    Status get_page_header(const tparquet::PageHeader** page_header) {
168
6
        if (UNLIKELY(_state != HEADER_PARSED)) {
169
0
            return Status::InternalError("Page header not parsed");
170
0
        }
171
6
        *page_header = &_cur_page_header;
172
6
        return Status::OK();
173
6
    }
Unexecuted instantiation: _ZN5doris10PageReaderILb0ELb1EE15get_page_headerEPPKN8tparquet10PageHeaderE
_ZN5doris10PageReaderILb0ELb0EE15get_page_headerEPPKN8tparquet10PageHeaderE
Line
Count
Source
167
553
    Status get_page_header(const tparquet::PageHeader** page_header) {
168
553
        if (UNLIKELY(_state != HEADER_PARSED)) {
169
0
            return Status::InternalError("Page header not parsed");
170
0
        }
171
553
        *page_header = &_cur_page_header;
172
553
        return Status::OK();
173
553
    }
174
175
    Status get_page_data(Slice& slice);
176
177
    // Skip page data and update offset (used when data is loaded from cache)
178
17
    void skip_page_data() {
179
17
        if (_state == HEADER_PARSED) {
180
17
            _offset += _cur_page_header.compressed_page_size;
181
17
            _state = DATA_LOADED;
182
17
        }
183
17
    }
Unexecuted instantiation: _ZN5doris10PageReaderILb1ELb1EE14skip_page_dataEv
Unexecuted instantiation: _ZN5doris10PageReaderILb1ELb0EE14skip_page_dataEv
Unexecuted instantiation: _ZN5doris10PageReaderILb0ELb1EE14skip_page_dataEv
_ZN5doris10PageReaderILb0ELb0EE14skip_page_dataEv
Line
Count
Source
178
17
    void skip_page_data() {
179
17
        if (_state == HEADER_PARSED) {
180
17
            _offset += _cur_page_header.compressed_page_size;
181
17
            _state = DATA_LOADED;
182
17
        }
183
17
    }
184
185
254
    const std::vector<uint8_t>& header_bytes() const { return _header_buf; }
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb1EE12header_bytesEv
_ZNK5doris10PageReaderILb1ELb0EE12header_bytesEv
Line
Count
Source
185
3
    const std::vector<uint8_t>& header_bytes() const { return _header_buf; }
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb1EE12header_bytesEv
_ZNK5doris10PageReaderILb0ELb0EE12header_bytesEv
Line
Count
Source
185
251
    const std::vector<uint8_t>& header_bytes() const { return _header_buf; }
186
    // header start offset for current page
187
63
    int64_t header_start_offset() const {
188
63
        return static_cast<int64_t>(_next_header_offset) - static_cast<int64_t>(_last_header_size) -
189
63
               static_cast<int64_t>(_cur_page_header.compressed_page_size);
190
63
    }
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb1EE19header_start_offsetEv
_ZNK5doris10PageReaderILb1ELb0EE19header_start_offsetEv
Line
Count
Source
187
1
    int64_t header_start_offset() const {
188
1
        return static_cast<int64_t>(_next_header_offset) - static_cast<int64_t>(_last_header_size) -
189
1
               static_cast<int64_t>(_cur_page_header.compressed_page_size);
190
1
    }
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb1EE19header_start_offsetEv
_ZNK5doris10PageReaderILb0ELb0EE19header_start_offsetEv
Line
Count
Source
187
62
    int64_t header_start_offset() const {
188
62
        return static_cast<int64_t>(_next_header_offset) - static_cast<int64_t>(_last_header_size) -
189
62
               static_cast<int64_t>(_cur_page_header.compressed_page_size);
190
62
    }
191
0
    uint64_t file_end_offset() const { return _end_offset; }
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb1EE15file_end_offsetEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb0EE15file_end_offsetEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb1EE15file_end_offsetEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb0EE15file_end_offsetEv
192
0
    bool cached_decompressed() const {
193
0
        return should_cache_decompressed(&_cur_page_header, _metadata);
194
0
    }
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb1EE19cached_decompressedEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb0EE19cached_decompressedEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb1EE19cached_decompressedEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb0EE19cached_decompressedEv
195
196
1.51k
    PageStatistics& page_statistics() { return _page_statistics; }
_ZN5doris10PageReaderILb0ELb0EE15page_statisticsEv
Line
Count
Source
196
1.48k
    PageStatistics& page_statistics() { return _page_statistics; }
Unexecuted instantiation: _ZN5doris10PageReaderILb1ELb1EE15page_statisticsEv
_ZN5doris10PageReaderILb1ELb0EE15page_statisticsEv
Line
Count
Source
196
24
    PageStatistics& page_statistics() { return _page_statistics; }
Unexecuted instantiation: _ZN5doris10PageReaderILb0ELb1EE15page_statisticsEv
197
198
436
    bool is_header_v2() { return _cur_page_header.__isset.data_page_header_v2; }
Unexecuted instantiation: _ZN5doris10PageReaderILb1ELb1EE12is_header_v2Ev
_ZN5doris10PageReaderILb1ELb0EE12is_header_v2Ev
Line
Count
Source
198
8
    bool is_header_v2() { return _cur_page_header.__isset.data_page_header_v2; }
Unexecuted instantiation: _ZN5doris10PageReaderILb0ELb1EE12is_header_v2Ev
_ZN5doris10PageReaderILb0ELb0EE12is_header_v2Ev
Line
Count
Source
198
428
    bool is_header_v2() { return _cur_page_header.__isset.data_page_header_v2; }
199
200
    // Returns whether the current page's cache payload is decompressed
201
121
    bool is_cache_payload_decompressed() const { return _is_cache_payload_decompressed; }
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb1EE29is_cache_payload_decompressedEv
_ZNK5doris10PageReaderILb1ELb0EE29is_cache_payload_decompressedEv
Line
Count
Source
201
1
    bool is_cache_payload_decompressed() const { return _is_cache_payload_decompressed; }
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb1EE29is_cache_payload_decompressedEv
_ZNK5doris10PageReaderILb0ELb0EE29is_cache_payload_decompressedEv
Line
Count
Source
201
120
    bool is_cache_payload_decompressed() const { return _is_cache_payload_decompressed; }
202
203
6
    size_t start_row() const { return _start_row; }
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb1EE9start_rowEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb0EE9start_rowEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb1EE9start_rowEv
_ZNK5doris10PageReaderILb0ELb0EE9start_rowEv
Line
Count
Source
203
6
    size_t start_row() const { return _start_row; }
204
205
192
    size_t end_row() const { return _end_row; }
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb1EE7end_rowEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb0EE7end_rowEv
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb1EE7end_rowEv
_ZNK5doris10PageReaderILb0ELb0EE7end_rowEv
Line
Count
Source
205
192
    size_t end_row() const { return _end_row; }
206
207
    // Accessors for cache handle
208
196
    bool has_page_cache_handle() const { return _page_cache_handle.cache() != nullptr; }
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb1EE21has_page_cache_handleEv
_ZNK5doris10PageReaderILb1ELb0EE21has_page_cache_handleEv
Line
Count
Source
208
2
    bool has_page_cache_handle() const { return _page_cache_handle.cache() != nullptr; }
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb1EE21has_page_cache_handleEv
_ZNK5doris10PageReaderILb0ELb0EE21has_page_cache_handleEv
Line
Count
Source
208
194
    bool has_page_cache_handle() const { return _page_cache_handle.cache() != nullptr; }
209
121
    const doris::PageCacheHandle& page_cache_handle() const { return _page_cache_handle; }
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb1EE17page_cache_handleEv
_ZNK5doris10PageReaderILb1ELb0EE17page_cache_handleEv
Line
Count
Source
209
1
    const doris::PageCacheHandle& page_cache_handle() const { return _page_cache_handle; }
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb1EE17page_cache_handleEv
_ZNK5doris10PageReaderILb0ELb0EE17page_cache_handleEv
Line
Count
Source
209
120
    const doris::PageCacheHandle& page_cache_handle() const { return _page_cache_handle; }
210
259
    StoragePageCache::CacheKey make_page_cache_key(int64_t offset) const {
211
259
        return _page_cache_key_builder.make_key(_end_offset, offset);
212
259
    }
Unexecuted instantiation: _ZNK5doris10PageReaderILb1ELb1EE19make_page_cache_keyEl
_ZNK5doris10PageReaderILb1ELb0EE19make_page_cache_keyEl
Line
Count
Source
210
3
    StoragePageCache::CacheKey make_page_cache_key(int64_t offset) const {
211
3
        return _page_cache_key_builder.make_key(_end_offset, offset);
212
3
    }
Unexecuted instantiation: _ZNK5doris10PageReaderILb0ELb1EE19make_page_cache_keyEl
_ZNK5doris10PageReaderILb0ELb0EE19make_page_cache_keyEl
Line
Count
Source
210
256
    StoragePageCache::CacheKey make_page_cache_key(int64_t offset) const {
211
256
        return _page_cache_key_builder.make_key(_end_offset, offset);
212
256
    }
213
214
private:
215
    enum PageReaderState { INITIALIZED, HEADER_PARSED, DATA_LOADED };
216
    PageReaderState _state = INITIALIZED;
217
    PageStatistics _page_statistics;
218
219
    io::BufferedStreamReader* _reader = nullptr;
220
    io::IOContext* _io_ctx = nullptr;
221
    // current reader offset in file location.
222
    uint64_t _offset = 0;
223
    // this page offset in file location.
224
    uint64_t _start_offset = 0;
225
    uint64_t _end_offset = 0;
226
    uint64_t _next_header_offset = 0;
227
    // current page row range
228
    size_t _start_row = 0;
229
    size_t _end_row = 0;
230
    // total rows in this column chunk
231
    size_t _total_rows = 0;
232
    // Column metadata for this column chunk
233
    const tparquet::ColumnMetaData& _metadata;
234
    // Session-level parquet page cache options
235
    ParquetPageReadContext _page_read_ctx;
236
    // for page index
237
    size_t _page_index = 0;
238
    const tparquet::OffsetIndex* _offset_index;
239
240
    tparquet::PageHeader _cur_page_header;
241
    bool _is_cache_payload_decompressed = true;
242
243
    // Page cache members
244
    ParquetPageCacheKeyBuilder _page_cache_key_builder;
245
    doris::PageCacheHandle _page_cache_handle;
246
    // stored header bytes when cache miss so we can insert header+payload into cache
247
    std::vector<uint8_t> _header_buf;
248
    // last parsed header size in bytes
249
    uint32_t _last_header_size = 0;
250
};
251
252
template <bool IN_COLLECTION, bool OFFSET_INDEX>
253
std::unique_ptr<PageReader<IN_COLLECTION, OFFSET_INDEX>> create_page_reader(
254
        io::BufferedStreamReader* reader, io::IOContext* io_ctx, uint64_t offset, uint64_t length,
255
        size_t total_rows, const tparquet::ColumnMetaData& metadata,
256
167
        const ParquetPageReadContext& ctx, const tparquet::OffsetIndex* offset_index = nullptr) {
257
167
    return std::make_unique<PageReader<IN_COLLECTION, OFFSET_INDEX>>(
258
167
            reader, io_ctx, offset, length, total_rows, metadata, ctx, offset_index);
259
167
}
Unexecuted instantiation: _ZN5doris18create_page_readerILb1ELb1EEESt10unique_ptrINS_10PageReaderIXT_EXT0_EEESt14default_deleteIS3_EEPNS_2io20BufferedStreamReaderEPNS7_9IOContextEmmmRKN8tparquet14ColumnMetaDataERKNS_22ParquetPageReadContextEPKNSC_11OffsetIndexE
_ZN5doris18create_page_readerILb1ELb0EEESt10unique_ptrINS_10PageReaderIXT_EXT0_EEESt14default_deleteIS3_EEPNS_2io20BufferedStreamReaderEPNS7_9IOContextEmmmRKN8tparquet14ColumnMetaDataERKNS_22ParquetPageReadContextEPKNSC_11OffsetIndexE
Line
Count
Source
256
2
        const ParquetPageReadContext& ctx, const tparquet::OffsetIndex* offset_index = nullptr) {
257
2
    return std::make_unique<PageReader<IN_COLLECTION, OFFSET_INDEX>>(
258
2
            reader, io_ctx, offset, length, total_rows, metadata, ctx, offset_index);
259
2
}
Unexecuted instantiation: _ZN5doris18create_page_readerILb0ELb1EEESt10unique_ptrINS_10PageReaderIXT_EXT0_EEESt14default_deleteIS3_EEPNS_2io20BufferedStreamReaderEPNS7_9IOContextEmmmRKN8tparquet14ColumnMetaDataERKNS_22ParquetPageReadContextEPKNSC_11OffsetIndexE
_ZN5doris18create_page_readerILb0ELb0EEESt10unique_ptrINS_10PageReaderIXT_EXT0_EEESt14default_deleteIS3_EEPNS_2io20BufferedStreamReaderEPNS7_9IOContextEmmmRKN8tparquet14ColumnMetaDataERKNS_22ParquetPageReadContextEPKNSC_11OffsetIndexE
Line
Count
Source
256
165
        const ParquetPageReadContext& ctx, const tparquet::OffsetIndex* offset_index = nullptr) {
257
165
    return std::make_unique<PageReader<IN_COLLECTION, OFFSET_INDEX>>(
258
165
            reader, io_ctx, offset, length, total_rows, metadata, ctx, offset_index);
259
165
}
260
261
} // namespace doris