@@ -1278,6 +1278,7 @@ SELECT id, s['value'] FROM simple_struct ORDER BY id, s['label'];
127812784 300
127912795 250
12801280
1281+
12811282###
12821283# Test 11a.3: TopK with dropped sort column
12831284# Same as test 11a.1 but with LIMIT
@@ -1608,3 +1609,188 @@ physical_plan
1608160902)--FilterExec: id@0 > 2, projection=[s@1]
1609161003)----RepartitionExec: partitioning=RoundRobinBatch(32), input_partitions=1
1610161104)------DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/projection_pushdown/simple.parquet]]}, projection=[id, s], file_type=parquet, predicate=id@0 > 2, pruning_predicate=id_null_count@1 != row_count@2 AND id_max@0 > 2, required_guarantees=[]
1612+
1613+ #####################
1614+ # Section 14: SubqueryAlias tests
1615+ #####################
1616+
1617+ # Reset target partitions
1618+ statement ok
1619+ SET datafusion.execution.target_partitions = 1;
1620+
1621+ # get_field pushdown through subquery alias with filter
1622+ query TT
1623+ EXPLAIN SELECT t.s['value'] FROM (SELECT * FROM simple_struct) t WHERE t.id > 2;
1624+ ----
1625+ logical_plan
1626+ 01)Projection: get_field(t.s, Utf8("value"))
1627+ 02)--SubqueryAlias: t
1628+ 03)----Projection: simple_struct.s
1629+ 04)------Filter: simple_struct.id > Int64(2)
1630+ 05)--------TableScan: simple_struct projection=[id, s], partial_filters=[simple_struct.id > Int64(2)]
1631+ physical_plan
1632+ 01)ProjectionExec: expr=[get_field(s@0, value) as t.s[value]]
1633+ 02)--FilterExec: id@0 > 2, projection=[s@1]
1634+ 03)----DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/projection_pushdown/simple.parquet]]}, projection=[id, s], file_type=parquet, predicate=id@0 > 2, pruning_predicate=id_null_count@1 != row_count@2 AND id_max@0 > 2, required_guarantees=[]
1635+
1636+ # Verify correctness
1637+ query I
1638+ SELECT t.s['value'] FROM (SELECT * FROM simple_struct) t WHERE t.id > 2 ORDER BY t.id;
1639+ ----
1640+ 150
1641+ 300
1642+ 250
1643+
1644+ # Multiple get_field through subquery alias with sort
1645+ query TT
1646+ EXPLAIN SELECT t.s['value'], t.s['label'] FROM (SELECT * FROM simple_struct) t ORDER BY t.s['value'];
1647+ ----
1648+ logical_plan
1649+ 01)Sort: t.s[value] ASC NULLS LAST
1650+ 02)--Projection: get_field(t.s, Utf8("value")), get_field(t.s, Utf8("label"))
1651+ 03)----SubqueryAlias: t
1652+ 04)------TableScan: simple_struct projection=[s]
1653+ physical_plan
1654+ 01)SortExec: expr=[t.s[value]@0 ASC NULLS LAST], preserve_partitioning=[false]
1655+ 02)--DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/projection_pushdown/simple.parquet]]}, projection=[get_field(s@1, value) as t.s[value], get_field(s@1, label) as t.s[label]], file_type=parquet
1656+
1657+ # Verify correctness
1658+ query IT
1659+ SELECT t.s['value'], t.s['label'] FROM (SELECT * FROM simple_struct) t ORDER BY t.s['value'];
1660+ ----
1661+ 100 alpha
1662+ 150 gamma
1663+ 200 beta
1664+ 250 epsilon
1665+ 300 delta
1666+
1667+ # Nested subquery aliases
1668+ query TT
1669+ EXPLAIN SELECT u.s['value'] FROM (SELECT * FROM (SELECT * FROM simple_struct) t) u WHERE u.id > 2;
1670+ ----
1671+ logical_plan
1672+ 01)Projection: get_field(u.s, Utf8("value"))
1673+ 02)--SubqueryAlias: u
1674+ 03)----SubqueryAlias: t
1675+ 04)------Projection: simple_struct.s
1676+ 05)--------Filter: simple_struct.id > Int64(2)
1677+ 06)----------TableScan: simple_struct projection=[id, s], partial_filters=[simple_struct.id > Int64(2)]
1678+ physical_plan
1679+ 01)ProjectionExec: expr=[get_field(s@0, value) as u.s[value]]
1680+ 02)--FilterExec: id@0 > 2, projection=[s@1]
1681+ 03)----DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/projection_pushdown/simple.parquet]]}, projection=[id, s], file_type=parquet, predicate=id@0 > 2, pruning_predicate=id_null_count@1 != row_count@2 AND id_max@0 > 2, required_guarantees=[]
1682+
1683+ # Verify correctness
1684+ query I
1685+ SELECT u.s['value'] FROM (SELECT * FROM (SELECT * FROM simple_struct) t) u WHERE u.id > 2 ORDER BY u.id;
1686+ ----
1687+ 150
1688+ 300
1689+ 250
1690+
1691+ # get_field in filter through subquery alias
1692+ query TT
1693+ EXPLAIN SELECT t.id FROM (SELECT * FROM simple_struct) t WHERE t.s['value'] > 200;
1694+ ----
1695+ logical_plan
1696+ 01)SubqueryAlias: t
1697+ 02)--Projection: simple_struct.id
1698+ 03)----Filter: get_field(simple_struct.s, Utf8("value")) > Int64(200)
1699+ 04)------TableScan: simple_struct projection=[id, s], partial_filters=[get_field(simple_struct.s, Utf8("value")) > Int64(200)]
1700+ physical_plan
1701+ 01)FilterExec: get_field(s@1, value) > 200, projection=[id@0]
1702+ 02)--DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/projection_pushdown/simple.parquet]]}, projection=[id, s], file_type=parquet
1703+
1704+ # Verify correctness
1705+ query I
1706+ SELECT t.id FROM (SELECT * FROM simple_struct) t WHERE t.s['value'] > 200 ORDER BY t.id;
1707+ ----
1708+ 4
1709+ 5
1710+
1711+ #####################
1712+ # Section 15: UNION ALL tests
1713+ #####################
1714+
1715+ # get_field on UNION ALL result
1716+ query TT
1717+ EXPLAIN SELECT s['value'] FROM (
1718+ SELECT s FROM simple_struct WHERE id <= 3
1719+ UNION ALL
1720+ SELECT s FROM simple_struct WHERE id > 3
1721+ ) t;
1722+ ----
1723+ logical_plan
1724+ 01)Projection: get_field(t.s, Utf8("value"))
1725+ 02)--SubqueryAlias: t
1726+ 03)----Union
1727+ 04)------Projection: simple_struct.s
1728+ 05)--------Filter: simple_struct.id <= Int64(3)
1729+ 06)----------TableScan: simple_struct projection=[id, s], partial_filters=[simple_struct.id <= Int64(3)]
1730+ 07)------Projection: simple_struct.s
1731+ 08)--------Filter: simple_struct.id > Int64(3)
1732+ 09)----------TableScan: simple_struct projection=[id, s], partial_filters=[simple_struct.id > Int64(3)]
1733+ physical_plan
1734+ 01)ProjectionExec: expr=[get_field(s@0, value) as t.s[value]]
1735+ 02)--UnionExec
1736+ 03)----FilterExec: id@0 <= 3, projection=[s@1]
1737+ 04)------DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/projection_pushdown/simple.parquet]]}, projection=[id, s], file_type=parquet, predicate=id@0 <= 3, pruning_predicate=id_null_count@1 != row_count@2 AND id_min@0 <= 3, required_guarantees=[]
1738+ 05)----FilterExec: id@0 > 3, projection=[s@1]
1739+ 06)------DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/projection_pushdown/simple.parquet]]}, projection=[id, s], file_type=parquet, predicate=id@0 > 3, pruning_predicate=id_null_count@1 != row_count@2 AND id_max@0 > 3, required_guarantees=[]
1740+
1741+ # Verify correctness
1742+ query I
1743+ SELECT s['value'] FROM (
1744+ SELECT s FROM simple_struct WHERE id <= 3
1745+ UNION ALL
1746+ SELECT s FROM simple_struct WHERE id > 3
1747+ ) t ORDER BY s['value'];
1748+ ----
1749+ 100
1750+ 150
1751+ 200
1752+ 250
1753+ 300
1754+
1755+ # Multiple get_field on UNION ALL with ORDER BY
1756+ query TT
1757+ EXPLAIN SELECT s['value'], s['label'] FROM (
1758+ SELECT s FROM simple_struct WHERE id <= 3
1759+ UNION ALL
1760+ SELECT s FROM simple_struct WHERE id > 3
1761+ ) t ORDER BY s['value'];
1762+ ----
1763+ logical_plan
1764+ 01)Sort: t.s[value] ASC NULLS LAST
1765+ 02)--Projection: get_field(t.s, Utf8("value")), get_field(t.s, Utf8("label"))
1766+ 03)----SubqueryAlias: t
1767+ 04)------Union
1768+ 05)--------Projection: simple_struct.s
1769+ 06)----------Filter: simple_struct.id <= Int64(3)
1770+ 07)------------TableScan: simple_struct projection=[id, s], partial_filters=[simple_struct.id <= Int64(3)]
1771+ 08)--------Projection: simple_struct.s
1772+ 09)----------Filter: simple_struct.id > Int64(3)
1773+ 10)------------TableScan: simple_struct projection=[id, s], partial_filters=[simple_struct.id > Int64(3)]
1774+ physical_plan
1775+ 01)SortPreservingMergeExec: [t.s[value]@0 ASC NULLS LAST]
1776+ 02)--SortExec: expr=[t.s[value]@0 ASC NULLS LAST], preserve_partitioning=[true]
1777+ 03)----ProjectionExec: expr=[get_field(s@0, value) as t.s[value], get_field(s@0, label) as t.s[label]]
1778+ 04)------UnionExec
1779+ 05)--------FilterExec: id@0 <= 3, projection=[s@1]
1780+ 06)----------DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/projection_pushdown/simple.parquet]]}, projection=[id, s], file_type=parquet, predicate=id@0 <= 3, pruning_predicate=id_null_count@1 != row_count@2 AND id_min@0 <= 3, required_guarantees=[]
1781+ 07)--------FilterExec: id@0 > 3, projection=[s@1]
1782+ 08)----------DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/projection_pushdown/simple.parquet]]}, projection=[id, s], file_type=parquet, predicate=id@0 > 3, pruning_predicate=id_null_count@1 != row_count@2 AND id_max@0 > 3, required_guarantees=[]
1783+
1784+ # Verify correctness
1785+ query IT
1786+ SELECT s['value'], s['label'] FROM (
1787+ SELECT s FROM simple_struct WHERE id <= 3
1788+ UNION ALL
1789+ SELECT s FROM simple_struct WHERE id > 3
1790+ ) t ORDER BY s['value'];
1791+ ----
1792+ 100 alpha
1793+ 150 gamma
1794+ 200 beta
1795+ 250 epsilon
1796+ 300 delta
0 commit comments