Is your feature request related to a problem or challenge?
When a projection wraps columns into a struct via named_struct (e.g., named_struct('ticker', ticker, ...) AS details), the optimizer loses track of the input column's ordering because ProjectionMapping maps the entire named_struct(...) expression to col("details").
Notably, there is no field-level decomposition, so it can't prove that get_field(details, "ticker") actually preserves the ordering of the input ticker column. This means ORDER BY details['ticker'] will require a SortExec, even when the input is already sorted by ticker.
Describe the solution you'd like
Add ScalarUDFImpl::struct_field_mapping that struct-producing UDFs can implement to declare their field-to-input-arg relationships, which ProjectionMapping then uses to add field-level entries so EquivalenceProperties can propagate orderings through the struct boundary.
Describe alternatives you've considered
No response
Additional context
No response
Is your feature request related to a problem or challenge?
When a projection wraps columns into a struct via
named_struct(e.g.,named_struct('ticker', ticker, ...) AS details), the optimizer loses track of the input column's ordering becauseProjectionMappingmaps the entirenamed_struct(...)expression tocol("details").Notably, there is no field-level decomposition, so it can't prove that
get_field(details, "ticker")actually preserves the ordering of the input ticker column. This meansORDER BY details['ticker']will require aSortExec, even when the input is already sorted byticker.Describe the solution you'd like
Add
ScalarUDFImpl::struct_field_mappingthat struct-producing UDFs can implement to declare their field-to-input-arg relationships, whichProjectionMappingthen uses to add field-level entries soEquivalencePropertiescan propagate orderings through the struct boundary.Describe alternatives you've considered
No response
Additional context
No response