Repository navigation
Avro: read named type references and write unique fixed type names - #4119
Open
ozenyunus35 wants to merge 3 commits into
Open
ozenyunus35 wants to merge 3 commits into
ozenyunus35 wants to merge 3 commits into
Conversation
Fokko
reviewed
Oct 18, 2026
Fokko
left a comment
Contributor
There was a problem hiding this comment.
I've suggested another approach in one of the comments, let me know what you think 👍
|
|
||
|
|
||
| # Avro types that have a name and can be referred to by it later in the schema | ||
| AVRO_NAMED_TYPES = {"record", "enum", "fixed"} |
| if name in self.defined_names: | ||
| return name | ||
| self.defined_names.add(name) | ||
| return named_type |
Contributor
There was a problem hiding this comment.
I think we're doing quite a bit of additional bookkeeping. I'm wondering if it wouldn't be easier to include the field-id to the name (which is unique by definition).
Author
There was a problem hiding this comment.
Good idea, thanks. 4f95b2e drops the bookkeeping: a fixed, decimal or uuid type now gets the field-id of the field, list element or map key/value that uses it in its name (e.g. decimal_10_2_1), like records are named r<field-id>. Reading the reference form is unchanged.
Review feedback: a fixed, decimal or uuid type now gets the field-id of the field, list element or map key/value that uses it in its name, the same way records are named r<field-id>. Field-ids are unique, so every definition has its own name and the writer no longer needs to track which names it has defined. AVRO_NAMED_TYPES is a frozenset.
This branch has not been deployed
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.
Closes #4116
Rationale for this change
As described in the issue, an Avro named type (
decimal_P_S,fixed_L,uuid_fixed) may only be defined once per schema; later uses must refer to it by name. PyIceberg couldn't read the reference form (TypeError: Type not recognized: decimal_10_2), so it failed on manifests written by Java and iceberg-rust, and it wrote the same definition every time a type was reused, which strict readers reject.AvroSchemaConversionremembers each named type (record,enum,fixed) it converts, and resolves a later string type with that name to the same Iceberg type. A repeated full definition is still accepted, so existing manifests keep working. The map is reset at the start ofavro_to_iceberg.ConvertSchemaToAvroadds the field-id of the field, list element or map key/value that uses a fixed, decimal or uuid type to its name (decimal_10_2_1,fixed_3_5,uuid_fixed_7), the same way records are namedr<field-id>. Field-ids are unique, so every definition has its own name and no bookkeeping of defined names is needed.Are these changes tested?
Yes, in the existing test files:
tests/utils/test_schema_conversion.py: reading the reference form (the repro from the issue, plusfixed_3anduuid_fixed), reading the repeated form, an unknown name still raisingTypeError, and writing a schema with repeated decimal, fixed (one inside a struct) and uuid types, including a list element and a map key and value: each gets the field-id in its name and the result reads back to the same schema.tests/avro/test_file.py:test_repeated_named_types_round_tripwrites a file with twodecimal(10,2)and two uuid fields throughAvroOutputFileand reads it back with PyIceberg and with fastavro. Without the change, fastavro refuses the file with aSchemaParseExceptionfor the redefined name.The new tests fail without the change.
tests/utils/test_schema_conversion.py,tests/avro,tests/test_avro_sanitization.pyandtests/utils/test_manifest.pypass. Failures in my environment from optional extras I didn't install are the same before and after the change. ruff 0.14.3 and mypy 1.18.2 (the pre-commit versions) are clean.Are there any user-facing changes?
Manifests and manifest lists that refer to a named type by name can now be read, and the fixed, decimal and uuid types PyIceberg writes now have the field-id in their name.
I used an AI assistant to help draft parts of the code and tests; I reviewed the changes and ran the tests myself.