rustlite_core/query/
ast.rs

1/// Abstract Syntax Tree (AST) node types for SQL-like queries
2///
3/// Defines the structure of parsed queries including SELECT, FROM, WHERE, ORDER BY, LIMIT, and JOIN.
4use std::fmt;
5
6/// A complete SQL-like query
7#[derive(Debug, Clone, PartialEq)]
8pub struct Query {
9    pub select: SelectClause,
10    pub from: FromClause,
11    pub where_clause: Option<WhereClause>,
12    pub group_by: Option<GroupByClause>,
13    pub having: Option<HavingClause>,
14    pub order_by: Option<OrderByClause>,
15    pub limit: Option<LimitClause>,
16}
17
18/// SELECT clause specifying columns to retrieve
19#[derive(Debug, Clone, PartialEq)]
20pub struct SelectClause {
21    pub columns: Vec<SelectColumn>,
22}
23
24/// A column in the SELECT clause
25#[derive(Debug, Clone, PartialEq)]
26pub enum SelectColumn {
27    /// SELECT * - all columns
28    Wildcard,
29    /// SELECT column_name or SELECT column_name AS alias
30    Column { name: String, alias: Option<String> },
31    /// SELECT COUNT(*), SUM(column), etc.
32    Aggregate {
33        function: AggregateFunction,
34        column: Box<SelectColumn>,
35        alias: Option<String>,
36    },
37}
38
39/// Aggregate functions
40#[derive(Debug, Clone, PartialEq)]
41pub enum AggregateFunction {
42    Count,
43    Sum,
44    Avg,
45    Min,
46    Max,
47}
48
49/// FROM clause specifying tables
50#[derive(Debug, Clone, PartialEq)]
51pub struct FromClause {
52    pub table: String,
53    pub joins: Vec<Join>,
54}
55
56/// JOIN clause
57#[derive(Debug, Clone, PartialEq)]
58pub struct Join {
59    pub join_type: JoinType,
60    pub table: String,
61    pub condition: Expression,
62}
63
64/// Types of joins
65#[derive(Debug, Clone, PartialEq)]
66pub enum JoinType {
67    Inner,
68    Left,
69    Right,
70    Full,
71}
72
73/// WHERE clause for filtering
74#[derive(Debug, Clone, PartialEq)]
75pub struct WhereClause {
76    pub condition: Expression,
77}
78
79/// GROUP BY clause for aggregation
80#[derive(Debug, Clone, PartialEq)]
81pub struct GroupByClause {
82    pub columns: Vec<String>,
83}
84
85/// HAVING clause for filtering grouped results
86#[derive(Debug, Clone, PartialEq)]
87pub struct HavingClause {
88    pub condition: Expression,
89}
90
91/// Boolean expression for WHERE and JOIN conditions
92#[derive(Debug, Clone, PartialEq)]
93pub enum Expression {
94    /// Column reference
95    Column(String),
96    /// Literal value
97    Literal(Literal),
98    /// Binary operation: column = value, column > value, etc.
99    BinaryOp {
100        left: Box<Expression>,
101        op: BinaryOperator,
102        right: Box<Expression>,
103    },
104    /// Logical AND/OR
105    LogicalOp {
106        left: Box<Expression>,
107        op: LogicalOperator,
108        right: Box<Expression>,
109    },
110    /// NOT expression
111    Not(Box<Expression>),
112    /// LIKE pattern matching
113    Like {
114        expr: Box<Expression>,
115        pattern: String,
116    },
117    /// IN (value1, value2, ...)
118    In {
119        expr: Box<Expression>,
120        values: Vec<Literal>,
121    },
122    /// BETWEEN min AND max
123    Between {
124        expr: Box<Expression>,
125        min: Box<Expression>,
126        max: Box<Expression>,
127    },
128}
129
130/// Binary comparison operators
131#[derive(Debug, Clone, PartialEq)]
132pub enum BinaryOperator {
133    Eq, // =
134    Ne, // !=
135    Lt, // <
136    Le, // <=
137    Gt, // >
138    Ge, // >=
139}
140
141/// Logical operators
142#[derive(Debug, Clone, PartialEq)]
143pub enum LogicalOperator {
144    And,
145    Or,
146}
147
148/// Literal values in queries
149#[derive(Debug, Clone, PartialEq)]
150pub enum Literal {
151    Integer(i64),
152    Float(f64),
153    String(String),
154    Boolean(bool),
155    Null,
156}
157
158/// ORDER BY clause for sorting
159#[derive(Debug, Clone, PartialEq)]
160pub struct OrderByClause {
161    pub columns: Vec<OrderByColumn>,
162}
163
164/// A column in ORDER BY
165#[derive(Debug, Clone, PartialEq)]
166pub struct OrderByColumn {
167    pub column: String,
168    pub direction: OrderDirection,
169}
170
171/// Sort direction
172#[derive(Debug, Clone, PartialEq)]
173pub enum OrderDirection {
174    Asc,
175    Desc,
176}
177
178/// LIMIT clause for result limiting
179#[derive(Debug, Clone, PartialEq)]
180pub struct LimitClause {
181    pub count: usize,
182    pub offset: Option<usize>,
183}
184
185// Display implementations for debugging and error messages
186
187impl fmt::Display for Query {
188    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
189        write!(f, "{} {}", self.select, self.from)?;
190        if let Some(ref where_clause) = self.where_clause {
191            write!(f, " {}", where_clause)?;
192        }
193        if let Some(ref group_by) = self.group_by {
194            write!(f, " {}", group_by)?;
195        }
196        if let Some(ref having) = self.having {
197            write!(f, " {}", having)?;
198        }
199        if let Some(ref order_by) = self.order_by {
200            write!(f, " {}", order_by)?;
201        }
202        if let Some(ref limit) = self.limit {
203            write!(f, " {}", limit)?;
204        }
205        Ok(())
206    }
207}
208
209impl fmt::Display for SelectClause {
210    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
211        write!(f, "SELECT ")?;
212        for (i, col) in self.columns.iter().enumerate() {
213            if i > 0 {
214                write!(f, ", ")?;
215            }
216            write!(f, "{}", col)?;
217        }
218        Ok(())
219    }
220}
221
222impl fmt::Display for SelectColumn {
223    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
224        match self {
225            SelectColumn::Wildcard => write!(f, "*"),
226            SelectColumn::Column { name, alias } => {
227                write!(f, "{}", name)?;
228                if let Some(ref alias) = alias {
229                    write!(f, " AS {}", alias)?;
230                }
231                Ok(())
232            }
233            SelectColumn::Aggregate {
234                function,
235                column,
236                alias,
237            } => {
238                write!(f, "{}({})", function, column)?;
239                if let Some(ref alias) = alias {
240                    write!(f, " AS {}", alias)?;
241                }
242                Ok(())
243            }
244        }
245    }
246}
247
248impl fmt::Display for AggregateFunction {
249    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
250        match self {
251            AggregateFunction::Count => write!(f, "COUNT"),
252            AggregateFunction::Sum => write!(f, "SUM"),
253            AggregateFunction::Avg => write!(f, "AVG"),
254            AggregateFunction::Min => write!(f, "MIN"),
255            AggregateFunction::Max => write!(f, "MAX"),
256        }
257    }
258}
259
260impl fmt::Display for FromClause {
261    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
262        write!(f, "FROM {}", self.table)?;
263        for join in &self.joins {
264            write!(f, " {}", join)?;
265        }
266        Ok(())
267    }
268}
269
270impl fmt::Display for Join {
271    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
272        write!(
273            f,
274            "{} JOIN {} ON {}",
275            self.join_type, self.table, self.condition
276        )
277    }
278}
279
280impl fmt::Display for JoinType {
281    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
282        match self {
283            JoinType::Inner => write!(f, "INNER"),
284            JoinType::Left => write!(f, "LEFT"),
285            JoinType::Right => write!(f, "RIGHT"),
286            JoinType::Full => write!(f, "FULL"),
287        }
288    }
289}
290
291impl fmt::Display for WhereClause {
292    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
293        write!(f, "WHERE {}", self.condition)
294    }
295}
296
297impl fmt::Display for GroupByClause {
298    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299        write!(f, "GROUP BY ")?;
300        for (i, col) in self.columns.iter().enumerate() {
301            if i > 0 {
302                write!(f, ", ")?;
303            }
304            write!(f, "{}", col)?;
305        }
306        Ok(())
307    }
308}
309
310impl fmt::Display for HavingClause {
311    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
312        write!(f, "HAVING {}", self.condition)
313    }
314}
315
316impl fmt::Display for Expression {
317    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
318        match self {
319            Expression::Column(name) => write!(f, "{}", name),
320            Expression::Literal(lit) => write!(f, "{}", lit),
321            Expression::BinaryOp { left, op, right } => {
322                write!(f, "({} {} {})", left, op, right)
323            }
324            Expression::LogicalOp { left, op, right } => {
325                write!(f, "({} {} {})", left, op, right)
326            }
327            Expression::Not(expr) => write!(f, "NOT ({})", expr),
328            Expression::Like { expr, pattern } => write!(f, "{} LIKE '{}'", expr, pattern),
329            Expression::In { expr, values } => {
330                write!(f, "{} IN (", expr)?;
331                for (i, val) in values.iter().enumerate() {
332                    if i > 0 {
333                        write!(f, ", ")?;
334                    }
335                    write!(f, "{}", val)?;
336                }
337                write!(f, ")")
338            }
339            Expression::Between { expr, min, max } => {
340                write!(f, "{} BETWEEN {} AND {}", expr, min, max)
341            }
342        }
343    }
344}
345
346impl fmt::Display for BinaryOperator {
347    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
348        match self {
349            BinaryOperator::Eq => write!(f, "="),
350            BinaryOperator::Ne => write!(f, "!="),
351            BinaryOperator::Lt => write!(f, "<"),
352            BinaryOperator::Le => write!(f, "<="),
353            BinaryOperator::Gt => write!(f, ">"),
354            BinaryOperator::Ge => write!(f, ">="),
355        }
356    }
357}
358
359impl fmt::Display for LogicalOperator {
360    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361        match self {
362            LogicalOperator::And => write!(f, "AND"),
363            LogicalOperator::Or => write!(f, "OR"),
364        }
365    }
366}
367
368impl fmt::Display for Literal {
369    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
370        match self {
371            Literal::Integer(i) => write!(f, "{}", i),
372            Literal::Float(fl) => write!(f, "{}", fl),
373            Literal::String(s) => write!(f, "'{}'", s),
374            Literal::Boolean(b) => write!(f, "{}", b),
375            Literal::Null => write!(f, "NULL"),
376        }
377    }
378}
379
380impl fmt::Display for OrderByClause {
381    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
382        write!(f, "ORDER BY ")?;
383        for (i, col) in self.columns.iter().enumerate() {
384            if i > 0 {
385                write!(f, ", ")?;
386            }
387            write!(f, "{}", col)?;
388        }
389        Ok(())
390    }
391}
392
393impl fmt::Display for OrderByColumn {
394    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395        write!(f, "{} {}", self.column, self.direction)
396    }
397}
398
399impl fmt::Display for OrderDirection {
400    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
401        match self {
402            OrderDirection::Asc => write!(f, "ASC"),
403            OrderDirection::Desc => write!(f, "DESC"),
404        }
405    }
406}
407
408impl fmt::Display for LimitClause {
409    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
410        write!(f, "LIMIT {}", self.count)?;
411        if let Some(offset) = self.offset {
412            write!(f, " OFFSET {}", offset)?;
413        }
414        Ok(())
415    }
416}