[format] Support nested variant column pruning for shredded parquet files - #9389
[format] Support nested variant column pruning for shredded parquet files#9389juntaozhang wants to merge 2 commits into
Conversation
| Type typedValueType = group.getType(PaimonShreddingUtils.TYPED_VALUE_FIELD_NAME); | ||
| GroupType typedValue = typedValueType.asGroupType(); | ||
| // typed_value is an object group: prune by object key. | ||
| boolean needValue = false; |
There was a problem hiding this comment.
When this shredding node is object-typed but the projection continues with an array segment (for example, the schema defines a as an object, a row contains {"a":[{"x":1}]}, and the read projects $.a[0].x), node.children is empty, so needValue remains false and this method produces an empty nested shredding row. The writer stored the type-mismatched array in a.value, so dropping it makes the scan fail with Invalid variant shredding schema: ROW<> NOT NULL; the same case succeeds on the base revision. Please retain value whenever node.arrayElement != null (and apply the symmetric fallback in the list branch for object children), with an end-to-end heterogeneous Variant test.
There was a problem hiding this comment.
Thanks for pointing out this issue, I have fixed it. PTAL
| } else if (segment instanceof VariantPathSegment.ObjectExtraction) { | ||
| String key = ((VariantPathSegment.ObjectExtraction) segment).getKey(); | ||
| if (!caseSensitive) { | ||
| key = key.toLowerCase(Locale.ROOT); |
There was a problem hiding this comment.
Variant object keys are resolved exactly downstream through objectSchemaMap.get(objExtr.getKey()), so lowercasing only in the pruner can select typed key a for requested path $.A and then drop the raw value that actually contains the exact key A. With case-insensitive table mode, shredding schema key a, row {"A":7}, and projection $.A, the base revision returns 7 but this change returns null. Please keep Variant-path key matching case-sensitive independently of Parquet column-name resolution, or make the entire extraction and fallback pipeline use one consistent semantic.
There was a problem hiding this comment.
Thanks for the guidance, I have removed the case-insensitivity support. PTAL
2ad3a3f to
ea5aeea
Compare
| newFields.add(group.getType(PaimonShreddingUtils.METADATA_FIELD_NAME)); | ||
| } | ||
|
|
||
| Type typedValue = group.getType(PaimonShreddingUtils.TYPED_VALUE_FIELD_NAME); |
There was a problem hiding this comment.
[P1] Preserve the fallback for mixed array/object projections
This branch selects list pruning whenever an array projection is present, even if the same Variant column also has object projections in node.children. For a list-typed shredding schema, querying $[0].x and $.y together therefore removes the parent value field; an object-shaped row such as {"y": 2} is stored only in that fallback and $.y silently returns null. I reproduced this on this head, and adding node.children.isEmpty() to this condition makes the regression test pass. Please either skip list pruning when object children coexist or retain value in that case.
Purpose
This PR introduces
VariantShreddingTypePruner, which builds a path trie from the logical Variant projection and recursively prunes unneeded typed columns while preservingvaluefallbacks for paths that cannot be satisfied from typed columns. Supported cases include:$.a.b.$.arr[0].x.$[0].x.Two-level or non-canonical list layouts and map-typed
typed_valuegroups are kept unchanged as a safe fallback.Tests
VariantShreddingReadTest#testReadNestedVariantWithPruning: end-to-end read test for both shredded and unshredded Parquet file, covering nested object fields, array index paths, missing fields inside array elements, and reading whole array elements asVARIANT.VariantShreddingTypePrunerTest: unit tests coveringvalue,keepAllsemantics and so on.