@@ -26,8 +26,6 @@ use datafusion_physical_expr::utils::{
26
26
} ;
27
27
use datafusion_physical_expr:: { PhysicalExpr , PhysicalSortExpr , SortProperties } ;
28
28
29
- use itertools:: Itertools ;
30
-
31
29
/// Takes information about the join inputs (i.e. tables) and determines
32
30
/// which input can be pruned during the join operation.
33
31
///
@@ -168,7 +166,7 @@ fn intermediate_schema_sort_expr(
168
166
///
169
167
/// While transforming a [`PhysicalExpr`] up, each node holds a [`PrunabilityState`]
170
168
/// to propagate these crucial pieces of information.
171
- #[ derive( Debug , Clone ) ]
169
+ #[ derive( Debug , Clone , Copy ) ]
172
170
struct PrunabilityState {
173
171
sort_options : SortProperties ,
174
172
table_side : TableSide ,
@@ -192,35 +190,23 @@ impl Default for PrunabilityState {
192
190
struct ExprPrunability {
193
191
expr : Arc < dyn PhysicalExpr > ,
194
192
state : PrunabilityState ,
195
- children_states : Vec < PrunabilityState > ,
193
+ children : Vec < ExprPrunability > ,
196
194
}
197
195
198
196
impl ExprPrunability {
199
- /// Creates a new [`ExprPrunability`] with default states for `expr` and
200
- /// its children.
197
+ /// Creates a new [`ExprPrunability`] tree with empty states.
201
198
fn new ( expr : Arc < dyn PhysicalExpr > ) -> Self {
202
- let size = expr. children ( ) . len ( ) ;
199
+ let children = expr. children ( ) ;
203
200
Self {
204
201
expr,
205
202
state : PrunabilityState :: default ( ) ,
206
- children_states : vec ! [ PrunabilityState :: default ( ) ; size ] ,
203
+ children : children . into_iter ( ) . map ( Self :: new ) . collect ( ) ,
207
204
}
208
205
}
209
206
210
- /// Updates this [`ExprPrunability`]'s children states with the given states.
211
- pub fn with_new_children ( mut self , children_states : Vec < PrunabilityState > ) -> Self {
212
- assert_eq ! ( self . children_states. len( ) , children_states. len( ) ) ;
213
- self . children_states = children_states;
214
- self
215
- }
216
-
217
- /// Creates new [`ExprPrunability`] objects for each child of the expression.
218
- pub fn children_expr_prunabilities ( & self ) -> Vec < ExprPrunability > {
219
- self . expr
220
- . children ( )
221
- . into_iter ( )
222
- . map ( ExprPrunability :: new)
223
- . collect ( )
207
+ /// Get state for each child
208
+ fn children_state ( & self ) -> Vec < PrunabilityState > {
209
+ self . children . iter ( ) . map ( |child| child. state ) . collect ( )
224
210
}
225
211
}
226
212
@@ -276,21 +262,21 @@ fn update_prunability<F: Fn() -> EquivalenceProperties>(
276
262
return Ok ( Transformed :: Yes ( node) ) ;
277
263
}
278
264
279
- if !node. children_states . is_empty ( ) {
265
+ if !node. children . is_empty ( ) {
280
266
// Handle the intermediate (non-leaf) node case:
281
- let children = & node. children_states ;
267
+ let children = node. children_state ( ) ;
282
268
let children_sort_options = children
283
269
. iter ( )
284
270
. map ( |prunability_state| prunability_state. sort_options )
285
271
. collect :: < Vec < _ > > ( ) ;
286
272
let parent_sort_options = node. expr . get_ordering ( & children_sort_options) ;
287
273
288
- let parent_table_side = calculate_tableside_from_children ( children) ;
274
+ let parent_table_side = calculate_tableside_from_children ( & children) ;
289
275
290
276
let prune_side = if let Ok ( DataType :: Boolean ) = node. expr . data_type ( filter_schema)
291
277
{
292
278
if let Some ( binary) = node. expr . as_any ( ) . downcast_ref :: < BinaryExpr > ( ) {
293
- calculate_pruneside_from_children ( binary, children)
279
+ calculate_pruneside_from_children ( binary, & children)
294
280
} else if let Some ( _cast) = node. expr . as_any ( ) . downcast_ref :: < CastExpr > ( ) {
295
281
children[ 0 ] . prune_side
296
282
} else {
@@ -465,8 +451,8 @@ impl TreeNode for ExprPrunability {
465
451
where
466
452
F : FnMut ( & Self ) -> Result < VisitRecursion > ,
467
453
{
468
- for child in self . children_expr_prunabilities ( ) {
469
- match op ( & child) ? {
454
+ for child in & self . children {
455
+ match op ( child) ? {
470
456
VisitRecursion :: Continue => { }
471
457
VisitRecursion :: Skip => return Ok ( VisitRecursion :: Continue ) ,
472
458
VisitRecursion :: Stop => return Ok ( VisitRecursion :: Stop ) ,
@@ -475,25 +461,19 @@ impl TreeNode for ExprPrunability {
475
461
Ok ( VisitRecursion :: Continue )
476
462
}
477
463
478
- fn map_children < F > ( self , transform : F ) -> Result < Self >
464
+ fn map_children < F > ( mut self , transform : F ) -> Result < Self >
479
465
where
480
466
F : FnMut ( Self ) -> Result < Self > ,
481
467
{
482
- if self . children_states . is_empty ( ) {
468
+ if self . children . is_empty ( ) {
483
469
Ok ( self )
484
470
} else {
485
- let child_expr_prunabilities = self . children_expr_prunabilities ( ) ;
486
- // After mapping over the children, the function `F` applies to the
487
- // current object and updates its state.
488
- Ok ( self . with_new_children (
489
- child_expr_prunabilities
490
- . into_iter ( )
491
- // Update children states after this transformation:
492
- . map ( transform)
493
- // Extract the state (i.e. prunability) information:
494
- . map_ok ( |c| c. state )
495
- . collect :: < Result < Vec < _ > > > ( ) ?,
496
- ) )
471
+ self . children = self
472
+ . children
473
+ . into_iter ( )
474
+ . map ( transform)
475
+ . collect :: < Result < Vec < _ > > > ( ) ?;
476
+ Ok ( self )
497
477
}
498
478
}
499
479
}
0 commit comments