Skip to content

[SPARK-56190][SQL] Support nested partition columns for DSV2 PartitionPredicate - #54995

Closed
szehon-ho wants to merge 10 commits into
apache:masterfrom
szehon-ho:nested_partition_filter
Closed

szehon-ho wants to merge 10 commits into
apache:masterfrom
szehon-ho:nested_partition_filter

Conversation

@szehon-ho

Copy link
Copy Markdown
Member

What changes were proposed in this pull request?

Supported nested columns.

  1. Pass an enhanced partitionSchema to the pushdownFilters()
  2. Add support to 'flatten' the provided filters (GetStruct(AttributeReference("parent"), "child")) into a schema understood by the partition predicate and pushdown.

Why are the changes needed?

DSV2 connectors support nested struct fields as partition fields.

Does this PR introduce any user-facing change?

No

How was this patch tested?

Add unit tests to DSV2EnhancedPartitionFilterSuite.

Was this patch authored or co-authored using generative AI tooling?

Yes, cursor with hand refactoring

@szehon-ho
szehon-ho force-pushed the nested_partition_filter branch from 302f3b8 to e23797a Compare March 25, 2026 01:17
@szehon-ho
szehon-ho force-pushed the nested_partition_filter branch from e23797a to 50d1e68 Compare March 25, 2026 01:20
@szehon-ho

Copy link
Copy Markdown
Member Author

@cloud-fan @peter-toth could you help take a look ? Thanks

@szehon-ho

szehon-ho commented Mar 25, 2026 •

Copy link
Copy Markdown
Member Author

thanks @peter-toth, addressed

FYI i found an issue in the first approach. The normalization of the nested partition field filters, ie GetStruct(AttributeRef("parent"), "child)) => AttributeRef("parent.child") messed up the post-scan filter if rejected, so restoring them to original form before returning.

@cloud-fan cloud-fan left a comment

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.

Review Summary

This PR extends DSV2 partition predicate pushdown (SPARK-55596) to support nested partition columns (e.g., PARTITIONED BY (s.tz)). The approach normalizes GetStructField chains to flat AttributeReferences before the existing partition filter machinery, then denormalizes results back for post-scan filters. The design is clean — normalization is localized to pushPartitionPredicates without changing shared utilities.

One correctness concern with the denormalization map lookup, and two minor text fixes from the rename.

@szehon-ho
szehon-ho force-pushed the nested_partition_filter branch from 1798ff3 to 4fb6bc8 Compare March 26, 2026 23:24

@cloud-fan cloud-fan left a comment

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.

Summary

The normalize-then-restore approach for extending partition predicate pushdown to nested columns is well-designed. The ExprId-based binding in PartitionPredicateImpl is a good improvement over the old name-based binding, and the Seq[String]-based path comparison in pathsMatch correctly handles case sensitivity.

One concern: the flattened dotted names in the partition StructType (e.g., "s.tz" for nested field s → tz) can collide with columns that have literal dots in their names when passed through getPartitionFiltersAndDataFilters, which matches by attr.name. See inline comment on pushPartitionPredicates.

Minor items: missing return type annotation, indentation fix, and a test coverage suggestion for deeply nested (3+ level) partition fields — the recursive flattenStructFieldChain should handle arbitrary depth but an end-to-end test would confirm.

- Add new getPartitionFiltersAndDataFilters overload that takes
  Seq[AttributeReference] and matches by ExprId via AttributeSet,
  avoiding collisions when field names contain literal dots.
- Add explicit return type to resolveIdentityPartitionField.
- Fix indentation in assertReferencedPartitionFieldOrdinals.
- Add test for nested partition field with dot in name.
@szehon-ho

Copy link
Copy Markdown
Member Author

Thanks @cloud-fan , i addressed the missed case and added a unit test for nested field with a dot in the field name.

@cloud-fan cloud-fan left a comment

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.

Prior reviews established context for the normalize-then-restore design. This round focuses on a binding simplification and minor text fixes.

General:

  • PartitionPredicate.java eval() Javadoc (line 82) still says "a subset of referenced columns" — should be "referenced fields" for consistency with the PartitionColumnReference → PartitionFieldReference rename.

@cloud-fan cloud-fan left a comment

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.

LGTM, minor comments only.

…c text

- Replace manual transform+exprIdToIndex binding with
  BindReferences.bindReference in PartitionPredicateImpl.
- Remove unused structField lazy val from PartitionPredicateField.
- Fix Javadoc: "columns" -> "fields" in PartitionPredicate.eval().
- Fix Scaladoc: "Return" -> "Returns", add plural "s" to
  [[AttributeReference]]s, "name" -> "names".
@cloud-fan

Copy link
Copy Markdown
Contributor

thanks, merging to master!

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.

3 participants