Skip to content

Commit b8bd306

Browse files
mergify[bot]Seaven
andauthored
[Enhancement] compute unused column by be (backport #60462) (#65844)
Signed-off-by: Seaven <seaven_7@qq.com> Co-authored-by: Seaven <seaven_7@qq.com>
1 parent d127a23 commit b8bd306

7 files changed

Lines changed: 108 additions & 183 deletions

File tree

be/src/connector/lake_connector.cpp

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,8 @@ Status LakeDataSource::init_unused_output_columns(const std::vector<std::string>
216216
return Status::OK();
217217
}
218218

219-
Status LakeDataSource::init_scanner_columns(std::vector<uint32_t>& scanner_columns) {
219+
Status LakeDataSource::init_scanner_columns(std::vector<uint32_t>& scanner_columns,
220+
std::vector<uint32_t>& reader_columns) {
220221
for (auto slot : *_slots) {
221222
DCHECK(slot->is_materialized());
222223
int32_t index = _tablet_schema->field_index(slot->col_name());
@@ -237,6 +238,23 @@ Status LakeDataSource::init_scanner_columns(std::vector<uint32_t>& scanner_colum
237238
if (scanner_columns.empty()) {
238239
return Status::InternalError("failed to build storage scanner, no materialized slot!");
239240
}
241+
242+
// Return columns
243+
if (_params.skip_aggregation) {
244+
reader_columns = scanner_columns;
245+
} else {
246+
for (size_t i = 0; i < _tablet_schema->num_key_columns(); i++) {
247+
reader_columns.push_back(i);
248+
}
249+
for (auto index : scanner_columns) {
250+
if (!_tablet_schema->column(index).is_key()) {
251+
reader_columns.push_back(index);
252+
}
253+
}
254+
}
255+
// Actually only the key columns need to be sorted by id, here we check all
256+
// for simplicity.
257+
DCHECK(std::is_sorted(reader_columns.begin(), reader_columns.end()));
240258
return Status::OK();
241259
}
242260

@@ -249,9 +267,7 @@ void LakeDataSource::decide_chunk_size(bool has_predicate) {
249267
}
250268
}
251269

252-
Status LakeDataSource::init_reader_params(const std::vector<OlapScanRange*>& key_ranges,
253-
const std::vector<uint32_t>& scanner_columns,
254-
std::vector<uint32_t>& reader_columns) {
270+
Status LakeDataSource::init_reader_params(const std::vector<OlapScanRange*>& key_ranges) {
255271
const TLakeScanNode& thrift_lake_scan_node = _provider->_t_lake_scan_node;
256272
bool skip_aggregation = thrift_lake_scan_node.is_preaggregation;
257273
auto parser = _obj_pool.add(new OlapPredicateParser(_tablet_schema));
@@ -282,6 +298,23 @@ Status LakeDataSource::init_reader_params(const std::vector<OlapScanRange*>& key
282298
_params.pred_tree = PredicateTree::create(std::move(pushdown_pred_root));
283299
_non_pushdown_pred_tree = PredicateTree::create(std::move(non_pushdown_pred_root));
284300

301+
for (const auto& cid : _non_pushdown_pred_tree.column_ids()) {
302+
_unused_output_column_ids.erase(cid);
303+
}
304+
305+
std::vector<ExprContext*> not_pushdown_conjuncts;
306+
_conjuncts_manager->get_not_push_down_conjuncts(&not_pushdown_conjuncts);
307+
std::unordered_set<SlotId> conjuncts_slot_ids;
308+
for (auto* expr : not_pushdown_conjuncts) {
309+
expr->root()->for_each_slot_id([&conjuncts_slot_ids](SlotId id) { conjuncts_slot_ids.insert(id); });
310+
}
311+
for (auto& slot : *_slots) {
312+
if (conjuncts_slot_ids.contains(slot->id())) {
313+
int32_t fid = _tablet_schema->field_index(slot->col_name());
314+
_unused_output_column_ids.erase(fid);
315+
}
316+
}
317+
285318
{
286319
GlobalDictPredicatesRewriter not_pushdown_predicate_rewriter(*_params.global_dictmaps);
287320
RETURN_IF_ERROR(not_pushdown_predicate_rewriter.rewrite_predicate(&_obj_pool, _non_pushdown_pred_tree));
@@ -302,22 +335,6 @@ Status LakeDataSource::init_reader_params(const std::vector<OlapScanRange*>& key
302335
_params.end_key.push_back(key_range->end_scan_range);
303336
}
304337

305-
// Return columns
306-
if (skip_aggregation) {
307-
reader_columns = scanner_columns;
308-
} else {
309-
for (size_t i = 0; i < _tablet_schema->num_key_columns(); i++) {
310-
reader_columns.push_back(i);
311-
}
312-
for (auto index : scanner_columns) {
313-
if (!_tablet_schema->column(index).is_key()) {
314-
reader_columns.push_back(index);
315-
}
316-
}
317-
}
318-
// Actually only the key columns need to be sorted by id, here we check all
319-
// for simplicity.
320-
DCHECK(std::is_sorted(reader_columns.begin(), reader_columns.end()));
321338
return Status::OK();
322339
}
323340

@@ -331,8 +348,8 @@ Status LakeDataSource::init_tablet_reader(RuntimeState* runtime_state) {
331348
RETURN_IF_ERROR(get_tablet(_scan_range));
332349
RETURN_IF_ERROR(init_global_dicts(&_params));
333350
RETURN_IF_ERROR(init_unused_output_columns(thrift_lake_scan_node.unused_output_column_name));
334-
RETURN_IF_ERROR(init_scanner_columns(scanner_columns));
335-
RETURN_IF_ERROR(init_reader_params(_scanner_ranges, scanner_columns, reader_columns));
351+
RETURN_IF_ERROR(init_scanner_columns(scanner_columns, reader_columns));
352+
RETURN_IF_ERROR(init_reader_params(_scanner_ranges));
336353

337354
if (_split_context != nullptr) {
338355
auto split_context = down_cast<const pipeline::LakeSplitContext*>(_split_context);

be/src/connector/lake_connector.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,9 @@ class LakeDataSource final : public DataSource {
5959
Status get_tablet(const TInternalScanRange& scan_range);
6060
Status init_global_dicts(TabletReaderParams* params);
6161
Status init_unused_output_columns(const std::vector<std::string>& unused_output_columns);
62-
Status init_scanner_columns(std::vector<uint32_t>& scanner_columns);
62+
Status init_scanner_columns(std::vector<uint32_t>& scanner_columns, std::vector<uint32_t>& reader_columns);
6363
void decide_chunk_size(bool has_predicate);
64-
Status init_reader_params(const std::vector<OlapScanRange*>& key_ranges,
65-
const std::vector<uint32_t>& scanner_columns, std::vector<uint32_t>& reader_columns);
64+
Status init_reader_params(const std::vector<OlapScanRange*>& key_ranges);
6665
Status init_tablet_reader(RuntimeState* state);
6766
Status build_scan_range(RuntimeState* state);
6867
void init_counter(RuntimeState* state);

be/src/exec/pipeline/scan/olap_chunk_source.cpp

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,7 @@ void OlapChunkSource::_decide_chunk_size(bool has_predicate) {
228228
}
229229
}
230230

231-
Status OlapChunkSource::_init_reader_params(const std::vector<std::unique_ptr<OlapScanRange>>& key_ranges,
232-
const std::vector<uint32_t>& scanner_columns,
233-
std::vector<uint32_t>& reader_columns) {
231+
Status OlapChunkSource::_init_reader_params(const std::vector<std::unique_ptr<OlapScanRange>>& key_ranges) {
234232
const TOlapScanNode& thrift_olap_scan_node = _scan_node->thrift_olap_scan_node();
235233
bool skip_aggregation = thrift_olap_scan_node.is_preaggregation;
236234
auto parser = _obj_pool.add(new OlapPredicateParser(_tablet_schema));
@@ -289,6 +287,23 @@ Status OlapChunkSource::_init_reader_params(const std::vector<std::unique_ptr<Ol
289287
_params.pred_tree = PredicateTree::create(std::move(pushdown_pred_root));
290288
_non_pushdown_pred_tree = PredicateTree::create(std::move(non_pushdown_pred_root));
291289

290+
for (auto& id : _non_pushdown_pred_tree.column_ids()) {
291+
_unused_output_column_ids.erase(id);
292+
}
293+
294+
std::vector<ExprContext*> not_pushdown_conjuncts;
295+
_scan_ctx->conjuncts_manager().get_not_push_down_conjuncts(&not_pushdown_conjuncts);
296+
std::unordered_set<SlotId> conjuncts_slot_ids;
297+
for (auto* expr : not_pushdown_conjuncts) {
298+
expr->root()->for_each_slot_id([&conjuncts_slot_ids](SlotId id) { conjuncts_slot_ids.insert(id); });
299+
}
300+
for (auto& slot : *_slots) {
301+
if (conjuncts_slot_ids.contains(slot->id())) {
302+
int32_t fid = _tablet_schema->field_index(slot->col_name());
303+
_unused_output_column_ids.erase(fid);
304+
}
305+
}
306+
292307
{
293308
GlobalDictPredicatesRewriter not_pushdown_predicate_rewriter(*_params.global_dictmaps);
294309
RETURN_IF_ERROR(not_pushdown_predicate_rewriter.rewrite_predicate(&_obj_pool, _non_pushdown_pred_tree));
@@ -309,26 +324,11 @@ Status OlapChunkSource::_init_reader_params(const std::vector<std::unique_ptr<Ol
309324
_params.end_key.push_back(key_range->end_scan_range);
310325
}
311326

312-
// Return columns
313-
if (skip_aggregation) {
314-
reader_columns = scanner_columns;
315-
} else {
316-
for (size_t i = 0; i < _tablet_schema->num_key_columns(); i++) {
317-
reader_columns.push_back(i);
318-
}
319-
for (auto index : scanner_columns) {
320-
if (!_tablet_schema->column(index).is_key()) {
321-
reader_columns.push_back(index);
322-
}
323-
}
324-
}
325-
// Actually only the key columns need to be sorted by id, here we check all
326-
// for simplicity.
327-
DCHECK(std::is_sorted(reader_columns.begin(), reader_columns.end()));
328327
return Status::OK();
329328
}
330329

331-
Status OlapChunkSource::_init_scanner_columns(std::vector<uint32_t>& scanner_columns) {
330+
Status OlapChunkSource::_init_scanner_columns(std::vector<uint32_t>& scanner_columns,
331+
std::vector<uint32_t>& reader_columns) {
332332
for (auto slot : *_slots) {
333333
DCHECK(slot->is_materialized());
334334
int32_t index;
@@ -357,6 +357,23 @@ Status OlapChunkSource::_init_scanner_columns(std::vector<uint32_t>& scanner_col
357357
return Status::InternalError("failed to build storage scanner, no materialized slot!");
358358
}
359359

360+
// Return columns
361+
if (_params.skip_aggregation) {
362+
reader_columns = scanner_columns;
363+
} else {
364+
for (size_t i = 0; i < _tablet_schema->num_key_columns(); i++) {
365+
reader_columns.push_back(i);
366+
}
367+
for (auto index : scanner_columns) {
368+
if (!_tablet_schema->column(index).is_key()) {
369+
reader_columns.push_back(index);
370+
}
371+
}
372+
}
373+
// Actually only the key columns need to be sorted by id, here we check all
374+
// for simplicity.
375+
DCHECK(std::is_sorted(reader_columns.begin(), reader_columns.end()));
376+
360377
return Status::OK();
361378
}
362379

@@ -499,8 +516,8 @@ Status OlapChunkSource::_init_olap_reader(RuntimeState* runtime_state) {
499516

500517
RETURN_IF_ERROR(_init_global_dicts(&_params));
501518
RETURN_IF_ERROR(_init_unused_output_columns(thrift_olap_scan_node.unused_output_column_name));
502-
RETURN_IF_ERROR(_init_scanner_columns(scanner_columns));
503-
RETURN_IF_ERROR(_init_reader_params(_scan_ctx->key_ranges(), scanner_columns, reader_columns));
519+
RETURN_IF_ERROR(_init_reader_params(_scan_ctx->key_ranges()));
520+
RETURN_IF_ERROR(_init_scanner_columns(scanner_columns, reader_columns));
504521

505522
// schema is new object, but fields not
506523
starrocks::Schema child_schema = ChunkHelper::convert_schema(_tablet_schema, reader_columns);

be/src/exec/pipeline/scan/olap_chunk_source.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,8 @@ class OlapChunkSource final : public ChunkSource {
5656
Status _read_chunk(RuntimeState* state, ChunkPtr* chunk) override;
5757

5858
Status _get_tablet(const TInternalScanRange* scan_range);
59-
Status _init_reader_params(const std::vector<std::unique_ptr<OlapScanRange>>& key_ranges,
60-
const std::vector<uint32_t>& scanner_columns, std::vector<uint32_t>& reader_columns);
61-
Status _init_scanner_columns(std::vector<uint32_t>& scanner_columns);
59+
Status _init_reader_params(const std::vector<std::unique_ptr<OlapScanRange>>& key_ranges);
60+
Status _init_scanner_columns(std::vector<uint32_t>& scanner_columns, std::vector<uint32_t>& reader_columns);
6261
Status _init_unused_output_columns(const std::vector<std::string>& unused_output_columns);
6362
Status _init_olap_reader(RuntimeState* state);
6463
TCounterMinMaxType::type _get_counter_min_max_type(const std::string& metric_name);

be/src/storage/rowset/segment_iterator.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1837,8 +1837,10 @@ Status SegmentIterator::_build_context(ScanContext* ctx) {
18371837
ctx->_column_iterators.emplace_back(iter);
18381838
ctx->_is_dict_column.emplace_back(false);
18391839
ctx->_dict_decode_schema.append(f);
1840-
ctx->_subfield_columns.emplace_back(i);
1841-
ctx->_subfield_iterators.emplace_back(iter);
1840+
if (output_columns.count(f->id()) != 0) {
1841+
ctx->_subfield_columns.emplace_back(i);
1842+
ctx->_subfield_iterators.emplace_back(iter);
1843+
}
18421844
} else {
18431845
ctx->_read_schema.append(f);
18441846
ctx->_column_iterators.emplace_back(_column_iterators[cid].get());

0 commit comments

Comments
 (0)