@@ -1554,3 +1554,65 @@ EXPLAIN SELECT * from ordered ORDER BY a;
15541554physical_plan
1555155501)SortExec: expr=[a@0 ASC NULLS LAST], preserve_partitioning=[false]
1556155602)--DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/data/composite_order.csv]]}, projection=[a, b], output_ordering=[a@0 + b@1 ASC NULLS LAST], file_type=csv, has_header=true
1557+
1558+ # Sort elimination through named_struct projections
1559+ #
1560+ # When data is sorted by a column and that column is wrapped into a struct
1561+ # via named_struct, sorting by the struct field should NOT require a
1562+ # separate SortExec because the optimizer can track that the struct field
1563+ # preserves the original ordering.
1564+
1565+ # Wrapping the ordered expression (a + b) into a struct field — sort eliminated
1566+ # Reuses the `ordered` table above which has WITH ORDER (a + b).
1567+ query TT
1568+ EXPLAIN SELECT named_struct('sum', a + b) AS s FROM ordered ORDER BY s['sum'];
1569+ ----
1570+ physical_plan
1571+ 01)ProjectionExec: expr=[named_struct(sum, a@0 + b@1) as s]
1572+ 02)--DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/data/composite_order.csv]]}, projection=[a, b], output_ordering=[a@0 + b@1 ASC NULLS LAST], file_type=csv, has_header=true
1573+
1574+ # Wrapping a non-ordered column into a struct — SortExec required
1575+ # Reuses the `ordered` table above which has WITH ORDER (a + b).
1576+ query TT
1577+ EXPLAIN SELECT named_struct('a', a, 'b', b) AS s FROM ordered ORDER BY s['a'];
1578+ ----
1579+ physical_plan
1580+ 01)SortExec: expr=[get_field(s@0, a) ASC NULLS LAST], preserve_partitioning=[false]
1581+ 02)--ProjectionExec: expr=[named_struct(a, a@0, b, b@1) as s]
1582+ 03)----DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/data/composite_order.csv]]}, projection=[a, b], output_ordering=[a@0 + b@1 ASC NULLS LAST], file_type=csv, has_header=true
1583+
1584+ # Simple column ordering tests using a table ordered by (a)
1585+ statement ok
1586+ CREATE EXTERNAL TABLE ordered_by_a (
1587+ a BIGINT NOT NULL,
1588+ b BIGINT NOT NULL
1589+ )
1590+ STORED AS CSV
1591+ LOCATION 'data/composite_order.csv'
1592+ OPTIONS ('format.has_header' 'true')
1593+ WITH ORDER (a);
1594+
1595+ # Single struct field matching source ordering -- sort eliminated
1596+ query TT
1597+ EXPLAIN SELECT named_struct('a', a, 'b', b) AS s FROM ordered_by_a ORDER BY s['a'];
1598+ ----
1599+ physical_plan
1600+ 01)ProjectionExec: expr=[named_struct(a, a@0, b, b@1) as s]
1601+ 02)--DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/data/composite_order.csv]]}, projection=[a, b], output_ordering=[a@0 ASC NULLS LAST], file_type=csv, has_header=true
1602+
1603+ # Struct field not matching source ordering -- SortExec required
1604+ query TT
1605+ EXPLAIN SELECT named_struct('a', a, 'b', b) AS s FROM ordered_by_a ORDER BY s['b'];
1606+ ----
1607+ physical_plan
1608+ 01)SortExec: expr=[get_field(s@0, b) ASC NULLS LAST], preserve_partitioning=[false]
1609+ 02)--ProjectionExec: expr=[named_struct(a, a@0, b, b@1) as s]
1610+ 03)----DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/data/composite_order.csv]]}, projection=[a, b], output_ordering=[a@0 ASC NULLS LAST], file_type=csv, has_header=true
1611+
1612+ # Mixed projection: top-level column alongside struct, order by struct field
1613+ query TT
1614+ EXPLAIN SELECT a, named_struct('a', a, 'b', b) AS s FROM ordered_by_a ORDER BY s['a'];
1615+ ----
1616+ physical_plan
1617+ 01)ProjectionExec: expr=[a@0 as a, named_struct(a, a@0, b, b@1) as s]
1618+ 02)--DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/data/composite_order.csv]]}, projection=[a, b], output_ordering=[a@0 ASC NULLS LAST], file_type=csv, has_header=true
0 commit comments