1use std::fmt;
5
6#[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#[derive(Debug, Clone, PartialEq)]
18pub struct SelectClause {
19 pub columns: Vec<SelectColumn>,
20}
21
22#[derive(Debug, Clone, PartialEq)]
24pub enum SelectColumn {
25 Wildcard,
27 Column { name: String, alias: Option<String> },
29 Aggregate {
31 function: AggregateFunction,
32 column: Box<SelectColumn>,
33 alias: Option<String>,
34 },
35}
36
37#[derive(Debug, Clone, PartialEq)]
39pub enum AggregateFunction {
40 Count,
41 Sum,
42 Avg,
43 Min,
44 Max,
45}
46
47#[derive(Debug, Clone, PartialEq)]
49pub struct FromClause {
50 pub table: String,
51 pub joins: Vec<Join>,
52}
53
54#[derive(Debug, Clone, PartialEq)]
56pub struct Join {
57 pub join_type: JoinType,
58 pub table: String,
59 pub condition: Expression,
60}
61
62#[derive(Debug, Clone, PartialEq)]
64pub enum JoinType {
65 Inner,
66 Left,
67 Right,
68 Full,
69}
70
71#[derive(Debug, Clone, PartialEq)]
73pub struct WhereClause {
74 pub condition: Expression,
75}
76
77#[derive(Debug, Clone, PartialEq)]
79pub enum Expression {
80 Column(String),
82 Literal(Literal),
84 BinaryOp {
86 left: Box<Expression>,
87 op: BinaryOperator,
88 right: Box<Expression>,
89 },
90 LogicalOp {
92 left: Box<Expression>,
93 op: LogicalOperator,
94 right: Box<Expression>,
95 },
96 Not(Box<Expression>),
98 Like {
100 expr: Box<Expression>,
101 pattern: String,
102 },
103 In {
105 expr: Box<Expression>,
106 values: Vec<Literal>,
107 },
108 Between {
110 expr: Box<Expression>,
111 min: Box<Expression>,
112 max: Box<Expression>,
113 },
114}
115
116#[derive(Debug, Clone, PartialEq)]
118pub enum BinaryOperator {
119 Eq, Ne, Lt, Le, Gt, Ge, }
126
127#[derive(Debug, Clone, PartialEq)]
129pub enum LogicalOperator {
130 And,
131 Or,
132}
133
134#[derive(Debug, Clone, PartialEq)]
136pub enum Literal {
137 Integer(i64),
138 Float(f64),
139 String(String),
140 Boolean(bool),
141 Null,
142}
143
144#[derive(Debug, Clone, PartialEq)]
146pub struct OrderByClause {
147 pub columns: Vec<OrderByColumn>,
148}
149
150#[derive(Debug, Clone, PartialEq)]
152pub struct OrderByColumn {
153 pub column: String,
154 pub direction: OrderDirection,
155}
156
157#[derive(Debug, Clone, PartialEq)]
159pub enum OrderDirection {
160 Asc,
161 Desc,
162}
163
164#[derive(Debug, Clone, PartialEq)]
166pub struct LimitClause {
167 pub count: usize,
168 pub offset: Option<usize>,
169}
170
171impl 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}