16
16
// under the License.
17
17
18
18
use super :: plan:: * ;
19
- use crate :: { lit, Expr } ;
19
+ use crate :: expr:: { Exists , InSubquery } ;
20
+ use crate :: Expr ;
20
21
use datafusion_common:: tree_node:: Transformed ;
21
22
use datafusion_common:: Result ;
22
23
use datafusion_common:: { DFSchema , DFSchemaRef } ;
@@ -27,25 +28,13 @@ use std::sync::Arc;
27
28
fn rewrite_expr_iter_mut < ' a , F > (
28
29
i : impl IntoIterator < Item = & ' a mut Expr > ,
29
30
mut f : F ,
30
- ) -> Result < ( ) >
31
+ ) -> Result < Transformed < ( ) > >
31
32
where
32
- F : FnMut ( Expr ) -> Result < Expr > ,
33
+ F : FnMut ( & mut Expr ) -> Result < Transformed < ( ) > > ,
33
34
{
34
- i. into_iter ( ) . try_for_each ( |e| rewrite_expr ( e, & mut f) )
35
- }
36
-
37
- /// Rewrites an expression in place using a function that takes the expression by ownership
38
- fn rewrite_expr < ' a , F > ( e : & ' a mut Expr , mut f : F ) -> Result < ( ) >
39
- where
40
- F : FnMut ( Expr ) -> Result < Expr > ,
41
- {
42
- let mut t = lit ( 0 ) ;
43
- std:: mem:: swap ( e, & mut t) ;
44
- // transform
45
- let mut t = f ( t) ?;
46
- // put it back
47
- std:: mem:: swap ( e, & mut t) ;
48
- Ok ( ( ) )
35
+ i. into_iter ( ) . fold ( Ok ( Transformed :: no ( ( ) ) ) , |acc, expr| {
36
+ acc. and_then ( |acc| acc. and_then ( || f ( expr) ) )
37
+ } )
49
38
}
50
39
51
40
impl LogicalPlan {
@@ -54,61 +43,58 @@ impl LogicalPlan {
54
43
///
55
44
/// If the closure returns an error, the error is returned and the expressions
56
45
/// are left in a partially modified state
57
- pub fn rewrite_exprs < F > ( mut self , mut f : F ) -> Result < Self >
46
+ pub fn rewrite_exprs < F > ( & mut self , mut f : F ) -> Result < Transformed < ( ) > >
58
47
where
59
- F : FnMut ( Expr ) -> Result < Expr > ,
48
+ F : FnMut ( & mut Expr ) -> Result < Transformed < ( ) > > ,
60
49
{
61
- match & mut self {
50
+ match self {
62
51
LogicalPlan :: Projection ( Projection { expr, .. } ) => {
63
- rewrite_expr_iter_mut ( expr. iter_mut ( ) , & mut f ) ? ;
52
+ rewrite_expr_iter_mut ( expr. iter_mut ( ) , f )
64
53
}
65
54
LogicalPlan :: Values ( Values { values, .. } ) => {
66
- rewrite_expr_iter_mut ( values. iter_mut ( ) . flatten ( ) , & mut f) ?;
67
- }
68
- LogicalPlan :: Filter ( Filter { predicate, .. } ) => {
69
- rewrite_expr ( predicate, & mut f) ?
55
+ rewrite_expr_iter_mut ( values. iter_mut ( ) . flatten ( ) , f)
70
56
}
57
+ LogicalPlan :: Filter ( Filter { predicate, .. } ) => f ( predicate) ,
71
58
LogicalPlan :: Repartition ( Repartition {
72
59
partitioning_scheme,
73
60
..
74
61
} ) => match partitioning_scheme {
75
- Partitioning :: Hash ( expr, _) => {
76
- rewrite_expr_iter_mut ( expr. iter_mut ( ) , & mut f) ?
77
- }
62
+ Partitioning :: Hash ( expr, _) => rewrite_expr_iter_mut ( expr. iter_mut ( ) , f) ,
78
63
Partitioning :: DistributeBy ( expr) => {
79
- rewrite_expr_iter_mut ( expr. iter_mut ( ) , & mut f ) ?
64
+ rewrite_expr_iter_mut ( expr. iter_mut ( ) , f )
80
65
}
81
- Partitioning :: RoundRobinBatch ( _) => { }
66
+ Partitioning :: RoundRobinBatch ( _) => Ok ( Transformed :: no ( ( ) ) ) ,
82
67
} ,
83
68
LogicalPlan :: Window ( Window { window_expr, .. } ) => {
84
- rewrite_expr_iter_mut ( window_expr. iter_mut ( ) , & mut f ) ? ;
69
+ rewrite_expr_iter_mut ( window_expr. iter_mut ( ) , f )
85
70
}
86
71
LogicalPlan :: Aggregate ( Aggregate {
87
72
group_expr,
88
73
aggr_expr,
89
74
..
90
- } ) => rewrite_expr_iter_mut (
91
- group_expr. iter_mut ( ) . chain ( aggr_expr. iter_mut ( ) ) ,
92
- & mut f ,
93
- ) ? ,
75
+ } ) => {
76
+ let exprs = group_expr. iter_mut ( ) . chain ( aggr_expr. iter_mut ( ) ) ;
77
+ rewrite_expr_iter_mut ( exprs , f )
78
+ }
94
79
// There are two part of expression for join, equijoin(on) and non-equijoin(filter).
95
80
// 1. the first part is `on.len()` equijoin expressions, and the struct of each expr is `left-on = right-on`.
96
81
// 2. the second part is non-equijoin(filter).
97
82
LogicalPlan :: Join ( Join { on, filter, .. } ) => {
98
83
// don't look at the equijoin expressions as a whole
99
- rewrite_expr_iter_mut (
100
- on. iter_mut ( ) . flat_map ( |( e1, e2) | {
101
- std:: iter:: once ( e1) . chain ( std:: iter:: once ( e2) )
102
- } ) ,
103
- & mut f,
104
- ) ?;
84
+ let exprs = on
85
+ . iter_mut ( )
86
+ . flat_map ( |( e1, e2) | std:: iter:: once ( e1) . chain ( std:: iter:: once ( e2) ) ) ;
87
+
88
+ let result = rewrite_expr_iter_mut ( exprs, & mut f) ?;
105
89
106
90
if let Some ( filter) = filter. as_mut ( ) {
107
- rewrite_expr ( filter, & mut f) ?;
91
+ result. and_then ( || f ( filter) )
92
+ } else {
93
+ Ok ( result)
108
94
}
109
95
}
110
96
LogicalPlan :: Sort ( Sort { expr, .. } ) => {
111
- rewrite_expr_iter_mut ( expr. iter_mut ( ) , & mut f ) ?
97
+ rewrite_expr_iter_mut ( expr. iter_mut ( ) , f )
112
98
}
113
99
LogicalPlan :: Extension ( extension) => {
114
100
// would be nice to avoid this copy -- maybe can
@@ -117,7 +103,7 @@ impl LogicalPlan {
117
103
todo ! ( ) ;
118
104
}
119
105
LogicalPlan :: TableScan ( TableScan { filters, .. } ) => {
120
- rewrite_expr_iter_mut ( filters. iter_mut ( ) , & mut f ) ? ;
106
+ rewrite_expr_iter_mut ( filters. iter_mut ( ) , f )
121
107
}
122
108
LogicalPlan :: Unnest ( Unnest { column, .. } ) => {
123
109
//f(&Expr::Column(column.clone()))
@@ -128,13 +114,14 @@ impl LogicalPlan {
128
114
select_expr,
129
115
sort_expr,
130
116
..
131
- } ) ) => rewrite_expr_iter_mut (
132
- on_expr
117
+ } ) ) => {
118
+ let exprs = on_expr
133
119
. iter_mut ( )
134
120
. chain ( select_expr. iter_mut ( ) )
135
- . chain ( sort_expr. iter_mut ( ) . flat_map ( |x| x. iter_mut ( ) ) ) ,
136
- & mut f,
137
- ) ?,
121
+ . chain ( sort_expr. iter_mut ( ) . flat_map ( |x| x. iter_mut ( ) ) ) ;
122
+
123
+ rewrite_expr_iter_mut ( exprs, f)
124
+ }
138
125
// plans without expressions
139
126
LogicalPlan :: EmptyRelation ( _)
140
127
| LogicalPlan :: RecursiveQuery ( _)
@@ -151,10 +138,8 @@ impl LogicalPlan {
151
138
| LogicalPlan :: Ddl ( _)
152
139
| LogicalPlan :: Copy ( _)
153
140
| LogicalPlan :: DescribeTable ( _)
154
- | LogicalPlan :: Prepare ( _) => { }
141
+ | LogicalPlan :: Prepare ( _) => Ok ( Transformed :: no ( ( ) ) ) ,
155
142
}
156
-
157
- Ok ( self )
158
143
}
159
144
}
160
145
@@ -168,7 +153,7 @@ const PLACEHOLDER: OnceCell<Arc<LogicalPlan>> = OnceCell::new();
168
153
/// of the Arc to avoid cloning the entire plan
169
154
///
170
155
/// On error, the node will be partially rewritten (left with a placeholder logical plan)
171
- fn rewrite_arc < F > ( node : & mut Arc < LogicalPlan > , f : & mut F ) -> Result < Transformed < ( ) > >
156
+ fn rewrite_arc < F > ( node : & mut Arc < LogicalPlan > , mut f : F ) -> Result < Transformed < ( ) > >
172
157
where
173
158
F : FnMut ( & mut LogicalPlan ) -> Result < Transformed < ( ) > > ,
174
159
{
@@ -215,7 +200,7 @@ impl LogicalPlan {
215
200
where
216
201
F : FnMut ( & mut LogicalPlan ) -> Result < Transformed < ( ) > > ,
217
202
{
218
- match self {
203
+ let children_result = match self {
219
204
LogicalPlan :: Projection ( Projection { input, .. } ) => {
220
205
rewrite_arc ( input, & mut f)
221
206
}
@@ -269,6 +254,27 @@ impl LogicalPlan {
269
254
| LogicalPlan :: EmptyRelation { .. }
270
255
| LogicalPlan :: Values { .. }
271
256
| LogicalPlan :: DescribeTable ( _) => Ok ( Transformed :: no ( ( ) ) ) ,
272
- }
257
+ } ?;
258
+
259
+ // after visiting the actual children we we need to visit any subqueries
260
+ // that are inside the expressions
261
+ children_result. and_then ( || self . rewrite_subqueries ( & mut f) )
262
+ }
263
+
264
+ /// applies the closure `f` to LogicalPlans in any subquery expressions
265
+ ///
266
+ /// If Err is returned, the plan may be left in a partially modified state
267
+ fn rewrite_subqueries < F > ( & mut self , mut f : F ) -> Result < Transformed < ( ) > >
268
+ where
269
+ F : FnMut ( & mut LogicalPlan ) -> Result < Transformed < ( ) > > ,
270
+ {
271
+ self . rewrite_exprs ( |expr| match expr {
272
+ Expr :: Exists ( Exists { subquery, .. } )
273
+ | Expr :: InSubquery ( InSubquery { subquery, .. } )
274
+ | Expr :: ScalarSubquery ( subquery) => {
275
+ rewrite_arc ( & mut subquery. subquery , & mut f)
276
+ }
277
+ _ => Ok ( Transformed :: no ( ( ) ) ) ,
278
+ } )
273
279
}
274
280
}
0 commit comments