@@ -905,6 +905,29 @@ impl SortExec {
905905 self
906906 }
907907
908+ /// Add or reset `self.filter` to a new `DynamicFilterPhysicalExpr`.
909+ fn create_filter ( & self ) -> Arc < DynamicFilterPhysicalExpr > {
910+ let children = self
911+ . expr
912+ . iter ( )
913+ . map ( |sort_expr| Arc :: clone ( & sort_expr. expr ) )
914+ . collect :: < Vec < _ > > ( ) ;
915+ Arc :: new ( DynamicFilterPhysicalExpr :: new ( children, lit ( true ) ) )
916+ }
917+
918+ fn cloned ( & self ) -> Self {
919+ SortExec {
920+ input : Arc :: clone ( & self . input ) ,
921+ expr : self . expr . clone ( ) ,
922+ metrics_set : self . metrics_set . clone ( ) ,
923+ preserve_partitioning : self . preserve_partitioning ,
924+ common_sort_prefix : self . common_sort_prefix . clone ( ) ,
925+ fetch : self . fetch ,
926+ cache : self . cache . clone ( ) ,
927+ filter : self . filter . clone ( ) ,
928+ }
929+ }
930+
908931 /// Modify how many rows to include in the result
909932 ///
910933 /// If None, then all rows will be returned, in sorted order.
@@ -926,25 +949,13 @@ impl SortExec {
926949 }
927950 let filter = fetch. is_some ( ) . then ( || {
928951 // If we already have a filter, keep it. Otherwise, create a new one.
929- self . filter . clone ( ) . unwrap_or_else ( || {
930- let children = self
931- . expr
932- . iter ( )
933- . map ( |sort_expr| Arc :: clone ( & sort_expr. expr ) )
934- . collect :: < Vec < _ > > ( ) ;
935- Arc :: new ( DynamicFilterPhysicalExpr :: new ( children, lit ( true ) ) )
936- } )
952+ self . filter . clone ( ) . unwrap_or_else ( || self . create_filter ( ) )
937953 } ) ;
938- SortExec {
939- input : Arc :: clone ( & self . input ) ,
940- expr : self . expr . clone ( ) ,
941- metrics_set : self . metrics_set . clone ( ) ,
942- preserve_partitioning : self . preserve_partitioning ,
943- common_sort_prefix : self . common_sort_prefix . clone ( ) ,
944- fetch,
945- cache,
946- filter,
947- }
954+ let mut new_sort = self . cloned ( ) ;
955+ new_sort. fetch = fetch;
956+ new_sort. cache = cache;
957+ new_sort. filter = filter;
958+ new_sort
948959 }
949960
950961 /// Input schema
@@ -1116,10 +1127,46 @@ impl ExecutionPlan for SortExec {
11161127 self : Arc < Self > ,
11171128 children : Vec < Arc < dyn ExecutionPlan > > ,
11181129 ) -> Result < Arc < dyn ExecutionPlan > > {
1119- let mut new_sort = SortExec :: new ( self . expr . clone ( ) , Arc :: clone ( & children[ 0 ] ) )
1120- . with_fetch ( self . fetch )
1121- . with_preserve_partitioning ( self . preserve_partitioning ) ;
1122- new_sort. filter = self . filter . clone ( ) ;
1130+ let mut new_sort = self . cloned ( ) ;
1131+ assert ! (
1132+ children. len( ) == 1 ,
1133+ "SortExec should have exactly one child"
1134+ ) ;
1135+ new_sort. input = Arc :: clone ( & children[ 0 ] ) ;
1136+ // Recompute the properties based on the new input since they may have changed.
1137+ let ( cache, sort_prefix) = Self :: compute_properties (
1138+ & new_sort. input ,
1139+ new_sort. expr . clone ( ) ,
1140+ new_sort. preserve_partitioning ,
1141+ )
1142+ . expect ( concat ! (
1143+ "Safety: we had already been calling `compute_properties(...).unwrap()` in `new()` " ,
1144+ "and it seems to be okay" ,
1145+ "\n " ,
1146+ "We assumed that doing the same thing here directly instead " ,
1147+ "of calling `new()` (as we did before this commit) is also okay but it's possible that " ,
1148+ "implementations have drifted and this is no longer safe even if `new()` still works, " ,
1149+ "for example if `new()` now does something different than just calling `compute_properties(...).unwrap()`" ,
1150+ "\n " ,
1151+ "This is clearly a bug, please report it!"
1152+ ) ) ;
1153+ new_sort. cache = cache;
1154+ new_sort. common_sort_prefix = sort_prefix;
1155+
1156+ Ok ( Arc :: new ( new_sort) )
1157+ }
1158+
1159+ fn reset_state ( self : Arc < Self > ) -> Result < Arc < dyn ExecutionPlan > > {
1160+ let children = self . children ( ) . into_iter ( ) . cloned ( ) . collect ( ) ;
1161+ let new_sort = self . with_new_children ( children) ?;
1162+ let mut new_sort = new_sort
1163+ . as_any ( )
1164+ . downcast_ref :: < SortExec > ( )
1165+ . expect ( "cloned 1 lines above this line, we know the type" )
1166+ . clone ( ) ;
1167+ // Our dynamic filter and execution metrics are the state we need to reset.
1168+ new_sort. filter = Some ( new_sort. create_filter ( ) ) ;
1169+ new_sort. metrics_set = ExecutionPlanMetricsSet :: new ( ) ;
11231170
11241171 Ok ( Arc :: new ( new_sort) )
11251172 }
0 commit comments