1use crate::ast;
2use partiql_common::node::NodeId;
3
4#[derive(PartialEq, Debug)]
6pub enum Traverse {
7 Continue,
9 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}