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 group_by: Option<GroupByClause>,
13 pub having: Option<HavingClause>,
14 pub order_by: Option<OrderByClause>,
15 pub limit: Option<LimitClause>,
16}
17
18#[derive(Debug, Clone, PartialEq)]
20pub struct SelectClause {
21 pub columns: Vec<SelectColumn>,
22}
23
24#[derive(Debug, Clone, PartialEq)]
26pub enum SelectColumn {
27 Wildcard,
29 Column { name: String, alias: Option<String> },
31 Aggregate {
33 function: AggregateFunction,
34 column: Box<SelectColumn>,
35 alias: Option<String>,
36 },
37}
38
39#[derive(Debug, Clone, PartialEq)]
41pub enum AggregateFunction {
42 Count,
43 Sum,
44 Avg,
45 Min,
46 Max,
47}
48
49#[derive(Debug, Clone, PartialEq)]
51pub struct FromClause {
52 pub table: String,
53 pub joins: Vec<Join>,
54}
55
56#[derive(Debug, Clone, PartialEq)]
58pub struct Join {
59 pub join_type: JoinType,
60 pub table: String,
61 pub condition: Expression,
62}
63
64#[derive(Debug, Clone, PartialEq)]
66pub enum JoinType {
67 Inner,
68 Left,
69 Right,
70 Full,
71}
72
73#[derive(Debug, Clone, PartialEq)]
75pub struct WhereClause {
76 pub condition: Expression,
77}
78
79#[derive(Debug, Clone, PartialEq)]
81pub struct GroupByClause {
82 pub columns: Vec<String>,
83}
84
85#[derive(Debug, Clone, PartialEq)]
87pub struct HavingClause {
88 pub condition: Expression,
89}
90
91#[derive(Debug, Clone, PartialEq)]
93pub enum Expression {
94 Column(String),
96 Literal(Literal),
98 BinaryOp {
100 left: Box<Expression>,
101 op: BinaryOperator,
102 right: Box<Expression>,
103 },
104 LogicalOp {
106 left: Box<Expression>,
107 op: LogicalOperator,
108 right: Box<Expression>,
109 },
110 Not(Box<Expression>),
112 Like {
114 expr: Box<Expression>,
115 pattern: String,
116 },
117 In {
119 expr: Box<Expression>,
120 values: Vec<Literal>,
121 },
122 Between {
124 expr: Box<Expression>,
125 min: Box<Expression>,
126 max: Box<Expression>,
127 },
128}
129
130#[derive(Debug, Clone, PartialEq)]
132pub enum BinaryOperator {
133 Eq, Ne, Lt, Le, Gt, Ge, }
140
141#[derive(Debug, Clone, PartialEq)]
143pub enum LogicalOperator {
144 And,
145 Or,
146}
147
148#[derive(Debug, Clone, PartialEq)]
150pub enum Literal {
151 Integer(i64),
152 Float(f64),
153 String(String),
154 Boolean(bool),
155 Null,
156}
157
158#[derive(Debug, Clone, PartialEq)]
160pub struct OrderByClause {
161 pub columns: Vec<OrderByColumn>,
162}
163
164#[derive(Debug, Clone, PartialEq)]
166pub struct OrderByColumn {
167 pub column: String,
168 pub direction: OrderDirection,
169}
170
171#[derive(Debug, Clone, PartialEq)]
173pub enum OrderDirection {
174 Asc,
175 Desc,
176}
177
178#[derive(Debug, Clone, PartialEq)]
180pub struct LimitClause {
181 pub count: usize,
182 pub offset: Option<usize>,
183}
184
185impl 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}