Repository navigation
GH-49704: [Format][C++] Add custom_metadata to DictionaryEncoding for the dictionary value type - #53994
Draft
rustyconover wants to merge 1 commit into
Draft
GH-49704: [Format][C++] Add custom_metadata to DictionaryEncoding for the dictionary value type#53994rustyconover wants to merge 1 commit into
rustyconover wants to merge 1 commit into
Conversation
This was referenced Oct 16, 2026
Draft
|
|
…ng for the dictionary value type In IPC, a dictionary-encoded field is a single Field whose type is the dictionary value type, so dictionary<values=extension<X>> and extension<X, storage=dictionary<...>> were serialized identically, with the extension keys in Field.custom_metadata. Add an optional custom_metadata member at the end of the DictionaryEncoding table holding the metadata of the dictionary value type (format version 1.6). The C++ IPC writer now puts the extension keys of a dictionary value type there, and the reader deserializes the value extension type from it before wrapping it in the dictionary type and applying Field.custom_metadata as before. The integration JSON format gains a matching optional "metadata" member in the "dictionary" object, and a "dictionary_extension" archery case, which C++ and Go produce and consume (Go skips the C schema format, Rust is skipped as it can read but not write the case). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
rustyconover
force-pushed
the
gh-49704-dictionary-value-metadata
branch
from
October 16, 2026 17:28
401634e to
0cd8838
Compare
rustyconover
pushed a commit
to rustyconover/arrow-nanoarrow
that referenced
this pull request
Oct 16, 2026
…ionary values Implements the draft Arrow format 1.6 change from apache/arrow#49704 (apache/arrow#53994): an optional custom_metadata on DictionaryEncoding that holds the metadata of the dictionary value type. It is the IPC counterpart of ArrowSchema.dictionary->metadata, and Field.custom_metadata corresponds to the parent ArrowSchema's metadata. - flatcc_generated.h is regenerated with dev/update_fbs.sh (flatcc e3e44836) from apache/arrow main plus the draft Schema.fbs change. - The encoder writes schema->dictionary->metadata (all keys) to DictionaryEncoding.custom_metadata, omitted when it is NULL or empty, and keeps writing schema->metadata to Field.custom_metadata. Before, the value metadata was dropped. - The decoder sets schema->dictionary->metadata from DictionaryEncoding.custom_metadata and keeps Field.custom_metadata on the parent schema, as before. This covers nested dictionaries and footer decoding. Footer encoding carries the member when the caller fills footer.dictionaries. - The integration JSON reader and writer support the optional "metadata" of a field's "dictionary" object, and the JSON comparison compares the dictionary value metadata, including nested dictionaries. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Rationale for this change
In IPC a dictionary-encoded column is a single
Fieldwhose type is the value type. The only metadata slot wasField.custom_metadata, sodictionary<values=extension<X>>andextension<X, storage=dictionary<...>>serialized identically. Arrow C++ reads both as the latter, so pyarrow cannot read back its own stream ofpa.dictionary(pa.int32(), pa.uuid()):Invalid storage type for UuidType: dictionary<...>. The dev@ thread (https://lists.apache.org/thread/4xj0yrl2vn0lbrv39p3dvd28okvkjxyz) reached lazy consensus on adding KeyValue metadata for the value type toDictionaryEncoding(option 1).This is a format change. It needs a
[VOTE]on dev@ and two reference implementations, so this PR is a draft. Companion PRs:Fieldmetadata until Field metadata for dictionary-encoded extension types is lost arrow-rs#7982 is fixed: Addcustom_metadatato IPCDictionaryEncodingarrow-rs#11622ArrowSchema.dictionary->metadata: feat(ipc): Read and write DictionaryEncoding.custom_metadata for dictionary values arrow-nanoarrow#972What changes are included in this PR?
custom_metadata: [KeyValue]appended toDictionaryEncoding. It is thecustom_metadataof the dictionary value type, with the same semantics asField.custom_metadata(including the reservedARROW:extension:*keys) but applied to the dictionary values. It is the IPC counterpart ofArrowSchema.dictionary->metadatain the C Data Interface.ARROW:extension:name/ARROW:extension:metadatathere rather than inField.custom_metadata.Field.custom_metadataas before.DictionaryTypecannot hold value-type metadata, so other keys and unregistered extension names are not preserved. That is an implementation limitation, not a spec rule.Schema.fbshistory and the Columnar, Versioning and Integration docs.MetadataVersionstays V5, and the file footer and Flight need no other change.Schema_generated.hregenerated with flatc 24.3.6, limited to the new member."dictionary": {..., "metadata": [...]}).dictionary_extensioncase, run for C++ only for now.ruby/red-arrow-format/.../dictionary_encoding.rb) were not regenerated, because no Ruby toolchain was available. They needrake flat_buffers:generate.DictionaryFieldMapperandDictionaryCollector(ipc/dictionary.cc) don't look through extension value types, so dictionaries nested inside extension dictionary values are not supported.ARROW:schemaround-trip test.Are these changes tested?
Yes.
Are there any user-facing changes?
Yes:
pa.dictionary(pa.int32(), pa.uuid())) through IPC.Field.custom_metadatatoDictionaryEncoding.custom_metadata.arrow.opaque, which older readers used to keep, though with the wrong nesting (as an extension type with dictionary storage).arrow.uuidon a dictionary still fails to read, as it does today.Was AI used for this PR?
PR code and description written by:
Reviewed before submission by:
🤖 Generated with Claude Code