sqlparser/ast/
query.rs

1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License at
4//
5// http://www.apache.org/licenses/LICENSE-2.0
6//
7// Unless required by applicable law or agreed to in writing, software
8// distributed under the License is distributed on an "AS IS" BASIS,
9// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10// See the License for the specific language governing permissions and
11// limitations under the License.
12
13#[cfg(not(feature = "std"))]
14use alloc::{boxed::Box, vec::Vec};
15
16#[cfg(feature = "serde")]
17use serde::{Deserialize, Serialize};
18
19#[cfg(feature = "visitor")]
20use sqlparser_derive::{Visit, VisitMut};
21
22use crate::ast::*;
23
24/// The most complete variant of a `SELECT` query expression, optionally
25/// including `WITH`, `UNION` / other set operations, and `ORDER BY`.
26#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
27#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
28#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
29#[cfg_attr(feature = "visitor", visit(with = "visit_query"))]
30pub struct Query {
31    /// WITH (common table expressions, or CTEs)
32    pub with: Option<With>,
33    /// SELECT or UNION / EXCEPT / INTERSECT
34    pub body: Box<SetExpr>,
35    /// ORDER BY
36    pub order_by: Vec<OrderByExpr>,
37    /// `LIMIT { <N> | ALL }`
38    pub limit: Option<Expr>,
39
40    /// `LIMIT { <N> } BY { <expr>,<expr>,... } }`
41    pub limit_by: Vec<Expr>,
42
43    /// `OFFSET <N> [ { ROW | ROWS } ]`
44    pub offset: Option<Offset>,
45    /// `FETCH { FIRST | NEXT } <N> [ PERCENT ] { ROW | ROWS } | { ONLY | WITH TIES }`
46    pub fetch: Option<Fetch>,
47    /// `FOR { UPDATE | SHARE } [ OF table_name ] [ SKIP LOCKED | NOWAIT ]`
48    pub locks: Vec<LockClause>,
49    /// `FOR XML { RAW | AUTO | EXPLICIT | PATH } [ , ELEMENTS ]`
50    /// `FOR JSON { AUTO | PATH } [ , INCLUDE_NULL_VALUES ]`
51    /// (MSSQL-specific)
52    pub for_clause: Option<ForClause>,
53}
54
55impl fmt::Display for Query {
56    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57        if let Some(ref with) = self.with {
58            write!(f, "{with} ")?;
59        }
60        write!(f, "{}", self.body)?;
61        if !self.order_by.is_empty() {
62            write!(f, " ORDER BY {}", display_comma_separated(&self.order_by))?;
63        }
64        if let Some(ref limit) = self.limit {
65            write!(f, " LIMIT {limit}")?;
66        }
67        if let Some(ref offset) = self.offset {
68            write!(f, " {offset}")?;
69        }
70        if !self.limit_by.is_empty() {
71            write!(f, " BY {}", display_separated(&self.limit_by, ", "))?;
72        }
73        if let Some(ref fetch) = self.fetch {
74            write!(f, " {fetch}")?;
75        }
76        if !self.locks.is_empty() {
77            write!(f, " {}", display_separated(&self.locks, " "))?;
78        }
79        if let Some(ref for_clause) = self.for_clause {
80            write!(f, " {}", for_clause)?;
81        }
82        Ok(())
83    }
84}
85
86/// A node in a tree, representing a "query body" expression, roughly:
87/// `SELECT ... [ {UNION|EXCEPT|INTERSECT} SELECT ...]`
88#[allow(clippy::large_enum_variant)]
89#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
90#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
91#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
92pub enum SetExpr {
93    /// Restricted SELECT .. FROM .. HAVING (no ORDER BY or set operations)
94    Select(Box<Select>),
95    /// Parenthesized SELECT subquery, which may include more set operations
96    /// in its body and an optional ORDER BY / LIMIT.
97    Query(Box<Query>),
98    /// UNION/EXCEPT/INTERSECT of two queries
99    SetOperation {
100        op: SetOperator,
101        set_quantifier: SetQuantifier,
102        left: Box<SetExpr>,
103        right: Box<SetExpr>,
104    },
105    Values(Values),
106    Insert(Statement),
107    Update(Statement),
108    Table(Box<Table>),
109}
110
111impl fmt::Display for SetExpr {
112    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113        match self {
114            SetExpr::Select(s) => write!(f, "{s}"),
115            SetExpr::Query(q) => write!(f, "({q})"),
116            SetExpr::Values(v) => write!(f, "{v}"),
117            SetExpr::Insert(v) => write!(f, "{v}"),
118            SetExpr::Update(v) => write!(f, "{v}"),
119            SetExpr::Table(t) => write!(f, "{t}"),
120            SetExpr::SetOperation {
121                left,
122                right,
123                op,
124                set_quantifier,
125            } => {
126                write!(f, "{left} {op}")?;
127                match set_quantifier {
128                    SetQuantifier::All
129                    | SetQuantifier::Distinct
130                    | SetQuantifier::ByName
131                    | SetQuantifier::AllByName
132                    | SetQuantifier::DistinctByName => write!(f, " {set_quantifier}")?,
133                    SetQuantifier::None => write!(f, "{set_quantifier}")?,
134                }
135                write!(f, " {right}")?;
136                Ok(())
137            }
138        }
139    }
140}
141
142#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
143#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
144#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
145pub enum SetOperator {
146    Union,
147    Except,
148    Intersect,
149}
150
151impl fmt::Display for SetOperator {
152    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
153        f.write_str(match self {
154            SetOperator::Union => "UNION",
155            SetOperator::Except => "EXCEPT",
156            SetOperator::Intersect => "INTERSECT",
157        })
158    }
159}
160
161/// A quantifier for [SetOperator].
162// TODO: Restrict parsing specific SetQuantifier in some specific dialects.
163// For example, BigQuery does not support `DISTINCT` for `EXCEPT` and `INTERSECT`
164#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
165#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
166#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
167pub enum SetQuantifier {
168    All,
169    Distinct,
170    ByName,
171    AllByName,
172    DistinctByName,
173    None,
174}
175
176impl fmt::Display for SetQuantifier {
177    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
178        match self {
179            SetQuantifier::All => write!(f, "ALL"),
180            SetQuantifier::Distinct => write!(f, "DISTINCT"),
181            SetQuantifier::ByName => write!(f, "BY NAME"),
182            SetQuantifier::AllByName => write!(f, "ALL BY NAME"),
183            SetQuantifier::DistinctByName => write!(f, "DISTINCT BY NAME"),
184            SetQuantifier::None => write!(f, ""),
185        }
186    }
187}
188
189#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
190#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
191/// A [`TABLE` command]( https://www.postgresql.org/docs/current/sql-select.html#SQL-TABLE)
192#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
193pub struct Table {
194    pub table_name: Option<String>,
195    pub schema_name: Option<String>,
196}
197
198impl fmt::Display for Table {
199    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
200        if let Some(ref schema_name) = self.schema_name {
201            write!(
202                f,
203                "TABLE {}.{}",
204                schema_name,
205                self.table_name.as_ref().unwrap(),
206            )?;
207        } else {
208            write!(f, "TABLE {}", self.table_name.as_ref().unwrap(),)?;
209        }
210        Ok(())
211    }
212}
213
214/// A restricted variant of `SELECT` (without CTEs/`ORDER BY`), which may
215/// appear either as the only body item of a `Query`, or as an operand
216/// to a set operation like `UNION`.
217#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
218#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
219#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
220pub struct Select {
221    pub distinct: Option<Distinct>,
222    /// MSSQL syntax: `TOP (<N>) [ PERCENT ] [ WITH TIES ]`
223    pub top: Option<Top>,
224    /// projection expressions
225    pub projection: Vec<SelectItem>,
226    /// INTO
227    pub into: Option<SelectInto>,
228    /// FROM
229    pub from: Vec<TableWithJoins>,
230    /// LATERAL VIEWs
231    pub lateral_views: Vec<LateralView>,
232    /// WHERE
233    pub selection: Option<Expr>,
234    /// GROUP BY
235    pub group_by: GroupByExpr,
236    /// CLUSTER BY (Hive)
237    pub cluster_by: Vec<Expr>,
238    /// DISTRIBUTE BY (Hive)
239    pub distribute_by: Vec<Expr>,
240    /// SORT BY (Hive)
241    pub sort_by: Vec<Expr>,
242    /// HAVING
243    pub having: Option<Expr>,
244    /// WINDOW AS
245    pub named_window: Vec<NamedWindowDefinition>,
246    /// QUALIFY (Snowflake)
247    pub qualify: Option<Expr>,
248}
249
250impl fmt::Display for Select {
251    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
252        write!(f, "SELECT")?;
253        if let Some(ref distinct) = self.distinct {
254            write!(f, " {distinct}")?;
255        }
256        if let Some(ref top) = self.top {
257            write!(f, " {top}")?;
258        }
259        write!(f, " {}", display_comma_separated(&self.projection))?;
260
261        if let Some(ref into) = self.into {
262            write!(f, " {into}")?;
263        }
264
265        if !self.from.is_empty() {
266            write!(f, " FROM {}", display_comma_separated(&self.from))?;
267        }
268        if !self.lateral_views.is_empty() {
269            for lv in &self.lateral_views {
270                write!(f, "{lv}")?;
271            }
272        }
273        if let Some(ref selection) = self.selection {
274            write!(f, " WHERE {selection}")?;
275        }
276        match &self.group_by {
277            GroupByExpr::All => write!(f, " GROUP BY ALL")?,
278            GroupByExpr::Expressions(exprs) => {
279                if !exprs.is_empty() {
280                    write!(f, " GROUP BY {}", display_comma_separated(exprs))?;
281                }
282            }
283        }
284        if !self.cluster_by.is_empty() {
285            write!(
286                f,
287                " CLUSTER BY {}",
288                display_comma_separated(&self.cluster_by)
289            )?;
290        }
291        if !self.distribute_by.is_empty() {
292            write!(
293                f,
294                " DISTRIBUTE BY {}",
295                display_comma_separated(&self.distribute_by)
296            )?;
297        }
298        if !self.sort_by.is_empty() {
299            write!(f, " SORT BY {}", display_comma_separated(&self.sort_by))?;
300        }
301        if let Some(ref having) = self.having {
302            write!(f, " HAVING {having}")?;
303        }
304        if !self.named_window.is_empty() {
305            write!(f, " WINDOW {}", display_comma_separated(&self.named_window))?;
306        }
307        if let Some(ref qualify) = self.qualify {
308            write!(f, " QUALIFY {qualify}")?;
309        }
310        Ok(())
311    }
312}
313
314/// A hive LATERAL VIEW with potential column aliases
315#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
316#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
317#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
318pub struct LateralView {
319    /// LATERAL VIEW
320    pub lateral_view: Expr,
321    /// LATERAL VIEW table name
322    pub lateral_view_name: ObjectName,
323    /// LATERAL VIEW optional column aliases
324    pub lateral_col_alias: Vec<Ident>,
325    /// LATERAL VIEW OUTER
326    pub outer: bool,
327}
328
329impl fmt::Display for LateralView {
330    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
331        write!(
332            f,
333            " LATERAL VIEW{outer} {} {}",
334            self.lateral_view,
335            self.lateral_view_name,
336            outer = if self.outer { " OUTER" } else { "" }
337        )?;
338        if !self.lateral_col_alias.is_empty() {
339            write!(
340                f,
341                " AS {}",
342                display_comma_separated(&self.lateral_col_alias)
343            )?;
344        }
345        Ok(())
346    }
347}
348
349#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
350#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
351#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
352pub struct NamedWindowDefinition(pub Ident, pub WindowSpec);
353
354impl fmt::Display for NamedWindowDefinition {
355    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
356        write!(f, "{} AS ({})", self.0, self.1)
357    }
358}
359
360#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
361#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
362#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
363pub struct With {
364    pub recursive: bool,
365    pub cte_tables: Vec<Cte>,
366}
367
368impl fmt::Display for With {
369    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
370        write!(
371            f,
372            "WITH {}{}",
373            if self.recursive { "RECURSIVE " } else { "" },
374            display_comma_separated(&self.cte_tables)
375        )
376    }
377}
378
379/// A single CTE (used after `WITH`): `alias [(col1, col2, ...)] AS ( query )`
380/// The names in the column list before `AS`, when specified, replace the names
381/// of the columns returned by the query. The parser does not validate that the
382/// number of columns in the query matches the number of columns in the query.
383#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
384#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
385#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
386pub struct Cte {
387    pub alias: TableAlias,
388    pub query: Box<Query>,
389    pub from: Option<Ident>,
390}
391
392impl fmt::Display for Cte {
393    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
394        write!(f, "{} AS ({})", self.alias, self.query)?;
395        if let Some(ref fr) = self.from {
396            write!(f, " FROM {fr}")?;
397        }
398        Ok(())
399    }
400}
401
402/// One item of the comma-separated list following `SELECT`
403#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
404#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
405#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
406pub enum SelectItem {
407    /// Any expression, not followed by `[ AS ] alias`
408    UnnamedExpr(Expr),
409    /// An expression, followed by `[ AS ] alias`
410    ExprWithAlias { expr: Expr, alias: Ident },
411    /// `alias.*` or even `schema.table.*`
412    QualifiedWildcard(ObjectName, WildcardAdditionalOptions),
413    /// An unqualified `*`
414    Wildcard(WildcardAdditionalOptions),
415}
416
417/// Single aliased identifier
418///
419/// # Syntax
420/// ```plaintext
421/// <ident> AS <alias>
422/// ```
423#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
424#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
425#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
426pub struct IdentWithAlias {
427    pub ident: Ident,
428    pub alias: Ident,
429}
430
431impl fmt::Display for IdentWithAlias {
432    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
433        write!(f, "{} AS {}", self.ident, self.alias)
434    }
435}
436
437/// Additional options for wildcards, e.g. Snowflake `EXCLUDE`/`RENAME` and Bigquery `EXCEPT`.
438#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
439#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
440#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
441pub struct WildcardAdditionalOptions {
442    /// `[EXCLUDE...]`.
443    pub opt_exclude: Option<ExcludeSelectItem>,
444    /// `[EXCEPT...]`.
445    ///  Clickhouse syntax: <https://clickhouse.com/docs/en/sql-reference/statements/select#except>
446    pub opt_except: Option<ExceptSelectItem>,
447    /// `[RENAME ...]`.
448    pub opt_rename: Option<RenameSelectItem>,
449    /// `[REPLACE]`
450    ///  BigQuery syntax: <https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#select_replace>
451    ///  Clickhouse syntax: <https://clickhouse.com/docs/en/sql-reference/statements/select#replace>
452    pub opt_replace: Option<ReplaceSelectItem>,
453}
454
455impl fmt::Display for WildcardAdditionalOptions {
456    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
457        if let Some(exclude) = &self.opt_exclude {
458            write!(f, " {exclude}")?;
459        }
460        if let Some(except) = &self.opt_except {
461            write!(f, " {except}")?;
462        }
463        if let Some(rename) = &self.opt_rename {
464            write!(f, " {rename}")?;
465        }
466        if let Some(replace) = &self.opt_replace {
467            write!(f, " {replace}")?;
468        }
469        Ok(())
470    }
471}
472
473/// Snowflake `EXCLUDE` information.
474///
475/// # Syntax
476/// ```plaintext
477/// <col_name>
478/// | (<col_name>, <col_name>, ...)
479/// ```
480#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
481#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
482#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
483pub enum ExcludeSelectItem {
484    /// Single column name without parenthesis.
485    ///
486    /// # Syntax
487    /// ```plaintext
488    /// <col_name>
489    /// ```
490    Single(Ident),
491    /// Multiple column names inside parenthesis.
492    /// # Syntax
493    /// ```plaintext
494    /// (<col_name>, <col_name>, ...)
495    /// ```
496    Multiple(Vec<Ident>),
497}
498
499impl fmt::Display for ExcludeSelectItem {
500    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
501        write!(f, "EXCLUDE")?;
502        match self {
503            Self::Single(column) => {
504                write!(f, " {column}")?;
505            }
506            Self::Multiple(columns) => {
507                write!(f, " ({})", display_comma_separated(columns))?;
508            }
509        }
510        Ok(())
511    }
512}
513
514/// Snowflake `RENAME` information.
515///
516/// # Syntax
517/// ```plaintext
518/// <col_name> AS <col_alias>
519/// | (<col_name> AS <col_alias>, <col_name> AS <col_alias>, ...)
520/// ```
521#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
522#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
523#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
524pub enum RenameSelectItem {
525    /// Single column name with alias without parenthesis.
526    ///
527    /// # Syntax
528    /// ```plaintext
529    /// <col_name> AS <col_alias>
530    /// ```
531    Single(IdentWithAlias),
532    /// Multiple column names with aliases inside parenthesis.
533    /// # Syntax
534    /// ```plaintext
535    /// (<col_name> AS <col_alias>, <col_name> AS <col_alias>, ...)
536    /// ```
537    Multiple(Vec<IdentWithAlias>),
538}
539
540impl fmt::Display for RenameSelectItem {
541    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
542        write!(f, "RENAME")?;
543        match self {
544            Self::Single(column) => {
545                write!(f, " {column}")?;
546            }
547            Self::Multiple(columns) => {
548                write!(f, " ({})", display_comma_separated(columns))?;
549            }
550        }
551        Ok(())
552    }
553}
554
555/// Bigquery `EXCEPT` information, with at least one column.
556///
557/// # Syntax
558/// ```plaintext
559/// EXCEPT (<col_name> [, ...])
560/// ```
561#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
562#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
563#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
564pub struct ExceptSelectItem {
565    /// First guaranteed column.
566    pub first_element: Ident,
567    /// Additional columns. This list can be empty.
568    pub additional_elements: Vec<Ident>,
569}
570
571impl fmt::Display for ExceptSelectItem {
572    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
573        write!(f, "EXCEPT ")?;
574        if self.additional_elements.is_empty() {
575            write!(f, "({})", self.first_element)?;
576        } else {
577            write!(
578                f,
579                "({}, {})",
580                self.first_element,
581                display_comma_separated(&self.additional_elements)
582            )?;
583        }
584        Ok(())
585    }
586}
587
588/// Bigquery `REPLACE` information.
589///
590/// # Syntax
591/// ```plaintext
592/// REPLACE (<new_expr> [AS] <col_name>)
593/// REPLACE (<col_name> [AS] <col_alias>, <col_name> [AS] <col_alias>, ...)
594/// ```
595#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
596#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
597#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
598pub struct ReplaceSelectItem {
599    pub items: Vec<Box<ReplaceSelectElement>>,
600}
601
602impl fmt::Display for ReplaceSelectItem {
603    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
604        write!(f, "REPLACE")?;
605        write!(f, " ({})", display_comma_separated(&self.items))?;
606        Ok(())
607    }
608}
609
610/// # Syntax
611/// ```plaintext
612/// <expr> [AS] <column_name>
613/// ```
614#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
615#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
616#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
617pub struct ReplaceSelectElement {
618    pub expr: Expr,
619    pub column_name: Ident,
620    pub as_keyword: bool,
621}
622
623impl fmt::Display for ReplaceSelectElement {
624    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
625        if self.as_keyword {
626            write!(f, "{} AS {}", self.expr, self.column_name)
627        } else {
628            write!(f, "{} {}", self.expr, self.column_name)
629        }
630    }
631}
632
633impl fmt::Display for SelectItem {
634    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
635        match &self {
636            SelectItem::UnnamedExpr(expr) => write!(f, "{expr}"),
637            SelectItem::ExprWithAlias { expr, alias } => write!(f, "{expr} AS {alias}"),
638            SelectItem::QualifiedWildcard(prefix, additional_options) => {
639                write!(f, "{prefix}.*")?;
640                write!(f, "{additional_options}")?;
641                Ok(())
642            }
643            SelectItem::Wildcard(additional_options) => {
644                write!(f, "*")?;
645                write!(f, "{additional_options}")?;
646                Ok(())
647            }
648        }
649    }
650}
651
652#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
653#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
654#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
655pub struct TableWithJoins {
656    pub relation: TableFactor,
657    pub joins: Vec<Join>,
658}
659
660impl fmt::Display for TableWithJoins {
661    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
662        write!(f, "{}", self.relation)?;
663        for join in &self.joins {
664            write!(f, "{join}")?;
665        }
666        Ok(())
667    }
668}
669
670/// A table name or a parenthesized subquery with an optional alias
671#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
672#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
673#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
674#[cfg_attr(feature = "visitor", visit(with = "visit_table_factor"))]
675pub enum TableFactor {
676    Table {
677        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
678        name: ObjectName,
679        alias: Option<TableAlias>,
680        /// Arguments of a table-valued function, as supported by Postgres
681        /// and MSSQL. Note that deprecated MSSQL `FROM foo (NOLOCK)` syntax
682        /// will also be parsed as `args`.
683        ///
684        /// This field's value is `Some(v)`, where `v` is a (possibly empty)
685        /// vector of arguments, in the case of a table-valued function call,
686        /// whereas it's `None` in the case of a regular table name.
687        args: Option<Vec<FunctionArg>>,
688        /// MSSQL-specific `WITH (...)` hints such as NOLOCK.
689        with_hints: Vec<Expr>,
690        /// Optional version qualifier to facilitate table time-travel, as
691        /// supported by BigQuery and MSSQL.
692        version: Option<TableVersion>,
693        /// [Partition selection](https://dev.mysql.com/doc/refman/8.0/en/partitioning-selection.html), supported by MySQL.
694        partitions: Vec<Ident>,
695    },
696    Derived {
697        lateral: bool,
698        subquery: Box<Query>,
699        alias: Option<TableAlias>,
700    },
701    /// `TABLE(<expr>)[ AS <alias> ]`
702    TableFunction {
703        expr: Expr,
704        alias: Option<TableAlias>,
705    },
706    /// `e.g. LATERAL FLATTEN(<args>)[ AS <alias> ]`
707    Function {
708        lateral: bool,
709        name: ObjectName,
710        args: Vec<FunctionArg>,
711        alias: Option<TableAlias>,
712    },
713    /// ```sql
714    /// SELECT * FROM UNNEST ([10,20,30]) as numbers WITH OFFSET;
715    /// +---------+--------+
716    /// | numbers | offset |
717    /// +---------+--------+
718    /// | 10      | 0      |
719    /// | 20      | 1      |
720    /// | 30      | 2      |
721    /// +---------+--------+
722    /// ```
723    UNNEST {
724        alias: Option<TableAlias>,
725        array_exprs: Vec<Expr>,
726        with_offset: bool,
727        with_offset_alias: Option<Ident>,
728    },
729    /// The `JSON_TABLE` table-valued function.
730    /// Part of the SQL standard, but implemented only by MySQL, Oracle, and DB2.
731    ///
732    /// <https://modern-sql.com/blog/2017-06/whats-new-in-sql-2016#json_table>
733    /// <https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html#function_json-table>
734    ///
735    /// ```sql
736    /// SELECT * FROM JSON_TABLE(
737    ///    '[{"a": 1, "b": 2}, {"a": 3, "b": 4}]',
738    ///    '$[*]' COLUMNS(
739    ///        a INT PATH '$.a' DEFAULT '0' ON EMPTY,
740    ///        b INT PATH '$.b' NULL ON ERROR
741    ///     )
742    /// ) AS jt;
743    /// ````
744    JsonTable {
745        /// The JSON expression to be evaluated. It must evaluate to a json string
746        json_expr: Expr,
747        /// The path to the array or object to be iterated over.
748        /// It must evaluate to a json array or object.
749        json_path: Value,
750        /// The columns to be extracted from each element of the array or object.
751        /// Each column must have a name and a type.
752        columns: Vec<JsonTableColumn>,
753        /// The alias for the table.
754        alias: Option<TableAlias>,
755    },
756    /// Represents a parenthesized table factor. The SQL spec only allows a
757    /// join expression (`(foo <JOIN> bar [ <JOIN> baz ... ])`) to be nested,
758    /// possibly several times.
759    ///
760    /// The parser may also accept non-standard nesting of bare tables for some
761    /// dialects, but the information about such nesting is stripped from AST.
762    NestedJoin {
763        table_with_joins: Box<TableWithJoins>,
764        alias: Option<TableAlias>,
765    },
766    /// Represents PIVOT operation on a table.
767    /// For example `FROM monthly_sales PIVOT(sum(amount) FOR MONTH IN ('JAN', 'FEB'))`
768    /// See <https://docs.snowflake.com/en/sql-reference/constructs/pivot>
769    Pivot {
770        table: Box<TableFactor>,
771        aggregate_function: Expr, // Function expression
772        value_column: Vec<Ident>,
773        pivot_values: Vec<Value>,
774        alias: Option<TableAlias>,
775    },
776    /// An UNPIVOT operation on a table.
777    ///
778    /// Syntax:
779    /// ```sql
780    /// table UNPIVOT(value FOR name IN (column1, [ column2, ... ])) [ alias ]
781    /// ```
782    ///
783    /// See <https://docs.snowflake.com/en/sql-reference/constructs/unpivot>.
784    Unpivot {
785        table: Box<TableFactor>,
786        value: Ident,
787        name: Ident,
788        columns: Vec<Ident>,
789        alias: Option<TableAlias>,
790    },
791}
792
793impl fmt::Display for TableFactor {
794    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
795        match self {
796            TableFactor::Table {
797                name,
798                alias,
799                args,
800                with_hints,
801                version,
802                partitions,
803            } => {
804                write!(f, "{name}")?;
805                if !partitions.is_empty() {
806                    write!(f, "PARTITION ({})", display_comma_separated(partitions))?;
807                }
808                if let Some(args) = args {
809                    write!(f, "({})", display_comma_separated(args))?;
810                }
811                if let Some(alias) = alias {
812                    write!(f, " AS {alias}")?;
813                }
814                if !with_hints.is_empty() {
815                    write!(f, " WITH ({})", display_comma_separated(with_hints))?;
816                }
817                if let Some(version) = version {
818                    write!(f, "{version}")?;
819                }
820                Ok(())
821            }
822            TableFactor::Derived {
823                lateral,
824                subquery,
825                alias,
826            } => {
827                if *lateral {
828                    write!(f, "LATERAL ")?;
829                }
830                write!(f, "({subquery})")?;
831                if let Some(alias) = alias {
832                    write!(f, " AS {alias}")?;
833                }
834                Ok(())
835            }
836            TableFactor::Function {
837                lateral,
838                name,
839                args,
840                alias,
841            } => {
842                if *lateral {
843                    write!(f, "LATERAL ")?;
844                }
845                write!(f, "{name}")?;
846                write!(f, "({})", display_comma_separated(args))?;
847                if let Some(alias) = alias {
848                    write!(f, " AS {alias}")?;
849                }
850                Ok(())
851            }
852            TableFactor::TableFunction { expr, alias } => {
853                write!(f, "TABLE({expr})")?;
854                if let Some(alias) = alias {
855                    write!(f, " AS {alias}")?;
856                }
857                Ok(())
858            }
859            TableFactor::UNNEST {
860                alias,
861                array_exprs,
862                with_offset,
863                with_offset_alias,
864            } => {
865                write!(f, "UNNEST({})", display_comma_separated(array_exprs))?;
866
867                if let Some(alias) = alias {
868                    write!(f, " AS {alias}")?;
869                }
870                if *with_offset {
871                    write!(f, " WITH OFFSET")?;
872                }
873                if let Some(alias) = with_offset_alias {
874                    write!(f, " AS {alias}")?;
875                }
876                Ok(())
877            }
878            TableFactor::JsonTable {
879                json_expr,
880                json_path,
881                columns,
882                alias,
883            } => {
884                write!(
885                    f,
886                    "JSON_TABLE({json_expr}, {json_path} COLUMNS({columns}))",
887                    columns = display_comma_separated(columns)
888                )?;
889                if let Some(alias) = alias {
890                    write!(f, " AS {alias}")?;
891                }
892                Ok(())
893            }
894            TableFactor::NestedJoin {
895                table_with_joins,
896                alias,
897            } => {
898                write!(f, "({table_with_joins})")?;
899                if let Some(alias) = alias {
900                    write!(f, " AS {alias}")?;
901                }
902                Ok(())
903            }
904            TableFactor::Pivot {
905                table,
906                aggregate_function,
907                value_column,
908                pivot_values,
909                alias,
910            } => {
911                write!(
912                    f,
913                    "{} PIVOT({} FOR {} IN ({}))",
914                    table,
915                    aggregate_function,
916                    Expr::CompoundIdentifier(value_column.to_vec()),
917                    display_comma_separated(pivot_values)
918                )?;
919                if alias.is_some() {
920                    write!(f, " AS {}", alias.as_ref().unwrap())?;
921                }
922                Ok(())
923            }
924            TableFactor::Unpivot {
925                table,
926                value,
927                name,
928                columns,
929                alias,
930            } => {
931                write!(
932                    f,
933                    "{} UNPIVOT({} FOR {} IN ({}))",
934                    table,
935                    value,
936                    name,
937                    display_comma_separated(columns)
938                )?;
939                if alias.is_some() {
940                    write!(f, " AS {}", alias.as_ref().unwrap())?;
941                }
942                Ok(())
943            }
944        }
945    }
946}
947
948#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
949#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
950#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
951pub struct TableAlias {
952    pub name: Ident,
953    pub columns: Vec<Ident>,
954}
955
956impl fmt::Display for TableAlias {
957    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
958        write!(f, "{}", self.name)?;
959        if !self.columns.is_empty() {
960            write!(f, " ({})", display_comma_separated(&self.columns))?;
961        }
962        Ok(())
963    }
964}
965
966#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
967#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
968#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
969pub enum TableVersion {
970    ForSystemTimeAsOf(Expr),
971}
972
973impl Display for TableVersion {
974    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
975        match self {
976            TableVersion::ForSystemTimeAsOf(e) => write!(f, " FOR SYSTEM_TIME AS OF {e}")?,
977        }
978        Ok(())
979    }
980}
981
982#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
983#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
984#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
985pub struct Join {
986    pub relation: TableFactor,
987    pub join_operator: JoinOperator,
988}
989
990impl fmt::Display for Join {
991    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
992        fn prefix(constraint: &JoinConstraint) -> &'static str {
993            match constraint {
994                JoinConstraint::Natural => "NATURAL ",
995                _ => "",
996            }
997        }
998        fn suffix(constraint: &'_ JoinConstraint) -> impl fmt::Display + '_ {
999            struct Suffix<'a>(&'a JoinConstraint);
1000            impl<'a> fmt::Display for Suffix<'a> {
1001                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1002                    match self.0 {
1003                        JoinConstraint::On(expr) => write!(f, " ON {expr}"),
1004                        JoinConstraint::Using(attrs) => {
1005                            write!(f, " USING({})", display_comma_separated(attrs))
1006                        }
1007                        _ => Ok(()),
1008                    }
1009                }
1010            }
1011            Suffix(constraint)
1012        }
1013        match &self.join_operator {
1014            JoinOperator::Inner(constraint) => write!(
1015                f,
1016                " {}JOIN {}{}",
1017                prefix(constraint),
1018                self.relation,
1019                suffix(constraint)
1020            ),
1021            JoinOperator::LeftOuter(constraint) => write!(
1022                f,
1023                " {}LEFT JOIN {}{}",
1024                prefix(constraint),
1025                self.relation,
1026                suffix(constraint)
1027            ),
1028            JoinOperator::RightOuter(constraint) => write!(
1029                f,
1030                " {}RIGHT JOIN {}{}",
1031                prefix(constraint),
1032                self.relation,
1033                suffix(constraint)
1034            ),
1035            JoinOperator::FullOuter(constraint) => write!(
1036                f,
1037                " {}FULL JOIN {}{}",
1038                prefix(constraint),
1039                self.relation,
1040                suffix(constraint)
1041            ),
1042            JoinOperator::CrossJoin => write!(f, " CROSS JOIN {}", self.relation),
1043            JoinOperator::LeftSemi(constraint) => write!(
1044                f,
1045                " {}LEFT SEMI JOIN {}{}",
1046                prefix(constraint),
1047                self.relation,
1048                suffix(constraint)
1049            ),
1050            JoinOperator::RightSemi(constraint) => write!(
1051                f,
1052                " {}RIGHT SEMI JOIN {}{}",
1053                prefix(constraint),
1054                self.relation,
1055                suffix(constraint)
1056            ),
1057            JoinOperator::LeftAnti(constraint) => write!(
1058                f,
1059                " {}LEFT ANTI JOIN {}{}",
1060                prefix(constraint),
1061                self.relation,
1062                suffix(constraint)
1063            ),
1064            JoinOperator::RightAnti(constraint) => write!(
1065                f,
1066                " {}RIGHT ANTI JOIN {}{}",
1067                prefix(constraint),
1068                self.relation,
1069                suffix(constraint)
1070            ),
1071            JoinOperator::CrossApply => write!(f, " CROSS APPLY {}", self.relation),
1072            JoinOperator::OuterApply => write!(f, " OUTER APPLY {}", self.relation),
1073        }
1074    }
1075}
1076
1077#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1078#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1079#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1080pub enum JoinOperator {
1081    Inner(JoinConstraint),
1082    LeftOuter(JoinConstraint),
1083    RightOuter(JoinConstraint),
1084    FullOuter(JoinConstraint),
1085    CrossJoin,
1086    /// LEFT SEMI (non-standard)
1087    LeftSemi(JoinConstraint),
1088    /// RIGHT SEMI (non-standard)
1089    RightSemi(JoinConstraint),
1090    /// LEFT ANTI (non-standard)
1091    LeftAnti(JoinConstraint),
1092    /// RIGHT ANTI (non-standard)
1093    RightAnti(JoinConstraint),
1094    /// CROSS APPLY (non-standard)
1095    CrossApply,
1096    /// OUTER APPLY (non-standard)
1097    OuterApply,
1098}
1099
1100#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1101#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1102#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1103pub enum JoinConstraint {
1104    On(Expr),
1105    Using(Vec<Ident>),
1106    Natural,
1107    None,
1108}
1109
1110/// An `ORDER BY` expression
1111#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1112#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1113#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1114pub struct OrderByExpr {
1115    pub expr: Expr,
1116    /// Optional `ASC` or `DESC`
1117    pub asc: Option<bool>,
1118    /// Optional `NULLS FIRST` or `NULLS LAST`
1119    pub nulls_first: Option<bool>,
1120}
1121
1122impl fmt::Display for OrderByExpr {
1123    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1124        write!(f, "{}", self.expr)?;
1125        match self.asc {
1126            Some(true) => write!(f, " ASC")?,
1127            Some(false) => write!(f, " DESC")?,
1128            None => (),
1129        }
1130        match self.nulls_first {
1131            Some(true) => write!(f, " NULLS FIRST")?,
1132            Some(false) => write!(f, " NULLS LAST")?,
1133            None => (),
1134        }
1135        Ok(())
1136    }
1137}
1138
1139#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1140#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1141#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1142pub struct Offset {
1143    pub value: Expr,
1144    pub rows: OffsetRows,
1145}
1146
1147impl fmt::Display for Offset {
1148    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1149        write!(f, "OFFSET {}{}", self.value, self.rows)
1150    }
1151}
1152
1153/// Stores the keyword after `OFFSET <number>`
1154#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1155#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1156#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1157pub enum OffsetRows {
1158    /// Omitting ROW/ROWS is non-standard MySQL quirk.
1159    None,
1160    Row,
1161    Rows,
1162}
1163
1164impl fmt::Display for OffsetRows {
1165    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1166        match self {
1167            OffsetRows::None => Ok(()),
1168            OffsetRows::Row => write!(f, " ROW"),
1169            OffsetRows::Rows => write!(f, " ROWS"),
1170        }
1171    }
1172}
1173
1174#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1175#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1176#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1177pub struct Fetch {
1178    pub with_ties: bool,
1179    pub percent: bool,
1180    pub quantity: Option<Expr>,
1181}
1182
1183impl fmt::Display for Fetch {
1184    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1185        let extension = if self.with_ties { "WITH TIES" } else { "ONLY" };
1186        if let Some(ref quantity) = self.quantity {
1187            let percent = if self.percent { " PERCENT" } else { "" };
1188            write!(f, "FETCH FIRST {quantity}{percent} ROWS {extension}")
1189        } else {
1190            write!(f, "FETCH FIRST ROWS {extension}")
1191        }
1192    }
1193}
1194
1195#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1196#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1197#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1198pub struct LockClause {
1199    pub lock_type: LockType,
1200    pub of: Option<ObjectName>,
1201    pub nonblock: Option<NonBlock>,
1202}
1203
1204impl fmt::Display for LockClause {
1205    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1206        write!(f, "FOR {}", &self.lock_type)?;
1207        if let Some(ref of) = self.of {
1208            write!(f, " OF {of}")?;
1209        }
1210        if let Some(ref nb) = self.nonblock {
1211            write!(f, " {nb}")?;
1212        }
1213        Ok(())
1214    }
1215}
1216
1217#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1218#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1219#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1220pub enum LockType {
1221    Share,
1222    Update,
1223}
1224
1225impl fmt::Display for LockType {
1226    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1227        let select_lock = match self {
1228            LockType::Share => "SHARE",
1229            LockType::Update => "UPDATE",
1230        };
1231        write!(f, "{select_lock}")
1232    }
1233}
1234
1235#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1236#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1237#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1238pub enum NonBlock {
1239    Nowait,
1240    SkipLocked,
1241}
1242
1243impl fmt::Display for NonBlock {
1244    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1245        let nonblock = match self {
1246            NonBlock::Nowait => "NOWAIT",
1247            NonBlock::SkipLocked => "SKIP LOCKED",
1248        };
1249        write!(f, "{nonblock}")
1250    }
1251}
1252
1253#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1254#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1255#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1256pub enum Distinct {
1257    /// DISTINCT
1258    Distinct,
1259
1260    /// DISTINCT ON({column names})
1261    On(Vec<Expr>),
1262}
1263
1264impl fmt::Display for Distinct {
1265    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1266        match self {
1267            Distinct::Distinct => write!(f, "DISTINCT"),
1268            Distinct::On(col_names) => {
1269                let col_names = display_comma_separated(col_names);
1270                write!(f, "DISTINCT ON ({col_names})")
1271            }
1272        }
1273    }
1274}
1275
1276#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1277#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1278#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1279pub struct Top {
1280    /// SQL semantic equivalent of LIMIT but with same structure as FETCH.
1281    /// MSSQL only.
1282    pub with_ties: bool,
1283    /// MSSQL only.
1284    pub percent: bool,
1285    pub quantity: Option<TopQuantity>,
1286}
1287
1288#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1289#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1290#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1291pub enum TopQuantity {
1292    // A parenthesized expression. MSSQL only.
1293    Expr(Expr),
1294    // An unparenthesized integer constant.
1295    Constant(u64),
1296}
1297
1298impl fmt::Display for Top {
1299    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1300        let extension = if self.with_ties { " WITH TIES" } else { "" };
1301        if let Some(ref quantity) = self.quantity {
1302            let percent = if self.percent { " PERCENT" } else { "" };
1303            match quantity {
1304                TopQuantity::Expr(quantity) => write!(f, "TOP ({quantity}){percent}{extension}"),
1305                TopQuantity::Constant(quantity) => {
1306                    write!(f, "TOP {quantity}{percent}{extension}")
1307                }
1308            }
1309        } else {
1310            write!(f, "TOP{extension}")
1311        }
1312    }
1313}
1314
1315#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1316#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1317#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1318pub struct Values {
1319    /// Was there an explicit ROWs keyword (MySQL)?
1320    /// <https://dev.mysql.com/doc/refman/8.0/en/values.html>
1321    pub explicit_row: bool,
1322    pub rows: Vec<Vec<Expr>>,
1323}
1324
1325impl fmt::Display for Values {
1326    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1327        write!(f, "VALUES ")?;
1328        let prefix = if self.explicit_row { "ROW" } else { "" };
1329        let mut delim = "";
1330        for row in &self.rows {
1331            write!(f, "{delim}")?;
1332            delim = ", ";
1333            write!(f, "{prefix}({})", display_comma_separated(row))?;
1334        }
1335        Ok(())
1336    }
1337}
1338
1339#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1340#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1341#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1342pub struct SelectInto {
1343    pub temporary: bool,
1344    pub unlogged: bool,
1345    pub table: bool,
1346    pub name: ObjectName,
1347}
1348
1349impl fmt::Display for SelectInto {
1350    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1351        let temporary = if self.temporary { " TEMPORARY" } else { "" };
1352        let unlogged = if self.unlogged { " UNLOGGED" } else { "" };
1353        let table = if self.table { " TABLE" } else { "" };
1354
1355        write!(f, "INTO{}{}{} {}", temporary, unlogged, table, self.name)
1356    }
1357}
1358
1359#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1360#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1361#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1362pub enum GroupByExpr {
1363    /// ALL syntax of [Snowflake], and [DuckDB]
1364    ///
1365    /// [Snowflake]: <https://docs.snowflake.com/en/sql-reference/constructs/group-by#label-group-by-all-columns>
1366    /// [DuckDB]:  <https://duckdb.org/docs/sql/query_syntax/groupby.html>
1367    All,
1368
1369    /// Expressions
1370    Expressions(Vec<Expr>),
1371}
1372
1373impl fmt::Display for GroupByExpr {
1374    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1375        match self {
1376            GroupByExpr::All => write!(f, "GROUP BY ALL"),
1377            GroupByExpr::Expressions(col_names) => {
1378                let col_names = display_comma_separated(col_names);
1379                write!(f, "GROUP BY ({col_names})")
1380            }
1381        }
1382    }
1383}
1384
1385/// FOR XML or FOR JSON clause, specific to MSSQL
1386/// (formats the output of a query as XML or JSON)
1387#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1388#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1389#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1390pub enum ForClause {
1391    Browse,
1392    Json {
1393        for_json: ForJson,
1394        root: Option<String>,
1395        include_null_values: bool,
1396        without_array_wrapper: bool,
1397    },
1398    Xml {
1399        for_xml: ForXml,
1400        elements: bool,
1401        binary_base64: bool,
1402        root: Option<String>,
1403        r#type: bool,
1404    },
1405}
1406
1407impl fmt::Display for ForClause {
1408    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1409        match self {
1410            ForClause::Browse => write!(f, "FOR BROWSE"),
1411            ForClause::Json {
1412                for_json,
1413                root,
1414                include_null_values,
1415                without_array_wrapper,
1416            } => {
1417                write!(f, "FOR JSON ")?;
1418                write!(f, "{}", for_json)?;
1419                if let Some(root) = root {
1420                    write!(f, ", ROOT('{}')", root)?;
1421                }
1422                if *include_null_values {
1423                    write!(f, ", INCLUDE_NULL_VALUES")?;
1424                }
1425                if *without_array_wrapper {
1426                    write!(f, ", WITHOUT_ARRAY_WRAPPER")?;
1427                }
1428                Ok(())
1429            }
1430            ForClause::Xml {
1431                for_xml,
1432                elements,
1433                binary_base64,
1434                root,
1435                r#type,
1436            } => {
1437                write!(f, "FOR XML ")?;
1438                write!(f, "{}", for_xml)?;
1439                if *binary_base64 {
1440                    write!(f, ", BINARY BASE64")?;
1441                }
1442                if *r#type {
1443                    write!(f, ", TYPE")?;
1444                }
1445                if let Some(root) = root {
1446                    write!(f, ", ROOT('{}')", root)?;
1447                }
1448                if *elements {
1449                    write!(f, ", ELEMENTS")?;
1450                }
1451                Ok(())
1452            }
1453        }
1454    }
1455}
1456
1457#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1458#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1459#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1460pub enum ForXml {
1461    Raw(Option<String>),
1462    Auto,
1463    Explicit,
1464    Path(Option<String>),
1465}
1466
1467impl fmt::Display for ForXml {
1468    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1469        match self {
1470            ForXml::Raw(root) => {
1471                write!(f, "RAW")?;
1472                if let Some(root) = root {
1473                    write!(f, "('{}')", root)?;
1474                }
1475                Ok(())
1476            }
1477            ForXml::Auto => write!(f, "AUTO"),
1478            ForXml::Explicit => write!(f, "EXPLICIT"),
1479            ForXml::Path(root) => {
1480                write!(f, "PATH")?;
1481                if let Some(root) = root {
1482                    write!(f, "('{}')", root)?;
1483                }
1484                Ok(())
1485            }
1486        }
1487    }
1488}
1489
1490#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1491#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1492#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1493pub enum ForJson {
1494    Auto,
1495    Path,
1496}
1497
1498impl fmt::Display for ForJson {
1499    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1500        match self {
1501            ForJson::Auto => write!(f, "AUTO"),
1502            ForJson::Path => write!(f, "PATH"),
1503        }
1504    }
1505}
1506
1507/// A single column definition in MySQL's `JSON_TABLE` table valued function.
1508/// ```sql
1509/// SELECT *
1510/// FROM JSON_TABLE(
1511///     '["a", "b"]',
1512///     '$[*]' COLUMNS (
1513///         value VARCHAR(20) PATH '$'
1514///     )
1515/// ) AS jt;
1516/// ```
1517#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1518#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1519#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1520pub struct JsonTableColumn {
1521    /// The name of the column to be extracted.
1522    pub name: Ident,
1523    /// The type of the column to be extracted.
1524    pub r#type: DataType,
1525    /// The path to the column to be extracted. Must be a literal string.
1526    pub path: Value,
1527    /// true if the column is a boolean set to true if the given path exists
1528    pub exists: bool,
1529    /// The empty handling clause of the column
1530    pub on_empty: Option<JsonTableColumnErrorHandling>,
1531    /// The error handling clause of the column
1532    pub on_error: Option<JsonTableColumnErrorHandling>,
1533}
1534
1535impl fmt::Display for JsonTableColumn {
1536    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1537        write!(
1538            f,
1539            "{} {}{} PATH {}",
1540            self.name,
1541            self.r#type,
1542            if self.exists { " EXISTS" } else { "" },
1543            self.path
1544        )?;
1545        if let Some(on_empty) = &self.on_empty {
1546            write!(f, " {} ON EMPTY", on_empty)?;
1547        }
1548        if let Some(on_error) = &self.on_error {
1549            write!(f, " {} ON ERROR", on_error)?;
1550        }
1551        Ok(())
1552    }
1553}
1554
1555/// Stores the error handling clause of a `JSON_TABLE` table valued function:
1556/// {NULL | DEFAULT json_string | ERROR} ON {ERROR | EMPTY }
1557#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1558#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1559#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1560pub enum JsonTableColumnErrorHandling {
1561    Null,
1562    Default(Value),
1563    Error,
1564}
1565
1566impl fmt::Display for JsonTableColumnErrorHandling {
1567    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1568        match self {
1569            JsonTableColumnErrorHandling::Null => write!(f, "NULL"),
1570            JsonTableColumnErrorHandling::Default(json_string) => {
1571                write!(f, "DEFAULT {}", json_string)
1572            }
1573            JsonTableColumnErrorHandling::Error => write!(f, "ERROR"),
1574        }
1575    }
1576}