Skip to content

GH-51275: [C++][GLib] Allow the CSV Reader to accept multi-character delimiters - #51286

Merged
HuaHuaY merged 9 commits into
apache:mainfrom
HuaHuaY:strengthen_csv
Nov 9, 2026
Merged

HuaHuaY merged 9 commits into
apache:mainfrom
HuaHuaY:strengthen_csv

Conversation

@HuaHuaY

@HuaHuaY HuaHuaY commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Rationale for this change

Now the type of delimiter in ParseOptions is char, and we can only read csv files whose delimiter is one character. I think we can lift this restriction.

What changes are included in this PR?

Added a higher-priority delimiter_string to ParseOptions, and added support for multi-character delimiters in both the chunker and the parser.

Are these changes tested?

Yes.

Are there any user-facing changes?

Yes. A new option delimiter_string is added to ParseOptions.

Copilot AI lite review requested due to automatic review settings September 10, 2026 13:14
@HuaHuaY
HuaHuaY requested a review from pitrou as a code owner September 10, 2026 13:14
@HuaHuaY
HuaHuaY requested a review from wgtmac September 10, 2026 13:15
@HuaHuaY

HuaHuaY commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

@ursabot please benchmark lang=C++

@rok

rok commented Sep 10, 2026

Copy link
Copy Markdown
Member

Benchmark runs are scheduled for commit 31adcd2. 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

CsvFileFormat::Equals() currently compares delimiter even when delimiter_string overrides it, which can produce incorrect inequality for semantically identical parse options.

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

Pull request overview

This PR extends the Arrow C++ CSV reader to support multi-character field delimiters by introducing a new ParseOptions::delimiter_string that overrides the existing single-character delimiter, and updating the parser/chunker accordingly.

Changes:

  • Add ParseOptions::delimiter_string (higher priority than delimiter) and validate delimiter interactions with quoting/escaping/line endings.
  • Implement multi-character delimiter matching in both the CSV parser and the chunker (lexing boundary finder).
  • Add unit tests covering multi-character delimiters across reader, parser, and chunker.
File summaries
File Description
cpp/src/arrow/dataset/file_csv.cc Include delimiter_string in format equality; reject CSV writing when delimiter_string is set.
cpp/src/arrow/csv/options.h Add ParseOptions::delimiter_string with override semantics.
cpp/src/arrow/csv/options.cc Extend ParseOptions::Validate() for delimiter-string constraints (escaping/quoting/CRLF).
cpp/src/arrow/csv/lexing_internal.h Add delimiter helpers and a streaming delimiter matcher; adjust bulk filter delimiter byte selection.
cpp/src/arrow/csv/chunker.cc Support multi-character delimiter detection (for quote recognition) during chunking when needed.
cpp/src/arrow/csv/parser.cc Add multi-character delimiter matching in the field parser state machine.
cpp/src/arrow/csv/reader_test.cc Add end-to-end reader test for multi-character delimiters.
cpp/src/arrow/csv/parser_test.cc Add parser tests for multi-character delimiters, delimiter-prefix-at-block-end, and single-char delimiter_string.
cpp/src/arrow/csv/chunker_test.cc Add chunker test for multi-character delimiter behavior with partial buffers.
Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 1
  • Review effort level: Lite

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

Comment thread cpp/src/arrow/dataset/file_csv.cc Resolved

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/chunking state machines and delimiter handling, which warrants final human review for subtle correctness/performance edge cases.

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

Comment thread cpp/src/arrow/csv/options.cc Resolved
@HuaHuaY

HuaHuaY commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

@ursabot please benchmark lang=C++

@rok

rok commented Sep 10, 2026

Copy link
Copy Markdown
Member

Benchmark runs are scheduled for commit a161eff. 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.

