Skip to content

fix(parquet): remap sorting columns for partitioned writes - #24211

Merged
xudong963 merged 1 commit into
apache:mainfrom
xudong963:xudong963/upstream-fix-pr
Aug 11, 2026
Merged

fix(parquet): remap sorting columns for partitioned writes#24211
xudong963 merged 1 commit into
apache:mainfrom
xudong963:xudong963/upstream-fix-pr

Conversation

@xudong963

@xudong963 xudong963 commented Aug 10, 2026

Copy link
Copy Markdown
Member

Which issue does this PR close?

Rationale for this change

When Hive partition columns are not kept in Parquet files, FileSinkConfig::output_schema() still describes the sink input while get_writer_schema(&conf) removes those partition columns. ParquetFormat::create_writer_physical_plan currently converts the input ordering directly to Parquet sorting_columns, so its column indices can reference removed columns or the wrong positions in the written schema. Reading that metadata can then panic in SchemaDescriptor::column with an out-of-bounds index.

The execution ordering and the Parquet footer ordering have different schema domains: DataSinkExec must retain the original input ordering, while ParquetSink metadata must use indices from the actual writer schema.

What changes are included in this PR?

  • Derive Parquet sorting_columns from both the input schema and get_writer_schema(&conf).
  • Omit ordering keys that are removed from the written file, such as Hive partition columns.
  • Remap retained ordering keys to their writer-schema indices while preserving sort direction and null ordering.
  • Keep the original order_requirements unchanged for DataSinkExec.
  • Avoid writing an empty sorting_columns list when every ordering key is removed.
  • Add unit and end-to-end regression coverage for partitioned Parquet writes.

Are these changes tested?

Yes. The new tests cover the writer-schema remapping directly and verify the resulting Parquet footer after a partitioned write.

Are there any user-facing changes?

There are no public API changes. Newly written partitioned Parquet files now contain valid sorting_columns metadata based on their physical file schema. Existing files with invalid metadata are unchanged and must be rewritten separately.

@github-actions github-actions Bot added core Core DataFusion crate datasource Changes to the datasource crate labels Aug 10, 2026
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.24590% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.05%. Comparing base (585867b) to head (026b985).

Files with missing lines Patch % Lines
datafusion/datasource-parquet/src/metadata.rs 85.00% 6 Missing and 3 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #24211      +/-   ##
==========================================
- Coverage   81.06%   81.05%   -0.01%     
==========================================
  Files        1106     1106              
  Lines      382191   382245      +54     
  Branches   382191   382245      +54     
==========================================
+ Hits       309807   309842      +35     
- Misses      54095    54105      +10     
- Partials    18289    18298       +9     

☔ 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.

@xudong963

Copy link
Copy Markdown
Member Author

@jayzhan211 Thanks for the review!

@xudong963
xudong963 added this pull request to the merge queue Aug 11, 2026
Merged via the queue into apache:main with commit a9b61ab Aug 11, 2026
38 checks passed
@xudong963
xudong963 deleted the xudong963/upstream-fix-pr branch August 11, 2026 02:13
kosiew pushed a commit to kosiew/datafusion that referenced this pull request Aug 12, 2026
)

## Which issue does this PR close?

- Closes apache#24210.

## Rationale for this change

When Hive partition columns are not kept in Parquet files,
`FileSinkConfig::output_schema()` still describes the sink input while
`get_writer_schema(&conf)` removes those partition columns.
`ParquetFormat::create_writer_physical_plan` currently converts the
input ordering directly to Parquet `sorting_columns`, so its column
indices can reference removed columns or the wrong positions in the
written schema. Reading that metadata can then panic in
`SchemaDescriptor::column` with an out-of-bounds index.

The execution ordering and the Parquet footer ordering have different
schema domains: `DataSinkExec` must retain the original input ordering,
while `ParquetSink` metadata must use indices from the actual writer
schema.

## What changes are included in this PR?

- Derive Parquet `sorting_columns` from both the input schema and
`get_writer_schema(&conf)`.
- Omit ordering keys that are removed from the written file, such as
Hive partition columns.
- Remap retained ordering keys to their writer-schema indices while
preserving sort direction and null ordering.
- Keep the original `order_requirements` unchanged for `DataSinkExec`.
- Avoid writing an empty `sorting_columns` list when every ordering key
is removed.
- Add unit and end-to-end regression coverage for partitioned Parquet
writes.

## Are these changes tested?

Yes. The new tests cover the writer-schema remapping directly and verify
the resulting Parquet footer after a partitioned write.

## Are there any user-facing changes?

There are no public API changes. Newly written partitioned Parquet files
now contain valid `sorting_columns` metadata based on their physical
file schema. Existing files with invalid metadata are unchanged and must
be rewritten separately.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Core DataFusion crate datasource Changes to the datasource crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parquet sorting columns use invalid indices for partitioned writes

3 participants