Skip to content

feat: separate Parquet I/O policy from filter pushdown - #4

Draft
peterxcli wants to merge 1 commit into
mainfrom
codex/parquet-io-1-policy
Draft

peterxcli wants to merge 1 commit into
mainfrom
codex/parquet-io-1-policy

Conversation

@peterxcli

@peterxcli peterxcli commented Sep 15, 2026

Copy link
Copy Markdown
Owner

Which issue does this PR close?

Related to apache#24393. Stage 1 of the Parquet I/O stack, split from #3.

Stack, with each PR targeting its predecessor: #4#5#7#8#9.

Rationale for this change

Filter pushdown currently requires dependent reads for predicate and output columns. Allow callers to fetch those pages together while retaining filter evaluation and page-index pruning.

What changes are included in this PR?

Add datafusion.execution.parquet.progressive_io and ParquetSource::with_progressive_io. Setting it to false combines the selected output and predicate ranges. Preserve dictionary pages, reversed selections, and fully matched row-group suppression; changing dynamic filters cannot establish a permanent full match. Serialized plans retain the policy, and older plans default to progressive I/O.

Background prefetch is added by the next PR.

What is the testing strategy for this PR?

On lsa-cupid1: workspace Clippy with all targets/features; 259 Parquet tests with encryption; SQL coverage for indexed/unindexed files, nested/dictionary output, and predicate-only columns; dynamic-filter safety and older-plan serialization regressions. Formatting and documentation checks pass.

Full partitioned ClickBench on lsa-cupid1, /work/peterxcli NVMe: 100 files, 99,997,497 rows, all 43 queries, eight workers/partitions. Versus the immediate parent, the sum of query medians changes +0.97% / +0.49% warm and -0.20% with evicted files (negative is faster). Warm values are two reversed-order passes; evicted files use three runs per query.

Retain this as an opt-in policy; the default stays progressive. Results and methodology · 43 per-query comparisons and CPU charts. Result-ordering limitations and synthetic-latency controls are documented in the report.

Are there any user-facing changes?

Set datafusion.execution.parquet.progressive_io=false before registering the table to request upfront reads. The default stays true; upfront reads can fetch pages that subsequent row filtering would skip.

@github-actions

Copy link
Copy Markdown

Thank you for opening this pull request!

Reviewer note: cargo-semver-checks reported the current version number is not SemVer-compatible with the changes in this pull request (compared against the base branch).

Details
     Cloning apache/main
    Building datafusion v55.1.0 (current)
       Built [  62.215s] (current)
     Parsing datafusion v55.1.0 (current)
      Parsed [   0.035s] (current)
    Building datafusion v55.1.0 (baseline)
       Built [  61.050s] (baseline)
     Parsing datafusion v55.1.0 (baseline)
      Parsed [   0.036s] (baseline)
    Checking datafusion v55.1.0 -> v55.1.0 (no change; assume patch)
     Checked [   0.560s] 223 checks: 223 pass, 31 skip
     Summary no semver update required
    Finished [ 125.710s] datafusion
    Building datafusion-common v55.1.0 (current)
       Built [  35.261s] (current)
     Parsing datafusion-common v55.1.0 (current)
      Parsed [   0.066s] (current)
    Building datafusion-common v55.1.0 (baseline)
       Built [  35.725s] (baseline)
     Parsing datafusion-common v55.1.0 (baseline)
      Parsed [   0.064s] (baseline)
    Checking datafusion-common v55.1.0 -> v55.1.0 (no change; assume patch)
     Checked [   0.650s] 223 checks: 222 pass, 1 fail, 0 warn, 31 skip

--- failure constructible_struct_adds_field: struct exhaustively constructible through public API adds field ---

Description:
A pub struct that could be exhaustively constructed with a literal using only public API has a new pub field, breaking existing exhaustive literals.
        ref: https://doc.rust-lang.org/reference/expressions/struct-expr.html
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.50.0/src/lints/constructible_struct_adds_field.ron

