Skip to content

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

Open
slachiewicz wants to merge 2 commits into
apache:mainfrom
slachiewicz:delta-nested-field-ids
Open

[911] Carry Delta's nested field ids into the converted schema#912
slachiewicz wants to merge 2 commits 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.
@slachiewicz
slachiewicz force-pushed the delta-nested-field-ids branch from b05ac71 to 759b226 Compare September 5, 2026 09:46
@slachiewicz
slachiewicz marked this pull request as ready for review September 5, 2026 10:47
}

@Test
public void testNestedFieldIdsInDeltaSchema() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also test when the values in the list or map are complex objects as well?

@slachiewicz

Copy link
Copy Markdown
Member Author

Addressed reviewer comment: added covering list/map with complex objects (struct values, nested arrays). All new tests pass.

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.

2 participants