Skip to content

Commit dfb7c2e

Browse files
authored
feat(geth-eventql): new eventql query parser (#41)
1 parent 75cd0cd commit dfb7c2e

18 files changed

+1428
-0
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ members = [
1212
"geth-node",
1313
"geth-grpc",
1414
"geth-quickstart",
15+
"geth-eventql",
1516
]

geth-eventql/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "geth-eventql"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]
7+
eyre = "0.6"

geth-eventql/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use crate::tokenizer::{Lexer, Pos};
2+
3+
mod parser;
4+
mod sym;
5+
mod tokenizer;
6+
7+
#[cfg(test)]
8+
mod tests;
9+
10+
pub use parser::{Expr, From, Limit, LimitKind, Order, Query, Sort, Value, Where};
11+
12+
pub fn parse(query: &str) -> eyre::Result<Query<Pos>> {
13+
let lexer = Lexer::new(query);
14+
parser::parse(lexer)
15+
}

geth-eventql/src/parser/ast.rs

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
use std::collections::HashMap;
2+
3+
use crate::sym::{Literal, Operation};
4+
5+
pub struct Query<A> {
6+
pub tag: A,
7+
pub from_stmts: Vec<From<A>>,
8+
pub predicate: Option<Where<A>>,
9+
pub group_by: Option<Expr<A>>,
10+
pub order_by: Option<Sort<A>>,
11+
pub limit: Option<Limit>,
12+
pub projection: Expr<A>,
13+
}
14+
15+
pub enum SourceType<A> {
16+
Events,
17+
Subject(String),
18+
Subquery(Box<Query<A>>),
19+
}
20+
21+
impl<A> SourceType<A> {
22+
pub fn as_subject(&self) -> Option<&String> {
23+
if let Self::Subject(sub) = self {
24+
return Some(sub);
25+
}
26+
27+
None
28+
}
29+
30+
pub fn targets_events(&self) -> bool {
31+
if let Self::Events = self {
32+
return true;
33+
}
34+
35+
false
36+
}
37+
}
38+
39+
pub struct Source<A> {
40+
pub tag: A,
41+
pub inner: SourceType<A>,
42+
}
43+
44+
impl<A> Source<A> {
45+
pub fn as_subquery(&self) -> Option<&Query<A>> {
46+
if let SourceType::Subquery(q) = &self.inner {
47+
return Some(q);
48+
}
49+
50+
None
51+
}
52+
}
53+
54+
pub struct From<A> {
55+
pub tag: A,
56+
pub ident: String,
57+
pub source: Source<A>,
58+
}
59+
60+
pub struct Where<A> {
61+
pub tag: A,
62+
pub expr: Expr<A>,
63+
}
64+
65+
pub struct Expr<A> {
66+
pub tag: A,
67+
pub value: Value<A>,
68+
}
69+
70+
impl<A> Expr<A> {
71+
pub fn as_path(&self) -> Option<&Vec<String>> {
72+
if let Value::Path(p) = &self.value {
73+
return Some(p);
74+
}
75+
76+
None
77+
}
78+
79+
pub fn as_binary_op(&self) -> Option<BinaryOp<'_, A>> {
80+
if let Value::Binary { lhs, op, rhs } = &self.value {
81+
return Some(BinaryOp {
82+
lhs: lhs.as_ref(),
83+
op: *op,
84+
rhs: rhs.as_ref(),
85+
});
86+
}
87+
88+
None
89+
}
90+
91+
pub fn as_string_literal(&self) -> Option<&String> {
92+
if let Value::Literal(Literal::String(s)) = &self.value {
93+
return Some(s);
94+
}
95+
96+
None
97+
}
98+
99+
pub fn as_i64_literal(&self) -> Option<i64> {
100+
if let Value::Literal(Literal::Integral(i)) = &self.value {
101+
return Some(*i);
102+
}
103+
104+
None
105+
}
106+
107+
pub fn as_record(&self) -> Option<&Record<A>> {
108+
if let Value::Record(r) = &self.value {
109+
return Some(r);
110+
}
111+
112+
None
113+
}
114+
115+
pub fn as_apply_fun(&self) -> Option<ApplyFun<'_, A>> {
116+
if let Value::App { fun, params } = &self.value {
117+
return Some(ApplyFun { name: fun, params });
118+
}
119+
120+
None
121+
}
122+
}
123+
124+
pub struct BinaryOp<'a, A> {
125+
pub lhs: &'a Expr<A>,
126+
pub op: Operation,
127+
pub rhs: &'a Expr<A>,
128+
}
129+
130+
pub struct ApplyFun<'a, A> {
131+
pub name: &'a String,
132+
pub params: &'a Vec<Expr<A>>,
133+
}
134+
135+
pub enum Value<A> {
136+
Literal(Literal),
137+
Path(Vec<String>),
138+
Record(Record<A>),
139+
Array(Vec<Expr<A>>),
140+
App {
141+
fun: String,
142+
params: Vec<Expr<A>>,
143+
},
144+
Binary {
145+
lhs: Box<Expr<A>>,
146+
op: Operation,
147+
rhs: Box<Expr<A>>,
148+
},
149+
Unary {
150+
op: Operation,
151+
expr: Box<Expr<A>>,
152+
},
153+
}
154+
155+
pub struct Record<A> {
156+
pub fields: HashMap<String, Expr<A>>,
157+
}
158+
159+
impl<A> Record<A> {
160+
pub fn get(&self, id: &str) -> Option<&Expr<A>> {
161+
self.fields.get(id)
162+
}
163+
}
164+
165+
pub struct Sort<A> {
166+
pub expr: Expr<A>,
167+
pub order: Order,
168+
}
169+
170+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
171+
pub enum LimitKind {
172+
Skip,
173+
Top,
174+
}
175+
176+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
177+
pub struct Limit {
178+
pub kind: LimitKind,
179+
pub value: u64,
180+
}
181+
182+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
183+
pub enum Order {
184+
Asc,
185+
Desc,
186+
}

0 commit comments

Comments
 (0)