sql::ast

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> { ... }
}
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 returned when the recursion returns early.

Provided Methods§

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>

Invoked for any queries that appear in the AST after visiting children

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>

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>

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>

Invoked for any table factors that appear in the AST after visiting children

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>

Invoked for any expressions that appear in the AST

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>

Invoked for any statements that appear in the AST after visiting children

Implementors§