Skip to content

Commit f9f2ec2

Browse files
committed
implement query pre-order traversal
1 parent 0a5c958 commit f9f2ec2

File tree

1 file changed

+58
-1
lines changed

1 file changed

+58
-1
lines changed

geth-eventql/src/parser/ast.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{fmt::Display, ptr::NonNull};
1+
use std::{collections::VecDeque, fmt::Display, ptr::NonNull};
22

33
use crate::{
44
Pos, Type,
@@ -40,6 +40,13 @@ impl Query {
4040
pub fn dfs_post_order<V: QueryVisitor>(&self, visitor: &mut V) {
4141
query_dfs_post_order(vec![Item::new(self)], visitor);
4242
}
43+
44+
pub fn dfs_pre_order<V: QueryVisitor>(&self, visitor: &mut V) {
45+
let mut queue = VecDeque::new();
46+
queue.push_back(self);
47+
48+
query_dfs_pre_order(queue, visitor);
49+
}
4350
}
4451

4552
fn query_dfs_post_order_mut<V: QueryVisitorMut>(
@@ -115,6 +122,56 @@ fn on_expr_mut<V: QueryVisitorMut>(visitor: &mut V, expr: &mut Expr) -> crate::R
115122
expr.dfs_post_order_mut(&mut expr_visitor)
116123
}
117124

125+
fn query_dfs_pre_order<V: QueryVisitor>(mut queue: VecDeque<&Query>, visitor: &mut V) {
126+
while let Some(query) = queue.pop_front() {
127+
visitor.enter_query(&query.attrs);
128+
129+
for from_stmt in query.from_stmts.iter() {
130+
visitor.enter_from(&from_stmt.attrs, &from_stmt.ident);
131+
132+
match &from_stmt.source.inner {
133+
SourceType::Events => visitor.on_source_events(&from_stmt.attrs, &from_stmt.ident),
134+
135+
SourceType::Subject(subject) => {
136+
visitor.on_source_subject(&from_stmt.attrs, &from_stmt.ident, subject)
137+
}
138+
139+
SourceType::Subquery(query) => {
140+
if visitor.on_source_subquery(&from_stmt.attrs, &from_stmt.ident) {
141+
queue.push_back(query);
142+
}
143+
}
144+
}
145+
146+
visitor.exit_source(&from_stmt.source.attrs);
147+
visitor.exit_from(&from_stmt.attrs, &from_stmt.ident);
148+
}
149+
150+
if let Some(predicate) = query.predicate.as_ref() {
151+
visitor.enter_where_clause(&predicate.attrs, &predicate.expr);
152+
on_expr(visitor, &predicate.expr);
153+
visitor.exit_where_clause(&predicate.attrs, &predicate.expr);
154+
}
155+
156+
if let Some(expr) = query.group_by.as_ref() {
157+
visitor.enter_group_by(expr);
158+
on_expr(visitor, expr);
159+
visitor.leave_group_by(expr);
160+
}
161+
162+
if let Some(sort) = query.order_by.as_ref() {
163+
visitor.enter_order_by(&sort.order, &sort.expr);
164+
on_expr(visitor, &sort.expr);
165+
visitor.leave_order_by(&sort.order, &sort.expr);
166+
}
167+
168+
visitor.enter_projection(&query.projection);
169+
on_expr(visitor, &query.projection);
170+
visitor.leave_projection(&query.projection);
171+
visitor.exit_query();
172+
}
173+
}
174+
118175
fn query_dfs_post_order<V: QueryVisitor>(mut stack: Vec<Item<Query>>, visitor: &mut V) {
119176
while let Some(mut item) = stack.pop() {
120177
let query = item.value;

0 commit comments

Comments
 (0)