Skip to content

[format] Follow Parquet list backward-compatibility rules in schema clipping - #9550

Open
juntaozhang wants to merge 1 commit into
apache:masterfrom
juntaozhang:pr-list-backward-compatibility
Open

[format] Follow Parquet list backward-compatibility rules in schema clipping#9550
juntaozhang wants to merge 1 commit into
apache:masterfrom
juntaozhang:pr-list-backward-compatibility

Conversation

@juntaozhang

Copy link
Copy Markdown
Contributor

Purpose

Follow Parquet's backward-compatibility rules for the LIST logical type when clipping Parquet schemas, so that nested variant column pruning and schema conversion correctly distinguish wrapper groups from element types across all standard and legacy list encodings:

  • Rule 1: repeated primitive field is the element type.
  • Rule 2: repeated group with multiple fields is the element type.
  • Rule 3: repeated group whose single child is also repeated is the element type.
  • Rule 4: repeated group named array or <list>_tuple is the element type.
  • Rule 5: any other repeated group with exactly one non-repeated child is a wrapper; its child is the element type.

Previously the list-structure check did not fully apply these rules, which could misidentify legacy two-level encodings as three-level lists and return the wrong element type during nested variant pruning.

Tests

mvn -pl paimon-format -DwildcardSuites=none -Dtest=ParquetSchemaConverterTest test

@juntaozhang juntaozhang closed this Sep 2, 2026
@juntaozhang juntaozhang reopened this Sep 2, 2026
clipParquetType(elementReadType, parquetListElementType(arrayGroup));

if (level == 3) {
if (isThreeLevelList(arrayGroup)) {

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.

[P1] Preserve the original Rule 2 interpretation after clipping

Rule 2 is identified from the original two-field repeated group here, but after recursive projection the rebuilt requested schema may contain only one field. ParquetReaderUtil.getArrayElementColumn then reclassifies that clipped group as a Rule 5 wrapper and unwraps it. For LIST<STRUCT<x,y>> read as ARRAY<ROW>, reader construction pairs the RowType with a PrimitiveColumnIO and throws ClassCastException. Please carry the original list interpretation into field construction, or otherwise keep Rule 2 unambiguous after projection, and add a one-field projection read test.


// Rule 5: the repeated group is a wrapper containing exactly one non-repeated child.
if (repeatedGroup.getFieldCount() != 1
|| repeatedGroup.getType(0).getRepetition() == Type.Repetition.REPEATED) {

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.

[P1] Complete Rule 3 handling beyond element selection

This correctly keeps the repeated group as the element, but downstream schema conversion still treats its repeated child as a scalar. With the Rule 3 shape added in the tests and two inner values [8, 9], the inferred type returns only 8; using the semantically correct nested array type instead fails during clipping. Please convert the nested repeated child as an array and align clipping and ColumnIO traversal, with an end-to-end multi-value read test.

"Parquet list type only have two level representation and three level representation.");
}

return listType.getType(0);

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.

[P2] Preserve required element nullability for Rules 1-4

The returned element node still has REPEATED repetition, while convertToPaimonField only applies notNull() to REQUIRED nodes. As a result, Rules 1-4 are converted to nullable Paimon elements even though the Parquet compatibility rules define them as required. Please force the converted element DataType to non-null for non-Rule-5 layouts, without changing the physical repeated Type used by clipping, and add conversion-level nullability assertions.

@JingsongLi

Copy link
Copy Markdown
Contributor

Overall assessment: HIGH RISK

Requirement fit: SUPPORTED
Implementation: FINDINGS

I consider this PR high risk in its current form. It changes persisted Parquet schema interpretation across schema conversion, requested-schema clipping, and reader construction. Focused reproductions exposed both silent data loss in Rule 3 handling and a deterministic reader-construction failure for a Rule 2 projection, plus incorrect element nullability for Rules 1-4. Helper-shape unit tests alone are not sufficient for this compatibility-sensitive path. Please address the inline findings and add end-to-end legacy LIST read coverage before merging.

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