feat(parquet): support page-level (page index) filtering for nested column types (patch arrow)#443
Open
zhf999 wants to merge 29 commits into
Open
feat(parquet): support page-level (page index) filtering for nested column types (patch arrow)#443zhf999 wants to merge 29 commits into
zhf999 wants to merge 29 commits into
Conversation
lxy-9602
reviewed
Jul 24, 2026
lxy-9602
reviewed
Jul 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
Page-level filtering (row skipping driven by the Parquet page index / OffsetIndex)
was previously disabled whenever the read schema contained a nested column
(struct / list / map).
ParquetFileBatchReader::SetReadSchemadetected any nestedfield and fell back to the non-page-filtered path, so nested reads could not skip
non-matching pages at the I/O and decode level.
This change enables page-level filtering for nested column types and reworks the
reader so that each leaf column is filtered and driven independently.
What changed:
Enable page filtering for nested schemas. Removed the
has_nested_fieldworkaround in
ParquetFileBatchReaderthat skipped page-index pushdown for boththe predicate and the selection-bitmap paths when any nested field was present.
Nested-aware page-filtered reader (
PageFilteredRowGroupReader). Eachtop-level field is read through an Arrow
ColumnReadertree(
FileReader::GetColumn+ leaf projection). A per-leafdata_page_filterisinstalled to skip non-matching pages during decode, and each leaf is then driven
independently with reset / skip / read primitives. The result schema is built
from the actually-produced column types (needed because column pruning can change
nested types).
Arrow patch (
cmake_modules/arrow.diff). Instead of a single monolithicentry point,
parquet::arrow::ColumnReadergains small, per-leaf primitives:LeafColumnIndices(),ResetLeaf(),SkipRecords()andReadRecords()(returning the actual record count), implemented across the leaf / extension /
list / struct readers.
parquet::arrow::FileColumnIterator::NextChunk()is madevirtualso the page-filter wiring lives in a Paimon-sidePageFilteringColumnIteratorsubclass, keeping the patch surface minimal.Tests
Unit tests in
src/paimon/format/parquet/page_filtered_row_group_reader_test.cpp:NestedStructColumnRowGroupFilter,NestedListColumnRowGroupFilter,NestedMapColumnRowGroupFilter,MultipleAdjacentNestedColumns,MultipleNestedColumns.NestedStructColumnOnlyReadIdField,NestedStructSubColumnProjection.NestedColumnsMisalignedPages— writes astruct<key:int64, s:struct<x:int32,y:int64>, tags:list<int32>, props:map<utf8,int32>>withwrite_batch_size=1and a byte-based data page sizeso leaves paginate at different (and, for the utf8 map key, irregular) row counts;
selects two disjoint row ranges via a bitmap and deep-compares every returned row
against the source data to catch any per-leaf skip/read desync.
ComputePageRanges, streaming and bitmap casescontinue to pass.
API and Format
include/paimon/is unchanged.cmake_modules/arrow.diff: new virtualmethods on
parquet::arrow::ColumnReaderand a virtualFileColumnIterator::NextChunk(). This affects only the vendored Arrow used bythe read path, not any symbol shipped from
include/paimon/.read-path optimization.
Documentation
No user-facing documentation change; this is an internal read-path optimization.
Generative AI tooling
Generated-by: GLM 5.2