Skip to content

[Variant] Support list paths in ShreddedSchemaBuilder - #10635

Open
cakeni wants to merge 4 commits into
apache:mainfrom
cakeni:feat/variant-schema-list-paths
Open

[Variant] Support list paths in ShreddedSchemaBuilder#10635
cakeni wants to merge 4 commits into
apache:mainfrom
cakeni:feat/variant-schema-list-paths

Conversation

@cakeni

@cakeni cakeni commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Rationale for this change

ShreddedSchemaBuilder can already parse indexed Variant paths, and core Variant shredding supports lists, but schema construction currently panics when a path reaches an index. This prevents callers from describing list element schemas through the builder.

What changes are included in this PR?

  • Add a list node to the builder's intermediate schema tree.
  • Treat numeric indexes as references to the shared list element schema, including for nested lists.
  • Document the index behavior and add coverage for list-of-struct and nested-list schemas.
  • Build the existing list shredding test schema through ShreddedSchemaBuilder.

Are these changes tested?

Yes. cargo test -p parquet-variant-compute test_variant_schema_builder passes (11 tests).

Are there any user-facing changes?

Yes. Callers can now use indexed paths such as items[0].id when constructing shredding schemas. This is backward compatible.

AI assistance

OpenAI Codex assisted with implementation, documentation, and test drafting. I reviewed the resulting design and changes.

@github-actions github-actions Bot added the parquet-variant parquet-variant* crates label Aug 11, 2026
@cakeni
cakeni marked this pull request as ready for review August 11, 2026 13:30

@sdf-jkl sdf-jkl 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.

Thanks @cakeni, looks good to me.

I have an open question I'd like to discuss before pushing this forward.

@klion26 @scovich

Comment on lines +2916 to +2918
let shredding_type = ShreddedSchemaBuilder::default()
.with_path("items[0].id", &DataType::Int64)?
.with_path("items[42].name", &DataType::Utf8)?

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.

I still wonder if we should allow number other than 0 or allow numbers at all. I guess it's an open question.

I like the jsonpath style with [*] - https://www.rfc-editor.org/rfc/rfc9535.html#section-2.3.2

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I agree that arbitrary indexes are a bit misleading here since they all map to the same list element schema.
For this PR, I’d prefer to allow only [0] and reject other indexes. [*] makes sense, but that probably belongs in a separate schema-path/API change.

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.

Using ['*'] is better than [0] here from my side because the variant_get will receive the variantpath and [0] means the first item in the array, and using [0] to indicate the whole array here may be confusing.

Does adding an interface for ShreddedSchemaBuilder to support list type solve this(like VariantBuilder::new_list())? But this seems can't handle the case where with_path(.., ..) receives a VariantPath for the first argument very well(there may be [] in the VariantPath), and not sure if it will be too complicated for such a case here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed, [0] is confusing here since it already means the first array element in VariantPath. I’d prefer [*] for the shared element schema and keep numeric indexes unchanged. A separate list API seems harder to compose with nested paths.

@klion26

klion26 commented Aug 26, 2026

Copy link
Copy Markdown
Member

Sorry for the late reply, a little busy for the inner works these days, will take a look at this tomorrow.

…-list-paths

# Conflicts:
#	parquet-variant-compute/src/shred_variant.rs
@sdf-jkl

sdf-jkl commented Sep 3, 2026

Copy link
Copy Markdown
Member

Agreed, [0] is confusing here since it already means the first array element in VariantPath. I’d prefer [*] for the shared element schema and keep numeric indexes unchanged. A separate list API seems harder to compose with nested paths.

Let's proceed with [*] here then. The new VariantPathElement can stay NYI for variant_get

Using ['*'] is better than [0]

We should use [*] as ["*"] would be a field name.

@sdf-jkl sdf-jkl 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.

Thanks @cakeni LGTM.

@klion26 Please take another look when available 🙏

@klion26 klion26 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.

Overall, the change LGTM, left one inline comment for the error type.

None => Ok(missing_path_step()),
}
}
VariantPathElement::ListElement => Err(ArrowError::NotYetImplemented(

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.

Do we need to implement this in the future? If not, maybe we can use InvalidArgumentError or another error type.

The two paths a.b and a.b.[*] both mean the whole list?

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.

Sounds good. I suggested NYI because I wasn't sure whether we'd want to support this later.

After checking, Spark's variant_get doesn't support [*] either.

a.b[*] selects all elements of the list, while a.b selects the whole list itself as one value. Since variant_get only support singular paths, I agree that InvalidArgumentError is better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

parquet-variant parquet-variant* crates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Variant] Support list paths in ShreddedSchemaBuilder

3 participants