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