12
12
13
13
//! Recursive visitors for ast Nodes. See [`Visitor`] for more details.
14
14
15
- use crate :: ast:: { Expr , ObjectName , Statement , TableFactor } ;
15
+ use crate :: ast:: { Expr , ObjectName , Query , Statement , TableFactor } ;
16
16
use core:: ops:: ControlFlow ;
17
17
18
18
/// A type that can be visited by a [`Visitor`]. See [`Visitor`] for
@@ -179,6 +179,16 @@ pub trait Visitor {
179
179
/// Type returned when the recursion returns early.
180
180
type Break ;
181
181
182
+ /// Invoked for any queries that appear in the AST before visiting children
183
+ fn pre_visit_query ( & mut self , _query : & Query ) -> ControlFlow < Self :: Break > {
184
+ ControlFlow :: Continue ( ( ) )
185
+ }
186
+
187
+ /// Invoked for any queries that appear in the AST after visiting children
188
+ fn post_visit_query ( & mut self , _query : & Query ) -> ControlFlow < Self :: Break > {
189
+ ControlFlow :: Continue ( ( ) )
190
+ }
191
+
182
192
/// Invoked for any relations (e.g. tables) that appear in the AST before visiting children
183
193
fn pre_visit_relation ( & mut self , _relation : & ObjectName ) -> ControlFlow < Self :: Break > {
184
194
ControlFlow :: Continue ( ( ) )
@@ -267,6 +277,16 @@ pub trait VisitorMut {
267
277
/// Type returned when the recursion returns early.
268
278
type Break ;
269
279
280
+ /// Invoked for any queries that appear in the AST before visiting children
281
+ fn pre_visit_query ( & mut self , _query : & mut Query ) -> ControlFlow < Self :: Break > {
282
+ ControlFlow :: Continue ( ( ) )
283
+ }
284
+
285
+ /// Invoked for any queries that appear in the AST after visiting children
286
+ fn post_visit_query ( & mut self , _query : & mut Query ) -> ControlFlow < Self :: Break > {
287
+ ControlFlow :: Continue ( ( ) )
288
+ }
289
+
270
290
/// Invoked for any relations (e.g. tables) that appear in the AST before visiting children
271
291
fn pre_visit_relation ( & mut self , _relation : & mut ObjectName ) -> ControlFlow < Self :: Break > {
272
292
ControlFlow :: Continue ( ( ) )
@@ -626,6 +646,18 @@ mod tests {
626
646
impl Visitor for TestVisitor {
627
647
type Break = ( ) ;
628
648
649
+ /// Invoked for any queries that appear in the AST before visiting children
650
+ fn pre_visit_query ( & mut self , query : & Query ) -> ControlFlow < Self :: Break > {
651
+ self . visited . push ( format ! ( "PRE: QUERY: {query}" ) ) ;
652
+ ControlFlow :: Continue ( ( ) )
653
+ }
654
+
655
+ /// Invoked for any queries that appear in the AST after visiting children
656
+ fn post_visit_query ( & mut self , query : & Query ) -> ControlFlow < Self :: Break > {
657
+ self . visited . push ( format ! ( "POST: QUERY: {query}" ) ) ;
658
+ ControlFlow :: Continue ( ( ) )
659
+ }
660
+
629
661
fn pre_visit_relation ( & mut self , relation : & ObjectName ) -> ControlFlow < Self :: Break > {
630
662
self . visited . push ( format ! ( "PRE: RELATION: {relation}" ) ) ;
631
663
ControlFlow :: Continue ( ( ) )
@@ -695,17 +727,20 @@ mod tests {
695
727
"SELECT * from table_name as my_table" ,
696
728
vec![
697
729
"PRE: STATEMENT: SELECT * FROM table_name AS my_table" ,
730
+ "PRE: QUERY: SELECT * FROM table_name AS my_table" ,
698
731
"PRE: TABLE FACTOR: table_name AS my_table" ,
699
732
"PRE: RELATION: table_name" ,
700
733
"POST: RELATION: table_name" ,
701
734
"POST: TABLE FACTOR: table_name AS my_table" ,
735
+ "POST: QUERY: SELECT * FROM table_name AS my_table" ,
702
736
"POST: STATEMENT: SELECT * FROM table_name AS my_table" ,
703
737
] ,
704
738
) ,
705
739
(
706
740
"SELECT * from t1 join t2 on t1.id = t2.t1_id" ,
707
741
vec![
708
742
"PRE: STATEMENT: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id" ,
743
+ "PRE: QUERY: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id" ,
709
744
"PRE: TABLE FACTOR: t1" ,
710
745
"PRE: RELATION: t1" ,
711
746
"POST: RELATION: t1" ,
@@ -720,70 +755,108 @@ mod tests {
720
755
"PRE: EXPR: t2.t1_id" ,
721
756
"POST: EXPR: t2.t1_id" ,
722
757
"POST: EXPR: t1.id = t2.t1_id" ,
758
+ "POST: QUERY: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id" ,
723
759
"POST: STATEMENT: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id" ,
724
760
] ,
725
761
) ,
726
762
(
727
763
"SELECT * from t1 where EXISTS(SELECT column from t2)" ,
728
764
vec![
729
765
"PRE: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
766
+ "PRE: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
730
767
"PRE: TABLE FACTOR: t1" ,
731
768
"PRE: RELATION: t1" ,
732
769
"POST: RELATION: t1" ,
733
770
"POST: TABLE FACTOR: t1" ,
734
771
"PRE: EXPR: EXISTS (SELECT column FROM t2)" ,
772
+ "PRE: QUERY: SELECT column FROM t2" ,
735
773
"PRE: EXPR: column" ,
736
774
"POST: EXPR: column" ,
737
775
"PRE: TABLE FACTOR: t2" ,
738
776
"PRE: RELATION: t2" ,
739
777
"POST: RELATION: t2" ,
740
778
"POST: TABLE FACTOR: t2" ,
779
+ "POST: QUERY: SELECT column FROM t2" ,
741
780
"POST: EXPR: EXISTS (SELECT column FROM t2)" ,
781
+ "POST: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
742
782
"POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
743
783
] ,
744
784
) ,
745
785
(
746
786
"SELECT * from t1 where EXISTS(SELECT column from t2)" ,
747
787
vec![
748
788
"PRE: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
789
+ "PRE: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
749
790
"PRE: TABLE FACTOR: t1" ,
750
791
"PRE: RELATION: t1" ,
751
792
"POST: RELATION: t1" ,
752
793
"POST: TABLE FACTOR: t1" ,
753
794
"PRE: EXPR: EXISTS (SELECT column FROM t2)" ,
795
+ "PRE: QUERY: SELECT column FROM t2" ,
754
796
"PRE: EXPR: column" ,
755
797
"POST: EXPR: column" ,
756
798
"PRE: TABLE FACTOR: t2" ,
757
799
"PRE: RELATION: t2" ,
758
800
"POST: RELATION: t2" ,
759
801
"POST: TABLE FACTOR: t2" ,
802
+ "POST: QUERY: SELECT column FROM t2" ,
760
803
"POST: EXPR: EXISTS (SELECT column FROM t2)" ,
804
+ "POST: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
761
805
"POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
762
806
] ,
763
807
) ,
764
808
(
765
809
"SELECT * from t1 where EXISTS(SELECT column from t2) UNION SELECT * from t3" ,
766
810
vec![
767
811
"PRE: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3" ,
812
+ "PRE: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3" ,
768
813
"PRE: TABLE FACTOR: t1" ,
769
814
"PRE: RELATION: t1" ,
770
815
"POST: RELATION: t1" ,
771
816
"POST: TABLE FACTOR: t1" ,
772
817
"PRE: EXPR: EXISTS (SELECT column FROM t2)" ,
818
+ "PRE: QUERY: SELECT column FROM t2" ,
773
819
"PRE: EXPR: column" ,
774
820
"POST: EXPR: column" ,
775
821
"PRE: TABLE FACTOR: t2" ,
776
822
"PRE: RELATION: t2" ,
777
823
"POST: RELATION: t2" ,
778
824
"POST: TABLE FACTOR: t2" ,
825
+ "POST: QUERY: SELECT column FROM t2" ,
779
826
"POST: EXPR: EXISTS (SELECT column FROM t2)" ,
780
827
"PRE: TABLE FACTOR: t3" ,
781
828
"PRE: RELATION: t3" ,
782
829
"POST: RELATION: t3" ,
783
830
"POST: TABLE FACTOR: t3" ,
831
+ "POST: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3" ,
784
832
"POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3" ,
785
833
] ,
786
834
) ,
835
+ (
836
+ concat!(
837
+ "SELECT * FROM monthly_sales " ,
838
+ "PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d) " ,
839
+ "ORDER BY EMPID"
840
+ ) ,
841
+ vec![
842
+ "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" ,
843
+ "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" ,
844
+ "PRE: TABLE FACTOR: monthly_sales PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d)" ,
845
+ "PRE: TABLE FACTOR: monthly_sales" ,
846
+ "PRE: RELATION: monthly_sales" ,
847
+ "POST: RELATION: monthly_sales" ,
848
+ "POST: TABLE FACTOR: monthly_sales" ,
849
+ "PRE: EXPR: SUM(a.amount)" ,
850
+ "PRE: EXPR: a.amount" ,
851
+ "POST: EXPR: a.amount" ,
852
+ "POST: EXPR: SUM(a.amount)" ,
853
+ "POST: TABLE FACTOR: monthly_sales PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d)" ,
854
+ "PRE: EXPR: EMPID" ,
855
+ "POST: EXPR: EMPID" ,
856
+ "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" ,
857
+ "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" ,
858
+ ]
859
+ )
787
860
] ;
788
861
for ( sql, expected) in tests {
789
862
let actual = do_visit ( sql) ;
0 commit comments