@@ -2749,6 +2749,111 @@ DROP TABLE tl_multikey;
27492749statement ok
27502750DROP TABLE tl_sorted;
27512751
2752+ # ===========================================================
2753+ # Test M: Multi-key Inexact sort pushdown (WITH ORDER multi-key)
2754+ # File declared WITH ORDER (id ASC, value ASC), query ORDER BY
2755+ # id DESC, value DESC → reversed matches → Inexact path.
2756+ # ===========================================================
2757+
2758+ statement ok
2759+ CREATE TABLE tm_data(id INT, value INT) AS VALUES
2760+ (1, 10), (1, 20), (1, 30),
2761+ (2, 40), (2, 50), (2, 60),
2762+ (3, 70), (3, 80), (3, 90),
2763+ (4, 100), (4, 110), (4, 120);
2764+
2765+ statement ok
2766+ SET datafusion.execution.parquet.max_row_group_size = 3;
2767+
2768+ # Write sorted by (id ASC, value ASC)
2769+ query I
2770+ COPY (SELECT * FROM tm_data ORDER BY id ASC, value ASC)
2771+ TO 'test_files/scratch/sort_pushdown/tm_multikey_sorted/data.parquet';
2772+ ----
2773+ 12
2774+
2775+ statement ok
2776+ SET datafusion.execution.parquet.max_row_group_size = 1048576;
2777+
2778+ statement ok
2779+ CREATE EXTERNAL TABLE tm_sorted(id INT, value INT)
2780+ STORED AS PARQUET
2781+ LOCATION 'test_files/scratch/sort_pushdown/tm_multikey_sorted/data.parquet'
2782+ WITH ORDER (id ASC, value ASC);
2783+
2784+ # Test M.1: Multi-key DESC that fully matches reversed ordering
2785+ # ORDER BY id DESC, value DESC matches reversed (id ASC, value ASC) → Inexact
2786+ query TT
2787+ EXPLAIN SELECT * FROM tm_sorted ORDER BY id DESC, value DESC LIMIT 3;
2788+ ----
2789+ logical_plan
2790+ 01)Sort: tm_sorted.id DESC NULLS FIRST, tm_sorted.value DESC NULLS FIRST, fetch=3
2791+ 02)--TableScan: tm_sorted projection=[id, value]
2792+ physical_plan
2793+ 01)SortExec: TopK(fetch=3), expr=[id@0 DESC, value@1 DESC], preserve_partitioning=[false]
2794+ 02)--DataSourceExec: file_groups={1 group: [[WORKSPACE_ROOT/datafusion/sqllogictest/test_files/scratch/sort_pushdown/tm_multikey_sorted/data.parquet]]}, projection=[id, value], file_type=parquet, predicate=DynamicFilter [ empty ], reverse_row_groups=true
2795+
2796+ # Test M.2: Results must be correct (largest id first, then largest value)
2797+ query II
2798+ SELECT * FROM tm_sorted ORDER BY id DESC, value DESC LIMIT 3;
2799+ ----
2800+ 4 120
2801+ 4 110
2802+ 4 100
2803+
2804+ # Test M.3: Larger limit spanning multiple RGs
2805+ query II
2806+ SELECT * FROM tm_sorted ORDER BY id DESC, value DESC LIMIT 6;
2807+ ----
2808+ 4 120
2809+ 4 110
2810+ 4 100
2811+ 3 90
2812+ 3 80
2813+ 3 70
2814+
2815+ # Test M.4: Multi-key ASC (same direction as file = Exact, sort elimination)
2816+ query II
2817+ SELECT * FROM tm_sorted ORDER BY id ASC, value ASC LIMIT 3;
2818+ ----
2819+ 1 10
2820+ 1 20
2821+ 1 30
2822+
2823+ # Test M.5: Partial match — first key reversed, second key SAME direction
2824+ # ORDER BY id DESC, value ASC does NOT match reversed (id DESC, value DESC)
2825+ # → NOT Inexact path (second key mismatch)
2826+ query II
2827+ SELECT * FROM tm_sorted ORDER BY id DESC, value ASC LIMIT 3;
2828+ ----
2829+ 4 100
2830+ 4 110
2831+ 4 120
2832+
2833+ # Test M.6: All rows, verify full data integrity
2834+ query II
2835+ SELECT * FROM tm_sorted ORDER BY id DESC, value DESC;
2836+ ----
2837+ 4 120
2838+ 4 110
2839+ 4 100
2840+ 3 90
2841+ 3 80
2842+ 3 70
2843+ 2 60
2844+ 2 50
2845+ 2 40
2846+ 1 30
2847+ 1 20
2848+ 1 10
2849+
2850+ # Cleanup Test M
2851+ statement ok
2852+ DROP TABLE tm_data;
2853+
2854+ statement ok
2855+ DROP TABLE tm_sorted;
2856+
27522857# Reset settings (SLT runner uses target_partitions=4, not system default)
27532858statement ok
27542859SET datafusion.execution.target_partitions = 4;
0 commit comments