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/// Result set limit specification.
278///
279/// EventQL supports two types of limits:
280/// - `TOP n` - Take the first n results
281/// - `SKIP n` - Skip the first n results
282///
283/// # Examples
284///
285/// - `TOP 10` limits to first 10 results
286/// - `SKIP 20` skips first 20 results
287#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
288pub enum Limit {
289    /// Skip the first n results
290    Skip(u64),
291    /// Take only the first n results
292    Top(u64),
293}
294
295/// A complete EventQL query.
296///
297/// This is the root node of the AST, representing a full query with all its clauses.
298/// A query must have at least one source and a projection; other clauses are optional.
299///
300/// # Structure
301///
302/// ```text
303/// FROM <sources>
304/// [WHERE <predicate>]
305/// [GROUP BY <expr>]
306/// [ORDER BY <expr> ASC|DESC]
307/// [TOP|SKIP <n>]
308/// PROJECT INTO <projection>
309/// ```
310///
311/// # Examples
312///
313/// ```
314/// use eventql_parser::parse_query;
315///
316/// let query = parse_query(
317///     "FROM e IN events \
318///      WHERE e.price > 100 \
319///      ORDER BY e.timestamp DESC \
320///      TOP 10 \
321///      PROJECT INTO {id: e.id, price: e.price}"
322/// ).unwrap();
323///
324/// assert_eq!(query.sources.len(), 1);
325/// assert!(query.predicate.is_some());
326/// assert!(query.order_by.is_some());
327/// assert!(query.limit.is_some());
328/// ```
329#[derive(Debug, Clone, Serialize)]
330pub struct Query {
331    /// Metadata about this query
332    pub attrs: Attrs,
333    /// FROM clause sources (must have at least one)
334    pub sources: Vec<Source>,
335    /// Optional WHERE clause filter predicate
336    pub predicate: Option<Expr>,
337    /// Optional GROUP BY clause expression
338    pub group_by: Option<Expr>,
339    /// Optional ORDER BY clause
340    pub order_by: Option<OrderBy>,
341    /// Optional LIMIT clause (TOP or SKIP)
342    pub limit: Option<Limit>,
343    /// PROJECT INTO clause expression (required)
344    pub projection: Expr,
345}