Comment thread cpp/src/arrow/csv/options.cc Resolved
Comment thread cpp/src/arrow/dataset/file_csv.cc Resolved
Status ParseOptions::Validate() const {
if (ARROW_PREDICT_FALSE(delimiter == '\n' || delimiter == '\r')) {
return Status::Invalid("ParseOptions: delimiter cannot be \\r or \\n");
// The chunker handles escapes before delimiter matching, so allowing the escape

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.

Is it cleaner to consolidate the two cases like below?

  std::string invalid_chars = "\r\n";
  if (escaping) {
    invalid_chars.push_back(escape_char);
  }

  const bool use_delimiter_string = !delimiter_string.empty();
  const auto invalid_pos =
      use_delimiter_string ? delimiter_string.find_first_of(invalid_chars)
                           : invalid_chars.find(delimiter);
  if (invalid_pos != std::string::npos) {
    return Status::Invalid("ParseOptions: delimiter contains an invalid character");
  }

  const char delimiter_first_byte =
      use_delimiter_string ? delimiter_string.front() : delimiter;
  if (quoting && delimiter_first_byte == quote_char) {
    return Status::Invalid(
        "ParseOptions: delimiter cannot start with the quote character");
  }

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.

However, by doing this, we lose the specific reason for the error.

Comment thread cpp/src/arrow/csv/parser.cc Resolved
Comment thread cpp/src/arrow/csv/parser_test.cc Resolved
Comment thread cpp/src/arrow/dataset/file_csv.cc Resolved
Comment thread cpp/src/arrow/dataset/file_csv.cc Resolved
Comment thread cpp/src/arrow/csv/chunker_test.cc Resolved
Copilot AI lite review requested due to automatic review settings October 9, 2026 15:57
@HuaHuaY
HuaHuaY requested a review from wgtmac October 9, 2026 15:58

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

Writer-option compatibility can silently produce comma-delimited output for an effectively equal delimiter configuration.

1 open finding
2 resolved since last review

🧠 Review effort: Lite

Comment thread cpp/src/arrow/dataset/file_csv.cc Resolved
Copilot AI lite review requested due to automatic review settings October 10, 2026 02:54

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

The available assessments do not establish sufficient confidence for automated approval.

0 open findings

1 resolved since last review

🧠 Review effort: Lite

Copilot AI lite review requested due to automatic review settings October 10, 2026 06:45
@HuaHuaY
HuaHuaY requested a review from kou as a code owner October 10, 2026 06:45

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

The broad parser, chunker, dataset, and binding changes warrant final human review.

0 open findings

🧠 Review effort: Lite

Copilot AI lite review requested due to automatic review settings October 29, 2026 09:50

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

A critical active finding identifies an unaddressed binary-breaking ABI change to the public ParseOptions struct.

1 open issue

Review effort: Lite

Comment thread cpp/src/arrow/csv/options.h Resolved
Comment thread cpp/src/arrow/csv/parser.cc Resolved
Copilot AI lite review requested due to automatic review settings October 29, 2026 11:20

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

The patch spans streaming CSV state-machine behavior and GLib-managed C++ object lifetimes, so delimiter-prefix splits, quoting/escaping, and build/runtime integration require maintainer validation beyond static review.

No open issues 🎉

1 resolved since last review

Review effort: Lite

@HuaHuaY

HuaHuaY commented Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

@pitrou Please take a look again.

Comment thread cpp/src/arrow/csv/chunker_test.cc Resolved
Comment thread cpp/src/arrow/csv/parser_test.cc Resolved
Comment thread cpp/src/arrow/csv/parser_test.cc Resolved
Comment thread cpp/src/arrow/csv/parser_test.cc Resolved
Copilot AI lite review requested due to automatic review settings November 2, 2026 10:02

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

The exported ParseOptions layout/lifetime changes and delimiter behavior span parser and chunker paths, so ABI/versioning and cross-language compatibility require maintainer validation beyond static review.

No open issues 🎉

Review effort: Lite

@HuaHuaY

HuaHuaY commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

@pitrou Please take a look again.

@HuaHuaY

HuaHuaY commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

If there are no further comments, I will merge this PR on Wednesday.

@pitrou

pitrou commented Nov 9, 2026

Copy link
Copy Markdown
Member

Please do :)

@HuaHuaY
HuaHuaY merged commit f8fb28d into apache:main Nov 9, 2026
61 of 63 checks passed
@HuaHuaY
HuaHuaY deleted the strengthen_csv branch November 9, 2026 09:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants