Skip to content

GH-50967: [C++] Allow CSV reader to ignore extra columns in rows with more columns - #51118

Open
HuaHuaY wants to merge 5 commits into
apache:mainfrom
HuaHuaY:strengthen_csv
Open

GH-50967: [C++] Allow CSV reader to ignore extra columns in rows with more columns#51118
HuaHuaY wants to merge 5 commits into
apache:mainfrom
HuaHuaY:strengthen_csv

Conversation

@HuaHuaY

@HuaHuaY HuaHuaY commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Rationale for this change

Currently, the C++ CSV reader rejects rows with more columns than expected. We can allow users to ignore the extra values instead of throwing exception.

What changes are included in this PR?

Add an option ignore_extra_columns in CSV struct ParseOptions that ignores extra columns.

Are these changes tested?

Yes.

Are there any user-facing changes?

Add an option ignore_extra_columns in CSV struct ParseOptions.

Copilot AI lite review requested due to automatic review settings September 1, 2026 06:35
@HuaHuaY
HuaHuaY requested a review from pitrou as a code owner September 1, 2026 06:35
@HuaHuaY
HuaHuaY requested a review from wgtmac September 1, 2026 06:35

Copilot AI 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.

Pull request overview

Adds a new C++ CSV parsing option to tolerate rows with more fields than expected by ignoring any extra columns, instead of treating such rows as invalid. This extends the existing “pad short rows” behavior on the other side of the mismatch spectrum and makes the CSV reader more flexible for imperfect inputs.

Changes:

  • Introduces ParseOptions::ignore_extra_columns (default false) to ignore surplus fields when the expected column count is known.
  • Updates the CSV block parser to avoid materializing/parsing data for ignored extra fields while still scanning correctly for delimiters/newlines.
  • Adds parser- and reader-level tests covering extra columns (including trailing delimiters) and updates dataset CsvFileFormat::Equals to account for the new option.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
cpp/src/arrow/dataset/file_csv.cc Includes ignore_extra_columns in CsvFileFormat::Equals so format equality reflects the new parse behavior.
cpp/src/arrow/csv/options.h Adds the ignore_extra_columns parse option to the public ParseOptions API.
cpp/src/arrow/csv/parser.cc Implements ignoring of extra fields in the core parsing state machine (including bulk filter path).
cpp/src/arrow/csv/parser_test.cc Adds a unit test validating that extra columns are ignored at the block parser level.
cpp/src/arrow/csv/reader_test.cc Adds an integration test validating TableReader behavior with extra columns.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI review requested due to automatic review settings September 1, 2026 07:22

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

@wgtmac wgtmac left a comment

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.

Looks reasonable to me. It would be good if @pitrou could take a look.

@github-actions github-actions Bot added awaiting committer review Awaiting committer review and removed awaiting review Awaiting review labels Sep 2, 2026
@pitrou

pitrou commented Sep 3, 2026

Copy link
Copy Markdown
Member

@ursabot please benchmark lang=C++

@rok

rok commented Sep 3, 2026

Copy link
Copy Markdown
Member

Benchmark runs are scheduled for commit 3e198d8. Watch https://buildkite.com/apache-arrow and https://conbench.arrow-dev.org for updates. A comment will be posted here when the runs are complete.

Copilot AI review requested due to automatic review settings September 4, 2026 08:03
@HuaHuaY

HuaHuaY commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

@ursabot please benchmark lang=C++

@rok

rok commented Sep 4, 2026

Copy link
Copy Markdown
Member

Benchmark runs are scheduled for commit 0f0c8c3. Watch https://buildkite.com/apache-arrow and https://conbench.arrow-dev.org for updates. A comment will be posted here when the runs are complete.

Copilot AI 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.

🟢 Approval recommended

