@@ -301,7 +301,7 @@ impl<E, F: FnMut(&ObjectName) -> ControlFlow<E>> Visitor for RelationVisitor<F>
301
301
impl < E , F : FnMut ( & mut ObjectName ) -> ControlFlow < E > > VisitorMut for RelationVisitor < F > {
302
302
type Break = E ;
303
303
304
- fn pre_visit_relation ( & mut self , relation : & mut ObjectName ) -> ControlFlow < Self :: Break > {
304
+ fn post_visit_relation ( & mut self , relation : & mut ObjectName ) -> ControlFlow < Self :: Break > {
305
305
self . 0 ( relation)
306
306
}
307
307
}
@@ -343,7 +343,10 @@ where
343
343
ControlFlow :: Continue ( ( ) )
344
344
}
345
345
346
- /// Invokes the provided closure on all relations (e.g. table names) present in `v`
346
+ /// Invokes the provided closure with a mutable reference to all relations (e.g. table names)
347
+ /// present in `v`.
348
+ ///
349
+ /// When the closure mutates its argument, the new mutated relation will not be visited again.
347
350
///
348
351
/// # Example
349
352
/// ```
@@ -386,7 +389,7 @@ impl<E, F: FnMut(&Expr) -> ControlFlow<E>> Visitor for ExprVisitor<F> {
386
389
impl < E , F : FnMut ( & mut Expr ) -> ControlFlow < E > > VisitorMut for ExprVisitor < F > {
387
390
type Break = E ;
388
391
389
- fn pre_visit_expr ( & mut self , expr : & mut Expr ) -> ControlFlow < Self :: Break > {
392
+ fn post_visit_expr ( & mut self , expr : & mut Expr ) -> ControlFlow < Self :: Break > {
390
393
self . 0 ( expr)
391
394
}
392
395
}
@@ -430,9 +433,14 @@ where
430
433
ControlFlow :: Continue ( ( ) )
431
434
}
432
435
433
- /// Invokes the provided closure on all expressions present in `v`
436
+ /// Invokes the provided closure iteratively with a mutable reference to all expressions
437
+ /// present in `v`.
438
+ ///
439
+ /// This performs a depth-first search, so if the closure mutates the expression
434
440
///
435
441
/// # Example
442
+ ///
443
+ /// ## Remove all select limits in sub-queries
436
444
/// ```
437
445
/// # use sqlparser::parser::Parser;
438
446
/// # use sqlparser::dialect::GenericDialect;
@@ -451,6 +459,35 @@ where
451
459
///
452
460
/// assert_eq!(statements[0].to_string(), "SELECT (SELECT y FROM z) FROM t LIMIT 3");
453
461
/// ```
462
+ ///
463
+ /// ## Wrap column name in function call
464
+ ///
465
+ /// This demonstrates how to effectively replace an expression with another more complicated one
466
+ /// that references the original. This example avoids unnecessary allocations by using the
467
+ /// [`std::mem`](std::mem) family of functions.
468
+ ///
469
+ /// ```
470
+ /// # use sqlparser::parser::Parser;
471
+ /// # use sqlparser::dialect::GenericDialect;
472
+ /// # use sqlparser::ast::{Expr, Function, FunctionArg, FunctionArgExpr, Ident, ObjectName, Value, visit_expressions_mut, visit_statements_mut};
473
+ /// # use core::ops::ControlFlow;
474
+ /// let sql = "SELECT x, y FROM t";
475
+ /// let mut statements = Parser::parse_sql(&GenericDialect{}, sql).unwrap();
476
+ ///
477
+ /// visit_expressions_mut(&mut statements, |expr| {
478
+ /// if matches!(expr, Expr::Identifier(col_name) if col_name.value == "x") {
479
+ /// let old_expr = std::mem::replace(expr, Expr::Value(Value::Null));
480
+ /// *expr = Expr::Function(Function {
481
+ /// name: ObjectName(vec![Ident::new("f")]),
482
+ /// args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(old_expr))],
483
+ /// over: None, distinct: false, special: false,
484
+ /// });
485
+ /// }
486
+ /// ControlFlow::<()>::Continue(())
487
+ /// });
488
+ ///
489
+ /// assert_eq!(statements[0].to_string(), "SELECT f(x), y FROM t");
490
+ /// ```
454
491
pub fn visit_expressions_mut < V , E , F > ( v : & mut V , f : F ) -> ControlFlow < E >
455
492
where
456
493
V : VisitMut ,
@@ -473,12 +510,13 @@ impl<E, F: FnMut(&Statement) -> ControlFlow<E>> Visitor for StatementVisitor<F>
473
510
impl < E , F : FnMut ( & mut Statement ) -> ControlFlow < E > > VisitorMut for StatementVisitor < F > {
474
511
type Break = E ;
475
512
476
- fn pre_visit_statement ( & mut self , statement : & mut Statement ) -> ControlFlow < Self :: Break > {
513
+ fn post_visit_statement ( & mut self , statement : & mut Statement ) -> ControlFlow < Self :: Break > {
477
514
self . 0 ( statement)
478
515
}
479
516
}
480
517
481
- /// Invokes the provided closure on all statements (e.g. `SELECT`, `CREATE TABLE`, etc) present in `v`
518
+ /// Invokes the provided closure iteratively with a mutable reference to all statements
519
+ /// present in `v` (e.g. `SELECT`, `CREATE TABLE`, etc).
482
520
///
483
521
/// # Example
484
522
/// ```
0 commit comments