Failed in:
  field ParquetOptions.progressive_io in /home/runner/work/datafusion/datafusion/datafusion/common/src/config.rs:1302

     Summary semver requires new major version: 1 major and 0 minor checks failed
    Finished [  72.793s] datafusion-common
    Building datafusion-datasource-parquet v55.1.0 (current)
       Built [  51.978s] (current)
     Parsing datafusion-datasource-parquet v55.1.0 (current)
      Parsed [   0.034s] (current)
    Building datafusion-datasource-parquet v55.1.0 (baseline)
       Built [  50.817s] (baseline)
     Parsing datafusion-datasource-parquet v55.1.0 (baseline)
      Parsed [   0.035s] (baseline)
    Checking datafusion-datasource-parquet v55.1.0 -> v55.1.0 (no change; assume patch)
     Checked [   0.161s] 223 checks: 223 pass, 31 skip
     Summary no semver update required
    Finished [ 104.090s] datafusion-datasource-parquet
    Building datafusion-proto v55.1.0 (current)
       Built [  57.676s] (current)
     Parsing datafusion-proto v55.1.0 (current)
      Parsed [   0.017s] (current)
    Building datafusion-proto v55.1.0 (baseline)
       Built [  57.543s] (baseline)
     Parsing datafusion-proto v55.1.0 (baseline)
      Parsed [   0.019s] (baseline)
    Checking datafusion-proto v55.1.0 -> v55.1.0 (no change; assume patch)
     Checked [   0.126s] 223 checks: 223 pass, 31 skip
     Summary no semver update required
    Finished [ 116.516s] datafusion-proto
    Building datafusion-proto-common v55.1.0 (current)
       Built [  23.598s] (current)
     Parsing datafusion-proto-common v55.1.0 (current)
      Parsed [   0.046s] (current)
    Building datafusion-proto-common v55.1.0 (baseline)
       Built [  22.862s] (baseline)
     Parsing datafusion-proto-common v55.1.0 (baseline)
      Parsed [   0.051s] (baseline)
    Checking datafusion-proto-common v55.1.0 -> v55.1.0 (no change; assume patch)
     Checked [   1.092s] 223 checks: 222 pass, 1 fail, 0 warn, 31 skip

--- failure constructible_struct_adds_field: struct exhaustively constructible through public API adds field ---

Description:
A pub struct that could be exhaustively constructed with a literal using only public API has a new pub field, breaking existing exhaustive literals.
        ref: https://doc.rust-lang.org/reference/expressions/struct-expr.html
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.50.0/src/lints/constructible_struct_adds_field.ron

Failed in:
  field ParquetOptions.progressive_io in /home/runner/work/datafusion/datafusion/datafusion/proto-common/src/generated/prost.rs:822
  field ParquetOptions.progressive_io in /home/runner/work/datafusion/datafusion/datafusion/proto-common/src/generated/prost.rs:822
  field ParquetOptions.progressive_io in /home/runner/work/datafusion/datafusion/datafusion/proto-common/src/generated/prost.rs:822

     Summary semver requires new major version: 1 major and 0 minor checks failed
    Finished [  48.616s] datafusion-proto-common
    Building datafusion-proto-models v55.1.0 (current)
       Built [  26.335s] (current)
     Parsing datafusion-proto-models v55.1.0 (current)
      Parsed [   0.137s] (current)
    Building datafusion-proto-models v55.1.0 (baseline)
       Built [  26.430s] (baseline)
     Parsing datafusion-proto-models v55.1.0 (baseline)
      Parsed [   0.136s] (baseline)
    Checking datafusion-proto-models v55.1.0 -> v55.1.0 (no change; assume patch)
     Checked [   1.734s] 223 checks: 222 pass, 1 fail, 0 warn, 31 skip

--- failure constructible_struct_adds_field: struct exhaustively constructible through public API adds field ---

Description:
A pub struct that could be exhaustively constructed with a literal using only public API has a new pub field, breaking existing exhaustive literals.
        ref: https://doc.rust-lang.org/reference/expressions/struct-expr.html
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.50.0/src/lints/constructible_struct_adds_field.ron

Failed in:
  field ParquetOptions.progressive_io in /home/runner/work/datafusion/datafusion/datafusion/proto-models/src/generated/datafusion_proto_common.rs:822
  field ParquetOptions.progressive_io in /home/runner/work/datafusion/datafusion/datafusion/proto-models/src/generated/datafusion_proto_common.rs:822

     Summary semver requires new major version: 1 major and 0 minor checks failed
    Finished [  56.111s] datafusion-proto-models
    Building datafusion-pruning v55.1.0 (current)
       Built [  42.513s] (current)
     Parsing datafusion-pruning v55.1.0 (current)
      Parsed [   0.015s] (current)
    Building datafusion-pruning v55.1.0 (baseline)
       Built [  42.098s] (baseline)
     Parsing datafusion-pruning v55.1.0 (baseline)
      Parsed [   0.016s] (baseline)
    Checking datafusion-pruning v55.1.0 -> v55.1.0 (no change; assume patch)
     Checked [   0.083s] 223 checks: 223 pass, 31 skip
     Summary no semver update required
    Finished [  85.739s] datafusion-pruning
    Building datafusion-sqllogictest v55.1.0 (current)
       Built [ 105.587s] (current)
     Parsing datafusion-sqllogictest v55.1.0 (current)
      Parsed [   0.021s] (current)
    Building datafusion-sqllogictest v55.1.0 (baseline)
       Built [ 106.389s] (baseline)
     Parsing datafusion-sqllogictest v55.1.0 (baseline)
      Parsed [   0.025s] (baseline)
    Checking datafusion-sqllogictest v55.1.0 -> v55.1.0 (no change; assume patch)
     Checked [   0.106s] 223 checks: 223 pass, 31 skip
     Summary no semver update required
    Finished [ 214.813s] datafusion-sqllogictest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant