eventql_parser/ast.rs
1//! Abstract syntax tree (AST) types for EventQL.
2//!
3//! This module defines the structure of parsed EventQL queries as an abstract
4//! syntax tree. The AST represents the semantic structure of a query, making it
5//! easy to analyze, transform, or execute queries.
6//!
7//! # Core Types
8//!
9//! - [`Query`] - The root of the AST, representing a complete query
10//! - [`Expr`] - Expressions with position and type information
11//! - [`Value`] - The various kinds of expression values (literals, operators, etc.)
12//! - [`Source`] - Data sources in FROM clauses
13//!
14use crate::token::{Operator, Token};
15use serde::Serialize;
16
17/// Position information for source code locations.
18///
19/// This struct tracks the line and column number of tokens and AST nodes,
20/// which is useful for error reporting and debugging.
21///
22/// # Examples
23///
24/// ```
25/// use eventql_parser::Pos;
26///
27/// let pos = Pos { line: 1, col: 10 };
28/// assert_eq!(pos.line, 1);
29/// assert_eq!(pos.col, 10);
30/// ```
31#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
32pub struct Pos {
33 /// Line number (1-indexed)
34 pub line: u32,
35 /// Column number (1-indexed)
36 pub col: u32,
37}
38
39impl From<Token<'_>> for Pos {
40 fn from(value: Token<'_>) -> Self {
41 Self {
42 line: value.line,
43 col: value.col,
44 }
45 }
46}
47
48/// Type information for expressions.
49///
50/// This enum represents the type of an expression in the EventQL type system.
51/// Types can be inferred during semantic analysis or left as `Unspecified`.
52#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize)]
53pub enum Type {
54 /// Type has not been determined yet
55 Unspecified,
56 /// Numeric type (f64)
57 Number,
58 /// String type
59 String,
60 /// Boolean type
61 Bool,
62 /// Array type
63 Array,
64 /// Record (object) type
65 Record,
66 /// Subject pattern type
67 Subject,
68}
69
70/// Attributes attached to each expression node.
71///
72/// These attributes provide metadata about an expression, including its
73/// position in the source code, scope information, and type information.
74#[derive(Debug, Clone, Copy, Serialize)]
75pub struct Attrs {
76 /// Source position of this expression
77 pub pos: Pos,
78 /// Scope level (0 for top-level, incremented for subqueries)
79 pub scope: u64,
80 /// Type of this expression
81 pub tpe: Type,
82}
83
84impl Attrs {
85 /// Create new attributes with unspecified type.
86 pub fn new(pos: Pos, scope: u64) -> Self {
87 Self {
88 pos,
89 scope,
90 tpe: Type::Unspecified,
91 }
92 }
93}
94
95/// An expression with metadata.
96///
97/// This is the fundamental building block of the AST. Every expression
98/// carries attributes (position, scope, type) and a value that determines
99/// what kind of expression it is.
100#[derive(Debug, Clone, Serialize)]
101pub struct Expr {
102 /// Metadata about this expression
103 pub attrs: Attrs,
104 /// The value/kind of this expression
105 pub value: Value,
106}
107
108/// Field access expression (e.g., `e.data.price`).
109///
110/// Represents accessing a field of a record or object using dot notation.
111/// Can be chained for nested field access.
112///
113/// # Examples
114///
115/// In the query `WHERE e.data.user.id == 1`, the expression `e.data.user.id`
116/// is parsed as nested `Access` nodes.
117#[derive(Debug, Clone, Serialize)]
118pub struct Access {
119 /// The target expression being accessed
120 pub target: Box<Expr>,
121 /// The name of the field being accessed
122 pub field: String,
123}
124
125/// Function application (e.g., `sum(e.price)`, `count()`).
126///
127/// Represents a function call with zero or more arguments.
128///
129/// # Examples
130///
131/// In the query `WHERE count(e.items) > 5`, the `count(e.items)` is an `App` node.
132#[derive(Debug, Clone, Serialize)]
133pub struct App {
134 /// Name of the function being called
135 pub func: String,
136 /// Arguments passed to the function
137 pub args: Vec<Expr>,
138}
139
140/// A field in a record literal (e.g., `{name: "Alice", age: 30}`).
141///
142/// Represents a key-value pair in a record construction.
143#[derive(Debug, Clone, Serialize)]
144pub struct Field {
145 /// Field name
146 pub name: String,
147 /// Field value expression
148 pub value: Expr,
149}
150
151/// Binary operation (e.g., `a + b`, `x == y`, `p AND q`).
152///
153/// Represents operations that take two operands, including arithmetic,
154/// comparison, and logical operators.
155///
156/// # Examples
157///
158/// In `WHERE e.price > 100 AND e.active == true`, there are multiple
159/// binary operations: `>`, `==`, and `AND`.
160#[derive(Debug, Clone, Serialize)]
161pub struct Binary {
162 /// Left-hand side operand
163 pub lhs: Box<Expr>,
164 /// The operator
165 pub operator: Operator,
166 /// Right-hand side operand
167 pub rhs: Box<Expr>,
168}
169
170/// Unary operation (e.g., `-x`, `NOT active`).
171///
172/// Represents operations that take a single operand.
173///
174/// # Examples
175///
176/// In `WHERE NOT e.deleted`, the `NOT e.deleted` is a unary operation.
177#[derive(Debug, Clone, Serialize)]
178pub struct Unary {
179 /// The operator (Add for +, Sub for -, Not for NOT)
180 pub operator: Operator,
181 /// The operand expression
182 pub expr: Box<Expr>,
183}
184
185/// The kind of value an expression represents.
186///
187/// This enum contains all the different types of expressions that can appear
188/// in an EventQL query, from simple literals to complex operations.
189#[derive(Debug, Clone, Serialize)]
190pub enum Value {
191 /// Numeric literal (e.g., `42`, `3.14`)
192 Number(f64),
193 /// String literal (e.g., `"hello"`)
194 String(String),
195 /// Boolean literal (`true` or `false`)
196 Bool(bool),
197 /// Identifier (e.g., variable name `e`, `x`)
198 Id(String),
199 /// Array literal (e.g., `[1, 2, 3]`)
200 Array(Vec<Expr>),
201 /// Record literal (e.g., `{name: "Alice", age: 30}`)
202 Record(Vec<Field>),
203 /// Field access (e.g., `e.data.price`)
204 Access(Access),
205 /// Function application (e.g., `sum(e.price)`)
206 App(App),
207 /// Binary operation (e.g., `a + b`, `x == y`)
208 Binary(Binary),
209 /// Unary operation (e.g., `-x`, `NOT active`)
210 Unary(Unary),
211 /// Grouped/parenthesized expression (e.g., `(a + b)`)
212 Group(Box<Expr>),
213}
214
215/// A data source in a FROM clause.
216///
217/// Sources specify where data comes from in a query. Each source has a binding
218/// (the variable name) and a kind (what it binds to).
219///
220/// # Examples
221///
222/// In `FROM e IN events`, the source has:
223/// - `binding`: `"e"`
224/// - `kind`: `SourceKind::Name("events")`
225#[derive(Debug, Clone, Serialize)]
226pub struct Source {
227 /// Variable name bound to this source
228 pub binding: String,
229 /// What this source represents
230 pub kind: SourceKind,
231}
232
233/// The kind of data source.
234///
235/// EventQL supports three types of sources:
236/// - Named sources (e.g., `FROM e IN events`)
237/// - Subject patterns (e.g., `FROM e IN "users/john"`)
238/// - Subqueries (e.g., `FROM e IN (SELECT ...)`)
239#[derive(Debug, Clone, Serialize)]
240pub enum SourceKind {
241 /// Named source (identifier)
242 Name(String),
243 /// Subject pattern (string literal used as event subject pattern)
244 Subject(String),
245 /// Nested subquery
246 Subquery(Box<Query>),
247}
248
249/// ORDER BY clause specification.
250///
251/// Defines how query results should be sorted.
252///
253/// # Examples
254///
255/// In `ORDER BY e.timestamp DESC`, this would be represented as:
256/// - `expr`: expression for `e.timestamp`
257/// - `order`: `Order::Desc`
258#[derive(Debug, Clone, Serialize)]
259pub struct OrderBy {
260 /// Expression to sort by
261 pub expr: Expr,
262 /// Sort direction (ascending or descending)
263 pub order: Order,
264}
265
266/// Sort order direction.
267///
268/// Specifies whether sorting is ascending or descending.
269#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
270pub enum Order {
271 /// Ascending order (smallest to largest)
272 Asc,
273 /// Descending order (largest to smallest)
274 Desc,
275}
276
277/// GROUP BY clause specification
278///
279/// Defines how query results should be order by.
280/// # Examples
281///
282/// In `GROUP BY e.age HAVING age > 123`, this would be represented as:
283/// - `expr`: expression for `e.age`
284/// - `predicate`: `age > 123`
285#[derive(Debug, Clone, Serialize)]
286pub struct GroupBy {
287 /// Expression to group by
288 pub expr: Expr,
289
290 /// Predicate to filter groups after aggregation
291 pub predicate: Option<Expr>,
292}
293
294/// Result set limit specification.
295///
296/// EventQL supports two types of limits:
297/// - `TOP n` - Take the first n results
298/// - `SKIP n` - Skip the first n results
299///
300/// # Examples
301///
302/// - `TOP 10` limits to first 10 results
303/// - `SKIP 20` skips first 20 results
304#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
305pub enum Limit {
306 /// Skip the first n results
307 Skip(u64),
308 /// Take only the first n results
309 Top(u64),
310}
311
312/// A complete EventQL query.
313///
314/// This is the root node of the AST, representing a full query with all its clauses.
315/// A query must have at least one source and a projection; other clauses are optional.
316///
317/// # Structure
318///
319/// ```text
320/// FROM <alias> <source>
321/// [FROM <alias> <source>] ...
322/// [WHERE <condition>]
323/// [GROUP BY <field> [HAVING <condition>]]
324/// [ORDER BY <field> ASC|DESC]
325/// [TOP|SKIP <n>]
326/// PROJECT INTO [DISTINCT] <projection>
327/// ```
328///
329/// # Examples
330///
331/// ```
332/// use eventql_parser::parse_query;
333///
334/// let query = parse_query(
335/// "FROM e IN events \
336/// WHERE e.price > 100 \
337/// ORDER BY e.timestamp DESC \
338/// TOP 10 \
339/// PROJECT INTO {id: e.id, price: e.price}"
340/// ).unwrap();
341///
342/// assert_eq!(query.sources.len(), 1);
343/// assert!(query.predicate.is_some());
344/// assert!(query.order_by.is_some());
345/// assert!(query.limit.is_some());
346/// ```
347#[derive(Debug, Clone, Serialize)]
348pub struct Query {
349 /// Metadata about this query
350 pub attrs: Attrs,
351 /// FROM clause sources (must have at least one)
352 pub sources: Vec<Source>,
353 /// Optional WHERE clause filter predicate
354 pub predicate: Option<Expr>,
355 /// Optional GROUP BY clause expression
356 pub group_by: Option<GroupBy>,
357 /// Optional ORDER BY clause
358 pub order_by: Option<OrderBy>,
359 /// Optional LIMIT clause (TOP or SKIP)
360 pub limit: Option<Limit>,
361 /// PROJECT INTO clause expression (required)
362 pub projection: Expr,
363 /// Remove duplicate rows from the query's results
364 pub distinct: bool,
365}