[Variant] Fix variant_get to return List<T> instead of List<Struct> - #9631
Conversation
…ct>` for list types
klion26
left a comment
There was a problem hiding this comment.
LGTM, thanks for this contribution.
scovich
left a comment
There was a problem hiding this comment.
LGTM. Once question and one nit.
| Typed(Box<VariantToArrowRowBuilder<'a>>), | ||
| /// Produces a shredded struct with `value` and `typed_value` fields. | ||
| Shredded(Box<VariantToShreddedVariantRowBuilder<'a>>), |
There was a problem hiding this comment.
Any particular reason these need to be boxed? They're fully strongly typed, no?
There was a problem hiding this comment.
They need to be boxed because of a recursive type cycle:
ListElementBuilder::Typed → VariantToArrowRowBuilder → Array(ArrayVariantToArrowRowBuilder) → VariantToListArrowRowBuilder → ListElementBuilder
It would be infinitely sized without Box.
| /// * `shredded` - If true, element builders produce shredded structs with `value`/`typed_value` | ||
| /// fields (for [`crate::shred_variant()`]). If false, element builders produce strongly typed | ||
| /// arrays directly (for [`crate::variant_get()`]). | ||
| pub(crate) fn try_new( |
There was a problem hiding this comment.
It looks like this shredded param allows quite a bit of code reuse. Should we look at other shred-vs-get pairs to see if similar consolidation is possible? Struct, in particular, is likely to be complex?
There was a problem hiding this comment.
From the current impl, the struct builders aren't as straightforward to consolidate as the list builders were. Created an issue #9633 to keep track of the refactor
# Conflicts: # parquet-variant-compute/src/variant_to_arrow.rs
scovich
left a comment
There was a problem hiding this comment.
LGTM, thanks for the fix
…ct>` (apache#9631) # Which issue does this PR close? <!-- We generally require a GitHub issue to be filed for all bug fixes and enhancements and this helps us generate change logs for our releases. You can link an issue to this PR using the GitHub syntax. --> - Closes apache#9615. # Rationale for this change <!-- Why are you proposing this change? If this is already explained clearly in the issue then this section is not needed. Explaining clearly why changes are proposed helps reviewers understand your changes and offer better suggestions for fixes. --> `variant_get(..., List<T>)` was returning `List<Struct<value, typed_value>>` instead of `List<T>`. This happened because `VariantToListArrowRowBuilder` unconditionally used `make_variant_to_shredded_variant_arrow_row_builder` for its element builder, which produces the shredded representation (a struct with `value` and `typed_value` fields). This is correct for `shred_variant`, but `variant_get` should produce strongly typed arrays directly. # What changes are included in this PR? <!-- There is no need to duplicate the description in the issue here but it is sometimes worth providing a summary of the individual changes in this PR. --> - Introduced a `ListElementBuilder` enum with `Typed` and `Shredded` variants to abstract over the two element output modes. - `Typed` wraps `VariantToArrowRowBuilder` and produces the target type directly (e.g., `Int64Array`). - `Shredded` wraps `VariantToShreddedVariantRowBuilder` and produces the `Struct<value, typed_value>` used by shredding. - Added a `shredded: bool` parameter to `ArrayVariantToArrowRowBuilder::try_new` and `VariantToListArrowRowBuilder::try_new` to select the appropriate mode. # Are these changes tested? <!-- We typically require tests for all PRs in order to: 1. Prevent the code from being accidentally broken by subsequent changes 2. Serve as another way to document the expected behavior of the code If tests are not included in your PR, please explain why (for example, are they covered by existing tests)? --> Yes # Are there any user-facing changes? <!-- If there are user-facing changes then we may require documentation to be updated before approving the PR. If there are any breaking changes to public APIs, please call them out. --> Yes, the `variant_get(..., List<T>)` should have correct behavior now
Which issue does this PR close?
variant_get(..., List<_>)non-Struct types support #9615.Rationale for this change
variant_get(..., List<T>)was returningList<Struct<value, typed_value>>instead ofList<T>. This happened becauseVariantToListArrowRowBuilderunconditionally usedmake_variant_to_shredded_variant_arrow_row_builderfor its element builder, which produces the shredded representation (a struct withvalueandtyped_valuefields). This is correct forshred_variant, butvariant_getshould produce strongly typed arrays directly.What changes are included in this PR?
ListElementBuilderenum withTypedandShreddedvariants to abstract over the two element output modes.TypedwrapsVariantToArrowRowBuilderand produces the target type directly (e.g.,Int64Array).ShreddedwrapsVariantToShreddedVariantRowBuilderand produces theStruct<value, typed_value>used by shredding.shredded: boolparameter toArrayVariantToArrowRowBuilder::try_newandVariantToListArrowRowBuilder::try_newto select the appropriate mode.Are these changes tested?
Yes
Are there any user-facing changes?
Yes, the
variant_get(..., List<T>)should have correct behavior now