partiql_ast/
visit.rs

1use crate::ast;
2use partiql_common::node::NodeId;
3
4/// Indicates if tree traversal of the entire tree should continue or not.
5#[derive(PartialEq, Debug)]
6pub enum Traverse {
7    /// Signals tree traversal of entire tree should continue.
8    Continue,
9    /// Signals tree traversal of entire tree should stop.
10    Stop,
11}
12
13pub trait Visit {
14    fn visit<'ast, V>(&'ast self, v: &mut V) -> Traverse
15    where
16        V: Visitor<'ast>;
17}
18
19impl<T> Visit for ast::AstNode<T>
20where
21    T: Visit,
22{
23    fn visit<'ast, V>(&'ast self, v: &mut V) -> Traverse
24    where
25        V: Visitor<'ast>,
26    {
27        if v.enter_ast_node(self.id) == Traverse::Stop {
28            return Traverse::Stop;
29        }
30        if self.node.visit(v) == Traverse::Stop {
31            return Traverse::Stop;
32        }
33        v.exit_ast_node(self.id)
34    }
35}
36
37impl<T> Visit for &T
38where
39    T: Visit,
40{
41    fn visit<'ast, V>(&'ast self, v: &mut V) -> Traverse
42    where
43        V: Visitor<'ast>,
44    {
45        (*self).visit(v)
46    }
47}
48
49impl<T> Visit for Box<T>
50where
51    T: Visit,
52{
53    fn visit<'ast, V>(&'ast self, v: &mut V) -> Traverse
54    where
55        V: Visitor<'ast>,
56    {
57        (**self).visit(v)
58    }
59}
60
61impl<T> Visit for Option<T>
62where
63    T: Visit,
64{
65    fn visit<'ast, V>(&'ast self, v: &mut V) -> Traverse
66    where
67        V: Visitor<'ast>,
68    {
69        if let Some(inner) = self {
70            if inner.visit(v) == Traverse::Stop {
71                return Traverse::Stop;
72            }
73        }
74        Traverse::Continue
75    }
76}
77
78impl<T> Visit for Vec<T>
79where
80    T: Visit,
81{
82    fn visit<'ast, V>(&'ast self, v: &mut V) -> Traverse
83    where
84        V: Visitor<'ast>,
85    {
86        for i in self {
87            if i.visit(v) == Traverse::Stop {
88                return Traverse::Stop;
89            }
90        }
91        Traverse::Continue
92    }
93}
94
95pub trait Visitor<'ast> {
96    fn enter_ast_node(&mut self, _id: NodeId) -> Traverse {
97        Traverse::Continue
98    }
99    fn exit_ast_node(&mut self, _id: NodeId) -> Traverse {
100        Traverse::Continue
101    }
102    fn enter_item(&mut self, _item: &'ast ast::Item) -> Traverse {
103        Traverse::Continue
104    }
105    fn exit_item(&mut self, _item: &'ast ast::Item) -> Traverse {
106        Traverse::Continue
107    }
108    fn enter_ddl(&mut self, _ddl: &'ast ast::Ddl) -> Traverse {
109        Traverse::Continue
110    }
111    fn exit_ddl(&mut self, _ddl: &'ast ast::Ddl) -> Traverse {
112        Traverse::Continue
113    }
114    fn enter_ddl_op(&mut self, _ddl_op: &'ast ast::DdlOp) -> Traverse {
115        Traverse::Continue
116    }
117    fn exit_ddl_op(&mut self, _ddl_op: &'ast ast::DdlOp) -> Traverse {
118        Traverse::Continue
119    }
120    fn enter_create_table(&mut self, _create_table: &'ast ast::CreateTable) -> Traverse {
121        Traverse::Continue
122    }
123    fn exit_create_table(&mut self, _create_table: &'ast ast::CreateTable) -> Traverse {
124        Traverse::Continue
125    }
126    fn enter_drop_table(&mut self, _drop_table: &'ast ast::DropTable) -> Traverse {
127        Traverse::Continue
128    }
129    fn exit_drop_table(&mut self, _drop_table: &'ast ast::DropTable) -> Traverse {
130        Traverse::Continue
131    }
132    fn enter_create_index(&mut self, _create_index: &'ast ast::CreateIndex) -> Traverse {
133        Traverse::Continue
134    }
135    fn exit_create_index(&mut self, _create_index: &'ast ast::CreateIndex) -> Traverse {
136        Traverse::Continue
137    }
138    fn enter_drop_index(&mut self, _drop_index: &'ast ast::DropIndex) -> Traverse {
139        Traverse::Continue
140    }
141    fn exit_drop_index(&mut self, _drop_index: &'ast ast::DropIndex) -> Traverse {
142        Traverse::Continue
143    }
144    fn enter_dml(&mut self, _dml: &'ast ast::Dml) -> Traverse {
145        Traverse::Continue
146    }
147    fn exit_dml(&mut self, _dml: &'ast ast::Dml) -> Traverse {
148        Traverse::Continue
149    }
150    fn enter_dml_op(&mut self, _dml_op: &'ast ast::DmlOp) -> Traverse {
151        Traverse::Continue
152    }
153    fn exit_dml_op(&mut self, _dml_op: &'ast ast::DmlOp) -> Traverse {
154        Traverse::Continue
155    }
156    fn enter_returning_expr(&mut self, _returning_expr: &'ast ast::ReturningExpr) -> Traverse {
157        Traverse::Continue
158    }
159    fn exit_returning_expr(&mut self, _returning_expr: &'ast ast::ReturningExpr) -> Traverse {
160        Traverse::Continue
161    }
162    fn enter_returning_elem(&mut self, _returning_elem: &'ast ast::ReturningElem) -> Traverse {
163        Traverse::Continue
164    }
165    fn exit_returning_elem(&mut self, _returning_elem: &'ast ast::ReturningElem) -> Traverse {
166        Traverse::Continue
167    }
168    fn enter_insert(&mut self, _insert: &'ast ast::Insert) -> Traverse {
169        Traverse::Continue
170    }
171    fn exit_insert(&mut self, _insert: &'ast ast::Insert) -> Traverse {
172        Traverse::Continue
173    }
174    fn enter_insert_value(&mut self, _insert_value: &'ast ast::InsertValue) -> Traverse {
175        Traverse::Continue
176    }
177    fn exit_insert_value(&mut self, _insert_value: &'ast ast::InsertValue) -> Traverse {
178        Traverse::Continue
179    }
180    fn enter_set(&mut self, _set: &'ast ast::Set) -> Traverse {
181        Traverse::Continue
182    }
183    fn exit_set(&mut self, _set: &'ast ast::Set) -> Traverse {
184        Traverse::Continue
185    }
186    fn enter_assignment(&mut self, _assignment: &'ast ast::Assignment) -> Traverse {
187        Traverse::Continue
188    }
189    fn exit_assignment(&mut self, _assignment: &'ast ast::Assignment) -> Traverse {
190        Traverse::Continue
191    }
192    fn enter_remove(&mut self, _remove: &'ast ast::Remove) -> Traverse {
193        Traverse::Continue
194    }
195    fn exit_remove(&mut self, _remove: &'ast ast::Remove) -> Traverse {
196        Traverse::Continue
197    }
198    fn enter_delete(&mut self, _delete: &'ast ast::Delete) -> Traverse {
199        Traverse::Continue
200    }
201    fn exit_delete(&mut self, _delete: &'ast ast::Delete) -> Traverse {
202        Traverse::Continue
203    }
204    fn enter_on_conflict(&mut self, _on_conflict: &'ast ast::OnConflict) -> Traverse {
205        Traverse::Continue
206    }
207    fn exit_on_conflict(&mut self, _on_conflict: &'ast ast::OnConflict) -> Traverse {
208        Traverse::Continue
209    }
210    fn enter_top_level_query(&mut self, _query: &'ast ast::TopLevelQuery) -> Traverse {
211        Traverse::Continue
212    }
213    fn exit_top_level_query(&mut self, _query: &'ast ast::TopLevelQuery) -> Traverse {
214        Traverse::Continue
215    }
216    fn enter_query(&mut self, _query: &'ast ast::Query) -> Traverse {
217        Traverse::Continue
218    }
219    fn exit_query(&mut self, _query: &'ast ast::Query) -> Traverse {
220        Traverse::Continue
221    }
222    fn enter_with_clause(&mut self, _query: &'ast ast::WithClause) -> Traverse {
223        Traverse::Continue
224    }
225    fn exit_with_clause(&mut self, _query: &'ast ast::WithClause) -> Traverse {
226        Traverse::Continue
227    }
228    fn enter_with_element(&mut self, _query: &'ast ast::WithElement) -> Traverse {
229        Traverse::Continue
230    }
231    fn exit_with_element(&mut self, _query: &'ast ast::WithElement) -> Traverse {
232        Traverse::Continue
233    }
234    fn enter_query_set(&mut self, _query_set: &'ast ast::QuerySet) -> Traverse {
235        Traverse::Continue
236    }
237    fn exit_query_set(&mut self, _query_set: &'ast ast::QuerySet) -> Traverse {
238        Traverse::Continue
239    }
240    fn enter_bag_op_expr(&mut self, _set_expr: &'ast ast::BagOpExpr) -> Traverse {
241        Traverse::Continue
242    }
243    fn exit_bag_op_expr(&mut self, _set_expr: &'ast ast::BagOpExpr) -> Traverse {
244        Traverse::Continue
245    }
246    fn enter_select(&mut self, _select: &'ast ast::Select) -> Traverse {
247        Traverse::Continue
248    }
249    fn exit_select(&mut self, _select: &'ast ast::Select) -> Traverse {
250        Traverse::Continue
251    }
252    fn enter_query_table(&mut self, _table: &'ast ast::QueryTable) -> Traverse {
253        Traverse::Continue
254    }
255    fn exit_query_table(&mut self, _table: &'ast ast::QueryTable) -> Traverse {
256        Traverse::Continue
257    }
258    fn enter_projection(&mut self, _projection: &'ast ast::Projection) -> Traverse {
259        Traverse::Continue
260    }
261    fn exit_projection(&mut self, _projection: &'ast ast::Projection) -> Traverse {
262        Traverse::Continue
263    }
264    fn enter_projection_kind(&mut self, _projection_kind: &'ast ast::ProjectionKind) -> Traverse {
265        Traverse::Continue
266    }
267    fn exit_projection_kind(&mut self, _projection_kind: &'ast ast::ProjectionKind) -> Traverse {
268        Traverse::Continue
269    }
270    fn enter_project_item(&mut self, _project_item: &'ast ast::ProjectItem) -> Traverse {
271        Traverse::Continue
272    }
273    fn exit_project_item(&mut self, _project_item: &'ast ast::ProjectItem) -> Traverse {
274        Traverse::Continue
275    }
276    fn enter_project_pivot(&mut self, _project_pivot: &'ast ast::ProjectPivot) -> Traverse {
277        Traverse::Continue
278    }
279    fn exit_project_pivot(&mut self, _project_pivot: &'ast ast::ProjectPivot) -> Traverse {
280        Traverse::Continue
281    }
282    fn enter_project_all(&mut self, _project_all: &'ast ast::ProjectAll) -> Traverse {
283        Traverse::Continue
284    }
285    fn exit_project_all(&mut self, _project_all: &'ast ast::ProjectAll) -> Traverse {
286        Traverse::Continue
287    }
288    fn enter_project_expr(&mut self, _project_expr: &'ast ast::ProjectExpr) -> Traverse {
289        Traverse::Continue
290    }
291    fn exit_project_expr(&mut self, _project_expr: &'ast ast::ProjectExpr) -> Traverse {
292        Traverse::Continue
293    }
294    fn enter_exclusion(&mut self, _exclusion: &'ast ast::Exclusion) -> Traverse {
295        Traverse::Continue
296    }
297    fn exit_exclusion(&mut self, _exclusion: &'ast ast::Exclusion) -> Traverse {
298        Traverse::Continue
299    }
300    fn enter_exclude_path(&mut self, _path: &'ast ast::ExcludePath) -> Traverse {
301        Traverse::Continue
302    }
303    fn exit_exclude_path(&mut self, _path: &'ast ast::ExcludePath) -> Traverse {
304        Traverse::Continue
305    }
306    fn enter_exclude_path_step(&mut self, _step: &'ast ast::ExcludePathStep) -> Traverse {
307        Traverse::Continue
308    }
309    fn exit_exclude_path_step(&mut self, _step: &'ast ast::ExcludePathStep) -> Traverse {
310        Traverse::Continue
311    }
312    fn enter_expr(&mut self, _expr: &'ast ast::Expr) -> Traverse {
313        Traverse::Continue
314    }
315    fn exit_expr(&mut self, _expr: &'ast ast::Expr) -> Traverse {
316        Traverse::Continue
317    }
318    fn enter_lit(&mut self, _lit: &'ast ast::Lit) -> Traverse {
319        Traverse::Continue
320    }
321    fn exit_lit(&mut self, _lit: &'ast ast::Lit) -> Traverse {
322        Traverse::Continue
323    }
324    fn enter_var_ref(&mut self, _var_ref: &'ast ast::VarRef) -> Traverse {
325        Traverse::Continue
326    }
327    fn exit_var_ref(&mut self, _var_ref: &'ast ast::VarRef) -> Traverse {
328        Traverse::Continue
329    }
330    fn enter_bin_op(&mut self, _bin_op: &'ast ast::BinOp) -> Traverse {
331        Traverse::Continue
332    }
333    fn exit_bin_op(&mut self, _bin_op: &'ast ast::BinOp) -> Traverse {
334        Traverse::Continue
335    }
336    fn enter_uni_op(&mut self, _uni_op: &'ast ast::UniOp) -> Traverse {
337        Traverse::Continue
338    }
339    fn exit_uni_op(&mut self, _uni_op: &'ast ast::UniOp) -> Traverse {
340        Traverse::Continue
341    }
342    fn enter_like(&mut self, _like: &'ast ast::Like) -> Traverse {
343        Traverse::Continue
344    }
345    fn exit_like(&mut self, _like: &'ast ast::Like) -> Traverse {
346        Traverse::Continue
347    }
348    fn enter_between(&mut self, _between: &'ast ast::Between) -> Traverse {
349        Traverse::Continue
350    }
351    fn exit_between(&mut self, _between: &'ast ast::Between) -> Traverse {
352        Traverse::Continue
353    }
354    fn enter_in(&mut self, _in: &'ast ast::In) -> Traverse {
355        Traverse::Continue
356    }
357    fn exit_in(&mut self, _in: &'ast ast::In) -> Traverse {
358        Traverse::Continue
359    }
360    fn enter_case(&mut self, _case: &'ast ast::Case) -> Traverse {
361        Traverse::Continue
362    }
363    fn exit_case(&mut self, _case: &'ast ast::Case) -> Traverse {
364        Traverse::Continue
365    }
366    fn enter_simple_case(&mut self, _simple_case: &'ast ast::SimpleCase) -> Traverse {
367        Traverse::Continue
368    }
369    fn exit_simple_case(&mut self, _simple_case: &'ast ast::SimpleCase) -> Traverse {
370        Traverse::Continue
371    }
372    fn enter_searched_case(&mut self, _searched_case: &'ast ast::SearchedCase) -> Traverse {
373        Traverse::Continue
374    }
375    fn exit_searched_case(&mut self, _searched_case: &'ast ast::SearchedCase) -> Traverse {
376        Traverse::Continue
377    }
378    fn enter_expr_pair(&mut self, _expr_pair: &'ast ast::ExprPair) -> Traverse {
379        Traverse::Continue
380    }
381    fn exit_expr_pair(&mut self, _expr_pair: &'ast ast::ExprPair) -> Traverse {
382        Traverse::Continue
383    }
384    fn enter_struct(&mut self, _struct: &'ast ast::Struct) -> Traverse {
385        Traverse::Continue
386    }
387    fn exit_struct(&mut self, _struct: &'ast ast::Struct) -> Traverse {
388        Traverse::Continue
389    }
390    fn enter_bag(&mut self, _bag: &'ast ast::Bag) -> Traverse {
391        Traverse::Continue
392    }
393    fn exit_bag(&mut self, _bag: &'ast ast::Bag) -> Traverse {
394        Traverse::Continue
395    }
396    fn enter_list(&mut self, _list: &'ast ast::List) -> Traverse {
397        Traverse::Continue
398    }
399    fn exit_list(&mut self, _list: &'ast ast::List) -> Traverse {
400        Traverse::Continue
401    }
402    fn enter_call(&mut self, _call: &'ast ast::Call) -> Traverse {
403        Traverse::Continue
404    }
405    fn exit_call(&mut self, _call: &'ast ast::Call) -> Traverse {
406        Traverse::Continue
407    }
408    fn enter_call_arg(&mut self, _call_arg: &'ast ast::CallArg) -> Traverse {
409        Traverse::Continue
410    }
411    fn exit_call_arg(&mut self, _call_arg: &'ast ast::CallArg) -> Traverse {
412        Traverse::Continue
413    }
414    fn enter_call_arg_named(&mut self, _call_arg_named: &'ast ast::CallArgNamed) -> Traverse {
415        Traverse::Continue
416    }
417    fn exit_call_arg_named(&mut self, _call_arg_named: &'ast ast::CallArgNamed) -> Traverse {
418        Traverse::Continue
419    }
420    fn enter_call_arg_named_type(
421        &mut self,
422        _call_arg_named_type: &'ast ast::CallArgNamedType,
423    ) -> Traverse {
424        Traverse::Continue
425    }
426    fn exit_call_arg_named_type(
427        &mut self,
428        _call_arg_named_type: &'ast ast::CallArgNamedType,
429    ) -> Traverse {
430        Traverse::Continue
431    }
432    fn enter_call_agg(&mut self, _call_agg: &'ast ast::CallAgg) -> Traverse {
433        Traverse::Continue
434    }
435    fn exit_call_agg(&mut self, _call_agg: &'ast ast::CallAgg) -> Traverse {
436        Traverse::Continue
437    }
438    fn enter_path(&mut self, _path: &'ast ast::Path) -> Traverse {
439        Traverse::Continue
440    }
441    fn exit_path(&mut self, _path: &'ast ast::Path) -> Traverse {
442        Traverse::Continue
443    }
444    fn enter_path_step(&mut self, _path_step: &'ast ast::PathStep) -> Traverse {
445        Traverse::Continue
446    }
447    fn exit_path_step(&mut self, _path_step: &'ast ast::PathStep) -> Traverse {
448        Traverse::Continue
449    }
450    fn enter_path_expr(&mut self, _path_expr: &'ast ast::PathExpr) -> Traverse {
451        Traverse::Continue
452    }
453    fn exit_path_expr(&mut self, _path_expr: &'ast ast::PathExpr) -> Traverse {
454        Traverse::Continue
455    }
456    fn enter_let(&mut self, _let: &'ast ast::Let) -> Traverse {
457        Traverse::Continue
458    }
459    fn exit_let(&mut self, _let: &'ast ast::Let) -> Traverse {
460        Traverse::Continue
461    }
462    fn enter_let_binding(&mut self, _let_binding: &'ast ast::LetBinding) -> Traverse {
463        Traverse::Continue
464    }
465    fn exit_let_binding(&mut self, _let_binding: &'ast ast::LetBinding) -> Traverse {
466        Traverse::Continue
467    }
468    fn enter_from_clause(&mut self, _from_clause: &'ast ast::FromClause) -> Traverse {
469        Traverse::Continue
470    }
471    fn exit_from_clause(&mut self, _from_clause: &'ast ast::FromClause) -> Traverse {
472        Traverse::Continue
473    }
474    fn enter_from_source(&mut self, _from_clause: &'ast ast::FromSource) -> Traverse {
475        Traverse::Continue
476    }
477    fn exit_from_source(&mut self, _from_clause: &'ast ast::FromSource) -> Traverse {
478        Traverse::Continue
479    }
480    fn enter_where_clause(&mut self, _where_clause: &'ast ast::WhereClause) -> Traverse {
481        Traverse::Continue
482    }
483    fn exit_where_clause(&mut self, _where_clause: &'ast ast::WhereClause) -> Traverse {
484        Traverse::Continue
485    }
486    fn enter_having_clause(&mut self, _having_clause: &'ast ast::HavingClause) -> Traverse {
487        Traverse::Continue
488    }
489    fn exit_having_clause(&mut self, _having_clause: &'ast ast::HavingClause) -> Traverse {
490        Traverse::Continue
491    }
492    fn enter_from_let(&mut self, _from_let: &'ast ast::FromLet) -> Traverse {
493        Traverse::Continue
494    }
495    fn exit_from_let(&mut self, _from_let: &'ast ast::FromLet) -> Traverse {
496        Traverse::Continue
497    }
498    fn enter_join(&mut self, _join: &'ast ast::Join) -> Traverse {
499        Traverse::Continue
500    }
501    fn exit_join(&mut self, _join: &'ast ast::Join) -> Traverse {
502        Traverse::Continue
503    }
504    fn enter_join_spec(&mut self, _join_spec: &'ast ast::JoinSpec) -> Traverse {
505        Traverse::Continue
506    }
507    fn exit_join_spec(&mut self, _join_spec: &'ast ast::JoinSpec) -> Traverse {
508        Traverse::Continue
509    }
510
511    fn enter_graph_table(&mut self, _gtable: &'ast ast::GraphTable) -> Traverse {
512        Traverse::Continue
513    }
514    fn exit_graph_table(&mut self, _gtable: &'ast ast::GraphTable) -> Traverse {
515        Traverse::Continue
516    }
517
518    fn enter_graph_match(&mut self, _gmatch: &'ast ast::GraphMatch) -> Traverse {
519        Traverse::Continue
520    }
521    fn exit_graph_match(&mut self, _gmatch: &'ast ast::GraphMatch) -> Traverse {
522        Traverse::Continue
523    }
524
525    fn enter_graph_pattern(&mut self, _graph_pattern: &'ast ast::GraphPattern) -> Traverse {
526        Traverse::Continue
527    }
528    fn exit_graph_pattern(&mut self, _graph_pattern: &'ast ast::GraphPattern) -> Traverse {
529        Traverse::Continue
530    }
531
532    fn enter_graph_path_pattern(
533        &mut self,
534        _graph_pattern: &'ast ast::GraphPathPattern,
535    ) -> Traverse {
536        Traverse::Continue
537    }
538    fn exit_graph_path_pattern(&mut self, _graph_pattern: &'ast ast::GraphPathPattern) -> Traverse {
539        Traverse::Continue
540    }
541
542    fn enter_graph_path_sub_pattern(
543        &mut self,
544        _graph_pattern: &'ast ast::GraphPathSubPattern,
545    ) -> Traverse {
546        Traverse::Continue
547    }
548    fn exit_graph_path_sub_pattern(
549        &mut self,
550        _graph_pattern: &'ast ast::GraphPathSubPattern,
551    ) -> Traverse {
552        Traverse::Continue
553    }
554
555    fn enter_graph_match_path_pattern(
556        &mut self,
557        _graph_pattern: &'ast ast::GraphMatchPathPattern,
558    ) -> Traverse {
559        Traverse::Continue
560    }
561    fn exit_graph_match_path_pattern(
562        &mut self,
563        _graph_pattern: &'ast ast::GraphMatchPathPattern,
564    ) -> Traverse {
565        Traverse::Continue
566    }
567
568    fn enter_graph_match_path_pattern_quantified(
569        &mut self,
570        _graph_pattern: &'ast ast::GraphMatchPathPatternQuantified,
571    ) -> Traverse {
572        Traverse::Continue
573    }
574    fn exit_graph_match_path_pattern_quantified(
575        &mut self,
576        _graph_pattern: &'ast ast::GraphMatchPathPatternQuantified,
577    ) -> Traverse {
578        Traverse::Continue
579    }
580    fn enter_graph_match_node(&mut self, _graph_pattern: &'ast ast::GraphMatchNode) -> Traverse {
581        Traverse::Continue
582    }
583    fn exit_graph_match_node(&mut self, _graph_pattern: &'ast ast::GraphMatchNode) -> Traverse {
584        Traverse::Continue
585    }
586    fn enter_graph_match_edge(&mut self, _graph_pattern: &'ast ast::GraphMatchEdge) -> Traverse {
587        Traverse::Continue
588    }
589    fn exit_graph_match_edge(&mut self, _graph_pattern: &'ast ast::GraphMatchEdge) -> Traverse {
590        Traverse::Continue
591    }
592
593    fn enter_group_by_expr(&mut self, _group_by_expr: &'ast ast::GroupByExpr) -> Traverse {
594        Traverse::Continue
595    }
596    fn exit_group_by_expr(&mut self, _group_by_expr: &'ast ast::GroupByExpr) -> Traverse {
597        Traverse::Continue
598    }
599    fn enter_group_key(&mut self, _group_key: &'ast ast::GroupKey) -> Traverse {
600        Traverse::Continue
601    }
602    fn exit_group_key(&mut self, _group_key: &'ast ast::GroupKey) -> Traverse {
603        Traverse::Continue
604    }
605    fn enter_order_by_expr(&mut self, _order_by_expr: &'ast ast::OrderByExpr) -> Traverse {
606        Traverse::Continue
607    }
608    fn exit_order_by_expr(&mut self, _order_by_expr: &'ast ast::OrderByExpr) -> Traverse {
609        Traverse::Continue
610    }
611    fn enter_limit_offset_clause(
612        &mut self,
613        _limit_offset: &'ast ast::LimitOffsetClause,
614    ) -> Traverse {
615        Traverse::Continue
616    }
617    fn exit_limit_offset_clause(
618        &mut self,
619        _limit_offset: &'ast ast::LimitOffsetClause,
620    ) -> Traverse {
621        Traverse::Continue
622    }
623    fn enter_sort_spec(&mut self, _sort_spec: &'ast ast::SortSpec) -> Traverse {
624        Traverse::Continue
625    }
626    fn exit_sort_spec(&mut self, _sort_spec: &'ast ast::SortSpec) -> Traverse {
627        Traverse::Continue
628    }
629    fn enter_custom_type(&mut self, _custom_type: &'ast ast::CustomType) -> Traverse {
630        Traverse::Continue
631    }
632    fn exit_custom_type(&mut self, _custom_type: &'ast ast::CustomType) -> Traverse {
633        Traverse::Continue
634    }
635}
636
637#[cfg(test)]
638mod tests {
639    use crate::ast;
640    use crate::visit::{Traverse, Visitor};
641    use ast::{AstNode, BinOp, BinOpKind, Expr, Lit};
642    use partiql_common::node::NodeId;
643    use std::ops::AddAssign;
644
645    #[test]
646    fn visit_accum() {
647        #[derive(Default)]
648        struct Accum {
649            val: Option<i64>,
650        }
651
652        impl<'ast> Visitor<'ast> for Accum {
653            fn enter_lit(&mut self, literal: &'ast Lit) -> Traverse {
654                match literal {
655                    Lit::Int8Lit(l) => self.val.get_or_insert(0i64).add_assign(i64::from(*l)),
656                    Lit::Int16Lit(l) => self.val.get_or_insert(0i64).add_assign(i64::from(*l)),
657                    Lit::Int32Lit(l) => self.val.get_or_insert(0i64).add_assign(i64::from(*l)),
658                    Lit::Int64Lit(l) => self.val.get_or_insert(0i64).add_assign(l),
659                    _ => {}
660                }
661                Traverse::Continue
662            }
663        }
664
665        fn create_bin_op(op: BinOpKind, lhs: Expr, rhs: Expr) -> Expr {
666            Expr::BinOp(AstNode {
667                id: NodeId(1),
668                node: BinOp {
669                    kind: op,
670                    lhs: Box::new(lhs),
671                    rhs: Box::new(rhs),
672                },
673            })
674        }
675
676        fn create_bin_op_lit(op: BinOpKind, lhs: Lit, rhs: Lit) -> Expr {
677            let lhs = Expr::Lit(AstNode {
678                id: NodeId(1),
679                node: lhs,
680            });
681            let rhs = Expr::Lit(AstNode {
682                id: NodeId(1),
683                node: rhs,
684            });
685            create_bin_op(op, lhs, rhs)
686        }
687
688        let lhs = create_bin_op_lit(BinOpKind::Add, Lit::Int32Lit(5), Lit::Int16Lit(4));
689        let rhs = create_bin_op_lit(BinOpKind::Mul, Lit::Int8Lit(-20), Lit::Int64Lit(3000));
690        let ast = create_bin_op(BinOpKind::Div, lhs, rhs);
691
692        let mut acc = Accum::default();
693
694        use super::Visit;
695        assert_eq!(Traverse::Continue, ast.visit(&mut acc));
696
697        let val = acc.val;
698        assert!(matches!(val, Some(2989)));
699    }
700}