18
18
//! SQL Utility Functions
19
19
20
20
use arrow_schema:: { DataType , DECIMAL128_MAX_PRECISION , DECIMAL_DEFAULT_SCALE } ;
21
+ use datafusion_common:: tree_node:: { Transformed , TreeNode } ;
21
22
use sqlparser:: ast:: Ident ;
22
23
23
24
use datafusion_common:: plan_err;
24
25
use datafusion_common:: { DataFusionError , Result , ScalarValue } ;
25
- use datafusion_expr:: expr:: {
26
- AggregateFunction , AggregateUDF , Alias , Between , BinaryExpr , Case , GetIndexedField ,
27
- GroupingSet , InList , InSubquery , Like , Placeholder , ScalarFunction , ScalarUDF ,
28
- WindowFunction ,
29
- } ;
30
- use datafusion_expr:: expr:: { Cast , Sort } ;
26
+ use datafusion_expr:: expr:: { Alias , GroupingSet , WindowFunction } ;
31
27
use datafusion_expr:: expr_vec_fmt;
32
28
use datafusion_expr:: utils:: { expr_as_column_expr, find_column_exprs} ;
33
- use datafusion_expr:: { Expr , LogicalPlan , TryCast } ;
29
+ use datafusion_expr:: { Expr , LogicalPlan } ;
34
30
use std:: collections:: HashMap ;
35
31
36
32
/// Make a best-effort attempt at resolving all columns in the expression tree
37
33
pub ( crate ) fn resolve_columns ( expr : & Expr , plan : & LogicalPlan ) -> Result < Expr > {
38
- clone_with_replacement ( expr, & |nested_expr| {
34
+ expr. clone ( ) . transform_up ( & |nested_expr| {
39
35
match nested_expr {
40
36
Expr :: Column ( col) => {
41
- let field = plan. schema ( ) . field_from_column ( col) ?;
42
- Ok ( Some ( Expr :: Column ( field. qualified_column ( ) ) ) )
37
+ let field = plan. schema ( ) . field_from_column ( & col) ?;
38
+ Ok ( Transformed :: Yes ( Expr :: Column ( field. qualified_column ( ) ) ) )
43
39
}
44
40
_ => {
45
41
// keep recursing
46
- Ok ( None )
42
+ Ok ( Transformed :: No ( nested_expr ) )
47
43
}
48
44
}
49
45
} )
@@ -68,11 +64,11 @@ pub(crate) fn rebase_expr(
68
64
base_exprs : & [ Expr ] ,
69
65
plan : & LogicalPlan ,
70
66
) -> Result < Expr > {
71
- clone_with_replacement ( expr, & |nested_expr| {
72
- if base_exprs. contains ( nested_expr) {
73
- Ok ( Some ( expr_as_column_expr ( nested_expr, plan) ?) )
67
+ expr. clone ( ) . transform_up ( & |nested_expr| {
68
+ if base_exprs. contains ( & nested_expr) {
69
+ Ok ( Transformed :: Yes ( expr_as_column_expr ( & nested_expr, plan) ?) )
74
70
} else {
75
- Ok ( None )
71
+ Ok ( Transformed :: No ( nested_expr ) )
76
72
}
77
73
} )
78
74
}
@@ -132,292 +128,6 @@ fn check_column_satisfies_expr(
132
128
Ok ( ( ) )
133
129
}
134
130
135
- /// Returns a cloned `Expr`, but any of the `Expr`'s in the tree may be
136
- /// replaced/customized by the replacement function.
137
- ///
138
- /// The replacement function is called repeatedly with `Expr`, starting with
139
- /// the argument `expr`, then descending depth-first through its
140
- /// descendants. The function chooses to replace or keep (clone) each `Expr`.
141
- ///
142
- /// The function's return type is `Result<Option<Expr>>>`, where:
143
- ///
144
- /// * `Ok(Some(replacement_expr))`: A replacement `Expr` is provided; it is
145
- /// swapped in at the particular node in the tree. Any nested `Expr` are
146
- /// not subject to cloning/replacement.
147
- /// * `Ok(None)`: A replacement `Expr` is not provided. The `Expr` is
148
- /// recreated, with all of its nested `Expr`'s subject to
149
- /// cloning/replacement.
150
- /// * `Err(err)`: Any error returned by the function is returned as-is by
151
- /// `clone_with_replacement()`.
152
- fn clone_with_replacement < F > ( expr : & Expr , replacement_fn : & F ) -> Result < Expr >
153
- where
154
- F : Fn ( & Expr ) -> Result < Option < Expr > > ,
155
- {
156
- let replacement_opt = replacement_fn ( expr) ?;
157
-
158
- match replacement_opt {
159
- // If we were provided a replacement, use the replacement. Do not
160
- // descend further.
161
- Some ( replacement) => Ok ( replacement) ,
162
- // No replacement was provided, clone the node and recursively call
163
- // clone_with_replacement() on any nested expressions.
164
- None => match expr {
165
- Expr :: AggregateFunction ( AggregateFunction {
166
- fun,
167
- args,
168
- distinct,
169
- filter,
170
- order_by,
171
- } ) => Ok ( Expr :: AggregateFunction ( AggregateFunction :: new (
172
- fun. clone ( ) ,
173
- args. iter ( )
174
- . map ( |e| clone_with_replacement ( e, replacement_fn) )
175
- . collect :: < Result < Vec < Expr > > > ( ) ?,
176
- * distinct,
177
- filter. clone ( ) ,
178
- order_by. clone ( ) ,
179
- ) ) ) ,
180
- Expr :: WindowFunction ( WindowFunction {
181
- fun,
182
- args,
183
- partition_by,
184
- order_by,
185
- window_frame,
186
- } ) => Ok ( Expr :: WindowFunction ( WindowFunction :: new (
187
- fun. clone ( ) ,
188
- args. iter ( )
189
- . map ( |e| clone_with_replacement ( e, replacement_fn) )
190
- . collect :: < Result < Vec < _ > > > ( ) ?,
191
- partition_by
192
- . iter ( )
193
- . map ( |e| clone_with_replacement ( e, replacement_fn) )
194
- . collect :: < Result < Vec < _ > > > ( ) ?,
195
- order_by
196
- . iter ( )
197
- . map ( |e| clone_with_replacement ( e, replacement_fn) )
198
- . collect :: < Result < Vec < _ > > > ( ) ?,
199
- window_frame. clone ( ) ,
200
- ) ) ) ,
201
- Expr :: AggregateUDF ( AggregateUDF {
202
- fun,
203
- args,
204
- filter,
205
- order_by,
206
- } ) => Ok ( Expr :: AggregateUDF ( AggregateUDF :: new (
207
- fun. clone ( ) ,
208
- args. iter ( )
209
- . map ( |e| clone_with_replacement ( e, replacement_fn) )
210
- . collect :: < Result < Vec < Expr > > > ( ) ?,
211
- filter. clone ( ) ,
212
- order_by. clone ( ) ,
213
- ) ) ) ,
214
- Expr :: Alias ( Alias { expr, name, .. } ) => Ok ( Expr :: Alias ( Alias :: new (
215
- clone_with_replacement ( expr, replacement_fn) ?,
216
- name. clone ( ) ,
217
- ) ) ) ,
218
- Expr :: Between ( Between {
219
- expr,
220
- negated,
221
- low,
222
- high,
223
- } ) => Ok ( Expr :: Between ( Between :: new (
224
- Box :: new ( clone_with_replacement ( expr, replacement_fn) ?) ,
225
- * negated,
226
- Box :: new ( clone_with_replacement ( low, replacement_fn) ?) ,
227
- Box :: new ( clone_with_replacement ( high, replacement_fn) ?) ,
228
- ) ) ) ,
229
- Expr :: InList ( InList {
230
- expr : nested_expr,
231
- list,
232
- negated,
233
- } ) => Ok ( Expr :: InList ( InList :: new (
234
- Box :: new ( clone_with_replacement ( nested_expr, replacement_fn) ?) ,
235
- list. iter ( )
236
- . map ( |e| clone_with_replacement ( e, replacement_fn) )
237
- . collect :: < Result < Vec < Expr > > > ( ) ?,
238
- * negated,
239
- ) ) ) ,
240
- Expr :: BinaryExpr ( BinaryExpr { left, right, op } ) => {
241
- Ok ( Expr :: BinaryExpr ( BinaryExpr :: new (
242
- Box :: new ( clone_with_replacement ( left, replacement_fn) ?) ,
243
- * op,
244
- Box :: new ( clone_with_replacement ( right, replacement_fn) ?) ,
245
- ) ) )
246
- }
247
- Expr :: Like ( Like {
248
- negated,
249
- expr,
250
- pattern,
251
- escape_char,
252
- case_insensitive,
253
- } ) => Ok ( Expr :: Like ( Like :: new (
254
- * negated,
255
- Box :: new ( clone_with_replacement ( expr, replacement_fn) ?) ,
256
- Box :: new ( clone_with_replacement ( pattern, replacement_fn) ?) ,
257
- * escape_char,
258
- * case_insensitive,
259
- ) ) ) ,
260
- Expr :: SimilarTo ( Like {
261
- negated,
262
- expr,
263
- pattern,
264
- escape_char,
265
- case_insensitive,
266
- } ) => Ok ( Expr :: SimilarTo ( Like :: new (
267
- * negated,
268
- Box :: new ( clone_with_replacement ( expr, replacement_fn) ?) ,
269
- Box :: new ( clone_with_replacement ( pattern, replacement_fn) ?) ,
270
- * escape_char,
271
- * case_insensitive,
272
- ) ) ) ,
273
- Expr :: Case ( case) => Ok ( Expr :: Case ( Case :: new (
274
- match & case. expr {
275
- Some ( case_expr) => {
276
- Some ( Box :: new ( clone_with_replacement ( case_expr, replacement_fn) ?) )
277
- }
278
- None => None ,
279
- } ,
280
- case. when_then_expr
281
- . iter ( )
282
- . map ( |( a, b) | {
283
- Ok ( (
284
- Box :: new ( clone_with_replacement ( a, replacement_fn) ?) ,
285
- Box :: new ( clone_with_replacement ( b, replacement_fn) ?) ,
286
- ) )
287
- } )
288
- . collect :: < Result < Vec < ( _ , _ ) > > > ( ) ?,
289
- match & case. else_expr {
290
- Some ( else_expr) => {
291
- Some ( Box :: new ( clone_with_replacement ( else_expr, replacement_fn) ?) )
292
- }
293
- None => None ,
294
- } ,
295
- ) ) ) ,
296
- Expr :: ScalarFunction ( ScalarFunction { fun, args } ) => {
297
- Ok ( Expr :: ScalarFunction ( ScalarFunction :: new (
298
- * fun,
299
- args. iter ( )
300
- . map ( |e| clone_with_replacement ( e, replacement_fn) )
301
- . collect :: < Result < Vec < Expr > > > ( ) ?,
302
- ) ) )
303
- }
304
- Expr :: ScalarUDF ( ScalarUDF { fun, args } ) => {
305
- Ok ( Expr :: ScalarUDF ( ScalarUDF :: new (
306
- fun. clone ( ) ,
307
- args. iter ( )
308
- . map ( |arg| clone_with_replacement ( arg, replacement_fn) )
309
- . collect :: < Result < Vec < Expr > > > ( ) ?,
310
- ) ) )
311
- }
312
- Expr :: Negative ( nested_expr) => Ok ( Expr :: Negative ( Box :: new (
313
- clone_with_replacement ( nested_expr, replacement_fn) ?,
314
- ) ) ) ,
315
- Expr :: Not ( nested_expr) => Ok ( Expr :: Not ( Box :: new ( clone_with_replacement (
316
- nested_expr,
317
- replacement_fn,
318
- ) ?) ) ) ,
319
- Expr :: IsNotNull ( nested_expr) => Ok ( Expr :: IsNotNull ( Box :: new (
320
- clone_with_replacement ( nested_expr, replacement_fn) ?,
321
- ) ) ) ,
322
- Expr :: IsNull ( nested_expr) => Ok ( Expr :: IsNull ( Box :: new (
323
- clone_with_replacement ( nested_expr, replacement_fn) ?,
324
- ) ) ) ,
325
- Expr :: IsTrue ( nested_expr) => Ok ( Expr :: IsTrue ( Box :: new (
326
- clone_with_replacement ( nested_expr, replacement_fn) ?,
327
- ) ) ) ,
328
- Expr :: IsFalse ( nested_expr) => Ok ( Expr :: IsFalse ( Box :: new (
329
- clone_with_replacement ( nested_expr, replacement_fn) ?,
330
- ) ) ) ,
331
- Expr :: IsUnknown ( nested_expr) => Ok ( Expr :: IsUnknown ( Box :: new (
332
- clone_with_replacement ( nested_expr, replacement_fn) ?,
333
- ) ) ) ,
334
- Expr :: IsNotTrue ( nested_expr) => Ok ( Expr :: IsNotTrue ( Box :: new (
335
- clone_with_replacement ( nested_expr, replacement_fn) ?,
336
- ) ) ) ,
337
- Expr :: IsNotFalse ( nested_expr) => Ok ( Expr :: IsNotFalse ( Box :: new (
338
- clone_with_replacement ( nested_expr, replacement_fn) ?,
339
- ) ) ) ,
340
- Expr :: IsNotUnknown ( nested_expr) => Ok ( Expr :: IsNotUnknown ( Box :: new (
341
- clone_with_replacement ( nested_expr, replacement_fn) ?,
342
- ) ) ) ,
343
- Expr :: Cast ( Cast { expr, data_type } ) => Ok ( Expr :: Cast ( Cast :: new (
344
- Box :: new ( clone_with_replacement ( expr, replacement_fn) ?) ,
345
- data_type. clone ( ) ,
346
- ) ) ) ,
347
- Expr :: TryCast ( TryCast {
348
- expr : nested_expr,
349
- data_type,
350
- } ) => Ok ( Expr :: TryCast ( TryCast :: new (
351
- Box :: new ( clone_with_replacement ( nested_expr, replacement_fn) ?) ,
352
- data_type. clone ( ) ,
353
- ) ) ) ,
354
- Expr :: Sort ( Sort {
355
- expr : nested_expr,
356
- asc,
357
- nulls_first,
358
- } ) => Ok ( Expr :: Sort ( Sort :: new (
359
- Box :: new ( clone_with_replacement ( nested_expr, replacement_fn) ?) ,
360
- * asc,
361
- * nulls_first,
362
- ) ) ) ,
363
- Expr :: Column { .. }
364
- | Expr :: OuterReferenceColumn ( _, _)
365
- | Expr :: Literal ( _)
366
- | Expr :: ScalarVariable ( _, _)
367
- | Expr :: Exists { .. }
368
- | Expr :: ScalarSubquery ( _) => Ok ( expr. clone ( ) ) ,
369
- Expr :: InSubquery ( InSubquery {
370
- expr : nested_expr,
371
- subquery,
372
- negated,
373
- } ) => Ok ( Expr :: InSubquery ( InSubquery :: new (
374
- Box :: new ( clone_with_replacement ( nested_expr, replacement_fn) ?) ,
375
- subquery. clone ( ) ,
376
- * negated,
377
- ) ) ) ,
378
- Expr :: Wildcard => Ok ( Expr :: Wildcard ) ,
379
- Expr :: QualifiedWildcard { .. } => Ok ( expr. clone ( ) ) ,
380
- Expr :: GetIndexedField ( GetIndexedField { expr, field } ) => {
381
- Ok ( Expr :: GetIndexedField ( GetIndexedField :: new (
382
- Box :: new ( clone_with_replacement ( expr. as_ref ( ) , replacement_fn) ?) ,
383
- field. clone ( ) ,
384
- ) ) )
385
- }
386
- Expr :: GroupingSet ( set) => match set {
387
- GroupingSet :: Rollup ( exprs) => Ok ( Expr :: GroupingSet ( GroupingSet :: Rollup (
388
- exprs
389
- . iter ( )
390
- . map ( |e| clone_with_replacement ( e, replacement_fn) )
391
- . collect :: < Result < Vec < Expr > > > ( ) ?,
392
- ) ) ) ,
393
- GroupingSet :: Cube ( exprs) => Ok ( Expr :: GroupingSet ( GroupingSet :: Cube (
394
- exprs
395
- . iter ( )
396
- . map ( |e| clone_with_replacement ( e, replacement_fn) )
397
- . collect :: < Result < Vec < Expr > > > ( ) ?,
398
- ) ) ) ,
399
- GroupingSet :: GroupingSets ( lists_of_exprs) => {
400
- let mut new_lists_of_exprs = vec ! [ ] ;
401
- for exprs in lists_of_exprs {
402
- new_lists_of_exprs. push (
403
- exprs
404
- . iter ( )
405
- . map ( |e| clone_with_replacement ( e, replacement_fn) )
406
- . collect :: < Result < Vec < Expr > > > ( ) ?,
407
- ) ;
408
- }
409
- Ok ( Expr :: GroupingSet ( GroupingSet :: GroupingSets (
410
- new_lists_of_exprs,
411
- ) ) )
412
- }
413
- } ,
414
- Expr :: Placeholder ( Placeholder { id, data_type } ) => Ok ( Expr :: Placeholder (
415
- Placeholder :: new ( id. clone ( ) , data_type. clone ( ) ) ,
416
- ) ) ,
417
- } ,
418
- }
419
- }
420
-
421
131
/// Returns mapping of each alias (`String`) to the expression (`Expr`) it is
422
132
/// aliasing.
423
133
pub ( crate ) fn extract_aliases ( exprs : & [ Expr ] ) -> HashMap < String , Expr > {
@@ -460,15 +170,15 @@ pub(crate) fn resolve_aliases_to_exprs(
460
170
expr : & Expr ,
461
171
aliases : & HashMap < String , Expr > ,
462
172
) -> Result < Expr > {
463
- clone_with_replacement ( expr, & |nested_expr| match nested_expr {
173
+ expr. clone ( ) . transform_up ( & |nested_expr| match nested_expr {
464
174
Expr :: Column ( c) if c. relation . is_none ( ) => {
465
175
if let Some ( aliased_expr) = aliases. get ( & c. name ) {
466
- Ok ( Some ( aliased_expr. clone ( ) ) )
176
+ Ok ( Transformed :: Yes ( aliased_expr. clone ( ) ) )
467
177
} else {
468
- Ok ( None )
178
+ Ok ( Transformed :: No ( Expr :: Column ( c ) ) )
469
179
}
470
180
}
471
- _ => Ok ( None ) ,
181
+ _ => Ok ( Transformed :: No ( nested_expr ) ) ,
472
182
} )
473
183
}
474
184
0 commit comments