Skip to content

fix(variant): write parquet field ids in shredded physical schema - #379

Merged
lxy-9602 merged 1 commit into
apache:mainfrom
SteNicholas:PAIMON-344
Sep 21, 2026
Merged

lxy-9602 merged 1 commit into
apache:mainfrom
SteNicholas:PAIMON-344

Conversation

@SteNicholas

Copy link
Copy Markdown
Member

Purpose

Linked issue: close #344

The generated physical schema of a shredded Variant column carried no paimon.id, so the parquet
writer emitted no field id for metadata, value, typed_value or any of their descendants. Java
Paimon converts the whole Variant group with its generic ParquetSchemaConverter, which
dereferences the field id of every converted field, so reading such a file threw a
NullPointerException before the first row. Configured, inferred and adaptive shredding share this
schema construction, so all three produced files that only paimon-cpp could read.

This numbers the generated fields the way the Java PaimonShreddingUtils does: each level is
numbered from 0 in insertion order, an object field keeps the id from the shredding schema or its
position when it has none, and an array element takes the id ParquetSchemaConverter generates for
it (SpecialFields.getArrayElementFieldId).

Tests

  • VariantShreddingTest.ShreddingSchemaFieldIds
  • VariantShreddingTest.ShreddingSchemaRejectsInvalidFieldIds
  • VariantShreddingTest.ShreddingArraySchemaFieldIds
  • VariantParquetTest.ShreddedWriteAndReadRoundTrip, extended to assert the raw parquet footer
    field ids of the whole shredded subtree under the configured, per-file and adaptive shredding
    modes
  • SpecialFieldsTest.TestGetArrayElementFieldId, pinning the generated element id against the
    values the Java SpecialFields produces

API and Format

No public API change. The storage format of shredded Variant columns changes: the generated
physical fields now carry parquet field ids, matching what the Java writer produces. Files written
before this change remain readable by paimon-cpp.

Documentation

No, this is a bug fix and introduces no new feature.

Generative AI tooling

Generated-by: Claude Code (Claude Opus 5)

The generated physical schema of a shredded Variant column carried no
`paimon.id`, so the parquet writer emitted no field id for `metadata`,
`value`, `typed_value` or any of their descendants. Java Paimon converts
the whole Variant group with its generic `ParquetSchemaConverter`, which
dereferences the field id of every converted field, so reading such a
file threw a NullPointerException before the first row. Configured,
inferred and adaptive shredding share this schema construction, so all
three produced files that only paimon-cpp could read.

Number the generated fields the way the Java `PaimonShreddingUtils` does:
each level is numbered from 0 in insertion order, an object field keeps
the id from the shredding schema or its position when it has none, and an
array element takes the id `ParquetSchemaConverter` generates for it.

@lxy-9602 lxy-9602 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

+1

@lxy-9602

Copy link
Copy Markdown
Member

Thanks to @SteNicholas for the fix. @suxiaogang223 , could you please check again whether the issue is resolved after this PR is merged? Thanks!

@lxy-9602
lxy-9602 merged commit 5a2fb5c into apache:main Sep 21, 2026
16 checks passed
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.

[Bug] Shredded Variant files miss internal field IDs and cannot be read by Java Paimon

2 participants