@@ -31,18 +31,6 @@ macro_rules! handle_transform_recursion {
31
31
} } ;
32
32
}
33
33
34
- macro_rules! handle_transform_recursion_down {
35
- ( $F_DOWN: expr, $F_CHILD: expr) => { {
36
- $F_DOWN?. transform_children( |n| n. map_children( $F_CHILD) )
37
- } } ;
38
- }
39
-
40
- macro_rules! handle_transform_recursion_up {
41
- ( $SELF: expr, $F_CHILD: expr, $F_UP: expr) => { {
42
- $SELF. map_children( $F_CHILD) ?. transform_parent( |n| $F_UP( n) )
43
- } } ;
44
- }
45
-
46
34
/// Defines a visitable and rewriteable tree node. This trait is implemented
47
35
/// for plans ([`ExecutionPlan`] and [`LogicalPlan`]) as well as expression
48
36
/// trees ([`PhysicalExpr`], [`Expr`]) in DataFusion.
@@ -137,61 +125,85 @@ pub trait TreeNode: Sized {
137
125
/// or run a check on the tree.
138
126
fn apply < F : FnMut ( & Self ) -> Result < TreeNodeRecursion > > (
139
127
& self ,
140
- f : & mut F ,
128
+ mut f : F ,
141
129
) -> Result < TreeNodeRecursion > {
142
- f ( self ) ?. visit_children ( || self . apply_children ( |c| c. apply ( f) ) )
130
+ fn apply_impl < N : TreeNode , F : FnMut ( & N ) -> Result < TreeNodeRecursion > > (
131
+ node : & N ,
132
+ f : & mut F ,
133
+ ) -> Result < TreeNodeRecursion > {
134
+ f ( node) ?. visit_children ( || node. apply_children ( |c| apply_impl ( c, f) ) )
135
+ }
136
+
137
+ apply_impl ( self , & mut f)
143
138
}
144
139
145
140
/// Convenience utility for writing optimizer rules: Recursively apply the
146
141
/// given function `f` to the tree in a bottom-up (post-order) fashion. When
147
142
/// `f` does not apply to a given node, it is left unchanged.
148
- fn transform < F : Fn ( Self ) -> Result < Transformed < Self > > > (
143
+ fn transform < F : FnMut ( Self ) -> Result < Transformed < Self > > > (
149
144
self ,
150
- f : & F ,
145
+ f : F ,
151
146
) -> Result < Transformed < Self > > {
152
147
self . transform_up ( f)
153
148
}
154
149
155
150
/// Convenience utility for writing optimizer rules: Recursively apply the
156
151
/// given function `f` to a node and then to its children (pre-order traversal).
157
152
/// When `f` does not apply to a given node, it is left unchanged.
158
- fn transform_down < F : Fn ( Self ) -> Result < Transformed < Self > > > (
153
+ fn transform_down < F : FnMut ( Self ) -> Result < Transformed < Self > > > (
159
154
self ,
160
- f : & F ,
155
+ mut f : F ,
161
156
) -> Result < Transformed < Self > > {
162
- handle_transform_recursion_down ! ( f( self ) , |c| c. transform_down( f) )
157
+ fn transform_down_impl < N : TreeNode , F : FnMut ( N ) -> Result < Transformed < N > > > (
158
+ node : N ,
159
+ f : & mut F ,
160
+ ) -> Result < Transformed < N > > {
161
+ f ( node) ?. transform_children ( |n| n. map_children ( |c| transform_down_impl ( c, f) ) )
162
+ }
163
+
164
+ transform_down_impl ( self , & mut f)
163
165
}
164
166
165
167
/// Convenience utility for writing optimizer rules: Recursively apply the
166
168
/// given mutable function `f` to a node and then to its children (pre-order
167
169
/// traversal). When `f` does not apply to a given node, it is left unchanged.
170
+ #[ deprecated( since = "38.0.0" , note = "Use `transform_down` instead" ) ]
168
171
fn transform_down_mut < F : FnMut ( Self ) -> Result < Transformed < Self > > > (
169
172
self ,
170
173
f : & mut F ,
171
174
) -> Result < Transformed < Self > > {
172
- handle_transform_recursion_down ! ( f ( self ) , |c| c . transform_down_mut ( f ) )
175
+ self . transform_down ( f )
173
176
}
174
177
175
178
/// Convenience utility for writing optimizer rules: Recursively apply the
176
179
/// given function `f` to all children of a node, and then to the node itself
177
180
/// (post-order traversal). When `f` does not apply to a given node, it is
178
181
/// left unchanged.
179
- fn transform_up < F : Fn ( Self ) -> Result < Transformed < Self > > > (
182
+ fn transform_up < F : FnMut ( Self ) -> Result < Transformed < Self > > > (
180
183
self ,
181
- f : & F ,
184
+ mut f : F ,
182
185
) -> Result < Transformed < Self > > {
183
- handle_transform_recursion_up ! ( self , |c| c. transform_up( f) , f)
186
+ fn transform_up_impl < N : TreeNode , F : FnMut ( N ) -> Result < Transformed < N > > > (
187
+ node : N ,
188
+ f : & mut F ,
189
+ ) -> Result < Transformed < N > > {
190
+ node. map_children ( |c| transform_up_impl ( c, f) ) ?
191
+ . transform_parent ( f)
192
+ }
193
+
194
+ transform_up_impl ( self , & mut f)
184
195
}
185
196
186
197
/// Convenience utility for writing optimizer rules: Recursively apply the
187
198
/// given mutable function `f` to all children of a node, and then to the
188
199
/// node itself (post-order traversal). When `f` does not apply to a given
189
200
/// node, it is left unchanged.
201
+ #[ deprecated( since = "38.0.0" , note = "Use `transform_up` instead" ) ]
190
202
fn transform_up_mut < F : FnMut ( Self ) -> Result < Transformed < Self > > > (
191
203
self ,
192
204
f : & mut F ,
193
205
) -> Result < Transformed < Self > > {
194
- handle_transform_recursion_up ! ( self , |c| c . transform_up_mut ( f ) , f)
206
+ self . transform_up ( f)
195
207
}
196
208
197
209
/// Transforms the tree using `f_down` while traversing the tree top-down
@@ -200,8 +212,8 @@ pub trait TreeNode: Sized {
200
212
///
201
213
/// Use this method if you want to start the `f_up` process right where `f_down` jumps.
202
214
/// This can make the whole process faster by reducing the number of `f_up` steps.
203
- /// If you don't need this, it's just like using `transform_down_mut ` followed by
204
- /// `transform_up_mut ` on the same tree.
215
+ /// If you don't need this, it's just like using `transform_down ` followed by
216
+ /// `transform_up ` on the same tree.
205
217
///
206
218
/// Consider the following tree structure:
207
219
/// ```text
@@ -288,22 +300,34 @@ pub trait TreeNode: Sized {
288
300
FU : FnMut ( Self ) -> Result < Transformed < Self > > ,
289
301
> (
290
302
self ,
291
- f_down : & mut FD ,
292
- f_up : & mut FU ,
303
+ mut f_down : FD ,
304
+ mut f_up : FU ,
293
305
) -> Result < Transformed < Self > > {
294
- handle_transform_recursion ! (
295
- f_down( self ) ,
296
- |c| c. transform_down_up( f_down, f_up) ,
297
- f_up
298
- )
306
+ fn transform_down_up_impl <
307
+ N : TreeNode ,
308
+ FD : FnMut ( N ) -> Result < Transformed < N > > ,
309
+ FU : FnMut ( N ) -> Result < Transformed < N > > ,
310
+ > (
311
+ node : N ,
312
+ f_down : & mut FD ,
313
+ f_up : & mut FU ,
314
+ ) -> Result < Transformed < N > > {
315
+ handle_transform_recursion ! (
316
+ f_down( node) ,
317
+ |c| transform_down_up_impl( c, f_down, f_up) ,
318
+ f_up
319
+ )
320
+ }
321
+
322
+ transform_down_up_impl ( self , & mut f_down, & mut f_up)
299
323
}
300
324
301
325
/// Returns true if `f` returns true for node in the tree.
302
326
///
303
327
/// Stops recursion as soon as a matching node is found
304
328
fn exists < F : FnMut ( & Self ) -> bool > ( & self , mut f : F ) -> bool {
305
329
let mut found = false ;
306
- self . apply ( & mut |n| {
330
+ self . apply ( |n| {
307
331
Ok ( if f ( n) {
308
332
found = true ;
309
333
TreeNodeRecursion :: Stop
@@ -439,9 +463,7 @@ impl TreeNodeRecursion {
439
463
/// This struct is used by tree transformation APIs such as
440
464
/// - [`TreeNode::rewrite`],
441
465
/// - [`TreeNode::transform_down`],
442
- /// - [`TreeNode::transform_down_mut`],
443
466
/// - [`TreeNode::transform_up`],
444
- /// - [`TreeNode::transform_up_mut`],
445
467
/// - [`TreeNode::transform_down_up`]
446
468
///
447
469
/// to control the transformation and return the transformed result.
@@ -1362,7 +1384,7 @@ mod tests {
1362
1384
fn $NAME( ) -> Result <( ) > {
1363
1385
let tree = test_tree( ) ;
1364
1386
let mut visits = vec![ ] ;
1365
- tree. apply( & mut |node| {
1387
+ tree. apply( |node| {
1366
1388
visits. push( format!( "f_down({})" , node. data) ) ;
1367
1389
$F( node)
1368
1390
} ) ?;
@@ -1451,10 +1473,7 @@ mod tests {
1451
1473
#[ test]
1452
1474
fn $NAME( ) -> Result <( ) > {
1453
1475
let tree = test_tree( ) ;
1454
- assert_eq!(
1455
- tree. transform_down_up( & mut $F_DOWN, & mut $F_UP, ) ?,
1456
- $EXPECTED_TREE
1457
- ) ;
1476
+ assert_eq!( tree. transform_down_up( $F_DOWN, $F_UP, ) ?, $EXPECTED_TREE) ;
1458
1477
1459
1478
Ok ( ( ) )
1460
1479
}
@@ -1466,7 +1485,7 @@ mod tests {
1466
1485
#[ test]
1467
1486
fn $NAME( ) -> Result <( ) > {
1468
1487
let tree = test_tree( ) ;
1469
- assert_eq!( tree. transform_down_mut ( & mut $F) ?, $EXPECTED_TREE) ;
1488
+ assert_eq!( tree. transform_down ( $F) ?, $EXPECTED_TREE) ;
1470
1489
1471
1490
Ok ( ( ) )
1472
1491
}
@@ -1478,7 +1497,7 @@ mod tests {
1478
1497
#[ test]
1479
1498
fn $NAME( ) -> Result <( ) > {
1480
1499
let tree = test_tree( ) ;
1481
- assert_eq!( tree. transform_up_mut ( & mut $F) ?, $EXPECTED_TREE) ;
1500
+ assert_eq!( tree. transform_up ( $F) ?, $EXPECTED_TREE) ;
1482
1501
1483
1502
Ok ( ( ) )
1484
1503
}
0 commit comments