1#[cfg(not(feature = "std"))]
14use alloc::{boxed::Box, vec::Vec};
15
16#[cfg(feature = "serde")]
17use serde::{Deserialize, Serialize};
18
19use crate::ast::*;
20
21#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
25pub struct Query {
26 pub with: Option<With>,
28 pub body: SetExpr,
30 pub order_by: Vec<OrderByExpr>,
32 pub limit: Option<Expr>,
34 pub offset: Option<Offset>,
36 pub fetch: Option<Fetch>,
38}
39
40impl fmt::Display for Query {
41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 if let Some(ref with) = self.with {
43 write!(f, "{} ", with)?;
44 }
45 write!(f, "{}", self.body)?;
46 if !self.order_by.is_empty() {
47 write!(f, " ORDER BY {}", display_comma_separated(&self.order_by))?;
48 }
49 if let Some(ref limit) = self.limit {
50 write!(f, " LIMIT {}", limit)?;
51 }
52 if let Some(ref offset) = self.offset {
53 write!(f, " {}", offset)?;
54 }
55 if let Some(ref fetch) = self.fetch {
56 write!(f, " {}", fetch)?;
57 }
58 Ok(())
59 }
60}
61
62#[allow(clippy::large_enum_variant)]
65#[derive(Debug, Clone, PartialEq, Eq, Hash)]
66#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
67pub enum SetExpr {
68 Select(Box<Select>),
70 Query(Box<Query>),
73 SetOperation {
75 op: SetOperator,
76 all: bool,
77 left: Box<SetExpr>,
78 right: Box<SetExpr>,
79 },
80 Values(Values),
81 Insert(Statement),
82 }
84
85impl fmt::Display for SetExpr {
86 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87 match self {
88 SetExpr::Select(s) => write!(f, "{}", s),
89 SetExpr::Query(q) => write!(f, "({})", q),
90 SetExpr::Values(v) => write!(f, "{}", v),
91 SetExpr::Insert(v) => write!(f, "{}", v),
92 SetExpr::SetOperation {
93 left,
94 right,
95 op,
96 all,
97 } => {
98 let all_str = if *all { " ALL" } else { "" };
99 write!(f, "{} {}{} {}", left, op, all_str, right)
100 }
101 }
102 }
103}
104
105#[derive(Debug, Clone, PartialEq, Eq, Hash)]
106#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
107pub enum SetOperator {
108 Union,
109 Except,
110 Intersect,
111}
112
113impl fmt::Display for SetOperator {
114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
115 f.write_str(match self {
116 SetOperator::Union => "UNION",
117 SetOperator::Except => "EXCEPT",
118 SetOperator::Intersect => "INTERSECT",
119 })
120 }
121}
122
123#[derive(Debug, Clone, PartialEq, Eq, Hash)]
127#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
128pub struct Select {
129 pub distinct: bool,
130 pub top: Option<Top>,
132 pub projection: Vec<SelectItem>,
134 pub from: Vec<TableWithJoins>,
136 pub lateral_views: Vec<LateralView>,
138 pub selection: Option<Expr>,
140 pub group_by: Vec<Expr>,
142 pub cluster_by: Vec<Expr>,
144 pub distribute_by: Vec<Expr>,
146 pub sort_by: Vec<Expr>,
148 pub having: Option<Expr>,
150}
151
152impl fmt::Display for Select {
153 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154 write!(f, "SELECT{}", if self.distinct { " DISTINCT" } else { "" })?;
155 if let Some(ref top) = self.top {
156 write!(f, " {}", top)?;
157 }
158 write!(f, " {}", display_comma_separated(&self.projection))?;
159 if !self.from.is_empty() {
160 write!(f, " FROM {}", display_comma_separated(&self.from))?;
161 }
162 if !self.lateral_views.is_empty() {
163 for lv in &self.lateral_views {
164 write!(f, "{}", lv)?;
165 }
166 }
167 if let Some(ref selection) = self.selection {
168 write!(f, " WHERE {}", selection)?;
169 }
170 if !self.group_by.is_empty() {
171 write!(f, " GROUP BY {}", display_comma_separated(&self.group_by))?;
172 }
173 if !self.cluster_by.is_empty() {
174 write!(
175 f,
176 " CLUSTER BY {}",
177 display_comma_separated(&self.cluster_by)
178 )?;
179 }
180 if !self.distribute_by.is_empty() {
181 write!(
182 f,
183 " DISTRIBUTE BY {}",
184 display_comma_separated(&self.distribute_by)
185 )?;
186 }
187 if !self.sort_by.is_empty() {
188 write!(f, " SORT BY {}", display_comma_separated(&self.sort_by))?;
189 }
190 if let Some(ref having) = self.having {
191 write!(f, " HAVING {}", having)?;
192 }
193 Ok(())
194 }
195}
196
197#[derive(Debug, Clone, PartialEq, Eq, Hash)]
199#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
200pub struct LateralView {
201 pub lateral_view: Expr,
203 pub lateral_view_name: ObjectName,
205 pub lateral_col_alias: Vec<Ident>,
207 pub outer: bool,
209}
210
211impl fmt::Display for LateralView {
212 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
213 write!(
214 f,
215 " LATERAL VIEW{outer} {} {}",
216 self.lateral_view,
217 self.lateral_view_name,
218 outer = if self.outer { " OUTER" } else { "" }
219 )?;
220 if !self.lateral_col_alias.is_empty() {
221 write!(
222 f,
223 " AS {}",
224 display_comma_separated(&self.lateral_col_alias)
225 )?;
226 }
227 Ok(())
228 }
229}
230
231#[derive(Debug, Clone, PartialEq, Eq, Hash)]
232#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
233pub struct With {
234 pub recursive: bool,
235 pub cte_tables: Vec<Cte>,
236}
237
238impl fmt::Display for With {
239 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
240 write!(
241 f,
242 "WITH {}{}",
243 if self.recursive { "RECURSIVE " } else { "" },
244 display_comma_separated(&self.cte_tables)
245 )
246 }
247}
248
249#[derive(Debug, Clone, PartialEq, Eq, Hash)]
254#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
255pub struct Cte {
256 pub alias: TableAlias,
257 pub query: Query,
258 pub from: Option<Ident>,
259}
260
261impl fmt::Display for Cte {
262 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
263 write!(f, "{} AS ({})", self.alias, self.query)?;
264 if let Some(ref fr) = self.from {
265 write!(f, " FROM {}", fr)?;
266 }
267 Ok(())
268 }
269}
270
271#[derive(Debug, Clone, PartialEq, Eq, Hash)]
273#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
274pub enum SelectItem {
275 UnnamedExpr(Expr),
277 ExprWithAlias { expr: Expr, alias: Ident },
279 QualifiedWildcard(ObjectName),
281 Wildcard,
283}
284
285impl fmt::Display for SelectItem {
286 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
287 match &self {
288 SelectItem::UnnamedExpr(expr) => write!(f, "{}", expr),
289 SelectItem::ExprWithAlias { expr, alias } => write!(f, "{} AS {}", expr, alias),
290 SelectItem::QualifiedWildcard(prefix) => write!(f, "{}.*", prefix),
291 SelectItem::Wildcard => write!(f, "*"),
292 }
293 }
294}
295
296#[derive(Debug, Clone, PartialEq, Eq, Hash)]
297#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
298pub struct TableWithJoins {
299 pub relation: TableFactor,
300 pub joins: Vec<Join>,
301}
302
303impl fmt::Display for TableWithJoins {
304 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
305 write!(f, "{}", self.relation)?;
306 for join in &self.joins {
307 write!(f, "{}", join)?;
308 }
309 Ok(())
310 }
311}
312
313#[derive(Debug, Clone, PartialEq, Eq, Hash)]
315#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
316pub enum TableFactor {
317 Table {
318 name: ObjectName,
319 alias: Option<TableAlias>,
320 args: Vec<FunctionArg>,
324 with_hints: Vec<Expr>,
326 },
327 Derived {
328 lateral: bool,
329 subquery: Box<Query>,
330 alias: Option<TableAlias>,
331 },
332 TableFunction {
334 expr: Expr,
335 alias: Option<TableAlias>,
336 },
337 NestedJoin(Box<TableWithJoins>),
344}
345
346impl fmt::Display for TableFactor {
347 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
348 match self {
349 TableFactor::Table {
350 name,
351 alias,
352 args,
353 with_hints,
354 } => {
355 write!(f, "{}", name)?;
356 if !args.is_empty() {
357 write!(f, "({})", display_comma_separated(args))?;
358 }
359 if let Some(alias) = alias {
360 write!(f, " AS {}", alias)?;
361 }
362 if !with_hints.is_empty() {
363 write!(f, " WITH ({})", display_comma_separated(with_hints))?;
364 }
365 Ok(())
366 }
367 TableFactor::Derived {
368 lateral,
369 subquery,
370 alias,
371 } => {
372 if *lateral {
373 write!(f, "LATERAL ")?;
374 }
375 write!(f, "({})", subquery)?;
376 if let Some(alias) = alias {
377 write!(f, " AS {}", alias)?;
378 }
379 Ok(())
380 }
381 TableFactor::TableFunction { expr, alias } => {
382 write!(f, "TABLE({})", expr)?;
383 if let Some(alias) = alias {
384 write!(f, " AS {}", alias)?;
385 }
386 Ok(())
387 }
388 TableFactor::NestedJoin(table_reference) => write!(f, "({})", table_reference),
389 }
390 }
391}
392
393#[derive(Debug, Clone, PartialEq, Eq, Hash)]
394#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
395pub struct TableAlias {
396 pub name: Ident,
397 pub columns: Vec<Ident>,
398}
399
400impl fmt::Display for TableAlias {
401 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
402 write!(f, "{}", self.name)?;
403 if !self.columns.is_empty() {
404 write!(f, " ({})", display_comma_separated(&self.columns))?;
405 }
406 Ok(())
407 }
408}
409
410#[derive(Debug, Clone, PartialEq, Eq, Hash)]
411#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
412pub struct Join {
413 pub relation: TableFactor,
414 pub join_operator: JoinOperator,
415}
416
417impl fmt::Display for Join {
418 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
419 fn prefix(constraint: &JoinConstraint) -> &'static str {
420 match constraint {
421 JoinConstraint::Natural => "NATURAL ",
422 _ => "",
423 }
424 }
425 fn suffix(constraint: &'_ JoinConstraint) -> impl fmt::Display + '_ {
426 struct Suffix<'a>(&'a JoinConstraint);
427 impl<'a> fmt::Display for Suffix<'a> {
428 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
429 match self.0 {
430 JoinConstraint::On(expr) => write!(f, " ON {}", expr),
431 JoinConstraint::Using(attrs) => {
432 write!(f, " USING({})", display_comma_separated(attrs))
433 }
434 _ => Ok(()),
435 }
436 }
437 }
438 Suffix(constraint)
439 }
440 match &self.join_operator {
441 JoinOperator::Inner(constraint) => write!(
442 f,
443 " {}JOIN {}{}",
444 prefix(constraint),
445 self.relation,
446 suffix(constraint)
447 ),
448 JoinOperator::LeftOuter(constraint) => write!(
449 f,
450 " {}LEFT JOIN {}{}",
451 prefix(constraint),
452 self.relation,
453 suffix(constraint)
454 ),
455 JoinOperator::RightOuter(constraint) => write!(
456 f,
457 " {}RIGHT JOIN {}{}",
458 prefix(constraint),
459 self.relation,
460 suffix(constraint)
461 ),
462 JoinOperator::FullOuter(constraint) => write!(
463 f,
464 " {}FULL JOIN {}{}",
465 prefix(constraint),
466 self.relation,
467 suffix(constraint)
468 ),
469 JoinOperator::CrossJoin => write!(f, " CROSS JOIN {}", self.relation),
470 JoinOperator::CrossApply => write!(f, " CROSS APPLY {}", self.relation),
471 JoinOperator::OuterApply => write!(f, " OUTER APPLY {}", self.relation),
472 }
473 }
474}
475
476#[derive(Debug, Clone, PartialEq, Eq, Hash)]
477#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
478pub enum JoinOperator {
479 Inner(JoinConstraint),
480 LeftOuter(JoinConstraint),
481 RightOuter(JoinConstraint),
482 FullOuter(JoinConstraint),
483 CrossJoin,
484 CrossApply,
486 OuterApply,
488}
489
490#[derive(Debug, Clone, PartialEq, Eq, Hash)]
491#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
492pub enum JoinConstraint {
493 On(Expr),
494 Using(Vec<Ident>),
495 Natural,
496 None,
497}
498
499#[derive(Debug, Clone, PartialEq, Eq, Hash)]
501#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
502pub struct OrderByExpr {
503 pub expr: Expr,
504 pub asc: Option<bool>,
506 pub nulls_first: Option<bool>,
508}
509
510impl fmt::Display for OrderByExpr {
511 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
512 write!(f, "{}", self.expr)?;
513 match self.asc {
514 Some(true) => write!(f, " ASC")?,
515 Some(false) => write!(f, " DESC")?,
516 None => (),
517 }
518 match self.nulls_first {
519 Some(true) => write!(f, " NULLS FIRST")?,
520 Some(false) => write!(f, " NULLS LAST")?,
521 None => (),
522 }
523 Ok(())
524 }
525}
526
527#[derive(Debug, Clone, PartialEq, Eq, Hash)]
528#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
529pub struct Offset {
530 pub value: Expr,
531 pub rows: OffsetRows,
532}
533
534impl fmt::Display for Offset {
535 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
536 write!(f, "OFFSET {}{}", self.value, self.rows)
537 }
538}
539
540#[derive(Debug, Clone, PartialEq, Eq, Hash)]
542#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
543pub enum OffsetRows {
544 None,
546 Row,
547 Rows,
548}
549
550impl fmt::Display for OffsetRows {
551 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
552 match self {
553 OffsetRows::None => Ok(()),
554 OffsetRows::Row => write!(f, " ROW"),
555 OffsetRows::Rows => write!(f, " ROWS"),
556 }
557 }
558}
559
560#[derive(Debug, Clone, PartialEq, Eq, Hash)]
561#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
562pub struct Fetch {
563 pub with_ties: bool,
564 pub percent: bool,
565 pub quantity: Option<Expr>,
566}
567
568impl fmt::Display for Fetch {
569 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
570 let extension = if self.with_ties { "WITH TIES" } else { "ONLY" };
571 if let Some(ref quantity) = self.quantity {
572 let percent = if self.percent { " PERCENT" } else { "" };
573 write!(f, "FETCH FIRST {}{} ROWS {}", quantity, percent, extension)
574 } else {
575 write!(f, "FETCH FIRST ROWS {}", extension)
576 }
577 }
578}
579
580#[derive(Debug, Clone, PartialEq, Eq, Hash)]
581#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
582pub struct Top {
583 pub with_ties: bool,
585 pub percent: bool,
586 pub quantity: Option<Expr>,
587}
588
589impl fmt::Display for Top {
590 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
591 let extension = if self.with_ties { " WITH TIES" } else { "" };
592 if let Some(ref quantity) = self.quantity {
593 let percent = if self.percent { " PERCENT" } else { "" };
594 write!(f, "TOP ({}){}{}", quantity, percent, extension)
595 } else {
596 write!(f, "TOP{}", extension)
597 }
598 }
599}
600
601#[derive(Debug, Clone, PartialEq, Eq, Hash)]
602#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
603pub struct Values(pub Vec<Vec<Expr>>);
604
605impl fmt::Display for Values {
606 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
607 write!(f, "VALUES ")?;
608 let mut delim = "";
609 for row in &self.0 {
610 write!(f, "{}", delim)?;
611 delim = ", ";
612 write!(f, "({})", display_comma_separated(row))?;
613 }
614 Ok(())
615 }
616}