Skip to main content

oxigdal_query/parser/
ast.rs

1//! Abstract Syntax Tree definitions for query language.
2
3use serde::{Deserialize, Serialize};
4use std::fmt;
5
6/// A complete query statement.
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8pub enum Statement {
9    /// SELECT query.
10    Select(SelectStatement),
11}
12
13/// A SELECT statement.
14#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
15pub struct SelectStatement {
16    /// Projection list.
17    pub projection: Vec<SelectItem>,
18    /// FROM clause.
19    pub from: Option<TableReference>,
20    /// WHERE clause.
21    pub selection: Option<Expr>,
22    /// GROUP BY clause.
23    pub group_by: Vec<Expr>,
24    /// HAVING clause.
25    pub having: Option<Expr>,
26    /// ORDER BY clause.
27    pub order_by: Vec<OrderByExpr>,
28    /// LIMIT clause.
29    pub limit: Option<usize>,
30    /// OFFSET clause.
31    pub offset: Option<usize>,
32}
33
34/// A select item in the projection list.
35#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
36pub enum SelectItem {
37    /// Wildcard (*).
38    Wildcard,
39    /// Qualified wildcard (table.*).
40    QualifiedWildcard(String),
41    /// Expression with optional alias.
42    Expr {
43        /// The expression to select.
44        expr: Expr,
45        /// Optional alias for the expression.
46        alias: Option<String>,
47    },
48}
49
50/// A table reference in FROM clause.
51#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
52pub enum TableReference {
53    /// Base table.
54    Table {
55        /// Table name.
56        name: String,
57        /// Optional alias.
58        alias: Option<String>,
59    },
60    /// Join.
61    Join {
62        /// Left table.
63        left: Box<TableReference>,
64        /// Right table.
65        right: Box<TableReference>,
66        /// Join type.
67        join_type: JoinType,
68        /// Join condition.
69        on: Option<Expr>,
70    },
71    /// Subquery.
72    Subquery {
73        /// Subquery.
74        query: Box<SelectStatement>,
75        /// Alias.
76        alias: String,
77    },
78}
79
80/// Join type.
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
82pub enum JoinType {
83    /// Inner join.
84    Inner,
85    /// Left outer join.
86    Left,
87    /// Right outer join.
88    Right,
89    /// Full outer join.
90    Full,
91    /// Cross join.
92    Cross,
93}
94
95/// An expression.
96#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
97pub enum Expr {
98    /// Column reference.
99    Column {
100        /// Optional table qualifier.
101        table: Option<String>,
102        /// Column name.
103        name: String,
104    },
105    /// Literal value.
106    Literal(Literal),
107    /// Binary operation.
108    BinaryOp {
109        /// Left operand.
110        left: Box<Expr>,
111        /// Operator.
112        op: BinaryOperator,
113        /// Right operand.
114        right: Box<Expr>,
115    },
116    /// Unary operation.
117    UnaryOp {
118        /// Operator.
119        op: UnaryOperator,
120        /// Operand.
121        expr: Box<Expr>,
122    },
123    /// Function call.
124    Function {
125        /// Function name.
126        name: String,
127        /// Arguments.
128        args: Vec<Expr>,
129    },
130    /// CASE expression.
131    Case {
132        /// Optional operand (for CASE x WHEN ...).
133        operand: Option<Box<Expr>>,
134        /// WHEN conditions and results.
135        when_then: Vec<(Expr, Expr)>,
136        /// ELSE result.
137        else_result: Option<Box<Expr>>,
138    },
139    /// CAST expression.
140    Cast {
141        /// Expression to cast.
142        expr: Box<Expr>,
143        /// Target data type.
144        data_type: DataType,
145    },
146    /// IS NULL.
147    IsNull(Box<Expr>),
148    /// IS NOT NULL.
149    IsNotNull(Box<Expr>),
150    /// IN list.
151    InList {
152        /// Expression.
153        expr: Box<Expr>,
154        /// List of values.
155        list: Vec<Expr>,
156        /// Negated (NOT IN).
157        negated: bool,
158    },
159    /// BETWEEN.
160    Between {
161        /// Expression.
162        expr: Box<Expr>,
163        /// Lower bound.
164        low: Box<Expr>,
165        /// Upper bound.
166        high: Box<Expr>,
167        /// Negated (NOT BETWEEN).
168        negated: bool,
169    },
170    /// Subquery.
171    Subquery(Box<SelectStatement>),
172    /// Wildcard (*).
173    Wildcard,
174}
175
176/// A literal value.
177#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
178pub enum Literal {
179    /// Null value.
180    Null,
181    /// Boolean value.
182    Boolean(bool),
183    /// Integer value.
184    Integer(i64),
185    /// Float value.
186    Float(f64),
187    /// String value.
188    String(String),
189}
190
191/// Binary operator.
192#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
193pub enum BinaryOperator {
194    /// Addition (+).
195    Plus,
196    /// Subtraction (-).
197    Minus,
198    /// Multiplication (*).
199    Multiply,
200    /// Division (/).
201    Divide,
202    /// Modulo (%).
203    Modulo,
204    /// Equality (=).
205    Eq,
206    /// Inequality (<>).
207    NotEq,
208    /// Less than (<).
209    Lt,
210    /// Less than or equal (<=).
211    LtEq,
212    /// Greater than (>).
213    Gt,
214    /// Greater than or equal (>=).
215    GtEq,
216    /// Logical AND.
217    And,
218    /// Logical OR.
219    Or,
220    /// String concatenation (||).
221    Concat,
222    /// LIKE pattern matching.
223    Like,
224    /// NOT LIKE pattern matching.
225    NotLike,
226}
227
228/// Unary operator.
229#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
230pub enum UnaryOperator {
231    /// Negation (-).
232    Minus,
233    /// Logical NOT.
234    Not,
235}
236
237/// ORDER BY expression.
238#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
239pub struct OrderByExpr {
240    /// Expression to order by.
241    pub expr: Expr,
242    /// Ascending or descending.
243    pub asc: bool,
244    /// Nulls first or last.
245    pub nulls_first: bool,
246}
247
248/// Data type.
249#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
250pub enum DataType {
251    /// Boolean.
252    Boolean,
253    /// 8-bit signed integer.
254    Int8,
255    /// 16-bit signed integer.
256    Int16,
257    /// 32-bit signed integer.
258    Int32,
259    /// 64-bit signed integer.
260    Int64,
261    /// 8-bit unsigned integer.
262    UInt8,
263    /// 16-bit unsigned integer.
264    UInt16,
265    /// 32-bit unsigned integer.
266    UInt32,
267    /// 64-bit unsigned integer.
268    UInt64,
269    /// 32-bit float.
270    Float32,
271    /// 64-bit float.
272    Float64,
273    /// UTF-8 string.
274    String,
275    /// Binary data.
276    Binary,
277    /// Timestamp.
278    Timestamp,
279    /// Date.
280    Date,
281    /// Geometry.
282    Geometry,
283}
284
285impl fmt::Display for Statement {
286    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287        match self {
288            Statement::Select(select) => write!(f, "{}", select),
289        }
290    }
291}
292
293impl fmt::Display for SelectStatement {
294    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
295        write!(f, "SELECT ")?;
296        for (i, item) in self.projection.iter().enumerate() {
297            if i > 0 {
298                write!(f, ", ")?;
299            }
300            write!(f, "{}", item)?;
301        }
302        if let Some(from) = &self.from {
303            write!(f, " FROM {}", from)?;
304        }
305        if let Some(selection) = &self.selection {
306            write!(f, " WHERE {}", selection)?;
307        }
308        if !self.group_by.is_empty() {
309            write!(f, " GROUP BY ")?;
310            for (i, expr) in self.group_by.iter().enumerate() {
311                if i > 0 {
312                    write!(f, ", ")?;
313                }
314                write!(f, "{}", expr)?;
315            }
316        }
317        if let Some(having) = &self.having {
318            write!(f, " HAVING {}", having)?;
319        }
320        if !self.order_by.is_empty() {
321            write!(f, " ORDER BY ")?;
322            for (i, expr) in self.order_by.iter().enumerate() {
323                if i > 0 {
324                    write!(f, ", ")?;
325                }
326                write!(f, "{}", expr)?;
327            }
328        }
329        if let Some(limit) = self.limit {
330            write!(f, " LIMIT {}", limit)?;
331        }
332        if let Some(offset) = self.offset {
333            write!(f, " OFFSET {}", offset)?;
334        }
335        Ok(())
336    }
337}
338
339impl fmt::Display for SelectItem {
340    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
341        match self {
342            SelectItem::Wildcard => write!(f, "*"),
343            SelectItem::QualifiedWildcard(table) => write!(f, "{}.*", table),
344            SelectItem::Expr { expr, alias } => {
345                write!(f, "{}", expr)?;
346                if let Some(alias) = alias {
347                    write!(f, " AS {}", alias)?;
348                }
349                Ok(())
350            }
351        }
352    }
353}
354
355impl fmt::Display for TableReference {
356    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
357        match self {
358            TableReference::Table { name, alias } => {
359                write!(f, "{}", name)?;
360                if let Some(alias) = alias {
361                    write!(f, " AS {}", alias)?;
362                }
363                Ok(())
364            }
365            TableReference::Join {
366                left,
367                right,
368                join_type,
369                on,
370            } => {
371                write!(f, "{} {} JOIN {}", left, join_type, right)?;
372                if let Some(on) = on {
373                    write!(f, " ON {}", on)?;
374                }
375                Ok(())
376            }
377            TableReference::Subquery { query, alias } => {
378                write!(f, "({}) AS {}", query, alias)
379            }
380        }
381    }
382}
383
384impl fmt::Display for JoinType {
385    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
386        match self {
387            JoinType::Inner => write!(f, "INNER"),
388            JoinType::Left => write!(f, "LEFT"),
389            JoinType::Right => write!(f, "RIGHT"),
390            JoinType::Full => write!(f, "FULL"),
391            JoinType::Cross => write!(f, "CROSS"),
392        }
393    }
394}
395
396impl fmt::Display for Expr {
397    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
398        match self {
399            Expr::Column { table, name } => {
400                if let Some(table) = table {
401                    write!(f, "{}.{}", table, name)
402                } else {
403                    write!(f, "{}", name)
404                }
405            }
406            Expr::Literal(lit) => write!(f, "{}", lit),
407            Expr::BinaryOp { left, op, right } => {
408                write!(f, "({} {} {})", left, op, right)
409            }
410            Expr::UnaryOp { op, expr } => write!(f, "({} {})", op, expr),
411            Expr::Function { name, args } => {
412                write!(f, "{}(", name)?;
413                for (i, arg) in args.iter().enumerate() {
414                    if i > 0 {
415                        write!(f, ", ")?;
416                    }
417                    write!(f, "{}", arg)?;
418                }
419                write!(f, ")")
420            }
421            Expr::Case {
422                operand,
423                when_then,
424                else_result,
425            } => {
426                write!(f, "CASE")?;
427                if let Some(operand) = operand {
428                    write!(f, " {}", operand)?;
429                }
430                for (when, then) in when_then {
431                    write!(f, " WHEN {} THEN {}", when, then)?;
432                }
433                if let Some(else_result) = else_result {
434                    write!(f, " ELSE {}", else_result)?;
435                }
436                write!(f, " END")
437            }
438            Expr::Cast { expr, data_type } => {
439                write!(f, "CAST({} AS {:?})", expr, data_type)
440            }
441            Expr::IsNull(expr) => write!(f, "{} IS NULL", expr),
442            Expr::IsNotNull(expr) => write!(f, "{} IS NOT NULL", expr),
443            Expr::InList {
444                expr,
445                list,
446                negated,
447            } => {
448                write!(f, "{}", expr)?;
449                if *negated {
450                    write!(f, " NOT")?;
451                }
452                write!(f, " IN (")?;
453                for (i, item) in list.iter().enumerate() {
454                    if i > 0 {
455                        write!(f, ", ")?;
456                    }
457                    write!(f, "{}", item)?;
458                }
459                write!(f, ")")
460            }
461            Expr::Between {
462                expr,
463                low,
464                high,
465                negated,
466            } => {
467                write!(f, "{}", expr)?;
468                if *negated {
469                    write!(f, " NOT")?;
470                }
471                write!(f, " BETWEEN {} AND {}", low, high)
472            }
473            Expr::Subquery(query) => write!(f, "({})", query),
474            Expr::Wildcard => write!(f, "*"),
475        }
476    }
477}
478
479impl fmt::Display for Literal {
480    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
481        match self {
482            Literal::Null => write!(f, "NULL"),
483            Literal::Boolean(b) => write!(f, "{}", b),
484            Literal::Integer(i) => write!(f, "{}", i),
485            Literal::Float(fl) => write!(f, "{}", fl),
486            Literal::String(s) => write!(f, "'{}'", s),
487        }
488    }
489}
490
491impl fmt::Display for BinaryOperator {
492    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
493        match self {
494            BinaryOperator::Plus => write!(f, "+"),
495            BinaryOperator::Minus => write!(f, "-"),
496            BinaryOperator::Multiply => write!(f, "*"),
497            BinaryOperator::Divide => write!(f, "/"),
498            BinaryOperator::Modulo => write!(f, "%"),
499            BinaryOperator::Eq => write!(f, "="),
500            BinaryOperator::NotEq => write!(f, "<>"),
501            BinaryOperator::Lt => write!(f, "<"),
502            BinaryOperator::LtEq => write!(f, "<="),
503            BinaryOperator::Gt => write!(f, ">"),
504            BinaryOperator::GtEq => write!(f, ">="),
505            BinaryOperator::And => write!(f, "AND"),
506            BinaryOperator::Or => write!(f, "OR"),
507            BinaryOperator::Concat => write!(f, "||"),
508            BinaryOperator::Like => write!(f, "LIKE"),
509            BinaryOperator::NotLike => write!(f, "NOT LIKE"),
510        }
511    }
512}
513
514impl fmt::Display for UnaryOperator {
515    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
516        match self {
517            UnaryOperator::Minus => write!(f, "-"),
518            UnaryOperator::Not => write!(f, "NOT"),
519        }
520    }
521}
522
523impl fmt::Display for OrderByExpr {
524    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
525        write!(f, "{}", self.expr)?;
526        if self.asc {
527            write!(f, " ASC")?;
528        } else {
529            write!(f, " DESC")?;
530        }
531        if self.nulls_first {
532            write!(f, " NULLS FIRST")?;
533        } else {
534            write!(f, " NULLS LAST")?;
535        }
536        Ok(())
537    }
538}