Function visit_expressions_mut
pub fn visit_expressions_mut<V, E, F>(v: &mut V, f: F) -> ControlFlow<E>
Expand description
Invokes the provided closure iteratively with a mutable reference to all expressions
present in v
.
This performs a depth-first search, so if the closure mutates the expression
§Example
§Remove all select limits in sub-queries
let sql = "SELECT (SELECT y FROM z LIMIT 9) FROM t LIMIT 3";
let mut statements = Parser::parse_sql(&GenericDialect{}, sql).unwrap();
// Remove all select limits in sub-queries
visit_expressions_mut(&mut statements, |expr| {
if let Expr::Subquery(q) = expr {
q.limit = None
}
ControlFlow::<()>::Continue(())
});
assert_eq!(statements[0].to_string(), "SELECT (SELECT y FROM z) FROM t LIMIT 3");
§Wrap column name in function call
This demonstrates how to effectively replace an expression with another more complicated one
that references the original. This example avoids unnecessary allocations by using the
std::mem
family of functions.
let sql = "SELECT x, y FROM t";
let mut statements = Parser::parse_sql(&GenericDialect{}, sql).unwrap();
visit_expressions_mut(&mut statements, |expr| {
if matches!(expr, Expr::Identifier(col_name) if col_name.value == "x") {
let old_expr = std::mem::replace(expr, Expr::Value(Value::Null));
*expr = Expr::Function(Function {
name: ObjectName(vec![Ident::new("f")]),
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(old_expr))],
null_treatment: None,
filter: None, over: None, distinct: false, special: false, order_by: vec![],
});
}
ControlFlow::<()>::Continue(())
});
assert_eq!(statements[0].to_string(), "SELECT f(x), y FROM t");