fix: [branch-1.0] work around DataFusion 54.1.0 Parquet page-index regression (#5132) - #5142
Merged
Merged
Conversation
mbutrovich
approved these changes
Jul 29, 2026
mbutrovich
left a comment
Contributor
There was a problem hiding this comment.
Thanks for the backport, @andygrove!
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.
Which issue does this PR close?
Backport of #5132 to
branch-1.0. Part of #3978.Rationale for this change
branch-1.0is on DataFusion 54.1.0, so it carries the samenative_datafusionParquet scan regression that #5132 works around onmain.Upstream apache/datafusion#22857 (backported to branch-54 as #23088, first released in 54.1.0) reordered the Parquet opener so the initial metadata load requests
PageIndexPolicy::Skip, deferring the page-index load until row-group statistics can't already prove the surviving row groups are fully matched. When that skip doesn't fire, the deferredload_page_indexreads the page index directly off theAsyncFileReader's byte-range methods, bypassingParquetFileReaderFactory::get_metadataand therefore theFileMetadataCache, and the result is never written back to the cache the initial load populated.For q88-shaped queries (three
IS NOT NULLpredicates on non-null foreign keys against a wide fact table),store_sales's row groups don't carry thenull_countstatistics the skip needs, so every open of the same file pays a fresh, uncached page-index fetch, once per row-group split. On the original benchmark, that query went from 24s to 34s between 54.0.0 and 54.1.0, with file-opening wall clock nearly doubling while bytes scanned moved only 3%.Tracked upstream as apache/datafusion#23978. This is a Comet-side workaround, not a fix for the upstream gap, and should be reverted once that is fixed.
What changes are included in this PR?
Clean cherry-pick of cde6052 with no conflicts and no adaptation needed:
EagerPageIndexReaderFactory(native/core/src/parquet/eager_page_index_reader_factory.rs), aParquetFileReaderFactorythat ignores thePageIndexPolicyDataFusion's opener requests and always fetches the page index eagerly viaDFParquetMetadata::with_page_index_policy(Some(PageIndexPolicy::Optional)), caching it in the same sharedFileMetadataCacheDataFusion's own factory uses. With the page index present after that first load, the opener'smissing_column_index || missing_offset_indexguard inload_page_indexnever issues the uncached fetch.init_datasource_execinnative/core/src/parquet/parquet_exec.rs, replacingCachedParquetFileReaderFactory.caches_full_metadata_with_page_index, added by perf: cache full Parquet metadata (incl. page index) via DataFusion's CachedParquetFileReaderFactory #4707) to assert the page index is present in the cache even for a scan with no pruning predicate, since this factory no longer depends on a predicate driving the load.The tradeoff is the same as on
main: this gives up #22857's skip for files where it would have legitimately avoided the page-index load (selective predicates, row groups with realnull_countstats), in exchange for avoiding unbounded repeated I/O at scale.How are these changes tested?
caches_full_metadata_with_page_indexinparquet_exec.rswrites a Parquet file with a page index, runs a scan throughinit_datasource_execwith no pruning predicate, and asserts theRuntimeEnvmetadata cache holds the column and offset index after the first open. Verified locally on this branch alongsidecargo clippy -p datafusion-comet --all-targets -- -D warnings.