@@ -3452,4 +3452,51 @@ mod tests {
34523452 assert_eq ! ( files1[ 1 ] . object_meta. location. as_ref( ) , "f5" ) ;
34533453 Ok ( ( ) )
34543454 }
3455+
3456+ #[ test]
3457+ fn sort_pushdown_reverse_preserves_file_order_with_stats ( ) -> Result < ( ) > {
3458+ // Reverse scan should reverse file order but NOT apply statistics-based
3459+ // sorting (which would undo the reversal). The result is Inexact.
3460+ let file_schema =
3461+ Arc :: new ( Schema :: new ( vec ! [ Field :: new( "a" , DataType :: Float64 , false ) ] ) ) ;
3462+ let table_schema = TableSchema :: new ( Arc :: clone ( & file_schema) , vec ! [ ] ) ;
3463+ let file_source = Arc :: new ( InexactSortPushdownSource :: new ( table_schema) ) ;
3464+
3465+ let sort_expr = PhysicalSortExpr :: new_default ( Arc :: new ( Column :: new ( "a" , 0 ) ) ) ;
3466+
3467+ // Files with stats, in ASC order. Output ordering is [a ASC].
3468+ let file_groups = vec ! [ FileGroup :: new( vec![
3469+ make_file_with_stats( "file1" , 0.0 , 9.0 ) ,
3470+ make_file_with_stats( "file2" , 10.0 , 19.0 ) ,
3471+ make_file_with_stats( "file3" , 20.0 , 30.0 ) ,
3472+ ] ) ] ;
3473+
3474+ let config =
3475+ FileScanConfigBuilder :: new ( ObjectStoreUrl :: local_filesystem ( ) , file_source)
3476+ . with_file_groups ( file_groups)
3477+ . with_output_ordering ( vec ! [
3478+ LexOrdering :: new( vec![ sort_expr. clone( ) ] ) . unwrap( ) ,
3479+ ] )
3480+ . build ( ) ;
3481+
3482+ // Request DESC → reverse path
3483+ let result = config. try_pushdown_sort ( & [ sort_expr. reverse ( ) ] ) ?;
3484+ let SortOrderPushdownResult :: Inexact { inner } = result else {
3485+ panic ! ( "Expected Inexact for reverse scan, got {result:?}" ) ;
3486+ } ;
3487+ let pushed_config = inner
3488+ . as_any ( )
3489+ . downcast_ref :: < FileScanConfig > ( )
3490+ . expect ( "Expected FileScanConfig" ) ;
3491+
3492+ // Files should be reversed (not re-sorted by stats)
3493+ let files = pushed_config. file_groups [ 0 ] . files ( ) ;
3494+ assert_eq ! ( files[ 0 ] . object_meta. location. as_ref( ) , "file3" ) ;
3495+ assert_eq ! ( files[ 1 ] . object_meta. location. as_ref( ) , "file2" ) ;
3496+ assert_eq ! ( files[ 2 ] . object_meta. location. as_ref( ) , "file1" ) ;
3497+
3498+ // output_ordering cleared (Inexact)
3499+ assert ! ( pushed_config. output_ordering. is_empty( ) ) ;
3500+ Ok ( ( ) )
3501+ }
34553502}
0 commit comments