1use crate::expr::Expr;
4use crate::{ColumnName, PgType, TableName};
5
6#[derive(Debug, Clone)]
8pub enum Stmt {
9 Select(SelectStmt),
11 Insert(InsertStmt),
13 InsertSelect(InsertSelectStmt),
15 Update(UpdateStmt),
17 Delete(DeleteStmt),
19}
20
21#[derive(Debug, Clone, Default)]
23pub struct SelectStmt {
24 pub distinct: bool,
26 pub distinct_on: Vec<Expr>,
28 pub columns: Vec<SelectColumn>,
30 pub from: Option<FromClause>,
32 pub joins: Vec<Join>,
34 pub where_: Option<Expr>,
36 pub order_by: Vec<OrderBy>,
38 pub limit: Option<Expr>,
40 pub offset: Option<Expr>,
42}
43
44#[derive(Debug, Clone)]
46pub enum SelectColumn {
47 Expr {
49 expr: Expr,
51 alias: Option<ColumnName>,
53 },
54
55 AllFrom(TableName),
57}
58
59impl SelectColumn {
60 pub fn expr(expr: Expr) -> Self {
61 SelectColumn::Expr { expr, alias: None }
62 }
63
64 pub fn aliased(expr: Expr, alias: ColumnName) -> Self {
65 SelectColumn::Expr {
66 expr,
67 alias: Some(alias),
68 }
69 }
70
71 pub fn all_from(table: TableName) -> Self {
72 SelectColumn::AllFrom(table)
73 }
74}
75
76#[derive(Debug, Clone)]
78pub struct FromClause {
79 pub table: TableName,
81 pub alias: Option<TableName>,
83}
84
85impl FromClause {
86 pub fn table(name: TableName) -> Self {
87 Self {
88 table: name,
89 alias: None,
90 }
91 }
92
93 pub fn aliased(name: TableName, alias: TableName) -> Self {
94 Self {
95 table: name,
96 alias: Some(alias),
97 }
98 }
99}
100
101#[derive(Debug, Clone)]
105pub struct Unnest {
106 pub params: Vec<UnnestParam>,
108 pub alias: TableName,
110}
111
112#[derive(Debug, Clone)]
114pub struct UnnestParam {
115 pub name: ColumnName,
117 pub pg_type: PgType,
119}
120
121impl UnnestParam {
122 pub fn new(name: ColumnName, pg_type: PgType) -> Self {
123 Self { name, pg_type }
124 }
125}
126
127impl Unnest {
128 pub fn new(alias: TableName) -> Self {
129 Self {
130 params: Vec::new(),
131 alias,
132 }
133 }
134
135 pub fn param(mut self, name: ColumnName, pg_type: PgType) -> Self {
136 self.params.push(UnnestParam::new(name, pg_type));
137 self
138 }
139
140 pub fn params(mut self, params: impl IntoIterator<Item = UnnestParam>) -> Self {
141 self.params.extend(params);
142 self
143 }
144}
145
146#[derive(Debug, Clone)]
148pub struct Join {
149 pub kind: JoinKind,
151 pub table: TableName,
153 pub alias: Option<TableName>,
155 pub on: Expr,
157}
158
159#[derive(Debug, Clone, Copy, PartialEq, Eq)]
161pub enum JoinKind {
162 Inner,
164 Left,
166 Right,
168 Full,
170}
171
172impl JoinKind {
173 pub fn as_str(self) -> &'static str {
174 match self {
175 JoinKind::Inner => "INNER JOIN",
176 JoinKind::Left => "LEFT JOIN",
177 JoinKind::Right => "RIGHT JOIN",
178 JoinKind::Full => "FULL JOIN",
179 }
180 }
181}
182
183#[derive(Debug, Clone)]
185pub struct OrderBy {
186 pub expr: Expr,
188 pub desc: bool,
190 pub nulls: Option<NullsOrder>,
192}
193
194impl OrderBy {
195 pub fn asc(expr: Expr) -> Self {
196 Self {
197 expr,
198 desc: false,
199 nulls: None,
200 }
201 }
202
203 pub fn desc(expr: Expr) -> Self {
204 Self {
205 expr,
206 desc: true,
207 nulls: None,
208 }
209 }
210}
211
212#[derive(Debug, Clone, Copy, PartialEq, Eq)]
214pub enum NullsOrder {
215 First,
217 Last,
219}
220
221#[derive(Debug, Clone)]
227pub struct InsertStmt {
228 pub table: TableName,
230 pub columns: Vec<ColumnName>,
232 pub values: Vec<Expr>,
234 pub on_conflict: Option<OnConflict>,
236 pub returning: Vec<ColumnName>,
238}
239
240#[derive(Debug, Clone)]
242pub struct OnConflict {
243 pub columns: Vec<ColumnName>,
245 pub action: ConflictAction,
247}
248
249#[derive(Debug, Clone)]
251pub enum ConflictAction {
252 DoNothing,
254 DoUpdate(Vec<UpdateAssignment>),
256}
257
258#[derive(Debug, Clone)]
268pub struct InsertSelectStmt {
269 pub table: TableName,
271 pub columns: Vec<ColumnName>,
273 pub select_exprs: Vec<Expr>,
275 pub unnest: Unnest,
277 pub on_conflict: Option<OnConflict>,
279 pub returning: Vec<ColumnName>,
281}
282
283#[derive(Debug, Clone)]
285pub struct UpdateAssignment {
286 pub column: ColumnName,
288 pub value: Expr,
290}
291
292impl UpdateAssignment {
293 pub fn new(column: ColumnName, value: Expr) -> Self {
294 Self { column, value }
295 }
296}
297
298#[derive(Debug, Clone)]
304pub struct UpdateStmt {
305 pub table: TableName,
307 pub assignments: Vec<UpdateAssignment>,
309 pub where_: Option<Expr>,
311 pub returning: Vec<ColumnName>,
313}
314
315#[derive(Debug, Clone)]
321pub struct DeleteStmt {
322 pub table: TableName,
324 pub where_: Option<Expr>,
326 pub returning: Vec<ColumnName>,
328}
329
330impl SelectStmt {
335 pub fn new() -> Self {
336 Self::default()
337 }
338
339 pub fn distinct(mut self) -> Self {
341 self.distinct = true;
342 self
343 }
344
345 pub fn distinct_on(mut self, cols: impl IntoIterator<Item = Expr>) -> Self {
348 self.distinct_on.extend(cols);
349 self
350 }
351
352 pub fn column(mut self, col: SelectColumn) -> Self {
353 self.columns.push(col);
354 self
355 }
356
357 pub fn columns(mut self, cols: impl IntoIterator<Item = SelectColumn>) -> Self {
358 self.columns.extend(cols);
359 self
360 }
361
362 pub fn from(mut self, from: FromClause) -> Self {
363 self.from = Some(from);
364 self
365 }
366
367 pub fn join(mut self, join: Join) -> Self {
368 self.joins.push(join);
369 self
370 }
371
372 pub fn where_(mut self, expr: Expr) -> Self {
373 self.where_ = Some(expr);
374 self
375 }
376
377 pub fn and_where(mut self, expr: Expr) -> Self {
378 self.where_ = Some(match self.where_ {
379 Some(existing) => existing.and(expr),
380 None => expr,
381 });
382 self
383 }
384
385 pub fn order_by(mut self, order: OrderBy) -> Self {
386 self.order_by.push(order);
387 self
388 }
389
390 pub fn limit(mut self, expr: Expr) -> Self {
391 self.limit = Some(expr);
392 self
393 }
394
395 pub fn offset(mut self, expr: Expr) -> Self {
396 self.offset = Some(expr);
397 self
398 }
399}
400
401impl InsertStmt {
402 pub fn new(table: TableName) -> Self {
403 Self {
404 table,
405 columns: Vec::new(),
406 values: Vec::new(),
407 on_conflict: None,
408 returning: Vec::new(),
409 }
410 }
411
412 pub fn column(mut self, name: ColumnName, value: Expr) -> Self {
413 self.columns.push(name);
414 self.values.push(value);
415 self
416 }
417
418 pub fn on_conflict(mut self, conflict: OnConflict) -> Self {
419 self.on_conflict = Some(conflict);
420 self
421 }
422
423 pub fn returning(mut self, cols: impl IntoIterator<Item = ColumnName>) -> Self {
424 self.returning.extend(cols);
425 self
426 }
427}
428
429impl UpdateStmt {
430 pub fn new(table: TableName) -> Self {
431 Self {
432 table,
433 assignments: Vec::new(),
434 where_: None,
435 returning: Vec::new(),
436 }
437 }
438
439 pub fn set(mut self, column: ColumnName, value: Expr) -> Self {
440 self.assignments.push(UpdateAssignment::new(column, value));
441 self
442 }
443
444 pub fn where_(mut self, expr: Expr) -> Self {
445 self.where_ = Some(expr);
446 self
447 }
448
449 pub fn and_where(mut self, expr: Expr) -> Self {
450 self.where_ = Some(match self.where_ {
451 Some(existing) => existing.and(expr),
452 None => expr,
453 });
454 self
455 }
456
457 pub fn returning(mut self, cols: impl IntoIterator<Item = ColumnName>) -> Self {
458 self.returning.extend(cols);
459 self
460 }
461}
462
463impl DeleteStmt {
464 pub fn new(table: TableName) -> Self {
465 Self {
466 table,
467 where_: None,
468 returning: Vec::new(),
469 }
470 }
471
472 pub fn where_(mut self, expr: Expr) -> Self {
473 self.where_ = Some(expr);
474 self
475 }
476
477 pub fn and_where(mut self, expr: Expr) -> Self {
478 self.where_ = Some(match self.where_ {
479 Some(existing) => existing.and(expr),
480 None => expr,
481 });
482 self
483 }
484
485 pub fn returning(mut self, cols: impl IntoIterator<Item = ColumnName>) -> Self {
486 self.returning.extend(cols);
487 self
488 }
489}
490
491impl InsertSelectStmt {
492 pub fn new(table: TableName, unnest: Unnest) -> Self {
493 Self {
494 table,
495 columns: Vec::new(),
496 select_exprs: Vec::new(),
497 unnest,
498 on_conflict: None,
499 returning: Vec::new(),
500 }
501 }
502
503 pub fn column(mut self, name: ColumnName, expr: Expr) -> Self {
505 self.columns.push(name);
506 self.select_exprs.push(expr);
507 self
508 }
509
510 pub fn on_conflict(mut self, conflict: OnConflict) -> Self {
511 self.on_conflict = Some(conflict);
512 self
513 }
514
515 pub fn returning(mut self, cols: impl IntoIterator<Item = ColumnName>) -> Self {
516 self.returning.extend(cols);
517 self
518 }
519}