The change is opt-in, localized to CSV parsing, and is covered by new parser- and reader-level tests for the intended behavior.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI review requested due to automatic review settings September 8, 2026 05:42
Comment thread cpp/src/arrow/csv/lexing_internal.h Outdated
template <typename... CompiledBools, typename Fn, typename... Rest>
requires std::invocable<Fn, CompiledBools...,
std::conditional_t<true, std::true_type, Rest>...>
decltype(auto) DispatchBool(Fn&& fn, Rest... rest) {

@HuaHuaY HuaHuaY Sep 8, 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.

I place this utility function here because it can also be used later when handling SpecializedOptions in chunker.cc.

@HuaHuaY

HuaHuaY commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@ursabot please benchmark lang=C++

@rok

rok commented Sep 8, 2026

Copy link
Copy Markdown
Member

Benchmark runs are scheduled for commit a02ebcf. Watch https://buildkite.com/apache-arrow and https://conbench.arrow-dev.org for updates. A comment will be posted here when the runs are complete.

Copilot AI 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.

🟡 Changes recommended

There are confirmed build/correctness issues (missing required header includes for DispatchBool, and incorrect handling of implicit trailing empty field metadata at EOF) that should be fixed before merge.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 3
  • Review effort level: Lite

Comment thread cpp/src/arrow/csv/lexing_internal.h Outdated
Comment thread cpp/src/arrow/csv/parser.cc
Comment on lines 493 to 501
AbortLine:
// Not a full line except perhaps if in final block
if (is_final) {
if constexpr (IgnoreExtraColumns) {
// Handle an implicit trailing empty field after a delimiter.
ignoring_extra_field = IsExtraField();
}
goto LineEnd;
}

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.

This appears to be a legacy issue and was not introduced by the current PR.

Copilot AI review requested due to automatic review settings September 8, 2026 05:49
Copilot AI review requested due to automatic review settings September 8, 2026 05:59

Copilot AI 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.

🔵 Needs a closer look

It changes core CSV parsing state-machine logic and warrants careful human validation beyond the automated review.

Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread cpp/src/arrow/csv/lexing_internal.h Outdated
Comment on lines +40 to +43
template <typename... CompiledBools, typename Fn, typename... Rest>
requires std::invocable<Fn, CompiledBools...,
std::conditional_t<true, std::true_type, Rest>...>
decltype(auto) DispatchBool(Fn&& fn, Rest... rest) {

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.

I feel this is a bit too strict; it actually makes the code complicated.

@HuaHuaY

HuaHuaY commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@ursabot please benchmark lang=C++

@rok

rok commented Sep 8, 2026

Copy link
Copy Markdown
Member

Benchmark runs are scheduled for commit a80a3aa. Watch https://buildkite.com/apache-arrow and https://conbench.arrow-dev.org for updates. A comment will be posted here when the runs are complete.

Copilot AI review requested due to automatic review settings September 8, 2026 07:57

Copilot AI 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.

🟢 Approval recommended

The change is localized, maintains default behavior, and includes targeted unit tests at both parser and reader levels.

Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@HuaHuaY

HuaHuaY commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@ursabot please benchmark lang=C++

@rok

rok commented Sep 8, 2026

Copy link
Copy Markdown
Member

Benchmark runs are scheduled for commit 2ac3639. Watch https://buildkite.com/apache-arrow and https://conbench.arrow-dev.org for updates. A comment will be posted here when the runs are complete.

@HuaHuaY

HuaHuaY commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

A comment will be posted here when the runs are complete.

Is this comment no longer being sent?

@HuaHuaY

HuaHuaY commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

I think the benchmark performance regression caused by this PR has basically disappeared. @pitrou Please take a look again.

Comment thread cpp/src/arrow/csv/parser_test.cc

template <bool... CompiledBools, typename Fn, typename... Rest>
decltype(auto) DispatchBool(Fn&& fn, Rest... rest)
requires requires {

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.

Double "requires"?

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.

Yes. The first requires is a syntactic construct. The second requires is a requires expression. We need the second requires when checking whether a statement compiles, rather than when passing a concept.

Comment thread cpp/src/arrow/csv/lexing_internal.h
@pitrou

pitrou commented Sep 9, 2026

Copy link
Copy Markdown
Member

Is this comment no longer being sent?

Indeed, it's not, because we disabled some of the benchmarking machines due to resource consumption issues (cc @rok ).

Or at least I think that's the reason.

@rok

rok commented Sep 9, 2026

Copy link
Copy Markdown
Member

Is this comment no longer being sent?

Indeed, it's not, because we disabled some of the benchmarking machines due to resource consumption issues (cc @rok ).

Or at least I think that's the reason.

Machines are still running, but maybe during optimization (I was changing node sizes etc) some callbacks were not executed. Please benchmark again if you need to and ping me if conbench doesn't post back.

@pitrou

pitrou commented Sep 9, 2026

Copy link
Copy Markdown
Member

When walking through the benchmark results directly from https://conbench.arrow-dev.org/, we see indeed that there's no regression anymore.

Copilot AI review requested due to automatic review settings September 9, 2026 15:23
@HuaHuaY

HuaHuaY commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

I rebase the code and add one more commit, which adds some comments about DispatchBool and a unit test using both ignore_extra_columns and pad_short_rows.

Copilot AI 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.

🟢 Approval recommended

The new option is consistently wired through parsing and dataset inspection, and is covered by targeted parser and reader tests.

Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@pitrou

pitrou commented Sep 9, 2026

Copy link
Copy Markdown
Member

@github-actions crossbow submit -g cpp

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

Revision: 3000cb4

Submitted crossbow builds: ursacomputing/crossbow @ actions-5d85f52df3

Task Status
example-cpp-minimal-build-static GitHub Actions
example-cpp-minimal-build-static-system-dependency GitHub Actions
example-cpp-tutorial GitHub Actions
test-build-cpp-fuzz GitHub Actions
test-conda-cpp GitHub Actions
test-conda-cpp-valgrind GitHub Actions
test-debian-13-cpp-amd64 GitHub Actions
test-debian-13-cpp-i386 GitHub Actions
test-debian-experimental-cpp-gcc-15 GitHub Actions
test-fedora-42-cpp GitHub Actions
test-ubuntu-22.04-cpp GitHub Actions
test-ubuntu-22.04-cpp-bundled GitHub Actions
test-ubuntu-22.04-cpp-emscripten GitHub Actions
test-ubuntu-22.04-cpp-no-threading GitHub Actions
test-ubuntu-24.04-cpp GitHub Actions
test-ubuntu-24.04-cpp-bundled-offline GitHub Actions
test-ubuntu-24.04-cpp-gcc-13-bundled GitHub Actions
test-ubuntu-24.04-cpp-gcc-14 GitHub Actions
test-ubuntu-24.04-cpp-minimal-with-formats GitHub Actions
test-ubuntu-24.04-cpp-thread-sanitizer GitHub Actions

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.

5 participants