Skip to content

Commit 5b014f8

Browse files
committed
feat(geth-engine): implement EventQL query execution
1 parent d5aa7a1 commit 5b014f8

3 files changed

Lines changed: 547 additions & 426 deletions

File tree

geth-eventql/src/codegen.rs

Lines changed: 127 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,79 @@
11
use crate::{
2-
Expr, ExprVisitor, Literal, NodeAttributes, Operation, Query, QueryVisitor, Var, parser::Record,
2+
Expr, ExprVisitor, Literal, NodeAttributes, Operation, Query, QueryVisitor, Subject, Var,
3+
parser::Record,
34
};
45

6+
trait IntoLiteral {
7+
fn into_literal(self) -> Literal;
8+
}
9+
10+
impl IntoLiteral for String {
11+
fn into_literal(self) -> Literal {
12+
Literal::String(self)
13+
}
14+
}
15+
16+
impl IntoLiteral for &'_ str {
17+
fn into_literal(self) -> Literal {
18+
Literal::String(self.to_string())
19+
}
20+
}
21+
22+
impl IntoLiteral for &'_ String {
23+
fn into_literal(self) -> Literal {
24+
Literal::String(self.to_string())
25+
}
26+
}
27+
28+
impl IntoLiteral for u64 {
29+
fn into_literal(self) -> Literal {
30+
Literal::Integral(self as i64)
31+
}
32+
}
33+
34+
impl IntoLiteral for i64 {
35+
fn into_literal(self) -> Literal {
36+
Literal::Integral(self)
37+
}
38+
}
39+
40+
impl IntoLiteral for usize {
41+
fn into_literal(self) -> Literal {
42+
Literal::Integral(self as i64)
43+
}
44+
}
45+
546
pub enum Instr {
47+
EnterScope,
48+
ExitScope,
649
Push(Literal),
7-
LoadVar(Var),
50+
EnterSource,
51+
ExitSource,
52+
LoadVar,
53+
LoadSource,
854
Operation(Operation),
9-
Array(usize),
55+
Array,
1056
Rec(usize),
1157
Call(String),
1258
}
1359

60+
impl Instr {
61+
pub fn push(value: impl IntoLiteral) -> Self {
62+
Instr::Push(value.into_literal())
63+
}
64+
}
65+
66+
pub enum SourceKind {
67+
Events,
68+
Subject,
69+
Subquery,
70+
}
71+
72+
pub struct LoadSource {
73+
binding: String,
74+
scope: u64,
75+
}
76+
1477
pub fn codegen(query: &Query) -> Vec<Instr> {
1578
let mut state = Codegen::default();
1679

@@ -27,6 +90,54 @@ pub struct Codegen {
2790
impl QueryVisitor for Codegen {
2891
type Inner<'a> = ExprCodegen<'a>;
2992

93+
fn enter_query(&mut self, attrs: &NodeAttributes) {
94+
self.instrs.push(Instr::push(attrs.scope));
95+
self.instrs.push(Instr::EnterScope);
96+
}
97+
98+
fn enter_from(&mut self, attrs: &NodeAttributes, _ident: &str) {
99+
self.instrs.push(Instr::push(attrs.scope));
100+
self.instrs.push(Instr::EnterSource);
101+
}
102+
103+
fn on_source_events(&mut self, attrs: &NodeAttributes, ident: &str) {
104+
self.instrs.push(Instr::push(attrs.scope));
105+
self.instrs.push(Instr::push(ident));
106+
self.instrs.push(Instr::push(0i64));
107+
self.instrs.push(Instr::LoadSource);
108+
}
109+
110+
fn on_source_subject(&mut self, attrs: &NodeAttributes, ident: &str, subject: &Subject) {
111+
self.instrs.push(Instr::push(attrs.scope));
112+
self.instrs.push(Instr::push(ident));
113+
for seg in subject.inner.iter() {
114+
self.instrs.push(Instr::push(seg));
115+
}
116+
117+
self.instrs.push(Instr::push(subject.inner.len()));
118+
self.instrs.push(Instr::Array);
119+
self.instrs.push(Instr::push(1i64));
120+
self.instrs.push(Instr::LoadSource);
121+
}
122+
123+
fn on_source_subquery(&mut self, attrs: &NodeAttributes, ident: &str) -> bool {
124+
self.instrs.push(Instr::push(attrs.scope));
125+
self.instrs.push(Instr::push(ident));
126+
self.instrs.push(Instr::push(2i64));
127+
self.instrs.push(Instr::LoadSource);
128+
129+
true
130+
}
131+
132+
fn exit_from(&mut self, attrs: &NodeAttributes, ident: &str) {
133+
self.instrs.push(Instr::push(attrs.scope));
134+
self.instrs.push(Instr::ExitSource);
135+
}
136+
137+
fn exit_query(&mut self) {
138+
self.instrs.push(Instr::ExitScope);
139+
}
140+
30141
fn expr_visitor<'a>(&'a mut self) -> Self::Inner<'a> {
31142
ExprCodegen { inner: self }
32143
}
@@ -41,8 +152,17 @@ impl ExprVisitor for ExprCodegen<'_> {
41152
self.inner.instrs.push(Instr::Push(lit.clone()));
42153
}
43154

44-
fn on_var(&mut self, _attrs: &NodeAttributes, var: &Var) {
45-
self.inner.instrs.push(Instr::LoadVar(var.clone()));
155+
fn on_var(&mut self, attrs: &NodeAttributes, var: &Var) {
156+
self.inner.instrs.push(Instr::push(attrs.scope));
157+
158+
self.inner.instrs.push(Instr::push(var.name.as_str()));
159+
for seg in &var.path {
160+
self.inner.instrs.push(Instr::push(seg));
161+
}
162+
163+
self.inner.instrs.push(Instr::push(var.path.len() + 1));
164+
self.inner.instrs.push(Instr::Array);
165+
self.inner.instrs.push(Instr::LoadVar);
46166
}
47167

48168
fn enter_record_entry(&mut self, _attrs: &NodeAttributes, key: &str, _expr: &Expr) {
@@ -56,7 +176,8 @@ impl ExprVisitor for ExprCodegen<'_> {
56176
}
57177

58178
fn exit_array(&mut self, _attrs: &NodeAttributes, values: &[Expr]) {
59-
self.inner.instrs.push(Instr::Array(values.len()));
179+
self.inner.instrs.push(Instr::push(values.len()));
180+
self.inner.instrs.push(Instr::Array);
60181
}
61182

62183
fn exit_app(&mut self, _attrs: &NodeAttributes, name: &str, _params: &[Expr]) {

0 commit comments

Comments
 (0)