Skip to content

GH-55446: [C++] Respect URI encoding in filename and directory partitioning when writing datasets - #55423

Merged
pitrou merged 13 commits into
apache:mainfrom
adamreeve:directory-partition-escape
Nov 10, 2026
Merged

pitrou merged 13 commits into
apache:mainfrom
adamreeve:directory-partition-escape

Conversation

@adamreeve

@adamreeve adamreeve commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Rationale for this change

Make dataset writing with directory and filename partitioning able to use URI encoding, to support writing values that require encoding to round-trip correctly.

What changes are included in this PR?

When writing a dataset with DirectoryPartitioning or FilenamePartitioning, respect the segment_encoding parameter and use URI encoding if it is enabled. Note that it's enabled by default, so this changes the default behaviour. Previously the segment_encoding parameter was only used when reading.

This also adds additional validation when no encoding is used, and rejects empty string values that cannot be round-tripped correctly with these two partitioning methods.

Are these changes tested?

Yes, this includes new unit tests.

Are there any user-facing changes?

Yes. DirectoryPartitioning and FilenamePartitioning both now URI encode path segments by default. This can be disabled if desired to revert to the previous behaviour by setting the the segment_encoding parameter to "none".

Was AI used for this PR?

In accordance to the AI generation guidelines, please disclose below whether and how AI was used in this PR.

PR code and description written by:

  • Human - Description and some code
  • AI - Code, with close supervision

Reviewed before submission by:

  • Human
  • AI
  • Not reviewed

@github-actions

This comment was marked as low quality.

@adamreeve
adamreeve force-pushed the directory-partition-escape branch from c0445a2 to c3959a6 Compare November 9, 2026 01:33
@adamreeve adamreeve changed the title DRAFT: [C++] Respect URI encoding setting for filename and directory partitioning when writing datasets GH-55446: [C++] Respect URI encoding setting for filename and directory partitioning when writing datasets Nov 9, 2026
@adamreeve adamreeve changed the title GH-55446: [C++] Respect URI encoding setting for filename and directory partitioning when writing datasets GH-55446: [C++] Respect URI encoding in filename and directory partitioning when writing datasets Nov 9, 2026
@adamreeve
adamreeve marked this pull request as ready for review November 9, 2026 02:25
Copilot AI balanced review requested due to automatic review settings November 9, 2026 02:25

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

No active review issues are blocking approval of the partition segment-encoding changes.

No open issues 🎉

What changed in this PR

Addresses GH-55446 by making C++ dataset writing respect segment_encoding for directory and filename partitioning, allowing encoded partition values to round-trip correctly.

Changes:

  • URI-encodes partition values by default, including filename separators and characters requiring special path handling.
  • Rejects empty values and unsafe unencoded segments.
  • Adds formatting and round-trip tests, updates Python expectations, and documents the encoding behavior.
File Description
python/​pyarrow/​tests/​test_dataset.py Updates expected formatted paths to use URI encoding.
python/​pyarrow/​_dataset.pyx Documents encoding during writing as well as decoding during reading.
cpp/​src/​arrow/​dataset/​partition.h Documents validation rules and adds the filename-separator escaping parameter.
cpp/​src/​arrow/​dataset/​partition.cc Implements encoding and validation for directory and filename partition values.
cpp/​src/​arrow/​dataset/​partition_test.cc Adds encoding, validation, dataset round-trip, and Hive empty-value regression tests.

Review effort: Balanced

@pitrou pitrou 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.

LGTM, thank you! Just two minor comments.

Comment thread cpp/src/arrow/dataset/partition.h Outdated
Comment on lines +226 to +227
/// \param[in] escape_filename_separator whether values must not contain the
/// filename partitioning separator ("_"). It is escaped when using

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.

The double negative reads a bit weird.

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.

Yeah this does sound a bit awkward, I've reworded it in f1d8404

Comment thread cpp/src/arrow/dataset/partition.cc Outdated
escaped.find(kFilenamePartitionSep) != std::string::npos) {
const std::string encoded_separator = PercentEncode(kFilenamePartitionSep);
std::string with_separator;
with_separator.reserve(escaped.size() + 2 * encoded_separator.size());

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.

Why 2 *? Are we expecting to escape two separators on average?

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.

Yeah this was to try to reduce the need for re-allocation. Although it doesn't account for the size of the unencoded separator character, so you actually get space for 3 separators.

I think it might be best to just remove this line. It makes the code less readable and this isn't performance critical, these strings should be small and this is only called once per partition in each dataset batch written.

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've removed this line in a14ba14

Copilot AI balanced review requested due to automatic review settings November 9, 2026 21: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

No active review issues were identified for the changes to honor segment encoding when writing dataset partitions.

No open issues 🎉

Review effort: Balanced

@pitrou pitrou 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.

Thanks a lot for fixing this @adamreeve !

@pitrou pitrou added Critical Fix Bugfixes for security vulnerabilities, crashes, or invalid data. backport-candidate labels Nov 10, 2026
@pitrou
pitrou merged commit 5f42d1f into apache:main Nov 10, 2026
76 of 99 checks passed
@adamreeve
adamreeve deleted the directory-partition-escape branch November 10, 2026 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-candidate Component: C++ Component: Python Critical Fix Bugfixes for security vulnerabilities, crashes, or invalid data.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants