1use crate::ast::{Expr, ObjectName, Query, Statement, TableFactor, Value};
21use core::ops::ControlFlow;
22
23pub trait Visit {
35 fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break>;
40}
41
42pub trait VisitMut {
54 fn visit<V: VisitorMut>(&mut self, visitor: &mut V) -> ControlFlow<V::Break>;
60}
61
62impl<T: Visit> Visit for Option<T> {
63 fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
64 if let Some(s) = self {
65 s.visit(visitor)?;
66 }
67 ControlFlow::Continue(())
68 }
69}
70
71impl<T: Visit> Visit for Vec<T> {
72 fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
73 for v in self {
74 v.visit(visitor)?;
75 }
76 ControlFlow::Continue(())
77 }
78}
79
80impl<T: Visit> Visit for Box<T> {
81 fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
82 T::visit(self, visitor)
83 }
84}
85
86impl<T: VisitMut> VisitMut for Option<T> {
87 fn visit<V: VisitorMut>(&mut self, visitor: &mut V) -> ControlFlow<V::Break> {
88 if let Some(s) = self {
89 s.visit(visitor)?;
90 }
91 ControlFlow::Continue(())
92 }
93}
94
95impl<T: VisitMut> VisitMut for Vec<T> {
96 fn visit<V: VisitorMut>(&mut self, visitor: &mut V) -> ControlFlow<V::Break> {
97 for v in self {
98 v.visit(visitor)?;
99 }
100 ControlFlow::Continue(())
101 }
102}
103
104impl<T: VisitMut> VisitMut for Box<T> {
105 fn visit<V: VisitorMut>(&mut self, visitor: &mut V) -> ControlFlow<V::Break> {
106 T::visit(self, visitor)
107 }
108}
109
110macro_rules! visit_noop {
111 ($($t:ty),+) => {
112 $(impl Visit for $t {
113 fn visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
114 ControlFlow::Continue(())
115 }
116 })+
117 $(impl VisitMut for $t {
118 fn visit<V: VisitorMut>(&mut self, _visitor: &mut V) -> ControlFlow<V::Break> {
119 ControlFlow::Continue(())
120 }
121 })+
122 };
123}
124
125impl Visit for String {
fn visit<V: Visitor>(&self, _visitor: &mut V) -> ControlFlow<V::Break> {
ControlFlow::Continue(())
}
}
impl VisitMut for u8 {
fn visit<V: VisitorMut>(&mut self, _visitor: &mut V)
-> ControlFlow<V::Break> {
ControlFlow::Continue(())
}
}
impl VisitMut for u16 {
fn visit<V: VisitorMut>(&mut self, _visitor: &mut V)
-> ControlFlow<V::Break> {
ControlFlow::Continue(())
}
}
impl VisitMut for u32 {
fn visit<V: VisitorMut>(&mut self, _visitor: &mut V)
-> ControlFlow<V::Break> {
ControlFlow::Continue(())
}
}
impl VisitMut for u64 {
fn visit<V: VisitorMut>(&mut self, _visitor: &mut V)
-> ControlFlow<V::Break> {
ControlFlow::Continue(())
}
}
impl VisitMut for i8 {
fn visit<V: VisitorMut>(&mut self, _visitor: &mut V)
-> ControlFlow<V::Break> {
ControlFlow::Continue(())
}
}
impl VisitMut for i16 {
fn visit<V: VisitorMut>(&mut self, _visitor: &mut V)
-> ControlFlow<V::Break> {
ControlFlow::Continue(())
}
}
impl VisitMut for i32 {
fn visit<V: VisitorMut>(&mut self, _visitor: &mut V)
-> ControlFlow<V::Break> {
ControlFlow::Continue(())
}
}
impl VisitMut for i64 {
fn visit<V: VisitorMut>(&mut self, _visitor: &mut V)
-> ControlFlow<V::Break> {
ControlFlow::Continue(())
}
}
impl VisitMut for char {
fn visit<V: VisitorMut>(&mut self, _visitor: &mut V)
-> ControlFlow<V::Break> {
ControlFlow::Continue(())
}
}
impl VisitMut for bool {
fn visit<V: VisitorMut>(&mut self, _visitor: &mut V)
-> ControlFlow<V::Break> {
ControlFlow::Continue(())
}
}
impl VisitMut for String {
fn visit<V: VisitorMut>(&mut self, _visitor: &mut V)
-> ControlFlow<V::Break> {
ControlFlow::Continue(())
}
}visit_noop!(u8, u16, u32, u64, i8, i16, i32, i64, char, bool, String);
126
127#[cfg(feature = "bigdecimal")]
128visit_noop!(bigdecimal::BigDecimal);
129
130pub trait Visitor {
193 type Break;
199
200 fn pre_visit_query(&mut self, _query: &Query) -> ControlFlow<Self::Break> {
202 ControlFlow::Continue(())
203 }
204
205 fn post_visit_query(&mut self, _query: &Query) -> ControlFlow<Self::Break> {
207 ControlFlow::Continue(())
208 }
209
210 fn pre_visit_relation(&mut self, _relation: &ObjectName) -> ControlFlow<Self::Break> {
212 ControlFlow::Continue(())
213 }
214
215 fn post_visit_relation(&mut self, _relation: &ObjectName) -> ControlFlow<Self::Break> {
217 ControlFlow::Continue(())
218 }
219
220 fn pre_visit_table_factor(&mut self, _table_factor: &TableFactor) -> ControlFlow<Self::Break> {
222 ControlFlow::Continue(())
223 }
224
225 fn post_visit_table_factor(&mut self, _table_factor: &TableFactor) -> ControlFlow<Self::Break> {
227 ControlFlow::Continue(())
228 }
229
230 fn pre_visit_expr(&mut self, _expr: &Expr) -> ControlFlow<Self::Break> {
232 ControlFlow::Continue(())
233 }
234
235 fn post_visit_expr(&mut self, _expr: &Expr) -> ControlFlow<Self::Break> {
237 ControlFlow::Continue(())
238 }
239
240 fn pre_visit_statement(&mut self, _statement: &Statement) -> ControlFlow<Self::Break> {
242 ControlFlow::Continue(())
243 }
244
245 fn post_visit_statement(&mut self, _statement: &Statement) -> ControlFlow<Self::Break> {
247 ControlFlow::Continue(())
248 }
249
250 fn pre_visit_value(&mut self, _value: &Value) -> ControlFlow<Self::Break> {
252 ControlFlow::Continue(())
253 }
254
255 fn post_visit_value(&mut self, _value: &Value) -> ControlFlow<Self::Break> {
257 ControlFlow::Continue(())
258 }
259}
260
261pub trait VisitorMut {
305 type Break;
311
312 fn pre_visit_query(&mut self, _query: &mut Query) -> ControlFlow<Self::Break> {
314 ControlFlow::Continue(())
315 }
316
317 fn post_visit_query(&mut self, _query: &mut Query) -> ControlFlow<Self::Break> {
319 ControlFlow::Continue(())
320 }
321
322 fn pre_visit_relation(&mut self, _relation: &mut ObjectName) -> ControlFlow<Self::Break> {
324 ControlFlow::Continue(())
325 }
326
327 fn post_visit_relation(&mut self, _relation: &mut ObjectName) -> ControlFlow<Self::Break> {
329 ControlFlow::Continue(())
330 }
331
332 fn pre_visit_table_factor(
334 &mut self,
335 _table_factor: &mut TableFactor,
336 ) -> ControlFlow<Self::Break> {
337 ControlFlow::Continue(())
338 }
339
340 fn post_visit_table_factor(
342 &mut self,
343 _table_factor: &mut TableFactor,
344 ) -> ControlFlow<Self::Break> {
345 ControlFlow::Continue(())
346 }
347
348 fn pre_visit_expr(&mut self, _expr: &mut Expr) -> ControlFlow<Self::Break> {
350 ControlFlow::Continue(())
351 }
352
353 fn post_visit_expr(&mut self, _expr: &mut Expr) -> ControlFlow<Self::Break> {
355 ControlFlow::Continue(())
356 }
357
358 fn pre_visit_statement(&mut self, _statement: &mut Statement) -> ControlFlow<Self::Break> {
360 ControlFlow::Continue(())
361 }
362
363 fn post_visit_statement(&mut self, _statement: &mut Statement) -> ControlFlow<Self::Break> {
365 ControlFlow::Continue(())
366 }
367
368 fn pre_visit_value(&mut self, _value: &mut Value) -> ControlFlow<Self::Break> {
370 ControlFlow::Continue(())
371 }
372
373 fn post_visit_value(&mut self, _value: &mut Value) -> ControlFlow<Self::Break> {
375 ControlFlow::Continue(())
376 }
377}
378
379struct RelationVisitor<F>(F);
380
381impl<E, F: FnMut(&ObjectName) -> ControlFlow<E>> Visitor for RelationVisitor<F> {
382 type Break = E;
383
384 fn pre_visit_relation(&mut self, relation: &ObjectName) -> ControlFlow<Self::Break> {
385 self.0(relation)
386 }
387}
388
389impl<E, F: FnMut(&mut ObjectName) -> ControlFlow<E>> VisitorMut for RelationVisitor<F> {
390 type Break = E;
391
392 fn post_visit_relation(&mut self, relation: &mut ObjectName) -> ControlFlow<Self::Break> {
393 self.0(relation)
394 }
395}
396
397pub fn visit_relations<V, E, F>(v: &V, f: F) -> ControlFlow<E>
425where
426 V: Visit,
427 F: FnMut(&ObjectName) -> ControlFlow<E>,
428{
429 let mut visitor = RelationVisitor(f);
430 v.visit(&mut visitor)?;
431 ControlFlow::Continue(())
432}
433
434pub fn visit_relations_mut<V, E, F>(v: &mut V, f: F) -> ControlFlow<E>
458where
459 V: VisitMut,
460 F: FnMut(&mut ObjectName) -> ControlFlow<E>,
461{
462 let mut visitor = RelationVisitor(f);
463 v.visit(&mut visitor)?;
464 ControlFlow::Continue(())
465}
466
467struct ExprVisitor<F>(F);
468
469impl<E, F: FnMut(&Expr) -> ControlFlow<E>> Visitor for ExprVisitor<F> {
470 type Break = E;
471
472 fn pre_visit_expr(&mut self, expr: &Expr) -> ControlFlow<Self::Break> {
473 self.0(expr)
474 }
475}
476
477impl<E, F: FnMut(&mut Expr) -> ControlFlow<E>> VisitorMut for ExprVisitor<F> {
478 type Break = E;
479
480 fn post_visit_expr(&mut self, expr: &mut Expr) -> ControlFlow<Self::Break> {
481 self.0(expr)
482 }
483}
484
485pub fn visit_expressions<V, E, F>(v: &V, f: F) -> ControlFlow<E>
515where
516 V: Visit,
517 F: FnMut(&Expr) -> ControlFlow<E>,
518{
519 let mut visitor = ExprVisitor(f);
520 v.visit(&mut visitor)?;
521 ControlFlow::Continue(())
522}
523
524pub fn visit_expressions_mut<V, E, F>(v: &mut V, f: F) -> ControlFlow<E>
589where
590 V: VisitMut,
591 F: FnMut(&mut Expr) -> ControlFlow<E>,
592{
593 v.visit(&mut ExprVisitor(f))?;
594 ControlFlow::Continue(())
595}
596
597struct StatementVisitor<F>(F);
598
599impl<E, F: FnMut(&Statement) -> ControlFlow<E>> Visitor for StatementVisitor<F> {
600 type Break = E;
601
602 fn pre_visit_statement(&mut self, statement: &Statement) -> ControlFlow<Self::Break> {
603 self.0(statement)
604 }
605}
606
607impl<E, F: FnMut(&mut Statement) -> ControlFlow<E>> VisitorMut for StatementVisitor<F> {
608 type Break = E;
609
610 fn post_visit_statement(&mut self, statement: &mut Statement) -> ControlFlow<Self::Break> {
611 self.0(statement)
612 }
613}
614
615pub fn visit_statements<V, E, F>(v: &V, f: F) -> ControlFlow<E>
644where
645 V: Visit,
646 F: FnMut(&Statement) -> ControlFlow<E>,
647{
648 let mut visitor = StatementVisitor(f);
649 v.visit(&mut visitor)?;
650 ControlFlow::Continue(())
651}
652
653pub fn visit_statements_mut<V, E, F>(v: &mut V, f: F) -> ControlFlow<E>
676where
677 V: VisitMut,
678 F: FnMut(&mut Statement) -> ControlFlow<E>,
679{
680 v.visit(&mut StatementVisitor(f))?;
681 ControlFlow::Continue(())
682}
683
684#[cfg(test)]
685mod tests {
686 use super::*;
687 use crate::ast::Statement;
688 use crate::dialect::GenericDialect;
689 use crate::parser::Parser;
690 use crate::tokenizer::Tokenizer;
691
692 #[derive(Default)]
693 struct TestVisitor {
694 visited: Vec<String>,
695 }
696
697 impl Visitor for TestVisitor {
698 type Break = ();
699
700 fn pre_visit_query(&mut self, query: &Query) -> ControlFlow<Self::Break> {
702 self.visited.push(format!("PRE: QUERY: {query}"));
703 ControlFlow::Continue(())
704 }
705
706 fn post_visit_query(&mut self, query: &Query) -> ControlFlow<Self::Break> {
708 self.visited.push(format!("POST: QUERY: {query}"));
709 ControlFlow::Continue(())
710 }
711
712 fn pre_visit_relation(&mut self, relation: &ObjectName) -> ControlFlow<Self::Break> {
713 self.visited.push(format!("PRE: RELATION: {relation}"));
714 ControlFlow::Continue(())
715 }
716
717 fn post_visit_relation(&mut self, relation: &ObjectName) -> ControlFlow<Self::Break> {
718 self.visited.push(format!("POST: RELATION: {relation}"));
719 ControlFlow::Continue(())
720 }
721
722 fn pre_visit_table_factor(
723 &mut self,
724 table_factor: &TableFactor,
725 ) -> ControlFlow<Self::Break> {
726 self.visited
727 .push(format!("PRE: TABLE FACTOR: {table_factor}"));
728 ControlFlow::Continue(())
729 }
730
731 fn post_visit_table_factor(
732 &mut self,
733 table_factor: &TableFactor,
734 ) -> ControlFlow<Self::Break> {
735 self.visited
736 .push(format!("POST: TABLE FACTOR: {table_factor}"));
737 ControlFlow::Continue(())
738 }
739
740 fn pre_visit_expr(&mut self, expr: &Expr) -> ControlFlow<Self::Break> {
741 self.visited.push(format!("PRE: EXPR: {expr}"));
742 ControlFlow::Continue(())
743 }
744
745 fn post_visit_expr(&mut self, expr: &Expr) -> ControlFlow<Self::Break> {
746 self.visited.push(format!("POST: EXPR: {expr}"));
747 ControlFlow::Continue(())
748 }
749
750 fn pre_visit_statement(&mut self, statement: &Statement) -> ControlFlow<Self::Break> {
751 self.visited.push(format!("PRE: STATEMENT: {statement}"));
752 ControlFlow::Continue(())
753 }
754
755 fn post_visit_statement(&mut self, statement: &Statement) -> ControlFlow<Self::Break> {
756 self.visited.push(format!("POST: STATEMENT: {statement}"));
757 ControlFlow::Continue(())
758 }
759 }
760
761 fn do_visit<V: Visitor<Break = ()>>(sql: &str, visitor: &mut V) -> Statement {
762 let dialect = GenericDialect {};
763 let tokens = Tokenizer::new(&dialect, sql).tokenize().unwrap();
764 let s = Parser::new(&dialect)
765 .with_tokens(tokens)
766 .parse_statement()
767 .unwrap();
768
769 let flow = s.visit(visitor);
770 assert_eq!(flow, ControlFlow::Continue(()));
771 s
772 }
773
774 #[test]
775 fn test_sql() {
776 let tests = vec![
777 (
778 "SELECT * from table_name as my_table",
779 vec![
780 "PRE: STATEMENT: SELECT * FROM table_name AS my_table",
781 "PRE: QUERY: SELECT * FROM table_name AS my_table",
782 "PRE: TABLE FACTOR: table_name AS my_table",
783 "PRE: RELATION: table_name",
784 "POST: RELATION: table_name",
785 "POST: TABLE FACTOR: table_name AS my_table",
786 "POST: QUERY: SELECT * FROM table_name AS my_table",
787 "POST: STATEMENT: SELECT * FROM table_name AS my_table",
788 ],
789 ),
790 (
791 "SELECT * from t1 join t2 on t1.id = t2.t1_id",
792 vec![
793 "PRE: STATEMENT: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id",
794 "PRE: QUERY: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id",
795 "PRE: TABLE FACTOR: t1",
796 "PRE: RELATION: t1",
797 "POST: RELATION: t1",
798 "POST: TABLE FACTOR: t1",
799 "PRE: TABLE FACTOR: t2",
800 "PRE: RELATION: t2",
801 "POST: RELATION: t2",
802 "POST: TABLE FACTOR: t2",
803 "PRE: EXPR: t1.id = t2.t1_id",
804 "PRE: EXPR: t1.id",
805 "POST: EXPR: t1.id",
806 "PRE: EXPR: t2.t1_id",
807 "POST: EXPR: t2.t1_id",
808 "POST: EXPR: t1.id = t2.t1_id",
809 "POST: QUERY: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id",
810 "POST: STATEMENT: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id",
811 ],
812 ),
813 (
814 "SELECT * from t1 where EXISTS(SELECT column from t2)",
815 vec![
816 "PRE: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
817 "PRE: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
818 "PRE: TABLE FACTOR: t1",
819 "PRE: RELATION: t1",
820 "POST: RELATION: t1",
821 "POST: TABLE FACTOR: t1",
822 "PRE: EXPR: EXISTS (SELECT column FROM t2)",
823 "PRE: QUERY: SELECT column FROM t2",
824 "PRE: EXPR: column",
825 "POST: EXPR: column",
826 "PRE: TABLE FACTOR: t2",
827 "PRE: RELATION: t2",
828 "POST: RELATION: t2",
829 "POST: TABLE FACTOR: t2",
830 "POST: QUERY: SELECT column FROM t2",
831 "POST: EXPR: EXISTS (SELECT column FROM t2)",
832 "POST: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
833 "POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
834 ],
835 ),
836 (
837 "SELECT * from t1 where EXISTS(SELECT column from t2)",
838 vec![
839 "PRE: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
840 "PRE: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
841 "PRE: TABLE FACTOR: t1",
842 "PRE: RELATION: t1",
843 "POST: RELATION: t1",
844 "POST: TABLE FACTOR: t1",
845 "PRE: EXPR: EXISTS (SELECT column FROM t2)",
846 "PRE: QUERY: SELECT column FROM t2",
847 "PRE: EXPR: column",
848 "POST: EXPR: column",
849 "PRE: TABLE FACTOR: t2",
850 "PRE: RELATION: t2",
851 "POST: RELATION: t2",
852 "POST: TABLE FACTOR: t2",
853 "POST: QUERY: SELECT column FROM t2",
854 "POST: EXPR: EXISTS (SELECT column FROM t2)",
855 "POST: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
856 "POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)",
857 ],
858 ),
859 (
860 "SELECT * from t1 where EXISTS(SELECT column from t2) UNION SELECT * from t3",
861 vec![
862 "PRE: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3",
863 "PRE: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3",
864 "PRE: TABLE FACTOR: t1",
865 "PRE: RELATION: t1",
866 "POST: RELATION: t1",
867 "POST: TABLE FACTOR: t1",
868 "PRE: EXPR: EXISTS (SELECT column FROM t2)",
869 "PRE: QUERY: SELECT column FROM t2",
870 "PRE: EXPR: column",
871 "POST: EXPR: column",
872 "PRE: TABLE FACTOR: t2",
873 "PRE: RELATION: t2",
874 "POST: RELATION: t2",
875 "POST: TABLE FACTOR: t2",
876 "POST: QUERY: SELECT column FROM t2",
877 "POST: EXPR: EXISTS (SELECT column FROM t2)",
878 "PRE: TABLE FACTOR: t3",
879 "PRE: RELATION: t3",
880 "POST: RELATION: t3",
881 "POST: TABLE FACTOR: t3",
882 "POST: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3",
883 "POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3",
884 ],
885 ),
886 (
887 concat!(
888 "SELECT * FROM monthly_sales ",
889 "PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d) ",
890 "ORDER BY EMPID"
891 ),
892 vec![
893 "PRE: STATEMENT: SELECT * FROM monthly_sales PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d) ORDER BY EMPID",
894 "PRE: QUERY: SELECT * FROM monthly_sales PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d) ORDER BY EMPID",
895 "PRE: TABLE FACTOR: monthly_sales PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d)",
896 "PRE: TABLE FACTOR: monthly_sales",
897 "PRE: RELATION: monthly_sales",
898 "POST: RELATION: monthly_sales",
899 "POST: TABLE FACTOR: monthly_sales",
900 "PRE: EXPR: SUM(a.amount)",
901 "PRE: EXPR: a.amount",
902 "POST: EXPR: a.amount",
903 "POST: EXPR: SUM(a.amount)",
904 "PRE: EXPR: a.MONTH",
905 "POST: EXPR: a.MONTH",
906 "PRE: EXPR: 'JAN'",
907 "POST: EXPR: 'JAN'",
908 "PRE: EXPR: 'FEB'",
909 "POST: EXPR: 'FEB'",
910 "PRE: EXPR: 'MAR'",
911 "POST: EXPR: 'MAR'",
912 "PRE: EXPR: 'APR'",
913 "POST: EXPR: 'APR'",
914 "POST: TABLE FACTOR: monthly_sales PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d)",
915 "PRE: EXPR: EMPID",
916 "POST: EXPR: EMPID",
917 "POST: QUERY: SELECT * FROM monthly_sales PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d) ORDER BY EMPID",
918 "POST: STATEMENT: SELECT * FROM monthly_sales PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d) ORDER BY EMPID",
919 ]
920 ),
921 (
922 "SHOW COLUMNS FROM t1",
923 vec![
924 "PRE: STATEMENT: SHOW COLUMNS FROM t1",
925 "PRE: RELATION: t1",
926 "POST: RELATION: t1",
927 "POST: STATEMENT: SHOW COLUMNS FROM t1",
928 ],
929 ),
930 ];
931 for (sql, expected) in tests {
932 let mut visitor = TestVisitor::default();
933 let _ = do_visit(sql, &mut visitor);
934 let actual: Vec<_> = visitor.visited.iter().map(|x| x.as_str()).collect();
935 assert_eq!(actual, expected)
936 }
937 }
938
939 struct QuickVisitor; impl Visitor for QuickVisitor {
942 type Break = ();
943 }
944
945 #[test]
946 fn overflow() {
947 let cond = (0..1000)
948 .map(|n| format!("X = {n}"))
949 .collect::<Vec<_>>()
950 .join(" OR ");
951 let sql = format!("SELECT x where {cond}");
952
953 let dialect = GenericDialect {};
954 let tokens = Tokenizer::new(&dialect, sql.as_str()).tokenize().unwrap();
955 let s = Parser::new(&dialect)
956 .with_tokens(tokens)
957 .parse_statement()
958 .unwrap();
959
960 let mut visitor = QuickVisitor {};
961 let flow = s.visit(&mut visitor);
962 assert_eq!(flow, ControlFlow::Continue(()));
963 }
964}
965
966#[cfg(test)]
967mod visit_mut_tests {
968 use crate::ast::{Statement, Value, VisitMut, VisitorMut};
969 use crate::dialect::GenericDialect;
970 use crate::parser::Parser;
971 use crate::tokenizer::Tokenizer;
972 use core::ops::ControlFlow;
973
974 #[derive(Default)]
975 struct MutatorVisitor {
976 index: u64,
977 }
978
979 impl VisitorMut for MutatorVisitor {
980 type Break = ();
981
982 fn pre_visit_value(&mut self, value: &mut Value) -> ControlFlow<Self::Break> {
983 self.index += 1;
984 *value = Value::SingleQuotedString(format!("REDACTED_{}", self.index));
985 ControlFlow::Continue(())
986 }
987
988 fn post_visit_value(&mut self, _value: &mut Value) -> ControlFlow<Self::Break> {
989 ControlFlow::Continue(())
990 }
991 }
992
993 fn do_visit_mut<V: VisitorMut<Break = ()>>(sql: &str, visitor: &mut V) -> Statement {
994 let dialect = GenericDialect {};
995 let tokens = Tokenizer::new(&dialect, sql).tokenize().unwrap();
996 let mut s = Parser::new(&dialect)
997 .with_tokens(tokens)
998 .parse_statement()
999 .unwrap();
1000
1001 let flow = s.visit(visitor);
1002 assert_eq!(flow, ControlFlow::Continue(()));
1003 s
1004 }
1005
1006 #[test]
1007 fn test_value_redact() {
1008 let tests = vec![
1009 (
1010 concat!(
1011 "SELECT * FROM monthly_sales ",
1012 "PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d) ",
1013 "ORDER BY EMPID"
1014 ),
1015 concat!(
1016 "SELECT * FROM monthly_sales ",
1017 "PIVOT(SUM(a.amount) FOR a.MONTH IN ('REDACTED_1', 'REDACTED_2', 'REDACTED_3', 'REDACTED_4')) AS p (c, d) ",
1018 "ORDER BY EMPID"
1019 ),
1020 ),
1021 ];
1022
1023 for (sql, expected) in tests {
1024 let mut visitor = MutatorVisitor::default();
1025 let mutated = do_visit_mut(sql, &mut visitor);
1026 assert_eq!(mutated.to_string(), expected)
1027 }
1028 }
1029}