sqlparser/ast/
visitor.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13//! Recursive visitors for ast Nodes. See [`Visitor`] for more details.
14
15use crate::ast::{Expr, ObjectName, Statement};
16use core::ops::ControlFlow;
17
18/// A type that can be visited by a [`Visitor`]. See [`Visitor`] for
19/// recursively visiting parsed SQL statements.
20///
21/// # Note
22///
23/// This trait should be automatically derived for sqlparser AST nodes
24/// using the [Visit](sqlparser_derive::Visit) proc macro.
25///
26/// ```text
27/// #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
28/// ```
29pub trait Visit {
30    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break>;
31}
32
33/// A type that can be visited by a [`VisitorMut`]. See [`VisitorMut`] for
34/// recursively visiting parsed SQL statements.
35///
36/// # Note
37///
38/// This trait should be automatically derived for sqlparser AST nodes
39/// using the [VisitMut](sqlparser_derive::VisitMut) proc macro.
40///
41/// ```text
42/// #[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
43/// ```
44pub trait VisitMut {
45    fn visit<V: VisitorMut>(&mut self, visitor: &mut V) -> ControlFlow<V::Break>;
46}
47
48impl<T: Visit> Visit for Option<T> {
49    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
50        if let Some(s) = self {
51            s.visit(visitor)?;
52        }
53        ControlFlow::Continue(())
54    }
55}
56
57impl<T: Visit> Visit for Vec<T> {
58    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
59        for v in self {
60            v.visit(visitor)?;
61        }
62        ControlFlow::Continue(())
63    }
64}
65
66impl<T: Visit> Visit for Box<T> {
67    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
68        T::visit(self, visitor)
69    }
70}
71
72impl<T: VisitMut> VisitMut for Option<T> {
73    fn visit<V: VisitorMut>(&mut self, visitor: &mut V) -> ControlFlow<V::Break> {
74        if let Some(s) = self {
75            s.visit(visitor)?;
76        }
77        ControlFlow::Continue(())
78    }
79}
80
81impl<T: VisitMut> VisitMut for Vec<T> {
82    fn visit<V: VisitorMut>(&mut self, visitor: &mut V) -> ControlFlow<V::Break> {
83        for v in self {
84            v.visit(visitor)?;
85        }
86        ControlFlow::Continue(())
87    }
88}
89
90impl<T: VisitMut> VisitMut for Box<T> {
91    fn visit<V: VisitorMut>(&mut self, visitor: &mut V) -> ControlFlow<V::Break> {
92        T::visit(self, visitor)
93    }
94}
95
96macro_rules! visit_noop {
97    ($($t:ty),+) => {
98        $(impl Visit for $t {
99            fn visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
100               ControlFlow::Continue(())
101            }
102        })+
103        $(impl VisitMut for $t {
104            fn visit<V: VisitorMut>(&mut self, _visitor: &mut V) -> ControlFlow<V::Break> {
105               ControlFlow::Continue(())
106            }
107        })+
108    };
109}
110
111visit_noop!(u8, u16, u32, u64, i8, i16, i32, i64, char, bool, String);
112
113#[cfg(feature = "bigdecimal")]
114visit_noop!(bigdecimal::BigDecimal);
115
116/// A visitor that can be used to walk an AST tree.
117///
118/// `previst_` methods are invoked before visiting all children of the
119/// node and `postvisit_` methods are invoked after visiting all
120/// children of the node.
121///
122/// # See also
123///
124/// These methods provide a more concise way of visiting nodes of a certain type:
125/// * [visit_relations]
126/// * [visit_expressions]
127/// * [visit_statements]
128///
129/// # Example
130/// ```
131/// # use sqlparser::parser::Parser;
132/// # use sqlparser::dialect::GenericDialect;
133/// # use sqlparser::ast::{Visit, Visitor, ObjectName, Expr};
134/// # use core::ops::ControlFlow;
135/// // A structure that records statements and relations
136/// #[derive(Default)]
137/// struct V {
138///    visited: Vec<String>,
139/// }
140///
141/// // Visit relations and exprs before children are visited (depth first walk)
142/// // Note you can also visit statements and visit exprs after children have been visitoed
143/// impl Visitor for V {
144///   type Break = ();
145///
146///   fn pre_visit_relation(&mut self, relation: &ObjectName) -> ControlFlow<Self::Break> {
147///     self.visited.push(format!("PRE: RELATION: {}", relation));
148///     ControlFlow::Continue(())
149///   }
150///
151///   fn pre_visit_expr(&mut self, expr: &Expr) -> ControlFlow<Self::Break> {
152///     self.visited.push(format!("PRE: EXPR: {}", expr));
153///     ControlFlow::Continue(())
154///   }
155/// }
156///
157/// let sql = "SELECT a FROM foo where x IN (SELECT y FROM bar)";
158/// let statements = Parser::parse_sql(&GenericDialect{}, sql)
159///    .unwrap();
160///
161/// // Drive the visitor through the AST
162/// let mut visitor = V::default();
163/// statements.visit(&mut visitor);
164///
165/// // The visitor has visited statements and expressions in pre-traversal order
166/// let expected : Vec<_> = [
167///   "PRE: EXPR: a",
168///   "PRE: RELATION: foo",
169///   "PRE: EXPR: x IN (SELECT y FROM bar)",
170///   "PRE: EXPR: x",
171///   "PRE: EXPR: y",
172///   "PRE: RELATION: bar",
173/// ]
174///   .into_iter().map(|s| s.to_string()).collect();
175///
176/// assert_eq!(visitor.visited, expected);
177/// ```
178pub trait Visitor {
179    /// Type returned when the recursion returns early.
180    type Break;
181
182    /// Invoked for any relations (e.g. tables) that appear in the AST before visiting children
183    fn pre_visit_relation(&mut self, _relation: &ObjectName) -> ControlFlow<Self::Break> {
184        ControlFlow::Continue(())
185    }
186
187    /// Invoked for any relations (e.g. tables) that appear in the AST after visiting children
188    fn post_visit_relation(&mut self, _relation: &ObjectName) -> ControlFlow<Self::Break> {
189        ControlFlow::Continue(())
190    }
191
192    /// Invoked for any expressions that appear in the AST before visiting children
193    fn pre_visit_expr(&mut self, _expr: &Expr) -> ControlFlow<Self::Break> {
194        ControlFlow::Continue(())
195    }
196
197    /// Invoked for any expressions that appear in the AST
198    fn post_visit_expr(&mut self, _expr: &Expr) -> ControlFlow<Self::Break> {
199        ControlFlow::Continue(())
200    }
201
202    /// Invoked for any statements that appear in the AST before visiting children
203    fn pre_visit_statement(&mut self, _statement: &Statement) -> ControlFlow<Self::Break> {
204        ControlFlow::Continue(())
205    }
206
207    /// Invoked for any statements that appear in the AST after visiting children
208    fn post_visit_statement(&mut self, _statement: &Statement) -> ControlFlow<Self::Break> {
209        ControlFlow::Continue(())
210    }
211}
212
213/// A visitor that can be used to mutate an AST tree.
214///
215/// `previst_` methods are invoked before visiting all children of the
216/// node and `postvisit_` methods are invoked after visiting all
217/// children of the node.
218///
219/// # See also
220///
221/// These methods provide a more concise way of visiting nodes of a certain type:
222/// * [visit_relations_mut]
223/// * [visit_expressions_mut]
224/// * [visit_statements_mut]
225///
226/// # Example
227/// ```
228/// # use sqlparser::parser::Parser;
229/// # use sqlparser::dialect::GenericDialect;
230/// # use sqlparser::ast::{VisitMut, VisitorMut, ObjectName, Expr, Ident};
231/// # use core::ops::ControlFlow;
232///
233/// // A visitor that replaces "to_replace" with "replaced" in all expressions
234/// struct Replacer;
235///
236/// // Visit each expression after its children have been visited
237/// impl VisitorMut for Replacer {
238///   type Break = ();
239///
240///   fn post_visit_expr(&mut self, expr: &mut Expr) -> ControlFlow<Self::Break> {
241///     if let Expr::Identifier(Ident{ value, ..}) = expr {
242///         *value = value.replace("to_replace", "replaced")
243///     }
244///     ControlFlow::Continue(())
245///   }
246/// }
247///
248/// let sql = "SELECT to_replace FROM foo where to_replace IN (SELECT to_replace FROM bar)";
249/// let mut statements = Parser::parse_sql(&GenericDialect{}, sql).unwrap();
250///
251/// // Drive the visitor through the AST
252/// statements.visit(&mut Replacer);
253///
254/// assert_eq!(statements[0].to_string(), "SELECT replaced FROM foo WHERE replaced IN (SELECT replaced FROM bar)");
255/// ```
256pub trait VisitorMut {
257    /// Type returned when the recursion returns early.
258    type Break;
259
260    /// Invoked for any relations (e.g. tables) that appear in the AST before visiting children
261    fn pre_visit_relation(&mut self, _relation: &mut ObjectName) -> ControlFlow<Self::Break> {
262        ControlFlow::Continue(())
263    }
264
265    /// Invoked for any relations (e.g. tables) that appear in the AST after visiting children
266    fn post_visit_relation(&mut self, _relation: &mut ObjectName) -> ControlFlow<Self::Break> {
267        ControlFlow::Continue(())
268    }
269
270    /// Invoked for any expressions that appear in the AST before visiting children
271    fn pre_visit_expr(&mut self, _expr: &mut Expr) -> ControlFlow<Self::Break> {
272        ControlFlow::Continue(())
273    }
274
275    /// Invoked for any expressions that appear in the AST
276    fn post_visit_expr(&mut self, _expr: &mut Expr) -> ControlFlow<Self::Break> {
277        ControlFlow::Continue(())
278    }
279
280    /// Invoked for any statements that appear in the AST before visiting children
281    fn pre_visit_statement(&mut self, _statement: &mut Statement) -> ControlFlow<Self::Break> {
282        ControlFlow::Continue(())
283    }
284
285    /// Invoked for any statements that appear in the AST after visiting children
286    fn post_visit_statement(&mut self, _statement: &mut Statement) -> ControlFlow<Self::Break> {
287        ControlFlow::Continue(())
288    }
289}
290
291struct RelationVisitor<F>(F);
292
293impl<E, F: FnMut(&ObjectName) -> ControlFlow<E>> Visitor for RelationVisitor<F> {
294    type Break = E;
295
296    fn pre_visit_relation(&mut self, relation: &ObjectName) -> ControlFlow<Self::Break> {
297        self.0(relation)
298    }
299}
300
301impl<E, F: FnMut(&mut ObjectName) -> ControlFlow<E>> VisitorMut for RelationVisitor<F> {
302    type Break = E;
303
304    fn post_visit_relation(&mut self, relation: &mut ObjectName) -> ControlFlow<Self::Break> {
305        self.0(relation)
306    }
307}
308
309/// Invokes the provided closure on all relations (e.g. table names) present in `v`
310///
311/// # Example
312/// ```
313/// # use sqlparser::parser::Parser;
314/// # use sqlparser::dialect::GenericDialect;
315/// # use sqlparser::ast::{visit_relations};
316/// # use core::ops::ControlFlow;
317/// let sql = "SELECT a FROM foo where x IN (SELECT y FROM bar)";
318/// let statements = Parser::parse_sql(&GenericDialect{}, sql)
319///    .unwrap();
320///
321/// // visit statements, capturing relations (table names)
322/// let mut visited = vec![];
323/// visit_relations(&statements, |relation| {
324///   visited.push(format!("RELATION: {}", relation));
325///   ControlFlow::<()>::Continue(())
326/// });
327///
328/// let expected : Vec<_> = [
329///   "RELATION: foo",
330///   "RELATION: bar",
331/// ]
332///   .into_iter().map(|s| s.to_string()).collect();
333///
334/// assert_eq!(visited, expected);
335/// ```
336pub fn visit_relations<V, E, F>(v: &V, f: F) -> ControlFlow<E>
337where
338    V: Visit,
339    F: FnMut(&ObjectName) -> ControlFlow<E>,
340{
341    let mut visitor = RelationVisitor(f);
342    v.visit(&mut visitor)?;
343    ControlFlow::Continue(())
344}
345
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.
350///
351/// # Example
352/// ```
353/// # use sqlparser::parser::Parser;
354/// # use sqlparser::dialect::GenericDialect;
355/// # use sqlparser::ast::{ObjectName, visit_relations_mut};
356/// # use core::ops::ControlFlow;
357/// let sql = "SELECT a FROM foo";
358/// let mut statements = Parser::parse_sql(&GenericDialect{}, sql)
359///    .unwrap();
360///
361/// // visit statements, renaming table foo to bar
362/// visit_relations_mut(&mut statements, |table| {
363///   table.0[0].value = table.0[0].value.replace("foo", "bar");
364///   ControlFlow::<()>::Continue(())
365/// });
366///
367/// assert_eq!(statements[0].to_string(), "SELECT a FROM bar");
368/// ```
369pub fn visit_relations_mut<V, E, F>(v: &mut V, f: F) -> ControlFlow<E>
370where
371    V: VisitMut,
372    F: FnMut(&mut ObjectName) -> ControlFlow<E>,
373{
374    let mut visitor = RelationVisitor(f);
375    v.visit(&mut visitor)?;
376    ControlFlow::Continue(())
377}
378
379struct ExprVisitor<F>(F);
380
381impl<E, F: FnMut(&Expr) -> ControlFlow<E>> Visitor for ExprVisitor<F> {
382    type Break = E;
383
384    fn pre_visit_expr(&mut self, expr: &Expr) -> ControlFlow<Self::Break> {
385        self.0(expr)
386    }
387}
388
389impl<E, F: FnMut(&mut Expr) -> ControlFlow<E>> VisitorMut for ExprVisitor<F> {
390    type Break = E;
391
392    fn post_visit_expr(&mut self, expr: &mut Expr) -> ControlFlow<Self::Break> {
393        self.0(expr)
394    }
395}
396
397/// Invokes the provided closure on all expressions (e.g. `1 + 2`) present in `v`
398///
399/// # Example
400/// ```
401/// # use sqlparser::parser::Parser;
402/// # use sqlparser::dialect::GenericDialect;
403/// # use sqlparser::ast::{visit_expressions};
404/// # use core::ops::ControlFlow;
405/// let sql = "SELECT a FROM foo where x IN (SELECT y FROM bar)";
406/// let statements = Parser::parse_sql(&GenericDialect{}, sql)
407///    .unwrap();
408///
409/// // visit all expressions
410/// let mut visited = vec![];
411/// visit_expressions(&statements, |expr| {
412///   visited.push(format!("EXPR: {}", expr));
413///   ControlFlow::<()>::Continue(())
414/// });
415///
416/// let expected : Vec<_> = [
417///   "EXPR: a",
418///   "EXPR: x IN (SELECT y FROM bar)",
419///   "EXPR: x",
420///   "EXPR: y",
421/// ]
422///   .into_iter().map(|s| s.to_string()).collect();
423///
424/// assert_eq!(visited, expected);
425/// ```
426pub fn visit_expressions<V, E, F>(v: &V, f: F) -> ControlFlow<E>
427where
428    V: Visit,
429    F: FnMut(&Expr) -> ControlFlow<E>,
430{
431    let mut visitor = ExprVisitor(f);
432    v.visit(&mut visitor)?;
433    ControlFlow::Continue(())
434}
435
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
440///
441/// # Example
442///
443/// ## Remove all select limits in sub-queries
444/// ```
445/// # use sqlparser::parser::Parser;
446/// # use sqlparser::dialect::GenericDialect;
447/// # use sqlparser::ast::{Expr, visit_expressions_mut, visit_statements_mut};
448/// # use core::ops::ControlFlow;
449/// let sql = "SELECT (SELECT y FROM z LIMIT 9) FROM t LIMIT 3";
450/// let mut statements = Parser::parse_sql(&GenericDialect{}, sql).unwrap();
451///
452/// // Remove all select limits in sub-queries
453/// visit_expressions_mut(&mut statements, |expr| {
454///   if let Expr::Subquery(q) = expr {
455///      q.limit = None
456///   }
457///   ControlFlow::<()>::Continue(())
458/// });
459///
460/// assert_eq!(statements[0].to_string(), "SELECT (SELECT y FROM z) FROM t LIMIT 3");
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/// ```
491pub fn visit_expressions_mut<V, E, F>(v: &mut V, f: F) -> ControlFlow<E>
492where
493    V: VisitMut,
494    F: FnMut(&mut Expr) -> ControlFlow<E>,
495{
496    v.visit(&mut ExprVisitor(f))?;
497    ControlFlow::Continue(())
498}
499
500struct StatementVisitor<F>(F);
501
502impl<E, F: FnMut(&Statement) -> ControlFlow<E>> Visitor for StatementVisitor<F> {
503    type Break = E;
504
505    fn pre_visit_statement(&mut self, statement: &Statement) -> ControlFlow<Self::Break> {
506        self.0(statement)
507    }
508}
509
510impl<E, F: FnMut(&mut Statement) -> ControlFlow<E>> VisitorMut for StatementVisitor<F> {
511    type Break = E;
512
513    fn post_visit_statement(&mut self, statement: &mut Statement) -> ControlFlow<Self::Break> {
514        self.0(statement)
515    }
516}
517
518/// Invokes the provided closure iteratively with a mutable reference to all statements
519/// present in `v` (e.g. `SELECT`, `CREATE TABLE`, etc).
520///
521/// # Example
522/// ```
523/// # use sqlparser::parser::Parser;
524/// # use sqlparser::dialect::GenericDialect;
525/// # use sqlparser::ast::{visit_statements};
526/// # use core::ops::ControlFlow;
527/// let sql = "SELECT a FROM foo where x IN (SELECT y FROM bar); CREATE TABLE baz(q int)";
528/// let statements = Parser::parse_sql(&GenericDialect{}, sql)
529///    .unwrap();
530///
531/// // visit all statements
532/// let mut visited = vec![];
533/// visit_statements(&statements, |stmt| {
534///   visited.push(format!("STATEMENT: {}", stmt));
535///   ControlFlow::<()>::Continue(())
536/// });
537///
538/// let expected : Vec<_> = [
539///   "STATEMENT: SELECT a FROM foo WHERE x IN (SELECT y FROM bar)",
540///   "STATEMENT: CREATE TABLE baz (q INT)"
541/// ]
542///   .into_iter().map(|s| s.to_string()).collect();
543///
544/// assert_eq!(visited, expected);
545/// ```
546pub fn visit_statements<V, E, F>(v: &V, f: F) -> ControlFlow<E>
547where
548    V: Visit,
549    F: FnMut(&Statement) -> ControlFlow<E>,
550{
551    let mut visitor = StatementVisitor(f);
552    v.visit(&mut visitor)?;
553    ControlFlow::Continue(())
554}
555
556/// Invokes the provided closure on all statements (e.g. `SELECT`, `CREATE TABLE`, etc) present in `v`
557///
558/// # Example
559/// ```
560/// # use sqlparser::parser::Parser;
561/// # use sqlparser::dialect::GenericDialect;
562/// # use sqlparser::ast::{Statement, visit_statements_mut};
563/// # use core::ops::ControlFlow;
564/// let sql = "SELECT x FROM foo LIMIT 9+$limit; SELECT * FROM t LIMIT f()";
565/// let mut statements = Parser::parse_sql(&GenericDialect{}, sql).unwrap();
566///
567/// // Remove all select limits in outer statements (not in sub-queries)
568/// visit_statements_mut(&mut statements, |stmt| {
569///   if let Statement::Query(q) = stmt {
570///      q.limit = None
571///   }
572///   ControlFlow::<()>::Continue(())
573/// });
574///
575/// assert_eq!(statements[0].to_string(), "SELECT x FROM foo");
576/// assert_eq!(statements[1].to_string(), "SELECT * FROM t");
577/// ```
578pub fn visit_statements_mut<V, E, F>(v: &mut V, f: F) -> ControlFlow<E>
579where
580    V: VisitMut,
581    F: FnMut(&mut Statement) -> ControlFlow<E>,
582{
583    v.visit(&mut StatementVisitor(f))?;
584    ControlFlow::Continue(())
585}
586
587#[cfg(test)]
588mod tests {
589    use super::*;
590    use crate::dialect::GenericDialect;
591    use crate::parser::Parser;
592    use crate::tokenizer::Tokenizer;
593
594    #[derive(Default)]
595    struct TestVisitor {
596        visited: Vec<String>,
597    }
598
599    impl Visitor for TestVisitor {
600        type Break = ();
601
602        fn pre_visit_relation(&mut self, relation: &ObjectName) -> ControlFlow<Self::Break> {
603            self.visited.push(format!("PRE: RELATION: {relation}"));
604            ControlFlow::Continue(())
605        }
606
607        fn post_visit_relation(&mut self, relation: &ObjectName) -> ControlFlow<Self::Break> {
608            self.visited.push(format!("POST: RELATION: {relation}"));
609            ControlFlow::Continue(())
610        }
611
612        fn pre_visit_expr(&mut self, expr: &Expr) -> ControlFlow<Self::Break> {
613            self.visited.push(format!("PRE: EXPR: {expr}"));
614            ControlFlow::Continue(())
615        }
616
617        fn post_visit_expr(&mut self, expr: &Expr) -> ControlFlow<Self::Break> {
618            self.visited.push(format!("POST: EXPR: {expr}"));
619            ControlFlow::Continue(())
620        }
621
622        fn pre_visit_statement(&mut self, statement: &Statement) -> ControlFlow<Self::Break> {
623            self.visited.push(format!("PRE: STATEMENT: {statement}"));
624            ControlFlow::Continue(())
625        }
626
627        fn post_visit_statement(&mut self, statement: &Statement) -> ControlFlow<Self::Break> {
628            self.visited.push(format!("POST: STATEMENT: {statement}"));
629            ControlFlow::Continue(())
630        }
631    }
632
633    fn do_visit(sql: &str) -> Vec<String> {
634        let dialect = GenericDialect {};
635        let mut tokenizer = Tokenizer::new(&dialect, sql);
636        let tokens = tokenizer.tokenize().unwrap();
637        let s = Parser::new(&dialect)
638            .with_tokens(tokens)
639            .parse_statement()
640            .unwrap();
641
642        let mut visitor = TestVisitor::default();
643        s.visit(&mut visitor);
644        visitor.visited
645    }
646
647    #[test]
648    fn test_sql() {
649        let tests = vec![
650            (
651                "SELECT * from table_name",
652                vec![
653                    "PRE: STATEMENT: SELECT * FROM table_name",
654                    "PRE: RELATION: table_name",
655                    "POST: RELATION: table_name",
656                    "POST: STATEMENT: SELECT * FROM table_name",
657                ],
658            ),
659            (
660                "SELECT * from t1 join t2 on t1.id = t2.t1_id",
661                vec![
662                    "PRE: STATEMENT: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id",
663                    "PRE: RELATION: t1",
664                    "POST: RELATION: t1",
665                    "PRE: RELATION: t2",
666                    "POST: RELATION: t2",
667                    "PRE: EXPR: t1.id = t2.t1_id",
668                    "PRE: EXPR: t1.id",
669                    "POST: EXPR: t1.id",
670                    "PRE: EXPR: t2.t1_id",
671                    "POST: EXPR: t2.t1_id",
672                    "POST: EXPR: t1.id = t2.t1_id",
673                    "POST: STATEMENT: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id",
674                ],
675            ),
676            (
677                "SELECT * from t1 where EXISTS(SELECT column from t2)",
678                vec![
679                    "PRE: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
680                    "PRE: RELATION: t1",
681                    "POST: RELATION: t1",
682                    "PRE: EXPR: EXISTS (SELECT column FROM t2)",
683                    "PRE: EXPR: column",
684                    "POST: EXPR: column",
685                    "PRE: RELATION: t2",
686                    "POST: RELATION: t2",
687                    "POST: EXPR: EXISTS (SELECT column FROM t2)",
688                    "POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
689                ],
690            ),
691            (
692                "SELECT * from t1 where EXISTS(SELECT column from t2)",
693                vec![
694                    "PRE: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
695                    "PRE: RELATION: t1",
696                    "POST: RELATION: t1",
697                    "PRE: EXPR: EXISTS (SELECT column FROM t2)",
698                    "PRE: EXPR: column",
699                    "POST: EXPR: column",
700                    "PRE: RELATION: t2",
701                    "POST: RELATION: t2",
702                    "POST: EXPR: EXISTS (SELECT column FROM t2)",
703                    "POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
704                ],
705            ),
706            (
707                "SELECT * from t1 where EXISTS(SELECT column from t2) UNION SELECT * from t3",
708                vec![
709                    "PRE: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3",
710                    "PRE: RELATION: t1",
711                    "POST: RELATION: t1",
712                    "PRE: EXPR: EXISTS (SELECT column FROM t2)",
713                    "PRE: EXPR: column",
714                    "POST: EXPR: column",
715                    "PRE: RELATION: t2",
716                    "POST: RELATION: t2",
717                    "POST: EXPR: EXISTS (SELECT column FROM t2)",
718                    "PRE: RELATION: t3",
719                    "POST: RELATION: t3",
720                    "POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3",
721                ],
722            ),
723        ];
724        for (sql, expected) in tests {
725            let actual = do_visit(sql);
726            let actual: Vec<_> = actual.iter().map(|x| x.as_str()).collect();
727            assert_eq!(actual, expected)
728        }
729    }
730}