Skip to content

perf: don't build a parquet stream for a file range with no row group left - #26476

Merged
alamb merged 3 commits into
apache:mainfrom
Braedon-Wooding-Displayr:perf/parquet-skip-empty-range
Oct 22, 2026
Merged

alamb merged 3 commits into
apache:mainfrom
Braedon-Wooding-Displayr:perf/parquet-skip-empty-range

Conversation

@Braedon-Wooding-Displayr

@Braedon-Wooding-Displayr Braedon-Wooding-Displayr commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

I've got a few fixes to upstream so just starting with small ones.

Which issue does this PR close?

Rationale for this change

If row-group statistics or Bloom filters prune every row group in a file range, the opener still builds the decoder read plans, the decoder and the row filter, then hands back a stream morsel that yields nothing. PruneFile already ends early when file statistics prune the range; this does the same once row-group pruning has.

What changes are included in this PR?

PruneWithStatistics and PruneWithBloomFilters return ParquetOpenState::Done when no row group survives.

What is the testing strategy for this PR?

Testing to ensure that we do actually skip them!

Are there any user-facing changes?

Nope!

@github-actions github-actions Bot added the datasource Changes to the datasource crate label Oct 18, 2026

/// Drives a [`ParquetMorselizer`] to completion and returns how many
/// morsels it produced.
async fn count_morsels(

@Braedon-Wooding-Displayr Braedon-Wooding-Displayr Oct 18, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only used by tests, I could put a #[cfg(test)] on it?

This also is a bit hacky but I opted not to care because it was just for tests but happy to clean it up a bit :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do #cfg(test)

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.23810% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.90%. Comparing base (3470bd0) to head (e5ca951).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
datafusion/datasource-parquet/src/opener/mod.rs 95.23% 0 Missing and 3 partials ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main   #26476   +/-   ##
=======================================
  Coverage   82.90%   82.90%           
=======================================
  Files        1154     1154           
  Lines      457654   457729   +75     
  Branches   457654   457729   +75     
=======================================
+ Hits       379398   379465   +67     
- Misses      55252    55256    +4     
- Partials    23004    23008    +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@alamb alamb left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me -- thank you @Braedon-Wooding-Displayr

I had a few suggestions

let mut prepared_row_groups = (*prepared).prune_row_groups()?;
if prepared_row_groups
.row_groups
.row_group_indexes()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe could check with empty()?


/// Drives a [`ParquetMorselizer`] to completion and returns how many
/// morsels it produced.
async fn count_morsels(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please do #cfg(test)

alamb and others added 2 commits October 22, 2026 15:35
Addresses review feedback on apache#26476: replace the inline
row_group_indexes().next().is_none() checks with a named helper.
RowGroupAccessPlanFilter::is_empty() cannot be used here because it
reports whether the file has zero row groups, not whether every row
group has been pruned.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@alamb

alamb commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

I merged up to get the PR flowing

@alamb
alamb enabled auto-merge October 22, 2026 19:43
@alamb
alamb added this pull request to the merge queue Oct 22, 2026
@Braedon-Wooding-Displayr

Copy link
Copy Markdown
Contributor Author

Sorry for not promptly following up! Thank you @alamb

Merged via the queue into apache:main with commit c0ec512 Oct 22, 2026
44 of 45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

datasource Changes to the datasource crate v56.0.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parquet scans still set up a reader for files whose row groups are all pruned

3 participants