2121use alloc:: { boxed:: Box , string:: String , vec:: Vec } ;
2222use core:: ops:: ControlFlow ;
2323
24- use crate :: ast:: { Expr , Ident , ObjectName , Query , Select , Statement , TableFactor , ValueWithSpan } ;
24+ use crate :: ast:: {
25+ Expr , GroupByExpr , Ident , ObjectName , OrderBy , OrderByExpr , Query , Select , Statement ,
26+ TableFactor , ValueWithSpan ,
27+ } ;
2528
2629/// A type that can be visited by a [`Visitor`]. See [`Visitor`] for
2730/// recursively visiting parsed SQL statements.
@@ -279,6 +282,42 @@ pub trait Visitor {
279282 fn post_visit_ident ( & mut self , _ident : & Ident ) -> ControlFlow < Self :: Break > {
280283 ControlFlow :: Continue ( ( ) )
281284 }
285+
286+ /// Invoked for any `ORDER BY` clauses that appear in the AST before visiting children
287+ fn pre_visit_order_by ( & mut self , _order_by : & OrderBy ) -> ControlFlow < Self :: Break > {
288+ ControlFlow :: Continue ( ( ) )
289+ }
290+
291+ /// Invoked for any `ORDER BY` clauses that appear in the AST after visiting children
292+ fn post_visit_order_by ( & mut self , _order_by : & OrderBy ) -> ControlFlow < Self :: Break > {
293+ ControlFlow :: Continue ( ( ) )
294+ }
295+
296+ /// Invoked for any `ORDER BY` expressions that appear in the AST before visiting children
297+ fn pre_visit_order_by_expr (
298+ & mut self ,
299+ _order_by_expr : & OrderByExpr ,
300+ ) -> ControlFlow < Self :: Break > {
301+ ControlFlow :: Continue ( ( ) )
302+ }
303+
304+ /// Invoked for any `ORDER BY` expressions that appear in the AST after visiting children
305+ fn post_visit_order_by_expr (
306+ & mut self ,
307+ _order_by_expr : & OrderByExpr ,
308+ ) -> ControlFlow < Self :: Break > {
309+ ControlFlow :: Continue ( ( ) )
310+ }
311+
312+ /// Invoked for any `GROUP BY` clauses that appear in the AST before visiting children
313+ fn pre_visit_group_by ( & mut self , _group_by : & GroupByExpr ) -> ControlFlow < Self :: Break > {
314+ ControlFlow :: Continue ( ( ) )
315+ }
316+
317+ /// Invoked for any `GROUP BY` clauses that appear in the AST after visiting children
318+ fn post_visit_group_by ( & mut self , _group_by : & GroupByExpr ) -> ControlFlow < Self :: Break > {
319+ ControlFlow :: Continue ( ( ) )
320+ }
282321}
283322
284323/// A visitor that can be used to mutate an AST tree.
@@ -417,6 +456,42 @@ pub trait VisitorMut {
417456 fn post_visit_ident ( & mut self , _ident : & mut Ident ) -> ControlFlow < Self :: Break > {
418457 ControlFlow :: Continue ( ( ) )
419458 }
459+
460+ /// Invoked for any `ORDER BY` clauses that appear in the AST before visiting children
461+ fn pre_visit_order_by ( & mut self , _order_by : & mut OrderBy ) -> ControlFlow < Self :: Break > {
462+ ControlFlow :: Continue ( ( ) )
463+ }
464+
465+ /// Invoked for any `ORDER BY` clauses that appear in the AST after visiting children
466+ fn post_visit_order_by ( & mut self , _order_by : & mut OrderBy ) -> ControlFlow < Self :: Break > {
467+ ControlFlow :: Continue ( ( ) )
468+ }
469+
470+ /// Invoked for any `ORDER BY` expressions that appear in the AST before visiting children
471+ fn pre_visit_order_by_expr (
472+ & mut self ,
473+ _order_by_expr : & mut OrderByExpr ,
474+ ) -> ControlFlow < Self :: Break > {
475+ ControlFlow :: Continue ( ( ) )
476+ }
477+
478+ /// Invoked for any `ORDER BY` expressions that appear in the AST after visiting children
479+ fn post_visit_order_by_expr (
480+ & mut self ,
481+ _order_by_expr : & mut OrderByExpr ,
482+ ) -> ControlFlow < Self :: Break > {
483+ ControlFlow :: Continue ( ( ) )
484+ }
485+
486+ /// Invoked for any `GROUP BY` clauses that appear in the AST before visiting children
487+ fn pre_visit_group_by ( & mut self , _group_by : & mut GroupByExpr ) -> ControlFlow < Self :: Break > {
488+ ControlFlow :: Continue ( ( ) )
489+ }
490+
491+ /// Invoked for any `GROUP BY` clauses that appear in the AST after visiting children
492+ fn post_visit_group_by ( & mut self , _group_by : & mut GroupByExpr ) -> ControlFlow < Self :: Break > {
493+ ControlFlow :: Continue ( ( ) )
494+ }
420495}
421496
422497struct RelationVisitor < F > ( F ) ;
@@ -809,6 +884,44 @@ mod tests {
809884 self . visited . push ( format ! ( "POST: STATEMENT: {statement}" ) ) ;
810885 ControlFlow :: Continue ( ( ) )
811886 }
887+
888+ fn pre_visit_order_by ( & mut self , order_by : & OrderBy ) -> ControlFlow < Self :: Break > {
889+ self . visited . push ( format ! ( "PRE: ORDER BY: {order_by}" ) ) ;
890+ ControlFlow :: Continue ( ( ) )
891+ }
892+
893+ fn post_visit_order_by ( & mut self , order_by : & OrderBy ) -> ControlFlow < Self :: Break > {
894+ self . visited . push ( format ! ( "POST: ORDER BY: {order_by}" ) ) ;
895+ ControlFlow :: Continue ( ( ) )
896+ }
897+
898+ fn pre_visit_order_by_expr (
899+ & mut self ,
900+ order_by_expr : & OrderByExpr ,
901+ ) -> ControlFlow < Self :: Break > {
902+ self . visited
903+ . push ( format ! ( "PRE: ORDER BY EXPR: {order_by_expr}" ) ) ;
904+ ControlFlow :: Continue ( ( ) )
905+ }
906+
907+ fn post_visit_order_by_expr (
908+ & mut self ,
909+ order_by_expr : & OrderByExpr ,
910+ ) -> ControlFlow < Self :: Break > {
911+ self . visited
912+ . push ( format ! ( "POST: ORDER BY EXPR: {order_by_expr}" ) ) ;
913+ ControlFlow :: Continue ( ( ) )
914+ }
915+
916+ fn pre_visit_group_by ( & mut self , group_by : & GroupByExpr ) -> ControlFlow < Self :: Break > {
917+ self . visited . push ( format ! ( "PRE: GROUP BY: {group_by}" ) ) ;
918+ ControlFlow :: Continue ( ( ) )
919+ }
920+
921+ fn post_visit_group_by ( & mut self , group_by : & GroupByExpr ) -> ControlFlow < Self :: Break > {
922+ self . visited . push ( format ! ( "POST: GROUP BY: {group_by}" ) ) ;
923+ ControlFlow :: Continue ( ( ) )
924+ }
812925 }
813926
814927 fn do_visit < V : Visitor < Break = ( ) > > ( sql : & str , visitor : & mut V ) -> Statement {
@@ -837,6 +950,8 @@ mod tests {
837950 "PRE: RELATION: table_name" ,
838951 "POST: RELATION: table_name" ,
839952 "POST: TABLE FACTOR: table_name AS my_table" ,
953+ "PRE: GROUP BY: GROUP BY " ,
954+ "POST: GROUP BY: GROUP BY " ,
840955 "POST: SELECT: SELECT * FROM table_name AS my_table" ,
841956 "POST: QUERY: SELECT * FROM table_name AS my_table" ,
842957 "POST: STATEMENT: SELECT * FROM table_name AS my_table" ,
@@ -862,6 +977,8 @@ mod tests {
862977 "PRE: EXPR: t2.t1_id" ,
863978 "POST: EXPR: t2.t1_id" ,
864979 "POST: EXPR: t1.id = t2.t1_id" ,
980+ "PRE: GROUP BY: GROUP BY " ,
981+ "POST: GROUP BY: GROUP BY " ,
865982 "POST: SELECT: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id" ,
866983 "POST: QUERY: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id" ,
867984 "POST: STATEMENT: SELECT * FROM t1 JOIN t2 ON t1.id = t2.t1_id" ,
@@ -886,9 +1003,13 @@ mod tests {
8861003 "PRE: RELATION: t2" ,
8871004 "POST: RELATION: t2" ,
8881005 "POST: TABLE FACTOR: t2" ,
1006+ "PRE: GROUP BY: GROUP BY " ,
1007+ "POST: GROUP BY: GROUP BY " ,
8891008 "POST: SELECT: SELECT column FROM t2" ,
8901009 "POST: QUERY: SELECT column FROM t2" ,
8911010 "POST: EXPR: EXISTS (SELECT column FROM t2)" ,
1011+ "PRE: GROUP BY: GROUP BY " ,
1012+ "POST: GROUP BY: GROUP BY " ,
8921013 "POST: SELECT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
8931014 "POST: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
8941015 "POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
@@ -913,9 +1034,13 @@ mod tests {
9131034 "PRE: RELATION: t2" ,
9141035 "POST: RELATION: t2" ,
9151036 "POST: TABLE FACTOR: t2" ,
1037+ "PRE: GROUP BY: GROUP BY " ,
1038+ "POST: GROUP BY: GROUP BY " ,
9161039 "POST: SELECT: SELECT column FROM t2" ,
9171040 "POST: QUERY: SELECT column FROM t2" ,
9181041 "POST: EXPR: EXISTS (SELECT column FROM t2)" ,
1042+ "PRE: GROUP BY: GROUP BY " ,
1043+ "POST: GROUP BY: GROUP BY " ,
9191044 "POST: SELECT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
9201045 "POST: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
9211046 "POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
@@ -940,15 +1065,21 @@ mod tests {
9401065 "PRE: RELATION: t2" ,
9411066 "POST: RELATION: t2" ,
9421067 "POST: TABLE FACTOR: t2" ,
1068+ "PRE: GROUP BY: GROUP BY " ,
1069+ "POST: GROUP BY: GROUP BY " ,
9431070 "POST: SELECT: SELECT column FROM t2" ,
9441071 "POST: QUERY: SELECT column FROM t2" ,
9451072 "POST: EXPR: EXISTS (SELECT column FROM t2)" ,
1073+ "PRE: GROUP BY: GROUP BY " ,
1074+ "POST: GROUP BY: GROUP BY " ,
9461075 "POST: SELECT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2)" ,
9471076 "PRE: SELECT: SELECT * FROM t3" ,
9481077 "PRE: TABLE FACTOR: t3" ,
9491078 "PRE: RELATION: t3" ,
9501079 "POST: RELATION: t3" ,
9511080 "POST: TABLE FACTOR: t3" ,
1081+ "PRE: GROUP BY: GROUP BY " ,
1082+ "POST: GROUP BY: GROUP BY " ,
9521083 "POST: SELECT: SELECT * FROM t3" ,
9531084 "POST: QUERY: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3" ,
9541085 "POST: STATEMENT: SELECT * FROM t1 WHERE EXISTS (SELECT column FROM t2) UNION SELECT * FROM t3" ,
@@ -984,9 +1115,15 @@ mod tests {
9841115 "PRE: EXPR: 'APR'" ,
9851116 "POST: EXPR: 'APR'" ,
9861117 "POST: TABLE FACTOR: monthly_sales PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d)" ,
1118+ "PRE: GROUP BY: GROUP BY " ,
1119+ "POST: GROUP BY: GROUP BY " ,
9871120 "POST: SELECT: SELECT * FROM monthly_sales PIVOT(SUM(a.amount) FOR a.MONTH IN ('JAN', 'FEB', 'MAR', 'APR')) AS p (c, d)" ,
1121+ "PRE: ORDER BY: ORDER BY EMPID" ,
1122+ "PRE: ORDER BY EXPR: EMPID" ,
9881123 "PRE: EXPR: EMPID" ,
9891124 "POST: EXPR: EMPID" ,
1125+ "POST: ORDER BY EXPR: EMPID" ,
1126+ "POST: ORDER BY: ORDER BY EMPID" ,
9901127 "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" ,
9911128 "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" ,
9921129 ]
@@ -1000,6 +1137,56 @@ mod tests {
10001137 "POST: STATEMENT: SHOW COLUMNS FROM t1" ,
10011138 ] ,
10021139 ) ,
1140+ (
1141+ "SELECT * FROM t1 ORDER BY a DESC, b" ,
1142+ vec![
1143+ "PRE: STATEMENT: SELECT * FROM t1 ORDER BY a DESC, b" ,
1144+ "PRE: QUERY: SELECT * FROM t1 ORDER BY a DESC, b" ,
1145+ "PRE: SELECT: SELECT * FROM t1" ,
1146+ "PRE: TABLE FACTOR: t1" ,
1147+ "PRE: RELATION: t1" ,
1148+ "POST: RELATION: t1" ,
1149+ "POST: TABLE FACTOR: t1" ,
1150+ "PRE: GROUP BY: GROUP BY " ,
1151+ "POST: GROUP BY: GROUP BY " ,
1152+ "POST: SELECT: SELECT * FROM t1" ,
1153+ "PRE: ORDER BY: ORDER BY a DESC, b" ,
1154+ "PRE: ORDER BY EXPR: a DESC" ,
1155+ "PRE: EXPR: a" ,
1156+ "POST: EXPR: a" ,
1157+ "POST: ORDER BY EXPR: a DESC" ,
1158+ "PRE: ORDER BY EXPR: b" ,
1159+ "PRE: EXPR: b" ,
1160+ "POST: EXPR: b" ,
1161+ "POST: ORDER BY EXPR: b" ,
1162+ "POST: ORDER BY: ORDER BY a DESC, b" ,
1163+ "POST: QUERY: SELECT * FROM t1 ORDER BY a DESC, b" ,
1164+ "POST: STATEMENT: SELECT * FROM t1 ORDER BY a DESC, b" ,
1165+ ] ,
1166+ ) ,
1167+ (
1168+ "SELECT a FROM t GROUP BY a, b" ,
1169+ vec![
1170+ "PRE: STATEMENT: SELECT a FROM t GROUP BY a, b" ,
1171+ "PRE: QUERY: SELECT a FROM t GROUP BY a, b" ,
1172+ "PRE: SELECT: SELECT a FROM t GROUP BY a, b" ,
1173+ "PRE: EXPR: a" ,
1174+ "POST: EXPR: a" ,
1175+ "PRE: TABLE FACTOR: t" ,
1176+ "PRE: RELATION: t" ,
1177+ "POST: RELATION: t" ,
1178+ "POST: TABLE FACTOR: t" ,
1179+ "PRE: GROUP BY: GROUP BY a, b" ,
1180+ "PRE: EXPR: a" ,
1181+ "POST: EXPR: a" ,
1182+ "PRE: EXPR: b" ,
1183+ "POST: EXPR: b" ,
1184+ "POST: GROUP BY: GROUP BY a, b" ,
1185+ "POST: SELECT: SELECT a FROM t GROUP BY a, b" ,
1186+ "POST: QUERY: SELECT a FROM t GROUP BY a, b" ,
1187+ "POST: STATEMENT: SELECT a FROM t GROUP BY a, b" ,
1188+ ] ,
1189+ ) ,
10031190 ] ;
10041191 for ( sql, expected) in tests {
10051192 let mut visitor = TestVisitor :: default ( ) ;
0 commit comments