Skip to content

feat: add match_columns_by_header option for CSV - #27021

Open
wyatt-herkamp wants to merge 2 commits into
apache:mainfrom
wyatt-herkamp:csv-match-columns-by-header
Open

wyatt-herkamp wants to merge 2 commits into
apache:mainfrom
wyatt-herkamp:csv-match-columns-by-header

Conversation

@wyatt-herkamp

@wyatt-herkamp wyatt-herkamp commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

arrow-csv parses columns by position, so when reading multiple CSV files where some file is missing a column (that isn't the last one), values land in the wrong columns or parsing fails.

What changes are included in this PR?

  • New match_columns_by_header CSV option (config, CsvFormat, CsvSource, and proto).
  • When enabled (requires has_header), each file's header is read and its columns are mapped to the table schema by name; missing columns are filled via PhysicalExprAdapterFactory. Works for both full-file and range (repartitioned) reads.
  • Header discovery follows the CSV parser: a leading UTF-8 BOM, blank records and comment lines before the header are skipped.
  • CsvReadOptions::match_columns_by_header exposes the option on the read_csv API.

Are these changes tested?

Yes: unit tests in datasource-csv/src/source.rs and core/src/datasource/physical_plan/csv.rs, a proto round-trip test, and sqllogictest cases in csv_files.slt.

Are there any user-facing changes?

New opt-in format.match_columns_by_header option, documented in format_options.md. Default behavior is unchanged.

API change: CsvOptions and CsvReadOptions gain a public match_columns_by_header field, and the protobuf CsvOptions / CsvScanExecNode messages gain the same field. Exhaustive struct literals need updating; noted in the 56.0.0 upgrade guide.

@github-actions github-actions Bot added documentation Improvements or additions to documentation core Core DataFusion crate sqllogictest SQL Logic Tests (.slt) common Related to common crate proto Related to proto crate datasource Changes to the datasource crate auto detected api change Auto detected API change labels Nov 2, 2026
@wyatt-herkamp
wyatt-herkamp marked this pull request as ready for review November 2, 2026 21:16
@xudong963
xudong963 self-requested a review November 3, 2026 00:23
@xudong963

Copy link
Copy Markdown
Member

Thanks @wyatt-herkamp —the per-file schema plus BatchAdapter design is a good fit for DataFusion!

Header discovery currently fails on leading blank records and BOM-prefixed comments, and the primary CsvReadOptions Rust API cannot enable the feature. How about aligning header discovery with Arrow’s CSV parsing semantics, adding regressions for those cases, exposing the option through CsvReadOptions, and marking/documenting the breaking API addition?

…y_header on CsvReadOptions

Header discovery now skips a leading UTF-8 BOM, blank records and comment
lines the same way csv-core does, so files with those before the header are
mapped by name rather than silently read by position.
@wyatt-herkamp
wyatt-herkamp force-pushed the csv-match-columns-by-header branch from 18a08c4 to 70ec58c Compare November 5, 2026 14:02
@wyatt-herkamp

wyatt-herkamp commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for the review @xudong963. Addressed in 70ec58c and rebased on main:

  • Header discovery now follows csv-core: a leading UTF-8 BOM is stripped, empty records are skipped (both \r and \n when no terminator is set), and comment lines end at \n. Whitespace-only lines are still records, as in the parser.
  • Regression tests: unit tests on find_header_line for BOM, blank lines and comments, plus an integration test with a BOM + comment + blank lines before the header across local, chunked and repartitioned reads.
  • CsvReadOptions::match_columns_by_header exposes the option on read_csv, with a test.

@github-actions github-actions Bot removed the auto detected api change Auto detected API change label Nov 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

common Related to common crate core Core DataFusion crate datasource Changes to the datasource crate documentation Improvements or additions to documentation proto Related to proto crate sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Column Match by header flag to datafusion csv

2 participants