@@ -2537,6 +2537,43 @@ impl PartialOrd for Window {
2537
2537
}
2538
2538
}
2539
2539
2540
+ #[ derive( Clone , PartialEq , Eq , Hash , PartialOrd , Default ) ]
2541
+ pub struct ScanOrdering {
2542
+ /// Optional preferred ordering for the scan that matches the output order of upstream query nodes.
2543
+ /// It is optional / best effort for the scan to produce this ordering.
2544
+ /// If the scan produces this exact ordering and sets it's properties to reflect this upstream sorts may be optimized away.
2545
+ /// Otherwise the sorts may remain in place but partial ordering may be exploited e.g. to do early stopping or reduce complexity of the sort.
2546
+ /// Thus it is recommended for the scan to also do a best effort to produce partially sorted data if possible.
2547
+ pub preferred_ordering : Option < Vec < SortExpr > > ,
2548
+ }
2549
+
2550
+ impl ScanOrdering {
2551
+ /// Create a new ScanOrdering
2552
+ pub fn with_preferred_ordering ( mut self , preferred_ordering : Vec < SortExpr > ) -> Self {
2553
+ self . preferred_ordering = Some ( preferred_ordering) ;
2554
+ self
2555
+ }
2556
+ }
2557
+
2558
+ impl Debug for ScanOrdering {
2559
+ fn fmt ( & self , f : & mut Formatter ) -> fmt:: Result {
2560
+ let ordering_display = self
2561
+ . preferred_ordering
2562
+ . as_ref ( )
2563
+ . map ( |ordering| {
2564
+ ordering
2565
+ . iter ( )
2566
+ . map ( |e| e. to_string ( ) )
2567
+ . collect :: < Vec < String > > ( )
2568
+ . join ( ", " )
2569
+ } )
2570
+ . unwrap_or_else ( || "None" . to_string ( ) ) ;
2571
+ f. debug_struct ( "ScanOrdering" )
2572
+ . field ( "preferred_ordering" , & ordering_display)
2573
+ . finish_non_exhaustive ( )
2574
+ }
2575
+ }
2576
+
2540
2577
/// Produces rows from a table provider by reference or from the context
2541
2578
#[ derive( Clone ) ]
2542
2579
pub struct TableScan {
@@ -2552,8 +2589,8 @@ pub struct TableScan {
2552
2589
pub filters : Vec < Expr > ,
2553
2590
/// Optional number of rows to read
2554
2591
pub fetch : Option < usize > ,
2555
- /// Optional preferred ordering for the scan
2556
- pub preferred_ordering : Option < Vec < SortExpr > > ,
2592
+ /// Ordering for the scan
2593
+ pub ordering : Option < ScanOrdering > ,
2557
2594
}
2558
2595
2559
2596
impl Debug for TableScan {
@@ -2565,7 +2602,7 @@ impl Debug for TableScan {
2565
2602
. field ( "projected_schema" , & self . projected_schema )
2566
2603
. field ( "filters" , & self . filters )
2567
2604
. field ( "fetch" , & self . fetch )
2568
- . field ( "preferred_ordering " , & self . preferred_ordering )
2605
+ . field ( "ordering " , & self . ordering )
2569
2606
. finish_non_exhaustive ( )
2570
2607
}
2571
2608
}
@@ -2577,7 +2614,7 @@ impl PartialEq for TableScan {
2577
2614
&& self . projected_schema == other. projected_schema
2578
2615
&& self . filters == other. filters
2579
2616
&& self . fetch == other. fetch
2580
- && self . preferred_ordering == other. preferred_ordering
2617
+ && self . ordering == other. ordering
2581
2618
}
2582
2619
}
2583
2620
@@ -2598,21 +2635,21 @@ impl PartialOrd for TableScan {
2598
2635
/// Optional number of rows to read
2599
2636
pub fetch : & ' a Option < usize > ,
2600
2637
/// Optional preferred ordering for the scan
2601
- pub preferred_ordering : & ' a Option < Vec < SortExpr > > ,
2638
+ pub ordering : & ' a Option < ScanOrdering > ,
2602
2639
}
2603
2640
let comparable_self = ComparableTableScan {
2604
2641
table_name : & self . table_name ,
2605
2642
projection : & self . projection ,
2606
2643
filters : & self . filters ,
2607
2644
fetch : & self . fetch ,
2608
- preferred_ordering : & self . preferred_ordering ,
2645
+ ordering : & self . ordering ,
2609
2646
} ;
2610
2647
let comparable_other = ComparableTableScan {
2611
2648
table_name : & other. table_name ,
2612
2649
projection : & other. projection ,
2613
2650
filters : & other. filters ,
2614
2651
fetch : & other. fetch ,
2615
- preferred_ordering : & other. preferred_ordering ,
2652
+ ordering : & other. ordering ,
2616
2653
} ;
2617
2654
comparable_self. partial_cmp ( & comparable_other)
2618
2655
}
@@ -2625,7 +2662,7 @@ impl Hash for TableScan {
2625
2662
self . projected_schema . hash ( state) ;
2626
2663
self . filters . hash ( state) ;
2627
2664
self . fetch . hash ( state) ;
2628
- self . preferred_ordering . hash ( state) ;
2665
+ self . ordering . hash ( state) ;
2629
2666
}
2630
2667
}
2631
2668
@@ -2679,7 +2716,7 @@ impl TableScan {
2679
2716
projected_schema,
2680
2717
filters,
2681
2718
fetch,
2682
- preferred_ordering : None ,
2719
+ ordering : None ,
2683
2720
} )
2684
2721
}
2685
2722
@@ -2734,11 +2771,8 @@ impl TableScan {
2734
2771
/// This is purely an optimization hint. The table provider may choose to ignore
2735
2772
/// the preferred ordering if it cannot be efficiently satisfied, and the query
2736
2773
/// execution engine should not rely on the data being returned in this order.
2737
- pub fn with_preferred_ordering (
2738
- mut self ,
2739
- preferred_ordering : Option < Vec < SortExpr > > ,
2740
- ) -> Self {
2741
- self . preferred_ordering = preferred_ordering;
2774
+ pub fn with_ordering ( mut self , ordering : ScanOrdering ) -> Self {
2775
+ self . ordering = Some ( ordering) ;
2742
2776
self
2743
2777
}
2744
2778
}
@@ -4965,7 +4999,7 @@ mod tests {
4965
4999
projected_schema : Arc :: clone ( & schema) ,
4966
5000
filters : vec ! [ ] ,
4967
5001
fetch : None ,
4968
- preferred_ordering : None ,
5002
+ ordering : None ,
4969
5003
} ) ) ;
4970
5004
let col = schema. field_names ( ) [ 0 ] . clone ( ) ;
4971
5005
@@ -4996,7 +5030,7 @@ mod tests {
4996
5030
projected_schema : Arc :: clone ( & unique_schema) ,
4997
5031
filters : vec ! [ ] ,
4998
5032
fetch : None ,
4999
- preferred_ordering : None ,
5033
+ ordering : None ,
5000
5034
} ) ) ;
5001
5035
let col = schema. field_names ( ) [ 0 ] . clone ( ) ;
5002
5036
0 commit comments