Skip to content

Read tables with multi-argument transforms as unknown transforms#3630

Open
moomindani wants to merge 2 commits into
apache:mainfrom
moomindani:moomindani/multi-arg-transforms
Open

Read tables with multi-argument transforms as unknown transforms#3630
moomindani wants to merge 2 commits into
apache:mainfrom
moomindani:moomindani/multi-arg-transforms

Conversation

@moomindani

Copy link
Copy Markdown

Closes #3628 (part of #1818)

Rationale for this change

The V3 spec requires readers to read tables with unknown transforms, ignoring them. PyIceberg raised (Multi argument transforms are not yet supported) on partition or sort fields with more than one entry in source-ids, so loading such tables failed entirely.

  • Model source-ids on PartitionField / SortField and treat multi-argument transforms as UnknownTransform, which already gives the spec behavior (no partition pruning: project returns None).
  • Serialize per spec: source-id only for single-argument transforms, source-ids only for multi-argument ones, so specs round-trip faithfully instead of being silently rewritten on the next commit.
  • Fix two latent tolerance bugs found along the way: unknown transform names sharing a prefix with known ones (e.g. bucketv2[4]) failed parsing instead of becoming UnknownTransform, and str(UnknownTransform) returned "unknown" instead of the original name, corrupting the transform name when metadata is rewritten.

Evaluating multi-argument transforms on write stays out of scope until the spec defines concrete ones.

Note on other implementations: none currently satisfies the spec's tolerance requirement in full. Java has not implemented source-ids (its parser requires source-id), though its transform parsing already matches names exactly and UnknownTransform.toString() preserves the original name — the two tolerance fixes here align PyIceberg with that behavior. iceberg-rust and iceberg-cpp reject unrecognized transform names outright. The source-ids handling here follows the spec text directly (partition/sort field JSON: single-argument transforms write only source-id, multi-argument only source-ids).

Are these changes tested?

Yes: eight new tests covering multi-argument parse tolerance (partition and sort), round-trip serialization (source-ids preserved, source-id omitted, transform name intact), single-element normalization, partition_type resolution, prefix-colliding unknown transform names, and str(UnknownTransform) name preservation. All fail without the fix. No new failures in tests/table, tests/catalog, tests/utils.

Are there any user-facing changes?

Yes: tables using multi-argument transforms now load and scan (without pruning on those fields) instead of raising.

This pull request and its description were written by Claude Fable 5.

Per the V3 spec, readers must read tables with unknown transforms,
ignoring them. PyIceberg raised on partition or sort fields with more
than one entry in source-ids, so such tables failed to load.

Model source-ids on PartitionField and SortField, treat multi-argument
transforms as UnknownTransform (null partition values, always-true
projection), and serialize per spec: source-id for single-argument
transforms, source-ids otherwise. Also fix two latent tolerance bugs:
unknown transform names sharing a prefix with known ones (e.g.
bucketv2[4]) failed to parse, and str(UnknownTransform) returned
"unknown" instead of the original name, corrupting metadata on
rewrite.

Closes apache#3628
A multi-argument field without a transform previously fabricated
UnknownTransform('None') and masked the missing required field; raise
a clear error instead. Assert explicitly that a single-element
source-ids is normalized onto source-id, and only use the list form
of __str__ for genuinely multi-argument fields.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support multi-argument transforms

1 participant