@@ -893,6 +893,47 @@ impl AggregateExec {
893893 & self . filter_expr
894894 }
895895
896+ /// Returns the dynamic filter expression for this aggregate, if set.
897+ pub fn dynamic_filter_expr ( & self ) -> Option < & Arc < DynamicFilterPhysicalExpr > > {
898+ self . dynamic_filter . as_ref ( ) . map ( |df| & df. filter )
899+ }
900+
901+ /// Replace the dynamic filter expression. This method errors if the aggregate does not
902+ /// support dynamic filtering or if the filter expression is incompatible with this
903+ /// [`AggregateExec`].
904+ pub fn with_dynamic_filter_expr (
905+ mut self ,
906+ filter : Arc < DynamicFilterPhysicalExpr > ,
907+ ) -> Result < Self > {
908+ // If there is no dynamic filter state initialized via `try_new`, then
909+ // we can safely assume that the aggregate does not support dynamic filtering.
910+ let Some ( dyn_filter) = self . dynamic_filter . as_ref ( ) else {
911+ return internal_err ! ( "Aggregate does not support dynamic filtering" ) ;
912+ } ;
913+
914+ // Validate that the filter is compatible with the aggregation columns.
915+ let cols = self . cols_for_dynamic_filter ( & dyn_filter. supported_accumulators_info ) ;
916+ if cols. len ( ) != filter. children ( ) . len ( ) {
917+ return internal_err ! (
918+ "Dynamic filter expression is incompatible with aggregate due to mismatched number of columns"
919+ ) ;
920+ }
921+ for ( col, child) in cols. iter ( ) . zip ( filter. children ( ) ) {
922+ if !col. eq ( child) {
923+ return internal_err ! (
924+ "Dynamic filter expression is incompatible with aggregate due to mismatched column references {col} != {child}"
925+ ) ;
926+ }
927+ }
928+
929+ // Overwrite our filter
930+ self . dynamic_filter = Some ( Arc :: new ( AggrDynFilter {
931+ filter,
932+ supported_accumulators_info : dyn_filter. supported_accumulators_info . clone ( ) ,
933+ } ) ) ;
934+ Ok ( self )
935+ }
936+
896937 /// Input plan
897938 pub fn input ( & self ) -> & Arc < dyn ExecutionPlan > {
898939 & self . input
@@ -1048,47 +1089,6 @@ impl AggregateExec {
10481089 & self . input_order_mode
10491090 }
10501091
1051- /// Returns the dynamic filter expression for this aggregate, if set.
1052- pub fn dynamic_filter ( & self ) -> Option < & Arc < DynamicFilterPhysicalExpr > > {
1053- self . dynamic_filter . as_ref ( ) . map ( |df| & df. filter )
1054- }
1055-
1056- /// Replace the dynamic filter expression. This method errors if the aggregate does not
1057- /// support dynamic filtering or if the filter expression is incompatible with this
1058- /// [`AggregateExec`].
1059- pub fn with_dynamic_filter (
1060- mut self ,
1061- filter : Arc < DynamicFilterPhysicalExpr > ,
1062- ) -> Result < Self > {
1063- // If there is no dynamic filter state initialized via `try_new`, then
1064- // we can safely assume that the aggregate does not support dynamic filtering.
1065- let Some ( dyn_filter) = self . dynamic_filter . as_ref ( ) else {
1066- return internal_err ! ( "Aggregate does not support dynamic filtering" ) ;
1067- } ;
1068-
1069- // Validate that the filter is compatible with the aggregation columns.
1070- let cols = self . cols_for_dynamic_filter ( & dyn_filter. supported_accumulators_info ) ;
1071- if cols. len ( ) != filter. children ( ) . len ( ) {
1072- return internal_err ! (
1073- "Dynamic filter expression is incompatible with aggregate due to mismatched number of columns"
1074- ) ;
1075- }
1076- for ( col, child) in cols. iter ( ) . zip ( filter. children ( ) ) {
1077- if !col. eq ( child) {
1078- return internal_err ! (
1079- "Dynamic filter expression is incompatible with aggregate due to mismatched column references {col} != {child}"
1080- ) ;
1081- }
1082- }
1083-
1084- // Overwrite our filter
1085- self . dynamic_filter = Some ( Arc :: new ( AggrDynFilter {
1086- filter,
1087- supported_accumulators_info : dyn_filter. supported_accumulators_info . clone ( ) ,
1088- } ) ) ;
1089- Ok ( self )
1090- }
1091-
10921092 /// Estimates output statistics for this aggregate node.
10931093 ///
10941094 /// For grouped aggregations with known input row count > 1, the output row
@@ -4842,7 +4842,7 @@ mod tests {
48424842 Ok ( ( ) )
48434843 }
48444844
4845- /// Test that [`AggregateExec::with_dynamic_filter `] overrides the existing dynamic filter
4845+ /// Test that [`AggregateExec::with_dynamic_filter_expr `] overrides the existing dynamic filter
48464846 #[ test]
48474847 fn test_with_dynamic_filter ( ) -> Result < ( ) > {
48484848 let schema = Arc :: new ( Schema :: new ( vec ! [ Field :: new( "a" , DataType :: Int64 , false ) ] ) ) ;
@@ -4869,11 +4869,11 @@ mod tests {
48694869 vec ! [ col( "a" , & schema) ?] ,
48704870 lit ( false ) ,
48714871 ) ) ;
4872- let agg = agg. with_dynamic_filter ( Arc :: clone ( & new_df) ) ?;
4872+ let agg = agg. with_dynamic_filter_expr ( Arc :: clone ( & new_df) ) ?;
48734873
48744874 // The aggregate's filter should now resolve to the new inner expression.
48754875 let swapped = agg
4876- . dynamic_filter ( )
4876+ . dynamic_filter_expr ( )
48774877 . expect ( "should still have dynamic filter" )
48784878 . current ( ) ?;
48794879 assert_eq ! ( format!( "{swapped}" ) , format!( "{}" , lit( false ) ) ) ;
@@ -4884,19 +4884,18 @@ mod tests {
48844884 Arc :: < DynamicFilterPhysicalExpr > :: clone ( & new_df) ;
48854885 let remapped_pexpr =
48864886 new_df_as_pexpr. with_new_children ( vec ! [ col( "a" , & schema) ?] ) ?;
4887- let Ok ( remapped_df) = ( remapped_pexpr
4888- as Arc < dyn std:: any:: Any + Send + Sync > )
4887+ let Ok ( remapped_df) = ( remapped_pexpr as Arc < dyn std:: any:: Any + Send + Sync > )
48894888 . downcast :: < DynamicFilterPhysicalExpr > ( )
48904889 else {
48914890 panic ! ( "should be DynamicFilterPhysicalExpr after with_new_children" ) ;
48924891 } ;
48934892 // Hard to assert this because the filter is identical. No error means
48944893 // the filter was accepted. That's a good enough assertion for now.
4895- let _agg = agg. with_dynamic_filter ( remapped_df) ?;
4894+ let _agg = agg. with_dynamic_filter_expr ( remapped_df) ?;
48964895 Ok ( ( ) )
48974896 }
48984897
4899- /// Test that [`AggregateExec::with_dynamic_filter `] errors when the aggregate does not support dynamic filtering
4898+ /// Test that [`AggregateExec::with_dynamic_filter_expr `] errors when the aggregate does not support dynamic filtering
49004899 #[ test]
49014900 fn test_with_dynamic_filter_error_unsupported ( ) -> Result < ( ) > {
49024901 let schema = Arc :: new ( Schema :: new ( vec ! [
@@ -4919,17 +4918,17 @@ mod tests {
49194918 child,
49204919 Arc :: clone ( & schema) ,
49214920 ) ?;
4922- assert ! ( agg. dynamic_filter ( ) . is_none( ) ) ;
4921+ assert ! ( agg. dynamic_filter_expr ( ) . is_none( ) ) ;
49234922
49244923 let df = Arc :: new ( DynamicFilterPhysicalExpr :: new (
49254924 vec ! [ col( "a" , & schema) ?] ,
49264925 lit ( true ) ,
49274926 ) ) ;
4928- assert ! ( agg. with_dynamic_filter ( df) . is_err( ) ) ;
4927+ assert ! ( agg. with_dynamic_filter_expr ( df) . is_err( ) ) ;
49294928 Ok ( ( ) )
49304929 }
49314930
4932- /// Test that [`AggregateExec::with_dynamic_filter `] errors when the column is not in the schema
4931+ /// Test that [`AggregateExec::with_dynamic_filter_expr `] errors when the column is not in the schema
49334932 #[ test]
49344933 fn test_with_dynamic_filter_error_column_mismatch ( ) -> Result < ( ) > {
49354934 let schema = Arc :: new ( Schema :: new ( vec ! [ Field :: new( "a" , DataType :: Int64 , false ) ] ) ) ;
@@ -4953,7 +4952,7 @@ mod tests {
49534952 vec ! [ Arc :: new( Column :: new( "bad" , 99 ) ) as _] ,
49544953 lit ( true ) ,
49554954 ) ) ;
4956- assert ! ( agg. with_dynamic_filter ( df) . is_err( ) ) ;
4955+ assert ! ( agg. with_dynamic_filter_expr ( df) . is_err( ) ) ;
49574956 Ok ( ( ) )
49584957 }
49594958}
0 commit comments