Trait Visitor
pub trait Visitor {
type Break;
// Provided methods
fn pre_visit_query(&mut self, _query: &Query) -> ControlFlow<Self::Break> { ... }
fn post_visit_query(&mut self, _query: &Query) -> ControlFlow<Self::Break> { ... }
fn pre_visit_relation(
&mut self,
_relation: &ObjectName,
) -> ControlFlow<Self::Break> { ... }
fn post_visit_relation(
&mut self,
_relation: &ObjectName,
) -> ControlFlow<Self::Break> { ... }
fn pre_visit_table_factor(
&mut self,
_table_factor: &TableFactor,
) -> ControlFlow<Self::Break> { ... }
fn post_visit_table_factor(
&mut self,
_table_factor: &TableFactor,
) -> ControlFlow<Self::Break> { ... }
fn pre_visit_expr(&mut self, _expr: &Expr) -> ControlFlow<Self::Break> { ... }
fn post_visit_expr(&mut self, _expr: &Expr) -> ControlFlow<Self::Break> { ... }
fn pre_visit_statement(
&mut self,
_statement: &Statement,
) -> ControlFlow<Self::Break> { ... }
fn post_visit_statement(
&mut self,
_statement: &Statement,
) -> ControlFlow<Self::Break> { ... }
fn pre_visit_value(&mut self, _value: &Value) -> ControlFlow<Self::Break> { ... }
fn post_visit_value(&mut self, _value: &Value) -> ControlFlow<Self::Break> { ... }
}Expand description
A visitor that can be used to walk an AST tree.
pre_visit_ methods are invoked before visiting all children of the
node and post_visit_ methods are invoked after visiting all
children of the node.
§See also
These methods provide a more concise way of visiting nodes of a certain type:
- [visit_relations]
- [visit_expressions]
- [visit_statements]
§Example
// A structure that records statements and relations
#[derive(Default)]
struct V {
visited: Vec<String>,
}
// Visit relations and exprs before children are visited (depth first walk)
// Note you can also visit statements and visit exprs after children have been visited
impl Visitor for V {
type Break = ();
fn pre_visit_relation(&mut self, relation: &ObjectName) -> ControlFlow<Self::Break> {
self.visited.push(format!("PRE: RELATION: {}", relation));
ControlFlow::Continue(())
}
fn pre_visit_expr(&mut self, expr: &Expr) -> ControlFlow<Self::Break> {
self.visited.push(format!("PRE: EXPR: {}", expr));
ControlFlow::Continue(())
}
}
let sql = "SELECT a FROM foo where x IN (SELECT y FROM bar)";
let statements = Parser::parse_sql(&GenericDialect{}, sql)
.unwrap();
// Drive the visitor through the AST
let mut visitor = V::default();
statements.visit(&mut visitor);
// The visitor has visited statements and expressions in pre-traversal order
let expected : Vec<_> = [
"PRE: EXPR: a",
"PRE: RELATION: foo",
"PRE: EXPR: x IN (SELECT y FROM bar)",
"PRE: EXPR: x",
"PRE: EXPR: y",
"PRE: RELATION: bar",
]
.into_iter().map(|s| s.to_string()).collect();
assert_eq!(visitor.visited, expected);Required Associated Types§
type Break
type Break
Type returned when the recursion returns early.
Important note: The Break type should be kept as small as possible to prevent
stack overflow during recursion. If you need to return an error, consider
boxing it with Box to minimize stack usage.
Provided Methods§
fn pre_visit_query(&mut self, _query: &Query) -> ControlFlow<Self::Break>
fn pre_visit_query(&mut self, _query: &Query) -> ControlFlow<Self::Break>
Invoked for any queries that appear in the AST before visiting children
fn post_visit_query(&mut self, _query: &Query) -> ControlFlow<Self::Break>
fn post_visit_query(&mut self, _query: &Query) -> ControlFlow<Self::Break>
Invoked for any queries that appear in the AST after visiting children
fn pre_visit_relation(
&mut self,
_relation: &ObjectName,
) -> ControlFlow<Self::Break>
fn pre_visit_relation( &mut self, _relation: &ObjectName, ) -> ControlFlow<Self::Break>
Invoked for any relations (e.g. tables) that appear in the AST before visiting children
fn post_visit_relation(
&mut self,
_relation: &ObjectName,
) -> ControlFlow<Self::Break>
fn post_visit_relation( &mut self, _relation: &ObjectName, ) -> ControlFlow<Self::Break>
Invoked for any relations (e.g. tables) that appear in the AST after visiting children
fn pre_visit_table_factor(
&mut self,
_table_factor: &TableFactor,
) -> ControlFlow<Self::Break>
fn pre_visit_table_factor( &mut self, _table_factor: &TableFactor, ) -> ControlFlow<Self::Break>
Invoked for any table factors that appear in the AST before visiting children
fn post_visit_table_factor(
&mut self,
_table_factor: &TableFactor,
) -> ControlFlow<Self::Break>
fn post_visit_table_factor( &mut self, _table_factor: &TableFactor, ) -> ControlFlow<Self::Break>
Invoked for any table factors that appear in the AST after visiting children
fn pre_visit_expr(&mut self, _expr: &Expr) -> ControlFlow<Self::Break>
fn pre_visit_expr(&mut self, _expr: &Expr) -> ControlFlow<Self::Break>
Invoked for any expressions that appear in the AST before visiting children
fn post_visit_expr(&mut self, _expr: &Expr) -> ControlFlow<Self::Break>
fn post_visit_expr(&mut self, _expr: &Expr) -> ControlFlow<Self::Break>
Invoked for any expressions that appear in the AST
fn pre_visit_statement(
&mut self,
_statement: &Statement,
) -> ControlFlow<Self::Break>
fn pre_visit_statement( &mut self, _statement: &Statement, ) -> ControlFlow<Self::Break>
Invoked for any statements that appear in the AST before visiting children
fn post_visit_statement(
&mut self,
_statement: &Statement,
) -> ControlFlow<Self::Break>
fn post_visit_statement( &mut self, _statement: &Statement, ) -> ControlFlow<Self::Break>
Invoked for any statements that appear in the AST after visiting children
fn pre_visit_value(&mut self, _value: &Value) -> ControlFlow<Self::Break>
fn pre_visit_value(&mut self, _value: &Value) -> ControlFlow<Self::Break>
Invoked for any Value that appear in the AST before visiting children
fn post_visit_value(&mut self, _value: &Value) -> ControlFlow<Self::Break>
fn post_visit_value(&mut self, _value: &Value) -> ControlFlow<Self::Break>
Invoked for any Value that appear in the AST after visiting children