Manifest: Use int for equality_ids in manifest schema per Iceberg spec (#3840) - #3842
Manifest: Use int for equality_ids in manifest schema per Iceberg spec (#3840)#3842hedger9487 wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Updates manifest equality_ids to use Iceberg’s specified int type while supporting legacy manifests.
Changes:
- Corrects manifest schemas for format versions 1–3.
- Adds legacy long-to-int decoding support.
- Adds serialization and compatibility tests.
- Resolver compatibility must be scoped to
equality_ids; the current broad handling can accept out-of-range values.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Summary |
|---|---|
tests/utils/test_manifest.py |
Tests current serialization and legacy manifest reading. |
pyiceberg/manifest.py |
Uses IntegerType for equality_ids. |
pyiceberg/avro/resolver.py |
Adds long-to-int compatibility, but the implementation is overly broad. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if isinstance(primitive, LongType) and isinstance(expected_primitive, IntegerType): | ||
| pass | ||
| else: | ||
| promote(primitive, expected_primitive) |
|
Oof. This isn't great. I'd like to do some digging to verify all of this. Here's my initial thoughts:
|
|
Thanks for the thoughtful feedback @rambleraptor! I have updated the PR accordingly:
All tests pass cleanly. Ready for another review! |
|
thanks for the PR @hedger9487 The main difference with the current PR is to not introduce a new compatibility flag. And instead allow pyiceberg to read Please let me know what you think! |
b52f97b to
05b4e0f
Compare
|
Thanks for the suggestion, @kevinjqliu! Connecting this fix with a future I have updated the PR to align with this proposal:
All tests and pre-commit checks are passing cleanly. I'll also be working on the Ready for another review whenever convenient, thanks! |
kevinjqliu
left a comment
There was a problem hiding this comment.
seems like there are a few unrelated changes in the PR
we should tighten the scope to include
- changing default from long -> int
- fallback read for long type w/ tests
we could split up (1) into its own PR. for (2), im curious what the best way to do this, i'll check with my agent 😄
|
Thanks for iterating on this @hedger9487! I took a pass at simplifying the read-side fallback and pushed a reference branch: main...kevinjqliu:iceberg-python:claude/schema-long-int-avro-fallback-4ec219 The main differences from this PR:
Would you mind adopting that shape here? Happy to take it over if you'd prefer, just let me know. Once this lands we can follow up with the |
…nifests (apache#3840) The Iceberg spec defines data_file.equality_ids as list<int>, but PyIceberg wrote list<long>, which strict readers such as iceberg-cpp reject. Fix the manifest schema so new manifests follow the spec, and let the Avro resolver read the legacy long element as int for that field only, so existing manifests stay readable without loosening type promotion anywhere else. Closes apache#3840. Co-authored-by: Kevin Liu <kevin.jq.liu@gmail.com>
05b4e0f to
6cc50cc
Compare
|
Thanks @kevinjqliu! That’s so much cleaner and more scoped. I've adopted your reference branch shape directly:
All pre-commit hooks, linters, and unit tests are green locally. I've rebased onto the latest |
Description
Fixes #3840.
In the Iceberg specification (
format/spec.md), Java reference implementation, andiceberg-cpp,equality_ids(field 135) is defined as a list ofint(list<136: int>). However,pyicebergpreviously declared field 136 withLongType(), causing manifests written by PyIceberg to be rejected by other spec-conformant readers (e.g.iceberg-cpp).This PR:
DATA_FILE_TYPEinpyiceberg/manifest.pyfor table format versions 1, 2, and 3 to useIntegerType()for element id 136 inequality_ids.ReadSchemaResolver.primitiveinpyiceberg/avro/resolver.pyto allow promotingLongTypein file schema toIntegerTypein read schema for Avro decoding (since both are encoded as zigzag varints on the wire), ensuring backward compatibility when reading historical manifests written by earlier versions of PyIceberg.equality_idswith element typeint, and that historical manifests with element typelongcan be read seamlessly.Testing
tests/utils/test_manifest.py.