Skip to content

[911] Carry Delta's nested field ids into the converted schema - #912

Draft
slachiewicz wants to merge 1 commit into
apache:mainfrom
slachiewicz:delta-nested-field-ids
Draft

[911] Carry Delta's nested field ids into the converted schema#912
slachiewicz wants to merge 1 commit into
apache:mainfrom
slachiewicz:delta-nested-field-ids

Conversation

@slachiewicz

@slachiewicz slachiewicz commented Aug 23, 2026

Copy link
Copy Markdown
Member

Part of #911.

What is the purpose of the pull request

Delta assigns column mapping IDs to struct fields only, so a map key, a map value, and a list element have no ID of their own. When delta.enableIcebergCompatV2 is set, Delta assigns them, writes them into the Parquet file, and records them on the enclosing field under delta.columnMapping.nested.ids, keyed by the path the child takes in the file, such as col-1234.key. This change reads that metadata and puts the IDs on the converted fields.

It matters because Delta 3.x writes Parquet field IDs where Delta 2.4 writes none, and Iceberg applies a name mapping only to files that carry no IDs at all. Once any ID is present, the nested children of a collection must resolve by ID too, and they have none. For the footers from both Delta versions and the failure that follows, see #911.

Brief change log

  • DeltaSchemaExtractor threads a field's delta.columnMapping.nested.ids metadata through the conversion and assigns the IDs it holds to the map key, map value, and list element fields.
  • IcebergSchemaExtractor needs no change: it already prefers a field's own ID over one it generates.
  • .gitignore ignores .claude/, which otherwise fails rat:check on a local build.

Verify this pull request

This change added tests and can be verified as follows:

  • TestDeltaSchemaExtractor#testNestedFieldIdsInDeltaSchema covers a map and a list that carry the metadata, and a field without it, which leaves the children unassigned as before.
  • ./mvnw -pl xtable-core test -Dtest=TestDeltaSchemaExtractor,TestIcebergSchemaExtractor runs 21 tests, all green.

The end-to-end effect is observable only on Delta 3.x, because Delta 2.4 has no IcebergCompatV2 and writes no Parquet field IDs, so the change is inert on this branch. Stacked under the Spark 3.5 and Delta 3.3 upgrade, ITConversionController#testColumnMappingEnabledDeltaToIceberg passes with IcebergCompatV2 enabled on the source table, where it fails on that branch without this change.

This change was created with AI assistance.

Delta assigns column mapping ids to struct fields only, so the key, value
and element of a collection have no id of their own. When IcebergCompatV2
is enabled Delta does assign them and records them per field under
delta.columnMapping.nested.ids, keyed by the path the child takes in the
parquet file. Read those and put them on the converted fields, which the
Iceberg target already prefers over the ids it generates itself.
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.

1 participant