Repository navigation
GH-55446: [C++] Respect URI encoding in filename and directory partitioning when writing datasets - #55423
Conversation
This comment was marked as low quality.
This comment was marked as low quality.
…dataset The segment_encoding option was already respected when reading a directory-partitioned dataset, but ignored when writing. This change now URI encodes path segments if the encoding mode is set to Uri. In addition, invalid path segments now raise an error if they are invalid.
5c631cf to
c0445a2
Compare
c0445a2 to
c3959a6
Compare
There was a problem hiding this comment.
🟢 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
left a comment
There was a problem hiding this comment.
LGTM, thank you! Just two minor comments.
| /// \param[in] escape_filename_separator whether values must not contain the | ||
| /// filename partitioning separator ("_"). It is escaped when using |
There was a problem hiding this comment.
The double negative reads a bit weird.
There was a problem hiding this comment.
Yeah this does sound a bit awkward, I've reworded it in f1d8404
| 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()); |
There was a problem hiding this comment.
Why 2 *? Are we expecting to escape two separators on average?
There was a problem hiding this comment.
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.
pitrou
left a comment
There was a problem hiding this comment.
Thanks a lot for fixing this @adamreeve !
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
DirectoryPartitioningorFilenamePartitioning, respect thesegment_encodingparameter and use URI encoding if it is enabled. Note that it's enabled by default, so this changes the default behaviour. Previously thesegment_encodingparameter 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.
DirectoryPartitioningandFilenamePartitioningboth now URI encode path segments by default. This can be disabled if desired to revert to the previous behaviour by setting the thesegment_encodingparameter 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:
Reviewed before submission by: