Skip to content

refactor: extract parquet projection read plan into its own module#23396

Open
adriangb wants to merge 2 commits into
apache:mainfrom
pydantic:extract-projection-read-plan
Open

refactor: extract parquet projection read plan into its own module#23396
adriangb wants to merge 2 commits into
apache:mainfrom
pydantic:extract-projection-read-plan

Conversation

@adriangb

@adriangb adriangb commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

row_filter.rs is 2,100+ lines and contains two distinct concerns: row-filter/ArrowPredicate construction, and the shared "expressions → parquet leaf indices → ProjectionMask + projected schema" resolution used by both the row filter and the opener's projection handling. This PR moves the second concern into its own module, projection_read_plan.rs, so upcoming changes to projection-mask derivation can be reviewed without wading through the row-filter machinery.

This is mergeable as standalone cleanup regardless of whether the follow-up feature is accepted.

What changes are included in this PR?

A move-only refactor (best reviewed with git diff --color-moved):

  • ParquetReadPlan, StructFieldAccess, build_projection_read_plan, leaf_indices_for_roots, resolve_struct_field_leaves, build_filter_schema, prune_struct_type and the path-grouping helpers move from row_filter.rs to a new projection_read_plan.rs, together with their test.
  • PushdownChecker / PushdownColumns become pub(crate) so the new module can keep using them.
  • decoder_projection.rs imports build_projection_read_plan from its new home.

No behavior change; net +57 lines (module docs, imports, visibility).

Are these changes tested?

Covered by existing tests (the moved unit test plus the datafusion-datasource-parquet and core parquet integration suites, which all pass unchanged).

Are there any user-facing changes?

No.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KuMaRtFSPDQesuzjN5Koyd

Move-only: `ParquetReadPlan`, `StructFieldAccess`,
`build_projection_read_plan` and the leaf-index/schema-pruning helpers
move from row_filter.rs (2100+ lines) into projection_read_plan.rs.
`PushdownChecker`/`PushdownColumns` become pub(crate) so the new module
can keep using them. No behavior change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KuMaRtFSPDQesuzjN5Koyd
@adriangb adriangb force-pushed the extract-projection-read-plan branch from 69b2791 to d4fb0c5 Compare July 8, 2026 22:36
@adriangb

adriangb commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

@mbutrovich I found this refactor useful while investigating apache/datafusion-comet#4859. row_filter.rs is a beast so I think splitting it up makes sense regardless of other work. wdyt?

use datafusion_physical_expr::expressions::Column;
use datafusion_physical_expr::utils::collect_columns;

use crate::row_filter::PushdownChecker;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

projection_read_plan imports PushdownChecker from row_filter, whilerow_filter imports ParquetReadPlan and helpers from projection_read_plan.

How about moving PushdownChecker /PushdownColumns into projection_read_plan.rs or a neutral module like column_access.rs, then have row_filter.rs call into that

Comment on lines +243 to +249
// A leaf matches if its path starts with our prefix.
// e.g., prefix=["s", "value"] matches leaf path ["s", "value"]
// prefix=["s", "outer"] matches ["s", "outer", "inner"]

// a leaf matches if its path starts with our prefix
// for example: prefix=["s", "value"] matches leaf path ["s", "value"]
// prefix=["s", "outer"] matches ["s", "outer", "inner"]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

duplicated comments

Makes the imports between row_filter and projection_read_plan
one-directional (row_filter -> projection_read_plan) instead of
circular, and removes a duplicated comment in
resolve_struct_field_leaves. Addresses review feedback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016zX5Ga66kQPkscPVf7p1AN
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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants