Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
query.rs - source
[go: Go Back, main page]

sqlparser/ast/
query.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18#[cfg(not(feature = "std"))]
19use alloc::{boxed::Box, vec::Vec};
20
21use helpers::attached_token::AttachedToken;
22#[cfg(feature = "serde")]
23use serde::{Deserialize, Serialize};
24
25#[cfg(feature = "visitor")]
26use sqlparser_derive::{Visit, VisitMut};
27
28use crate::{
29    ast::*,
30    tokenizer::{Token, TokenWithSpan},
31};
32
33/// The most complete variant of a `SELECT` query expression, optionally
34/// including `WITH`, `UNION` / other set operations, and `ORDER BY`.
35#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
36#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
37#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
38#[cfg_attr(feature = "visitor", visit(with = "visit_query"))]
39pub struct Query {
40    /// WITH (common table expressions, or CTEs)
41    pub with: Option<With>,
42    /// SELECT or UNION / EXCEPT / INTERSECT
43    pub body: Box<SetExpr>,
44    /// ORDER BY
45    pub order_by: Option<OrderBy>,
46    /// `LIMIT { <N> | ALL }`
47    pub limit: Option<Expr>,
48
49    /// `LIMIT { <N> } BY { <expr>,<expr>,... } }`
50    pub limit_by: Vec<Expr>,
51
52    /// `OFFSET <N> [ { ROW | ROWS } ]`
53    pub offset: Option<Offset>,
54    /// `FETCH { FIRST | NEXT } <N> [ PERCENT ] { ROW | ROWS } | { ONLY | WITH TIES }`
55    pub fetch: Option<Fetch>,
56    /// `FOR { UPDATE | SHARE } [ OF table_name ] [ SKIP LOCKED | NOWAIT ]`
57    pub locks: Vec<LockClause>,
58    /// `FOR XML { RAW | AUTO | EXPLICIT | PATH } [ , ELEMENTS ]`
59    /// `FOR JSON { AUTO | PATH } [ , INCLUDE_NULL_VALUES ]`
60    /// (MSSQL-specific)
61    pub for_clause: Option<ForClause>,
62    /// ClickHouse syntax: `SELECT * FROM t SETTINGS key1 = value1, key2 = value2`
63    ///
64    /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/select#settings-in-select-query)
65    pub settings: Option<Vec<Setting>>,
66    /// `SELECT * FROM t FORMAT JSONCompact`
67    ///
68    /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/select/format)
69    /// (ClickHouse-specific)
70    pub format_clause: Option<FormatClause>,
71}
72
73impl fmt::Display for Query {
74    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
75        if let Some(ref with) = self.with {
76            write!(f, "{with} ")?;
77        }
78        write!(f, "{}", self.body)?;
79        if let Some(ref order_by) = self.order_by {
80            write!(f, " {order_by}")?;
81        }
82        if let Some(ref limit) = self.limit {
83            write!(f, " LIMIT {limit}")?;
84        }
85        if let Some(ref offset) = self.offset {
86            write!(f, " {offset}")?;
87        }
88        if !self.limit_by.is_empty() {
89            write!(f, " BY {}", display_separated(&self.limit_by, ", "))?;
90        }
91        if let Some(ref settings) = self.settings {
92            write!(f, " SETTINGS {}", display_comma_separated(settings))?;
93        }
94        if let Some(ref fetch) = self.fetch {
95            write!(f, " {fetch}")?;
96        }
97        if !self.locks.is_empty() {
98            write!(f, " {}", display_separated(&self.locks, " "))?;
99        }
100        if let Some(ref for_clause) = self.for_clause {
101            write!(f, " {}", for_clause)?;
102        }
103        if let Some(ref format) = self.format_clause {
104            write!(f, " {}", format)?;
105        }
106        Ok(())
107    }
108}
109
110/// Query syntax for ClickHouse ADD PROJECTION statement.
111/// Its syntax is similar to SELECT statement, but it is used to add a new projection to a table.
112/// Syntax is `SELECT <COLUMN LIST EXPR> [GROUP BY] [ORDER BY]`
113///
114/// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/alter/projection#add-projection)
115#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
116#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
117#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
118pub struct ProjectionSelect {
119    pub projection: Vec<SelectItem>,
120    pub order_by: Option<OrderBy>,
121    pub group_by: Option<GroupByExpr>,
122}
123
124impl fmt::Display for ProjectionSelect {
125    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
126        write!(f, "SELECT {}", display_comma_separated(&self.projection))?;
127        if let Some(ref group_by) = self.group_by {
128            write!(f, " {group_by}")?;
129        }
130        if let Some(ref order_by) = self.order_by {
131            write!(f, " {order_by}")?;
132        }
133        Ok(())
134    }
135}
136
137/// A node in a tree, representing a "query body" expression, roughly:
138/// `SELECT ... [ {UNION|EXCEPT|INTERSECT} SELECT ...]`
139#[allow(clippy::large_enum_variant)]
140#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
141#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
142#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
143pub enum SetExpr {
144    /// Restricted SELECT .. FROM .. HAVING (no ORDER BY or set operations)
145    Select(Box<Select>),
146    /// Parenthesized SELECT subquery, which may include more set operations
147    /// in its body and an optional ORDER BY / LIMIT.
148    Query(Box<Query>),
149    /// UNION/EXCEPT/INTERSECT of two queries
150    SetOperation {
151        op: SetOperator,
152        set_quantifier: SetQuantifier,
153        left: Box<SetExpr>,
154        right: Box<SetExpr>,
155    },
156    Values(Values),
157    Insert(Statement),
158    Update(Statement),
159    Table(Box<Table>),
160}
161
162impl SetExpr {
163    /// If this `SetExpr` is a `SELECT`, returns the [`Select`].
164    pub fn as_select(&self) -> Option<&Select> {
165        if let Self::Select(select) = self {
166            Some(&**select)
167        } else {
168            None
169        }
170    }
171}
172
173impl fmt::Display for SetExpr {
174    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
175        match self {
176            SetExpr::Select(s) => write!(f, "{s}"),
177            SetExpr::Query(q) => write!(f, "({q})"),
178            SetExpr::Values(v) => write!(f, "{v}"),
179            SetExpr::Insert(v) => write!(f, "{v}"),
180            SetExpr::Update(v) => write!(f, "{v}"),
181            SetExpr::Table(t) => write!(f, "{t}"),
182            SetExpr::SetOperation {
183                left,
184                right,
185                op,
186                set_quantifier,
187            } => {
188                write!(f, "{left} {op}")?;
189                match set_quantifier {
190                    SetQuantifier::All
191                    | SetQuantifier::Distinct
192                    | SetQuantifier::ByName
193                    | SetQuantifier::AllByName
194                    | SetQuantifier::DistinctByName => write!(f, " {set_quantifier}")?,
195                    SetQuantifier::None => write!(f, "{set_quantifier}")?,
196                }
197                write!(f, " {right}")?;
198                Ok(())
199            }
200        }
201    }
202}
203
204#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
205#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
206#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
207pub enum SetOperator {
208    Union,
209    Except,
210    Intersect,
211    Minus,
212}
213
214impl fmt::Display for SetOperator {
215    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
216        f.write_str(match self {
217            SetOperator::Union => "UNION",
218            SetOperator::Except => "EXCEPT",
219            SetOperator::Intersect => "INTERSECT",
220            SetOperator::Minus => "MINUS",
221        })
222    }
223}
224
225/// A quantifier for [SetOperator].
226// TODO: Restrict parsing specific SetQuantifier in some specific dialects.
227// For example, BigQuery does not support `DISTINCT` for `EXCEPT` and `INTERSECT`
228#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
229#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
230#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
231pub enum SetQuantifier {
232    All,
233    Distinct,
234    ByName,
235    AllByName,
236    DistinctByName,
237    None,
238}
239
240impl fmt::Display for SetQuantifier {
241    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
242        match self {
243            SetQuantifier::All => write!(f, "ALL"),
244            SetQuantifier::Distinct => write!(f, "DISTINCT"),
245            SetQuantifier::ByName => write!(f, "BY NAME"),
246            SetQuantifier::AllByName => write!(f, "ALL BY NAME"),
247            SetQuantifier::DistinctByName => write!(f, "DISTINCT BY NAME"),
248            SetQuantifier::None => write!(f, ""),
249        }
250    }
251}
252
253#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
254#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
255/// A [`TABLE` command]( https://www.postgresql.org/docs/current/sql-select.html#SQL-TABLE)
256#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
257pub struct Table {
258    pub table_name: Option<String>,
259    pub schema_name: Option<String>,
260}
261
262impl fmt::Display for Table {
263    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
264        if let Some(ref schema_name) = self.schema_name {
265            write!(
266                f,
267                "TABLE {}.{}",
268                schema_name,
269                self.table_name.as_ref().unwrap(),
270            )?;
271        } else {
272            write!(f, "TABLE {}", self.table_name.as_ref().unwrap(),)?;
273        }
274        Ok(())
275    }
276}
277
278/// What did this select look like?
279#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
280#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
281#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
282pub enum SelectFlavor {
283    /// `SELECT *`
284    Standard,
285    /// `FROM ... SELECT *`
286    FromFirst,
287    /// `FROM *`
288    FromFirstNoSelect,
289}
290
291/// A restricted variant of `SELECT` (without CTEs/`ORDER BY`), which may
292/// appear either as the only body item of a `Query`, or as an operand
293/// to a set operation like `UNION`.
294#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
295#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
296#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
297pub struct Select {
298    /// Token for the `SELECT` keyword
299    pub select_token: AttachedToken,
300    /// `SELECT [DISTINCT] ...`
301    pub distinct: Option<Distinct>,
302    /// MSSQL syntax: `TOP (<N>) [ PERCENT ] [ WITH TIES ]`
303    pub top: Option<Top>,
304    /// Whether the top was located before `ALL`/`DISTINCT`
305    pub top_before_distinct: bool,
306    /// projection expressions
307    pub projection: Vec<SelectItem>,
308    /// INTO
309    pub into: Option<SelectInto>,
310    /// FROM
311    pub from: Vec<TableWithJoins>,
312    /// LATERAL VIEWs
313    pub lateral_views: Vec<LateralView>,
314    /// ClickHouse syntax: `PREWHERE a = 1 WHERE b = 2`,
315    /// and it can be used together with WHERE selection.
316    ///
317    /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/select/prewhere)
318    pub prewhere: Option<Expr>,
319    /// WHERE
320    pub selection: Option<Expr>,
321    /// GROUP BY
322    pub group_by: GroupByExpr,
323    /// CLUSTER BY (Hive)
324    pub cluster_by: Vec<Expr>,
325    /// DISTRIBUTE BY (Hive)
326    pub distribute_by: Vec<Expr>,
327    /// SORT BY (Hive)
328    pub sort_by: Vec<Expr>,
329    /// HAVING
330    pub having: Option<Expr>,
331    /// WINDOW AS
332    pub named_window: Vec<NamedWindowDefinition>,
333    /// QUALIFY (Snowflake)
334    pub qualify: Option<Expr>,
335    /// The positioning of QUALIFY and WINDOW clauses differ between dialects.
336    /// e.g. BigQuery requires that WINDOW comes after QUALIFY, while DUCKDB accepts
337    /// WINDOW before QUALIFY.
338    /// We accept either positioning and flag the accepted variant.
339    pub window_before_qualify: bool,
340    /// BigQuery syntax: `SELECT AS VALUE | SELECT AS STRUCT`
341    pub value_table_mode: Option<ValueTableMode>,
342    /// STARTING WITH .. CONNECT BY
343    pub connect_by: Option<ConnectBy>,
344    /// Was this a FROM-first query?
345    pub flavor: SelectFlavor,
346}
347
348impl fmt::Display for Select {
349    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
350        match self.flavor {
351            SelectFlavor::Standard => {
352                write!(f, "SELECT")?;
353            }
354            SelectFlavor::FromFirst => {
355                write!(f, "FROM {} SELECT", display_comma_separated(&self.from))?;
356            }
357            SelectFlavor::FromFirstNoSelect => {
358                write!(f, "FROM {}", display_comma_separated(&self.from))?;
359            }
360        }
361
362        if let Some(value_table_mode) = self.value_table_mode {
363            write!(f, " {value_table_mode}")?;
364        }
365
366        if let Some(ref top) = self.top {
367            if self.top_before_distinct {
368                write!(f, " {top}")?;
369            }
370        }
371        if let Some(ref distinct) = self.distinct {
372            write!(f, " {distinct}")?;
373        }
374        if let Some(ref top) = self.top {
375            if !self.top_before_distinct {
376                write!(f, " {top}")?;
377            }
378        }
379
380        if !self.projection.is_empty() {
381            write!(f, " {}", display_comma_separated(&self.projection))?;
382        }
383
384        if let Some(ref into) = self.into {
385            write!(f, " {into}")?;
386        }
387
388        if self.flavor == SelectFlavor::Standard && !self.from.is_empty() {
389            write!(f, " FROM {}", display_comma_separated(&self.from))?;
390        }
391        if !self.lateral_views.is_empty() {
392            for lv in &self.lateral_views {
393                write!(f, "{lv}")?;
394            }
395        }
396        if let Some(ref prewhere) = self.prewhere {
397            write!(f, " PREWHERE {prewhere}")?;
398        }
399        if let Some(ref selection) = self.selection {
400            write!(f, " WHERE {selection}")?;
401        }
402        match &self.group_by {
403            GroupByExpr::All(_) => write!(f, " {}", self.group_by)?,
404            GroupByExpr::Expressions(exprs, _) => {
405                if !exprs.is_empty() {
406                    write!(f, " {}", self.group_by)?
407                }
408            }
409        }
410        if !self.cluster_by.is_empty() {
411            write!(
412                f,
413                " CLUSTER BY {}",
414                display_comma_separated(&self.cluster_by)
415            )?;
416        }
417        if !self.distribute_by.is_empty() {
418            write!(
419                f,
420                " DISTRIBUTE BY {}",
421                display_comma_separated(&self.distribute_by)
422            )?;
423        }
424        if !self.sort_by.is_empty() {
425            write!(f, " SORT BY {}", display_comma_separated(&self.sort_by))?;
426        }
427        if let Some(ref having) = self.having {
428            write!(f, " HAVING {having}")?;
429        }
430        if self.window_before_qualify {
431            if !self.named_window.is_empty() {
432                write!(f, " WINDOW {}", display_comma_separated(&self.named_window))?;
433            }
434            if let Some(ref qualify) = self.qualify {
435                write!(f, " QUALIFY {qualify}")?;
436            }
437        } else {
438            if let Some(ref qualify) = self.qualify {
439                write!(f, " QUALIFY {qualify}")?;
440            }
441            if !self.named_window.is_empty() {
442                write!(f, " WINDOW {}", display_comma_separated(&self.named_window))?;
443            }
444        }
445        if let Some(ref connect_by) = self.connect_by {
446            write!(f, " {connect_by}")?;
447        }
448        Ok(())
449    }
450}
451
452/// A hive LATERAL VIEW with potential column aliases
453#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
454#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
455#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
456pub struct LateralView {
457    /// LATERAL VIEW
458    pub lateral_view: Expr,
459    /// LATERAL VIEW table name
460    pub lateral_view_name: ObjectName,
461    /// LATERAL VIEW optional column aliases
462    pub lateral_col_alias: Vec<Ident>,
463    /// LATERAL VIEW OUTER
464    pub outer: bool,
465}
466
467impl fmt::Display for LateralView {
468    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
469        write!(
470            f,
471            " LATERAL VIEW{outer} {} {}",
472            self.lateral_view,
473            self.lateral_view_name,
474            outer = if self.outer { " OUTER" } else { "" }
475        )?;
476        if !self.lateral_col_alias.is_empty() {
477            write!(
478                f,
479                " AS {}",
480                display_comma_separated(&self.lateral_col_alias)
481            )?;
482        }
483        Ok(())
484    }
485}
486
487/// An expression used in a named window declaration.
488///
489/// ```sql
490/// WINDOW mywindow AS [named_window_expr]
491/// ```
492#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
493#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
494#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
495pub enum NamedWindowExpr {
496    /// A direct reference to another named window definition.
497    /// [BigQuery]
498    ///
499    /// Example:
500    /// ```sql
501    /// WINDOW mywindow AS prev_window
502    /// ```
503    ///
504    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls#ref_named_window
505    NamedWindow(Ident),
506    /// A window expression.
507    ///
508    /// Example:
509    /// ```sql
510    /// WINDOW mywindow AS (ORDER BY 1)
511    /// ```
512    WindowSpec(WindowSpec),
513}
514
515impl fmt::Display for NamedWindowExpr {
516    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
517        match self {
518            NamedWindowExpr::NamedWindow(named_window) => {
519                write!(f, "{named_window}")?;
520            }
521            NamedWindowExpr::WindowSpec(window_spec) => {
522                write!(f, "({window_spec})")?;
523            }
524        };
525        Ok(())
526    }
527}
528
529#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
530#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
531#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
532pub struct NamedWindowDefinition(pub Ident, pub NamedWindowExpr);
533
534impl fmt::Display for NamedWindowDefinition {
535    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
536        write!(f, "{} AS {}", self.0, self.1)
537    }
538}
539
540#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
541#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
542#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
543pub struct With {
544    /// Token for the "WITH" keyword
545    pub with_token: AttachedToken,
546    pub recursive: bool,
547    pub cte_tables: Vec<Cte>,
548}
549
550impl fmt::Display for With {
551    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
552        write!(
553            f,
554            "WITH {}{}",
555            if self.recursive { "RECURSIVE " } else { "" },
556            display_comma_separated(&self.cte_tables)
557        )
558    }
559}
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 enum CteAsMaterialized {
565    /// The `WITH` statement specifies `AS MATERIALIZED` behavior
566    Materialized,
567    /// The `WITH` statement specifies `AS NOT MATERIALIZED` behavior
568    NotMaterialized,
569}
570
571impl fmt::Display for CteAsMaterialized {
572    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
573        match *self {
574            CteAsMaterialized::Materialized => {
575                write!(f, "MATERIALIZED")?;
576            }
577            CteAsMaterialized::NotMaterialized => {
578                write!(f, "NOT MATERIALIZED")?;
579            }
580        };
581        Ok(())
582    }
583}
584
585/// A single CTE (used after `WITH`): `<alias> [(col1, col2, ...)] AS <materialized> ( <query> )`
586/// The names in the column list before `AS`, when specified, replace the names
587/// of the columns returned by the query. The parser does not validate that the
588/// number of columns in the query matches the number of columns in the query.
589#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
590#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
591#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
592pub struct Cte {
593    pub alias: TableAlias,
594    pub query: Box<Query>,
595    pub from: Option<Ident>,
596    pub materialized: Option<CteAsMaterialized>,
597    /// Token for the closing parenthesis
598    pub closing_paren_token: AttachedToken,
599}
600
601impl fmt::Display for Cte {
602    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
603        match self.materialized.as_ref() {
604            None => write!(f, "{} AS ({})", self.alias, self.query)?,
605            Some(materialized) => write!(f, "{} AS {materialized} ({})", self.alias, self.query)?,
606        };
607        if let Some(ref fr) = self.from {
608            write!(f, " FROM {fr}")?;
609        }
610        Ok(())
611    }
612}
613
614/// Represents an expression behind a wildcard expansion in a projection.
615/// `SELECT T.* FROM T;
616#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
617#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
618#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
619pub enum SelectItemQualifiedWildcardKind {
620    /// Expression is an object name.
621    /// e.g. `alias.*` or even `schema.table.*`
622    ObjectName(ObjectName),
623    /// Select star on an arbitrary expression.
624    /// e.g. `STRUCT<STRING>('foo').*`
625    Expr(Expr),
626}
627
628/// One item of the comma-separated list following `SELECT`
629#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
630#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
631#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
632pub enum SelectItem {
633    /// Any expression, not followed by `[ AS ] alias`
634    UnnamedExpr(Expr),
635    /// An expression, followed by `[ AS ] alias`
636    ExprWithAlias { expr: Expr, alias: Ident },
637    /// An expression, followed by a wildcard expansion.
638    /// e.g. `alias.*`, `STRUCT<STRING>('foo').*`
639    QualifiedWildcard(SelectItemQualifiedWildcardKind, WildcardAdditionalOptions),
640    /// An unqualified `*`
641    Wildcard(WildcardAdditionalOptions),
642}
643
644impl fmt::Display for SelectItemQualifiedWildcardKind {
645    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
646        match &self {
647            SelectItemQualifiedWildcardKind::ObjectName(object_name) => {
648                write!(f, "{object_name}.*")
649            }
650            SelectItemQualifiedWildcardKind::Expr(expr) => write!(f, "{expr}.*"),
651        }
652    }
653}
654
655/// Single aliased identifier
656///
657/// # Syntax
658/// ```plaintext
659/// <ident> AS <alias>
660/// ```
661#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
662#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
663#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
664pub struct IdentWithAlias {
665    pub ident: Ident,
666    pub alias: Ident,
667}
668
669impl fmt::Display for IdentWithAlias {
670    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
671        write!(f, "{} AS {}", self.ident, self.alias)
672    }
673}
674
675/// Additional options for wildcards, e.g. Snowflake `EXCLUDE`/`RENAME` and Bigquery `EXCEPT`.
676#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
677#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
678#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
679pub struct WildcardAdditionalOptions {
680    /// The wildcard token `*`
681    pub wildcard_token: AttachedToken,
682    /// `[ILIKE...]`.
683    ///  Snowflake syntax: <https://docs.snowflake.com/en/sql-reference/sql/select#parameters>
684    pub opt_ilike: Option<IlikeSelectItem>,
685    /// `[EXCLUDE...]`.
686    pub opt_exclude: Option<ExcludeSelectItem>,
687    /// `[EXCEPT...]`.
688    ///  Clickhouse syntax: <https://clickhouse.com/docs/en/sql-reference/statements/select#except>
689    pub opt_except: Option<ExceptSelectItem>,
690    /// `[REPLACE]`
691    ///  BigQuery syntax: <https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#select_replace>
692    ///  Clickhouse syntax: <https://clickhouse.com/docs/en/sql-reference/statements/select#replace>
693    ///  Snowflake syntax: <https://docs.snowflake.com/en/sql-reference/sql/select#parameters>
694    pub opt_replace: Option<ReplaceSelectItem>,
695    /// `[RENAME ...]`.
696    pub opt_rename: Option<RenameSelectItem>,
697}
698
699impl Default for WildcardAdditionalOptions {
700    fn default() -> Self {
701        Self {
702            wildcard_token: TokenWithSpan::wrap(Token::Mul).into(),
703            opt_ilike: None,
704            opt_exclude: None,
705            opt_except: None,
706            opt_replace: None,
707            opt_rename: None,
708        }
709    }
710}
711
712impl fmt::Display for WildcardAdditionalOptions {
713    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
714        if let Some(ilike) = &self.opt_ilike {
715            write!(f, " {ilike}")?;
716        }
717        if let Some(exclude) = &self.opt_exclude {
718            write!(f, " {exclude}")?;
719        }
720        if let Some(except) = &self.opt_except {
721            write!(f, " {except}")?;
722        }
723        if let Some(replace) = &self.opt_replace {
724            write!(f, " {replace}")?;
725        }
726        if let Some(rename) = &self.opt_rename {
727            write!(f, " {rename}")?;
728        }
729        Ok(())
730    }
731}
732
733/// Snowflake `ILIKE` information.
734///
735/// # Syntax
736/// ```plaintext
737/// ILIKE <value>
738/// ```
739#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
740#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
741#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
742pub struct IlikeSelectItem {
743    pub pattern: String,
744}
745
746impl fmt::Display for IlikeSelectItem {
747    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
748        write!(
749            f,
750            "ILIKE '{}'",
751            value::escape_single_quote_string(&self.pattern)
752        )?;
753        Ok(())
754    }
755}
756/// Snowflake `EXCLUDE` information.
757///
758/// # Syntax
759/// ```plaintext
760/// <col_name>
761/// | (<col_name>, <col_name>, ...)
762/// ```
763#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
764#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
765#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
766pub enum ExcludeSelectItem {
767    /// Single column name without parenthesis.
768    ///
769    /// # Syntax
770    /// ```plaintext
771    /// <col_name>
772    /// ```
773    Single(Ident),
774    /// Multiple column names inside parenthesis.
775    /// # Syntax
776    /// ```plaintext
777    /// (<col_name>, <col_name>, ...)
778    /// ```
779    Multiple(Vec<Ident>),
780}
781
782impl fmt::Display for ExcludeSelectItem {
783    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
784        write!(f, "EXCLUDE")?;
785        match self {
786            Self::Single(column) => {
787                write!(f, " {column}")?;
788            }
789            Self::Multiple(columns) => {
790                write!(f, " ({})", display_comma_separated(columns))?;
791            }
792        }
793        Ok(())
794    }
795}
796
797/// Snowflake `RENAME` information.
798///
799/// # Syntax
800/// ```plaintext
801/// <col_name> AS <col_alias>
802/// | (<col_name> AS <col_alias>, <col_name> AS <col_alias>, ...)
803/// ```
804#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
805#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
806#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
807pub enum RenameSelectItem {
808    /// Single column name with alias without parenthesis.
809    ///
810    /// # Syntax
811    /// ```plaintext
812    /// <col_name> AS <col_alias>
813    /// ```
814    Single(IdentWithAlias),
815    /// Multiple column names with aliases inside parenthesis.
816    /// # Syntax
817    /// ```plaintext
818    /// (<col_name> AS <col_alias>, <col_name> AS <col_alias>, ...)
819    /// ```
820    Multiple(Vec<IdentWithAlias>),
821}
822
823impl fmt::Display for RenameSelectItem {
824    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
825        write!(f, "RENAME")?;
826        match self {
827            Self::Single(column) => {
828                write!(f, " {column}")?;
829            }
830            Self::Multiple(columns) => {
831                write!(f, " ({})", display_comma_separated(columns))?;
832            }
833        }
834        Ok(())
835    }
836}
837
838/// Bigquery `EXCEPT` information, with at least one column.
839///
840/// # Syntax
841/// ```plaintext
842/// EXCEPT (<col_name> [, ...])
843/// ```
844#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
845#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
846#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
847pub struct ExceptSelectItem {
848    /// First guaranteed column.
849    pub first_element: Ident,
850    /// Additional columns. This list can be empty.
851    pub additional_elements: Vec<Ident>,
852}
853
854impl fmt::Display for ExceptSelectItem {
855    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
856        write!(f, "EXCEPT ")?;
857        if self.additional_elements.is_empty() {
858            write!(f, "({})", self.first_element)?;
859        } else {
860            write!(
861                f,
862                "({}, {})",
863                self.first_element,
864                display_comma_separated(&self.additional_elements)
865            )?;
866        }
867        Ok(())
868    }
869}
870
871/// Bigquery `REPLACE` information.
872///
873/// # Syntax
874/// ```plaintext
875/// REPLACE (<new_expr> [AS] <col_name>)
876/// REPLACE (<col_name> [AS] <col_alias>, <col_name> [AS] <col_alias>, ...)
877/// ```
878#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
879#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
880#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
881pub struct ReplaceSelectItem {
882    pub items: Vec<Box<ReplaceSelectElement>>,
883}
884
885impl fmt::Display for ReplaceSelectItem {
886    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
887        write!(f, "REPLACE")?;
888        write!(f, " ({})", display_comma_separated(&self.items))?;
889        Ok(())
890    }
891}
892
893/// # Syntax
894/// ```plaintext
895/// <expr> [AS] <column_name>
896/// ```
897#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
898#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
899#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
900pub struct ReplaceSelectElement {
901    pub expr: Expr,
902    pub column_name: Ident,
903    pub as_keyword: bool,
904}
905
906impl fmt::Display for ReplaceSelectElement {
907    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
908        if self.as_keyword {
909            write!(f, "{} AS {}", self.expr, self.column_name)
910        } else {
911            write!(f, "{} {}", self.expr, self.column_name)
912        }
913    }
914}
915
916impl fmt::Display for SelectItem {
917    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
918        match &self {
919            SelectItem::UnnamedExpr(expr) => write!(f, "{expr}"),
920            SelectItem::ExprWithAlias { expr, alias } => write!(f, "{expr} AS {alias}"),
921            SelectItem::QualifiedWildcard(kind, additional_options) => {
922                write!(f, "{kind}")?;
923                write!(f, "{additional_options}")?;
924                Ok(())
925            }
926            SelectItem::Wildcard(additional_options) => {
927                write!(f, "*")?;
928                write!(f, "{additional_options}")?;
929                Ok(())
930            }
931        }
932    }
933}
934
935#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
936#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
937#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
938pub struct TableWithJoins {
939    pub relation: TableFactor,
940    pub joins: Vec<Join>,
941}
942
943impl fmt::Display for TableWithJoins {
944    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
945        write!(f, "{}", self.relation)?;
946        for join in &self.joins {
947            write!(f, "{join}")?;
948        }
949        Ok(())
950    }
951}
952
953/// Joins a table to itself to process hierarchical data in the table.
954///
955/// See <https://docs.snowflake.com/en/sql-reference/constructs/connect-by>.
956#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
957#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
958#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
959pub struct ConnectBy {
960    /// START WITH
961    pub condition: Expr,
962    /// CONNECT BY
963    pub relationships: Vec<Expr>,
964}
965
966impl fmt::Display for ConnectBy {
967    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
968        write!(
969            f,
970            "START WITH {condition} CONNECT BY {relationships}",
971            condition = self.condition,
972            relationships = display_comma_separated(&self.relationships)
973        )
974    }
975}
976
977#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
978#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
979#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
980pub struct Setting {
981    pub key: Ident,
982    pub value: Value,
983}
984
985impl fmt::Display for Setting {
986    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
987        write!(f, "{} = {}", self.key, self.value)
988    }
989}
990
991/// An expression optionally followed by an alias.
992///
993/// Example:
994/// ```sql
995/// 42 AS myint
996/// ```
997#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
998#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
999#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1000pub struct ExprWithAlias {
1001    pub expr: Expr,
1002    pub alias: Option<Ident>,
1003}
1004
1005impl fmt::Display for ExprWithAlias {
1006    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1007        let ExprWithAlias { expr, alias } = self;
1008        write!(f, "{expr}")?;
1009        if let Some(alias) = alias {
1010            write!(f, " AS {alias}")?;
1011        }
1012        Ok(())
1013    }
1014}
1015
1016/// Arguments to a table-valued function
1017#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1018#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1019#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1020pub struct TableFunctionArgs {
1021    pub args: Vec<FunctionArg>,
1022    /// ClickHouse-specific SETTINGS clause.
1023    /// For example,
1024    /// `SELECT * FROM executable('generate_random.py', TabSeparated, 'id UInt32, random String', SETTINGS send_chunk_header = false, pool_size = 16)`
1025    /// [`executable` table function](https://clickhouse.com/docs/en/engines/table-functions/executable)
1026    pub settings: Option<Vec<Setting>>,
1027}
1028
1029#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1030#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1031#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1032pub enum TableIndexHintType {
1033    Use,
1034    Ignore,
1035    Force,
1036}
1037
1038impl fmt::Display for TableIndexHintType {
1039    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1040        f.write_str(match self {
1041            TableIndexHintType::Use => "USE",
1042            TableIndexHintType::Ignore => "IGNORE",
1043            TableIndexHintType::Force => "FORCE",
1044        })
1045    }
1046}
1047
1048#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1049#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1050#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1051pub enum TableIndexType {
1052    Index,
1053    Key,
1054}
1055
1056impl fmt::Display for TableIndexType {
1057    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1058        f.write_str(match self {
1059            TableIndexType::Index => "INDEX",
1060            TableIndexType::Key => "KEY",
1061        })
1062    }
1063}
1064
1065#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1066#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1067#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1068pub enum TableIndexHintForClause {
1069    Join,
1070    OrderBy,
1071    GroupBy,
1072}
1073
1074impl fmt::Display for TableIndexHintForClause {
1075    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1076        f.write_str(match self {
1077            TableIndexHintForClause::Join => "JOIN",
1078            TableIndexHintForClause::OrderBy => "ORDER BY",
1079            TableIndexHintForClause::GroupBy => "GROUP BY",
1080        })
1081    }
1082}
1083
1084#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1085#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1086#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1087pub struct TableIndexHints {
1088    pub hint_type: TableIndexHintType,
1089    pub index_type: TableIndexType,
1090    pub for_clause: Option<TableIndexHintForClause>,
1091    pub index_names: Vec<Ident>,
1092}
1093
1094impl fmt::Display for TableIndexHints {
1095    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1096        write!(f, "{} {} ", self.hint_type, self.index_type)?;
1097        if let Some(for_clause) = &self.for_clause {
1098            write!(f, "FOR {} ", for_clause)?;
1099        }
1100        write!(f, "({})", display_comma_separated(&self.index_names))
1101    }
1102}
1103
1104/// A table name or a parenthesized subquery with an optional alias
1105#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1106#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1107#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1108#[cfg_attr(feature = "visitor", visit(with = "visit_table_factor"))]
1109pub enum TableFactor {
1110    Table {
1111        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
1112        name: ObjectName,
1113        alias: Option<TableAlias>,
1114        /// Arguments of a table-valued function, as supported by Postgres
1115        /// and MSSQL. Note that deprecated MSSQL `FROM foo (NOLOCK)` syntax
1116        /// will also be parsed as `args`.
1117        ///
1118        /// This field's value is `Some(v)`, where `v` is a (possibly empty)
1119        /// vector of arguments, in the case of a table-valued function call,
1120        /// whereas it's `None` in the case of a regular table name.
1121        args: Option<TableFunctionArgs>,
1122        /// MSSQL-specific `WITH (...)` hints such as NOLOCK.
1123        with_hints: Vec<Expr>,
1124        /// Optional version qualifier to facilitate table time-travel, as
1125        /// supported by BigQuery and MSSQL.
1126        version: Option<TableVersion>,
1127        //  Optional table function modifier to generate the ordinality for column.
1128        /// For example, `SELECT * FROM generate_series(1, 10) WITH ORDINALITY AS t(a, b);`
1129        /// [WITH ORDINALITY](https://www.postgresql.org/docs/current/functions-srf.html), supported by Postgres.
1130        with_ordinality: bool,
1131        /// [Partition selection](https://dev.mysql.com/doc/refman/8.0/en/partitioning-selection.html), supported by MySQL.
1132        partitions: Vec<Ident>,
1133        /// Optional PartiQL JsonPath: <https://partiql.org/dql/from.html>
1134        json_path: Option<JsonPath>,
1135        /// Optional table sample modifier
1136        /// See: <https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#sample-clause>
1137        sample: Option<TableSampleKind>,
1138        /// Optional index hints(mysql)
1139        /// See: <https://dev.mysql.com/doc/refman/8.4/en/index-hints.html>
1140        index_hints: Vec<TableIndexHints>,
1141    },
1142    Derived {
1143        lateral: bool,
1144        subquery: Box<Query>,
1145        alias: Option<TableAlias>,
1146    },
1147    /// `TABLE(<expr>)[ AS <alias> ]`
1148    TableFunction {
1149        expr: Expr,
1150        alias: Option<TableAlias>,
1151    },
1152    /// `e.g. LATERAL FLATTEN(<args>)[ AS <alias> ]`
1153    Function {
1154        lateral: bool,
1155        name: ObjectName,
1156        args: Vec<FunctionArg>,
1157        alias: Option<TableAlias>,
1158    },
1159    /// ```sql
1160    /// SELECT * FROM UNNEST ([10,20,30]) as numbers WITH OFFSET;
1161    /// +---------+--------+
1162    /// | numbers | offset |
1163    /// +---------+--------+
1164    /// | 10      | 0      |
1165    /// | 20      | 1      |
1166    /// | 30      | 2      |
1167    /// +---------+--------+
1168    /// ```
1169    UNNEST {
1170        alias: Option<TableAlias>,
1171        array_exprs: Vec<Expr>,
1172        with_offset: bool,
1173        with_offset_alias: Option<Ident>,
1174        with_ordinality: bool,
1175    },
1176    /// The `JSON_TABLE` table-valued function.
1177    /// Part of the SQL standard, but implemented only by MySQL, Oracle, and DB2.
1178    ///
1179    /// <https://modern-sql.com/blog/2017-06/whats-new-in-sql-2016#json_table>
1180    /// <https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html#function_json-table>
1181    ///
1182    /// ```sql
1183    /// SELECT * FROM JSON_TABLE(
1184    ///    '[{"a": 1, "b": 2}, {"a": 3, "b": 4}]',
1185    ///    '$[*]' COLUMNS(
1186    ///        a INT PATH '$.a' DEFAULT '0' ON EMPTY,
1187    ///        b INT PATH '$.b' NULL ON ERROR
1188    ///     )
1189    /// ) AS jt;
1190    /// ````
1191    JsonTable {
1192        /// The JSON expression to be evaluated. It must evaluate to a json string
1193        json_expr: Expr,
1194        /// The path to the array or object to be iterated over.
1195        /// It must evaluate to a json array or object.
1196        json_path: Value,
1197        /// The columns to be extracted from each element of the array or object.
1198        /// Each column must have a name and a type.
1199        columns: Vec<JsonTableColumn>,
1200        /// The alias for the table.
1201        alias: Option<TableAlias>,
1202    },
1203    /// The MSSQL's `OPENJSON` table-valued function.
1204    ///
1205    /// ```sql
1206    /// OPENJSON( jsonExpression [ , path ] )  [ <with_clause> ]
1207    ///
1208    /// <with_clause> ::= WITH ( { colName type [ column_path ] [ AS JSON ] } [ ,...n ] )
1209    /// ````
1210    ///
1211    /// Reference: <https://learn.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql?view=sql-server-ver16#syntax>
1212    OpenJsonTable {
1213        /// The JSON expression to be evaluated. It must evaluate to a json string
1214        json_expr: Expr,
1215        /// The path to the array or object to be iterated over.
1216        /// It must evaluate to a json array or object.
1217        json_path: Option<Value>,
1218        /// The columns to be extracted from each element of the array or object.
1219        /// Each column must have a name and a type.
1220        columns: Vec<OpenJsonTableColumn>,
1221        /// The alias for the table.
1222        alias: Option<TableAlias>,
1223    },
1224    /// Represents a parenthesized table factor. The SQL spec only allows a
1225    /// join expression (`(foo <JOIN> bar [ <JOIN> baz ... ])`) to be nested,
1226    /// possibly several times.
1227    ///
1228    /// The parser may also accept non-standard nesting of bare tables for some
1229    /// dialects, but the information about such nesting is stripped from AST.
1230    NestedJoin {
1231        table_with_joins: Box<TableWithJoins>,
1232        alias: Option<TableAlias>,
1233    },
1234    /// Represents PIVOT operation on a table.
1235    /// For example `FROM monthly_sales PIVOT(sum(amount) FOR MONTH IN ('JAN', 'FEB'))`
1236    ///
1237    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#pivot_operator)
1238    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/constructs/pivot)
1239    Pivot {
1240        table: Box<TableFactor>,
1241        aggregate_functions: Vec<ExprWithAlias>, // Function expression
1242        value_column: Vec<Ident>,
1243        value_source: PivotValueSource,
1244        default_on_null: Option<Expr>,
1245        alias: Option<TableAlias>,
1246    },
1247    /// An UNPIVOT operation on a table.
1248    ///
1249    /// Syntax:
1250    /// ```sql
1251    /// table UNPIVOT(value FOR name IN (column1, [ column2, ... ])) [ alias ]
1252    /// ```
1253    ///
1254    /// See <https://docs.snowflake.com/en/sql-reference/constructs/unpivot>.
1255    Unpivot {
1256        table: Box<TableFactor>,
1257        value: Ident,
1258        name: Ident,
1259        columns: Vec<Ident>,
1260        alias: Option<TableAlias>,
1261    },
1262    /// A `MATCH_RECOGNIZE` operation on a table.
1263    ///
1264    /// See <https://docs.snowflake.com/en/sql-reference/constructs/match_recognize>.
1265    MatchRecognize {
1266        table: Box<TableFactor>,
1267        /// `PARTITION BY <expr> [, ... ]`
1268        partition_by: Vec<Expr>,
1269        /// `ORDER BY <expr> [, ... ]`
1270        order_by: Vec<OrderByExpr>,
1271        /// `MEASURES <expr> [AS] <alias> [, ... ]`
1272        measures: Vec<Measure>,
1273        /// `ONE ROW PER MATCH | ALL ROWS PER MATCH [ <option> ]`
1274        rows_per_match: Option<RowsPerMatch>,
1275        /// `AFTER MATCH SKIP <option>`
1276        after_match_skip: Option<AfterMatchSkip>,
1277        /// `PATTERN ( <pattern> )`
1278        pattern: MatchRecognizePattern,
1279        /// `DEFINE <symbol> AS <expr> [, ... ]`
1280        symbols: Vec<SymbolDefinition>,
1281        alias: Option<TableAlias>,
1282    },
1283}
1284
1285/// The table sample modifier options
1286#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1287#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1288#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1289
1290pub enum TableSampleKind {
1291    /// Table sample located before the table alias option
1292    BeforeTableAlias(Box<TableSample>),
1293    /// Table sample located after the table alias option
1294    AfterTableAlias(Box<TableSample>),
1295}
1296
1297#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1298#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1299#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1300pub struct TableSample {
1301    pub modifier: TableSampleModifier,
1302    pub name: Option<TableSampleMethod>,
1303    pub quantity: Option<TableSampleQuantity>,
1304    pub seed: Option<TableSampleSeed>,
1305    pub bucket: Option<TableSampleBucket>,
1306    pub offset: Option<Expr>,
1307}
1308
1309#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1310#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1311#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1312pub enum TableSampleModifier {
1313    Sample,
1314    TableSample,
1315}
1316
1317impl fmt::Display for TableSampleModifier {
1318    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1319        match self {
1320            TableSampleModifier::Sample => write!(f, "SAMPLE")?,
1321            TableSampleModifier::TableSample => write!(f, "TABLESAMPLE")?,
1322        }
1323        Ok(())
1324    }
1325}
1326
1327#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1328#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1329#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1330pub struct TableSampleQuantity {
1331    pub parenthesized: bool,
1332    pub value: Expr,
1333    pub unit: Option<TableSampleUnit>,
1334}
1335
1336impl fmt::Display for TableSampleQuantity {
1337    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1338        if self.parenthesized {
1339            write!(f, "(")?;
1340        }
1341        write!(f, "{}", self.value)?;
1342        if let Some(unit) = &self.unit {
1343            write!(f, " {}", unit)?;
1344        }
1345        if self.parenthesized {
1346            write!(f, ")")?;
1347        }
1348        Ok(())
1349    }
1350}
1351
1352/// The table sample method names
1353#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1354#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1355#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1356pub enum TableSampleMethod {
1357    Row,
1358    Bernoulli,
1359    System,
1360    Block,
1361}
1362
1363impl fmt::Display for TableSampleMethod {
1364    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1365        match self {
1366            TableSampleMethod::Bernoulli => write!(f, "BERNOULLI"),
1367            TableSampleMethod::Row => write!(f, "ROW"),
1368            TableSampleMethod::System => write!(f, "SYSTEM"),
1369            TableSampleMethod::Block => write!(f, "BLOCK"),
1370        }
1371    }
1372}
1373
1374#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1375#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1376#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1377pub struct TableSampleSeed {
1378    pub modifier: TableSampleSeedModifier,
1379    pub value: Value,
1380}
1381
1382impl fmt::Display for TableSampleSeed {
1383    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1384        write!(f, "{} ({})", self.modifier, self.value)?;
1385        Ok(())
1386    }
1387}
1388
1389#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1390#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1391#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1392pub enum TableSampleSeedModifier {
1393    Repeatable,
1394    Seed,
1395}
1396
1397impl fmt::Display for TableSampleSeedModifier {
1398    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1399        match self {
1400            TableSampleSeedModifier::Repeatable => write!(f, "REPEATABLE"),
1401            TableSampleSeedModifier::Seed => write!(f, "SEED"),
1402        }
1403    }
1404}
1405
1406#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1407#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1408#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1409pub enum TableSampleUnit {
1410    Rows,
1411    Percent,
1412}
1413
1414impl fmt::Display for TableSampleUnit {
1415    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1416        match self {
1417            TableSampleUnit::Percent => write!(f, "PERCENT"),
1418            TableSampleUnit::Rows => write!(f, "ROWS"),
1419        }
1420    }
1421}
1422
1423#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1424#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1425#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1426pub struct TableSampleBucket {
1427    pub bucket: Value,
1428    pub total: Value,
1429    pub on: Option<Expr>,
1430}
1431
1432impl fmt::Display for TableSampleBucket {
1433    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1434        write!(f, "BUCKET {} OUT OF {}", self.bucket, self.total)?;
1435        if let Some(on) = &self.on {
1436            write!(f, " ON {}", on)?;
1437        }
1438        Ok(())
1439    }
1440}
1441impl fmt::Display for TableSample {
1442    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1443        write!(f, " {}", self.modifier)?;
1444        if let Some(name) = &self.name {
1445            write!(f, " {}", name)?;
1446        }
1447        if let Some(quantity) = &self.quantity {
1448            write!(f, " {}", quantity)?;
1449        }
1450        if let Some(seed) = &self.seed {
1451            write!(f, " {}", seed)?;
1452        }
1453        if let Some(bucket) = &self.bucket {
1454            write!(f, " ({})", bucket)?;
1455        }
1456        if let Some(offset) = &self.offset {
1457            write!(f, " OFFSET {}", offset)?;
1458        }
1459        Ok(())
1460    }
1461}
1462
1463/// The source of values in a `PIVOT` operation.
1464#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1465#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1466#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1467pub enum PivotValueSource {
1468    /// Pivot on a static list of values.
1469    ///
1470    /// See <https://docs.snowflake.com/en/sql-reference/constructs/pivot#pivot-on-a-specified-list-of-column-values-for-the-pivot-column>.
1471    List(Vec<ExprWithAlias>),
1472    /// Pivot on all distinct values of the pivot column.
1473    ///
1474    /// See <https://docs.snowflake.com/en/sql-reference/constructs/pivot#pivot-on-all-distinct-column-values-automatically-with-dynamic-pivot>.
1475    Any(Vec<OrderByExpr>),
1476    /// Pivot on all values returned by a subquery.
1477    ///
1478    /// See <https://docs.snowflake.com/en/sql-reference/constructs/pivot#pivot-on-column-values-using-a-subquery-with-dynamic-pivot>.
1479    Subquery(Box<Query>),
1480}
1481
1482impl fmt::Display for PivotValueSource {
1483    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1484        match self {
1485            PivotValueSource::List(values) => write!(f, "{}", display_comma_separated(values)),
1486            PivotValueSource::Any(order_by) => {
1487                write!(f, "ANY")?;
1488                if !order_by.is_empty() {
1489                    write!(f, " ORDER BY {}", display_comma_separated(order_by))?;
1490                }
1491                Ok(())
1492            }
1493            PivotValueSource::Subquery(query) => write!(f, "{query}"),
1494        }
1495    }
1496}
1497
1498/// An item in the `MEASURES` subclause of a `MATCH_RECOGNIZE` operation.
1499///
1500/// See <https://docs.snowflake.com/en/sql-reference/constructs/match_recognize#measures-specifying-additional-output-columns>.
1501#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1502#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1503#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1504pub struct Measure {
1505    pub expr: Expr,
1506    pub alias: Ident,
1507}
1508
1509impl fmt::Display for Measure {
1510    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1511        write!(f, "{} AS {}", self.expr, self.alias)
1512    }
1513}
1514
1515/// The rows per match option in a `MATCH_RECOGNIZE` operation.
1516///
1517/// See <https://docs.snowflake.com/en/sql-reference/constructs/match_recognize#row-s-per-match-specifying-the-rows-to-return>.
1518#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1519#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1520#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1521pub enum RowsPerMatch {
1522    /// `ONE ROW PER MATCH`
1523    OneRow,
1524    /// `ALL ROWS PER MATCH <mode>`
1525    AllRows(Option<EmptyMatchesMode>),
1526}
1527
1528impl fmt::Display for RowsPerMatch {
1529    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1530        match self {
1531            RowsPerMatch::OneRow => write!(f, "ONE ROW PER MATCH"),
1532            RowsPerMatch::AllRows(mode) => {
1533                write!(f, "ALL ROWS PER MATCH")?;
1534                if let Some(mode) = mode {
1535                    write!(f, " {}", mode)?;
1536                }
1537                Ok(())
1538            }
1539        }
1540    }
1541}
1542
1543/// The after match skip option in a `MATCH_RECOGNIZE` operation.
1544///
1545/// See <https://docs.snowflake.com/en/sql-reference/constructs/match_recognize#after-match-skip-specifying-where-to-continue-after-a-match>.
1546#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1547#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1548#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1549pub enum AfterMatchSkip {
1550    /// `PAST LAST ROW`
1551    PastLastRow,
1552    /// `TO NEXT ROW`
1553    ToNextRow,
1554    /// `TO FIRST <symbol>`
1555    ToFirst(Ident),
1556    /// `TO LAST <symbol>`
1557    ToLast(Ident),
1558}
1559
1560impl fmt::Display for AfterMatchSkip {
1561    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1562        write!(f, "AFTER MATCH SKIP ")?;
1563        match self {
1564            AfterMatchSkip::PastLastRow => write!(f, "PAST LAST ROW"),
1565            AfterMatchSkip::ToNextRow => write!(f, " TO NEXT ROW"),
1566            AfterMatchSkip::ToFirst(symbol) => write!(f, "TO FIRST {symbol}"),
1567            AfterMatchSkip::ToLast(symbol) => write!(f, "TO LAST {symbol}"),
1568        }
1569    }
1570}
1571
1572#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1573#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1574#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1575pub enum EmptyMatchesMode {
1576    /// `SHOW EMPTY MATCHES`
1577    Show,
1578    /// `OMIT EMPTY MATCHES`
1579    Omit,
1580    /// `WITH UNMATCHED ROWS`
1581    WithUnmatched,
1582}
1583
1584impl fmt::Display for EmptyMatchesMode {
1585    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1586        match self {
1587            EmptyMatchesMode::Show => write!(f, "SHOW EMPTY MATCHES"),
1588            EmptyMatchesMode::Omit => write!(f, "OMIT EMPTY MATCHES"),
1589            EmptyMatchesMode::WithUnmatched => write!(f, "WITH UNMATCHED ROWS"),
1590        }
1591    }
1592}
1593
1594/// A symbol defined in a `MATCH_RECOGNIZE` operation.
1595///
1596/// See <https://docs.snowflake.com/en/sql-reference/constructs/match_recognize#define-defining-symbols>.
1597#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1598#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1599#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1600pub struct SymbolDefinition {
1601    pub symbol: Ident,
1602    pub definition: Expr,
1603}
1604
1605impl fmt::Display for SymbolDefinition {
1606    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1607        write!(f, "{} AS {}", self.symbol, self.definition)
1608    }
1609}
1610
1611/// A symbol in a `MATCH_RECOGNIZE` pattern.
1612#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1613#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1614#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1615pub enum MatchRecognizeSymbol {
1616    /// A named symbol, e.g. `S1`.
1617    Named(Ident),
1618    /// A virtual symbol representing the start of the of partition (`^`).
1619    Start,
1620    /// A virtual symbol representing the end of the partition (`$`).
1621    End,
1622}
1623
1624impl fmt::Display for MatchRecognizeSymbol {
1625    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1626        match self {
1627            MatchRecognizeSymbol::Named(symbol) => write!(f, "{symbol}"),
1628            MatchRecognizeSymbol::Start => write!(f, "^"),
1629            MatchRecognizeSymbol::End => write!(f, "$"),
1630        }
1631    }
1632}
1633
1634/// The pattern in a `MATCH_RECOGNIZE` operation.
1635///
1636/// See <https://docs.snowflake.com/en/sql-reference/constructs/match_recognize#pattern-specifying-the-pattern-to-match>.
1637#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1638#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1639#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1640pub enum MatchRecognizePattern {
1641    /// A named symbol such as `S1` or a virtual symbol such as `^`.
1642    Symbol(MatchRecognizeSymbol),
1643    /// {- symbol -}
1644    Exclude(MatchRecognizeSymbol),
1645    /// PERMUTE(symbol_1, ..., symbol_n)
1646    Permute(Vec<MatchRecognizeSymbol>),
1647    /// pattern_1 pattern_2 ... pattern_n
1648    Concat(Vec<MatchRecognizePattern>),
1649    /// ( pattern )
1650    Group(Box<MatchRecognizePattern>),
1651    /// pattern_1 | pattern_2 | ... | pattern_n
1652    Alternation(Vec<MatchRecognizePattern>),
1653    /// e.g. pattern*
1654    Repetition(Box<MatchRecognizePattern>, RepetitionQuantifier),
1655}
1656
1657impl fmt::Display for MatchRecognizePattern {
1658    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1659        use MatchRecognizePattern::*;
1660        match self {
1661            Symbol(symbol) => write!(f, "{}", symbol),
1662            Exclude(symbol) => write!(f, "{{- {symbol} -}}"),
1663            Permute(symbols) => write!(f, "PERMUTE({})", display_comma_separated(symbols)),
1664            Concat(patterns) => write!(f, "{}", display_separated(patterns, " ")),
1665            Group(pattern) => write!(f, "( {pattern} )"),
1666            Alternation(patterns) => write!(f, "{}", display_separated(patterns, " | ")),
1667            Repetition(pattern, op) => write!(f, "{pattern}{op}"),
1668        }
1669    }
1670}
1671
1672/// Determines the minimum and maximum allowed occurrences of a pattern in a
1673/// `MATCH_RECOGNIZE` operation.
1674#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1675#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1676#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1677pub enum RepetitionQuantifier {
1678    /// `*`
1679    ZeroOrMore,
1680    /// `+`
1681    OneOrMore,
1682    /// `?`
1683    AtMostOne,
1684    /// `{n}`
1685    Exactly(u32),
1686    /// `{n,}`
1687    AtLeast(u32),
1688    /// `{,n}`
1689    AtMost(u32),
1690    /// `{n,m}
1691    Range(u32, u32),
1692}
1693
1694impl fmt::Display for RepetitionQuantifier {
1695    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1696        use RepetitionQuantifier::*;
1697        match self {
1698            ZeroOrMore => write!(f, "*"),
1699            OneOrMore => write!(f, "+"),
1700            AtMostOne => write!(f, "?"),
1701            Exactly(n) => write!(f, "{{{n}}}"),
1702            AtLeast(n) => write!(f, "{{{n},}}"),
1703            AtMost(n) => write!(f, "{{,{n}}}"),
1704            Range(n, m) => write!(f, "{{{n},{m}}}"),
1705        }
1706    }
1707}
1708
1709impl fmt::Display for TableFactor {
1710    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1711        match self {
1712            TableFactor::Table {
1713                name,
1714                alias,
1715                args,
1716                with_hints,
1717                version,
1718                partitions,
1719                with_ordinality,
1720                json_path,
1721                sample,
1722                index_hints,
1723            } => {
1724                write!(f, "{name}")?;
1725                if let Some(json_path) = json_path {
1726                    write!(f, "{json_path}")?;
1727                }
1728                if !partitions.is_empty() {
1729                    write!(f, "PARTITION ({})", display_comma_separated(partitions))?;
1730                }
1731                if let Some(args) = args {
1732                    write!(f, "(")?;
1733                    write!(f, "{}", display_comma_separated(&args.args))?;
1734                    if let Some(ref settings) = args.settings {
1735                        if !args.args.is_empty() {
1736                            write!(f, ", ")?;
1737                        }
1738                        write!(f, "SETTINGS {}", display_comma_separated(settings))?;
1739                    }
1740                    write!(f, ")")?;
1741                }
1742                if *with_ordinality {
1743                    write!(f, " WITH ORDINALITY")?;
1744                }
1745                if let Some(TableSampleKind::BeforeTableAlias(sample)) = sample {
1746                    write!(f, "{sample}")?;
1747                }
1748                if let Some(alias) = alias {
1749                    write!(f, " AS {alias}")?;
1750                }
1751                if !index_hints.is_empty() {
1752                    write!(f, " {}", display_separated(index_hints, " "))?;
1753                }
1754                if !with_hints.is_empty() {
1755                    write!(f, " WITH ({})", display_comma_separated(with_hints))?;
1756                }
1757                if let Some(version) = version {
1758                    write!(f, "{version}")?;
1759                }
1760                if let Some(TableSampleKind::AfterTableAlias(sample)) = sample {
1761                    write!(f, "{sample}")?;
1762                }
1763                Ok(())
1764            }
1765            TableFactor::Derived {
1766                lateral,
1767                subquery,
1768                alias,
1769            } => {
1770                if *lateral {
1771                    write!(f, "LATERAL ")?;
1772                }
1773                write!(f, "({subquery})")?;
1774                if let Some(alias) = alias {
1775                    write!(f, " AS {alias}")?;
1776                }
1777                Ok(())
1778            }
1779            TableFactor::Function {
1780                lateral,
1781                name,
1782                args,
1783                alias,
1784            } => {
1785                if *lateral {
1786                    write!(f, "LATERAL ")?;
1787                }
1788                write!(f, "{name}")?;
1789                write!(f, "({})", display_comma_separated(args))?;
1790                if let Some(alias) = alias {
1791                    write!(f, " AS {alias}")?;
1792                }
1793                Ok(())
1794            }
1795            TableFactor::TableFunction { expr, alias } => {
1796                write!(f, "TABLE({expr})")?;
1797                if let Some(alias) = alias {
1798                    write!(f, " AS {alias}")?;
1799                }
1800                Ok(())
1801            }
1802            TableFactor::UNNEST {
1803                alias,
1804                array_exprs,
1805                with_offset,
1806                with_offset_alias,
1807                with_ordinality,
1808            } => {
1809                write!(f, "UNNEST({})", display_comma_separated(array_exprs))?;
1810
1811                if *with_ordinality {
1812                    write!(f, " WITH ORDINALITY")?;
1813                }
1814
1815                if let Some(alias) = alias {
1816                    write!(f, " AS {alias}")?;
1817                }
1818                if *with_offset {
1819                    write!(f, " WITH OFFSET")?;
1820                }
1821                if let Some(alias) = with_offset_alias {
1822                    write!(f, " AS {alias}")?;
1823                }
1824                Ok(())
1825            }
1826            TableFactor::JsonTable {
1827                json_expr,
1828                json_path,
1829                columns,
1830                alias,
1831            } => {
1832                write!(
1833                    f,
1834                    "JSON_TABLE({json_expr}, {json_path} COLUMNS({columns}))",
1835                    columns = display_comma_separated(columns)
1836                )?;
1837                if let Some(alias) = alias {
1838                    write!(f, " AS {alias}")?;
1839                }
1840                Ok(())
1841            }
1842            TableFactor::OpenJsonTable {
1843                json_expr,
1844                json_path,
1845                columns,
1846                alias,
1847            } => {
1848                write!(f, "OPENJSON({json_expr}")?;
1849                if let Some(json_path) = json_path {
1850                    write!(f, ", {json_path}")?;
1851                }
1852                write!(f, ")")?;
1853                if !columns.is_empty() {
1854                    write!(f, " WITH ({})", display_comma_separated(columns))?;
1855                }
1856                if let Some(alias) = alias {
1857                    write!(f, " AS {alias}")?;
1858                }
1859                Ok(())
1860            }
1861            TableFactor::NestedJoin {
1862                table_with_joins,
1863                alias,
1864            } => {
1865                write!(f, "({table_with_joins})")?;
1866                if let Some(alias) = alias {
1867                    write!(f, " AS {alias}")?;
1868                }
1869                Ok(())
1870            }
1871            TableFactor::Pivot {
1872                table,
1873                aggregate_functions,
1874                value_column,
1875                value_source,
1876                default_on_null,
1877                alias,
1878            } => {
1879                write!(
1880                    f,
1881                    "{table} PIVOT({} FOR {} IN ({value_source})",
1882                    display_comma_separated(aggregate_functions),
1883                    Expr::CompoundIdentifier(value_column.to_vec()),
1884                )?;
1885                if let Some(expr) = default_on_null {
1886                    write!(f, " DEFAULT ON NULL ({expr})")?;
1887                }
1888                write!(f, ")")?;
1889                if alias.is_some() {
1890                    write!(f, " AS {}", alias.as_ref().unwrap())?;
1891                }
1892                Ok(())
1893            }
1894            TableFactor::Unpivot {
1895                table,
1896                value,
1897                name,
1898                columns,
1899                alias,
1900            } => {
1901                write!(
1902                    f,
1903                    "{} UNPIVOT({} FOR {} IN ({}))",
1904                    table,
1905                    value,
1906                    name,
1907                    display_comma_separated(columns)
1908                )?;
1909                if alias.is_some() {
1910                    write!(f, " AS {}", alias.as_ref().unwrap())?;
1911                }
1912                Ok(())
1913            }
1914            TableFactor::MatchRecognize {
1915                table,
1916                partition_by,
1917                order_by,
1918                measures,
1919                rows_per_match,
1920                after_match_skip,
1921                pattern,
1922                symbols,
1923                alias,
1924            } => {
1925                write!(f, "{table} MATCH_RECOGNIZE(")?;
1926                if !partition_by.is_empty() {
1927                    write!(f, "PARTITION BY {} ", display_comma_separated(partition_by))?;
1928                }
1929                if !order_by.is_empty() {
1930                    write!(f, "ORDER BY {} ", display_comma_separated(order_by))?;
1931                }
1932                if !measures.is_empty() {
1933                    write!(f, "MEASURES {} ", display_comma_separated(measures))?;
1934                }
1935                if let Some(rows_per_match) = rows_per_match {
1936                    write!(f, "{rows_per_match} ")?;
1937                }
1938                if let Some(after_match_skip) = after_match_skip {
1939                    write!(f, "{after_match_skip} ")?;
1940                }
1941                write!(f, "PATTERN ({pattern}) ")?;
1942                write!(f, "DEFINE {})", display_comma_separated(symbols))?;
1943                if alias.is_some() {
1944                    write!(f, " AS {}", alias.as_ref().unwrap())?;
1945                }
1946                Ok(())
1947            }
1948        }
1949    }
1950}
1951
1952#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1953#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1954#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1955pub struct TableAlias {
1956    pub name: Ident,
1957    pub columns: Vec<TableAliasColumnDef>,
1958}
1959
1960impl fmt::Display for TableAlias {
1961    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1962        write!(f, "{}", self.name)?;
1963        if !self.columns.is_empty() {
1964            write!(f, " ({})", display_comma_separated(&self.columns))?;
1965        }
1966        Ok(())
1967    }
1968}
1969
1970/// SQL column definition in a table expression alias.
1971/// Most of the time, the data type is not specified.
1972/// But some table-valued functions do require specifying the data type.
1973///
1974/// See <https://www.postgresql.org/docs/17/queries-table-expressions.html#QUERIES-TABLEFUNCTIONS>
1975#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1976#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1977#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1978pub struct TableAliasColumnDef {
1979    /// Column name alias
1980    pub name: Ident,
1981    /// Some table-valued functions require specifying the data type in the alias.
1982    pub data_type: Option<DataType>,
1983}
1984
1985impl TableAliasColumnDef {
1986    /// Create a new table alias column definition with only a name and no type
1987    pub fn from_name<S: Into<String>>(name: S) -> Self {
1988        TableAliasColumnDef {
1989            name: Ident::new(name),
1990            data_type: None,
1991        }
1992    }
1993}
1994
1995impl fmt::Display for TableAliasColumnDef {
1996    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1997        write!(f, "{}", self.name)?;
1998        if let Some(ref data_type) = self.data_type {
1999            write!(f, " {}", data_type)?;
2000        }
2001        Ok(())
2002    }
2003}
2004
2005#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2006#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2007#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2008pub enum TableVersion {
2009    /// When the table version is defined using `FOR SYSTEM_TIME AS OF`.
2010    /// For example: `SELECT * FROM tbl FOR SYSTEM_TIME AS OF TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)`
2011    ForSystemTimeAsOf(Expr),
2012    /// When the table version is defined using a function.
2013    /// For example: `SELECT * FROM tbl AT(TIMESTAMP => '2020-08-14 09:30:00')`
2014    Function(Expr),
2015}
2016
2017impl Display for TableVersion {
2018    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2019        match self {
2020            TableVersion::ForSystemTimeAsOf(e) => write!(f, " FOR SYSTEM_TIME AS OF {e}")?,
2021            TableVersion::Function(func) => write!(f, " {func}")?,
2022        }
2023        Ok(())
2024    }
2025}
2026
2027#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2028#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2029#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2030pub struct Join {
2031    pub relation: TableFactor,
2032    /// ClickHouse supports the optional `GLOBAL` keyword before the join operator.
2033    /// See [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/select/join)
2034    pub global: bool,
2035    pub join_operator: JoinOperator,
2036}
2037
2038impl fmt::Display for Join {
2039    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2040        fn prefix(constraint: &JoinConstraint) -> &'static str {
2041            match constraint {
2042                JoinConstraint::Natural => "NATURAL ",
2043                _ => "",
2044            }
2045        }
2046        fn suffix(constraint: &'_ JoinConstraint) -> impl fmt::Display + '_ {
2047            struct Suffix<'a>(&'a JoinConstraint);
2048            impl fmt::Display for Suffix<'_> {
2049                fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2050                    match self.0 {
2051                        JoinConstraint::On(expr) => write!(f, " ON {expr}"),
2052                        JoinConstraint::Using(attrs) => {
2053                            write!(f, " USING({})", display_comma_separated(attrs))
2054                        }
2055                        _ => Ok(()),
2056                    }
2057                }
2058            }
2059            Suffix(constraint)
2060        }
2061        if self.global {
2062            write!(f, " GLOBAL")?;
2063        }
2064
2065        match &self.join_operator {
2066            JoinOperator::Join(constraint) => write!(
2067                f,
2068                " {}JOIN {}{}",
2069                prefix(constraint),
2070                self.relation,
2071                suffix(constraint)
2072            ),
2073            JoinOperator::Inner(constraint) => write!(
2074                f,
2075                " {}INNER JOIN {}{}",
2076                prefix(constraint),
2077                self.relation,
2078                suffix(constraint)
2079            ),
2080            JoinOperator::Left(constraint) => write!(
2081                f,
2082                " {}LEFT JOIN {}{}",
2083                prefix(constraint),
2084                self.relation,
2085                suffix(constraint)
2086            ),
2087            JoinOperator::LeftOuter(constraint) => write!(
2088                f,
2089                " {}LEFT OUTER JOIN {}{}",
2090                prefix(constraint),
2091                self.relation,
2092                suffix(constraint)
2093            ),
2094            JoinOperator::Right(constraint) => write!(
2095                f,
2096                " {}RIGHT JOIN {}{}",
2097                prefix(constraint),
2098                self.relation,
2099                suffix(constraint)
2100            ),
2101            JoinOperator::RightOuter(constraint) => write!(
2102                f,
2103                " {}RIGHT OUTER JOIN {}{}",
2104                prefix(constraint),
2105                self.relation,
2106                suffix(constraint)
2107            ),
2108            JoinOperator::FullOuter(constraint) => write!(
2109                f,
2110                " {}FULL JOIN {}{}",
2111                prefix(constraint),
2112                self.relation,
2113                suffix(constraint)
2114            ),
2115            JoinOperator::CrossJoin => write!(f, " CROSS JOIN {}", self.relation),
2116            JoinOperator::Semi(constraint) => write!(
2117                f,
2118                " {}SEMI JOIN {}{}",
2119                prefix(constraint),
2120                self.relation,
2121                suffix(constraint)
2122            ),
2123            JoinOperator::LeftSemi(constraint) => write!(
2124                f,
2125                " {}LEFT SEMI JOIN {}{}",
2126                prefix(constraint),
2127                self.relation,
2128                suffix(constraint)
2129            ),
2130            JoinOperator::RightSemi(constraint) => write!(
2131                f,
2132                " {}RIGHT SEMI JOIN {}{}",
2133                prefix(constraint),
2134                self.relation,
2135                suffix(constraint)
2136            ),
2137            JoinOperator::Anti(constraint) => write!(
2138                f,
2139                " {}ANTI JOIN {}{}",
2140                prefix(constraint),
2141                self.relation,
2142                suffix(constraint)
2143            ),
2144            JoinOperator::LeftAnti(constraint) => write!(
2145                f,
2146                " {}LEFT ANTI JOIN {}{}",
2147                prefix(constraint),
2148                self.relation,
2149                suffix(constraint)
2150            ),
2151            JoinOperator::RightAnti(constraint) => write!(
2152                f,
2153                " {}RIGHT ANTI JOIN {}{}",
2154                prefix(constraint),
2155                self.relation,
2156                suffix(constraint)
2157            ),
2158            JoinOperator::CrossApply => write!(f, " CROSS APPLY {}", self.relation),
2159            JoinOperator::OuterApply => write!(f, " OUTER APPLY {}", self.relation),
2160            JoinOperator::AsOf {
2161                match_condition,
2162                constraint,
2163            } => write!(
2164                f,
2165                " ASOF JOIN {} MATCH_CONDITION ({match_condition}){}",
2166                self.relation,
2167                suffix(constraint)
2168            ),
2169        }
2170    }
2171}
2172
2173#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2174#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2175#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2176pub enum JoinOperator {
2177    Join(JoinConstraint),
2178    Inner(JoinConstraint),
2179    Left(JoinConstraint),
2180    LeftOuter(JoinConstraint),
2181    Right(JoinConstraint),
2182    RightOuter(JoinConstraint),
2183    FullOuter(JoinConstraint),
2184    CrossJoin,
2185    /// SEMI (non-standard)
2186    Semi(JoinConstraint),
2187    /// LEFT SEMI (non-standard)
2188    LeftSemi(JoinConstraint),
2189    /// RIGHT SEMI (non-standard)
2190    RightSemi(JoinConstraint),
2191    /// ANTI (non-standard)
2192    Anti(JoinConstraint),
2193    /// LEFT ANTI (non-standard)
2194    LeftAnti(JoinConstraint),
2195    /// RIGHT ANTI (non-standard)
2196    RightAnti(JoinConstraint),
2197    /// CROSS APPLY (non-standard)
2198    CrossApply,
2199    /// OUTER APPLY (non-standard)
2200    OuterApply,
2201    /// `ASOF` joins are used for joining tables containing time-series data
2202    /// whose timestamp columns do not match exactly.
2203    ///
2204    /// See <https://docs.snowflake.com/en/sql-reference/constructs/asof-join>.
2205    AsOf {
2206        match_condition: Expr,
2207        constraint: JoinConstraint,
2208    },
2209}
2210
2211#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2212#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2213#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2214pub enum JoinConstraint {
2215    On(Expr),
2216    Using(Vec<ObjectName>),
2217    Natural,
2218    None,
2219}
2220
2221#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2222#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2223#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2224pub enum OrderByKind {
2225    /// ALL syntax of [DuckDB] and [ClickHouse].
2226    ///
2227    /// [DuckDB]:  <https://duckdb.org/docs/sql/query_syntax/orderby>
2228    /// [ClickHouse]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by>
2229    All(OrderByOptions),
2230
2231    /// Expressions
2232    Expressions(Vec<OrderByExpr>),
2233}
2234
2235#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2236#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2237#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2238pub struct OrderBy {
2239    pub kind: OrderByKind,
2240
2241    /// Optional: `INTERPOLATE`
2242    /// Supported by [ClickHouse syntax]
2243    pub interpolate: Option<Interpolate>,
2244}
2245
2246impl fmt::Display for OrderBy {
2247    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2248        write!(f, "ORDER BY")?;
2249        match &self.kind {
2250            OrderByKind::Expressions(exprs) => {
2251                write!(f, " {}", display_comma_separated(exprs))?;
2252            }
2253            OrderByKind::All(all) => {
2254                write!(f, " ALL{}", all)?;
2255            }
2256        }
2257
2258        if let Some(ref interpolate) = self.interpolate {
2259            match &interpolate.exprs {
2260                Some(exprs) => write!(f, " INTERPOLATE ({})", display_comma_separated(exprs))?,
2261                None => write!(f, " INTERPOLATE")?,
2262            }
2263        }
2264
2265        Ok(())
2266    }
2267}
2268
2269/// An `ORDER BY` expression
2270#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2271#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2272#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2273pub struct OrderByExpr {
2274    pub expr: Expr,
2275    pub options: OrderByOptions,
2276    /// Optional: `WITH FILL`
2277    /// Supported by [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
2278    pub with_fill: Option<WithFill>,
2279}
2280
2281impl fmt::Display for OrderByExpr {
2282    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2283        write!(f, "{}{}", self.expr, self.options)?;
2284        if let Some(ref with_fill) = self.with_fill {
2285            write!(f, " {}", with_fill)?
2286        }
2287        Ok(())
2288    }
2289}
2290
2291/// ClickHouse `WITH FILL` modifier for `ORDER BY` clause.
2292/// Supported by [ClickHouse syntax]
2293///
2294/// [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
2295#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2296#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2297#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2298pub struct WithFill {
2299    pub from: Option<Expr>,
2300    pub to: Option<Expr>,
2301    pub step: Option<Expr>,
2302}
2303
2304impl fmt::Display for WithFill {
2305    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2306        write!(f, "WITH FILL")?;
2307        if let Some(ref from) = self.from {
2308            write!(f, " FROM {}", from)?;
2309        }
2310        if let Some(ref to) = self.to {
2311            write!(f, " TO {}", to)?;
2312        }
2313        if let Some(ref step) = self.step {
2314            write!(f, " STEP {}", step)?;
2315        }
2316        Ok(())
2317    }
2318}
2319
2320/// ClickHouse `INTERPOLATE` clause for use in `ORDER BY` clause when using `WITH FILL` modifier.
2321/// Supported by [ClickHouse syntax]
2322///
2323/// [ClickHouse syntax]: <https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier>
2324#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2325#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2326#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2327pub struct InterpolateExpr {
2328    pub column: Ident,
2329    pub expr: Option<Expr>,
2330}
2331
2332#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2333#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2334#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2335pub struct Interpolate {
2336    pub exprs: Option<Vec<InterpolateExpr>>,
2337}
2338
2339impl fmt::Display for InterpolateExpr {
2340    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2341        write!(f, "{}", self.column)?;
2342        if let Some(ref expr) = self.expr {
2343            write!(f, " AS {}", expr)?;
2344        }
2345        Ok(())
2346    }
2347}
2348
2349#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2350#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2351#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2352pub struct OrderByOptions {
2353    /// Optional `ASC` or `DESC`
2354    pub asc: Option<bool>,
2355    /// Optional `NULLS FIRST` or `NULLS LAST`
2356    pub nulls_first: Option<bool>,
2357}
2358
2359impl fmt::Display for OrderByOptions {
2360    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2361        match self.asc {
2362            Some(true) => write!(f, " ASC")?,
2363            Some(false) => write!(f, " DESC")?,
2364            None => (),
2365        }
2366        match self.nulls_first {
2367            Some(true) => write!(f, " NULLS FIRST")?,
2368            Some(false) => write!(f, " NULLS LAST")?,
2369            None => (),
2370        }
2371        Ok(())
2372    }
2373}
2374
2375#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2376#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2377#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2378pub struct Offset {
2379    pub value: Expr,
2380    pub rows: OffsetRows,
2381}
2382
2383impl fmt::Display for Offset {
2384    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2385        write!(f, "OFFSET {}{}", self.value, self.rows)
2386    }
2387}
2388
2389/// Stores the keyword after `OFFSET <number>`
2390#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2391#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2392#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2393pub enum OffsetRows {
2394    /// Omitting ROW/ROWS is non-standard MySQL quirk.
2395    None,
2396    Row,
2397    Rows,
2398}
2399
2400impl fmt::Display for OffsetRows {
2401    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2402        match self {
2403            OffsetRows::None => Ok(()),
2404            OffsetRows::Row => write!(f, " ROW"),
2405            OffsetRows::Rows => write!(f, " ROWS"),
2406        }
2407    }
2408}
2409
2410#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2411#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2412#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2413pub struct Fetch {
2414    pub with_ties: bool,
2415    pub percent: bool,
2416    pub quantity: Option<Expr>,
2417}
2418
2419impl fmt::Display for Fetch {
2420    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2421        let extension = if self.with_ties { "WITH TIES" } else { "ONLY" };
2422        if let Some(ref quantity) = self.quantity {
2423            let percent = if self.percent { " PERCENT" } else { "" };
2424            write!(f, "FETCH FIRST {quantity}{percent} ROWS {extension}")
2425        } else {
2426            write!(f, "FETCH FIRST ROWS {extension}")
2427        }
2428    }
2429}
2430
2431#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2432#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2433#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2434pub struct LockClause {
2435    pub lock_type: LockType,
2436    pub of: Option<ObjectName>,
2437    pub nonblock: Option<NonBlock>,
2438}
2439
2440impl fmt::Display for LockClause {
2441    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2442        write!(f, "FOR {}", &self.lock_type)?;
2443        if let Some(ref of) = self.of {
2444            write!(f, " OF {of}")?;
2445        }
2446        if let Some(ref nb) = self.nonblock {
2447            write!(f, " {nb}")?;
2448        }
2449        Ok(())
2450    }
2451}
2452
2453#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2454#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2455#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2456pub enum LockType {
2457    Share,
2458    Update,
2459}
2460
2461impl fmt::Display for LockType {
2462    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2463        let select_lock = match self {
2464            LockType::Share => "SHARE",
2465            LockType::Update => "UPDATE",
2466        };
2467        write!(f, "{select_lock}")
2468    }
2469}
2470
2471#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2472#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2473#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2474pub enum NonBlock {
2475    Nowait,
2476    SkipLocked,
2477}
2478
2479impl fmt::Display for NonBlock {
2480    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2481        let nonblock = match self {
2482            NonBlock::Nowait => "NOWAIT",
2483            NonBlock::SkipLocked => "SKIP LOCKED",
2484        };
2485        write!(f, "{nonblock}")
2486    }
2487}
2488
2489#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2490#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2491#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2492pub enum Distinct {
2493    /// DISTINCT
2494    Distinct,
2495
2496    /// DISTINCT ON({column names})
2497    On(Vec<Expr>),
2498}
2499
2500impl fmt::Display for Distinct {
2501    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2502        match self {
2503            Distinct::Distinct => write!(f, "DISTINCT"),
2504            Distinct::On(col_names) => {
2505                let col_names = display_comma_separated(col_names);
2506                write!(f, "DISTINCT ON ({col_names})")
2507            }
2508        }
2509    }
2510}
2511
2512#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2513#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2514#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2515pub struct Top {
2516    /// SQL semantic equivalent of LIMIT but with same structure as FETCH.
2517    /// MSSQL only.
2518    pub with_ties: bool,
2519    /// MSSQL only.
2520    pub percent: bool,
2521    pub quantity: Option<TopQuantity>,
2522}
2523
2524#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2525#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2526#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2527pub enum TopQuantity {
2528    // A parenthesized expression. MSSQL only.
2529    Expr(Expr),
2530    // An unparenthesized integer constant.
2531    Constant(u64),
2532}
2533
2534impl fmt::Display for Top {
2535    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2536        let extension = if self.with_ties { " WITH TIES" } else { "" };
2537        if let Some(ref quantity) = self.quantity {
2538            let percent = if self.percent { " PERCENT" } else { "" };
2539            match quantity {
2540                TopQuantity::Expr(quantity) => write!(f, "TOP ({quantity}){percent}{extension}"),
2541                TopQuantity::Constant(quantity) => {
2542                    write!(f, "TOP {quantity}{percent}{extension}")
2543                }
2544            }
2545        } else {
2546            write!(f, "TOP{extension}")
2547        }
2548    }
2549}
2550
2551#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2552#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2553#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2554pub struct Values {
2555    /// Was there an explicit ROWs keyword (MySQL)?
2556    /// <https://dev.mysql.com/doc/refman/8.0/en/values.html>
2557    pub explicit_row: bool,
2558    pub rows: Vec<Vec<Expr>>,
2559}
2560
2561impl fmt::Display for Values {
2562    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2563        write!(f, "VALUES ")?;
2564        let prefix = if self.explicit_row { "ROW" } else { "" };
2565        let mut delim = "";
2566        for row in &self.rows {
2567            write!(f, "{delim}")?;
2568            delim = ", ";
2569            write!(f, "{prefix}({})", display_comma_separated(row))?;
2570        }
2571        Ok(())
2572    }
2573}
2574
2575#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2576#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2577#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2578pub struct SelectInto {
2579    pub temporary: bool,
2580    pub unlogged: bool,
2581    pub table: bool,
2582    pub name: ObjectName,
2583}
2584
2585impl fmt::Display for SelectInto {
2586    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2587        let temporary = if self.temporary { " TEMPORARY" } else { "" };
2588        let unlogged = if self.unlogged { " UNLOGGED" } else { "" };
2589        let table = if self.table { " TABLE" } else { "" };
2590
2591        write!(f, "INTO{}{}{} {}", temporary, unlogged, table, self.name)
2592    }
2593}
2594
2595/// ClickHouse supports GROUP BY WITH modifiers(includes ROLLUP|CUBE|TOTALS).
2596/// e.g. GROUP BY year WITH ROLLUP WITH TOTALS
2597///
2598/// [ClickHouse]: <https://clickhouse.com/docs/en/sql-reference/statements/select/group-by#rollup-modifier>
2599#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2600#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2601#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2602pub enum GroupByWithModifier {
2603    Rollup,
2604    Cube,
2605    Totals,
2606    /// Hive supports GROUP BY GROUPING SETS syntax.
2607    /// e.g. GROUP BY year , month GROUPING SETS((year,month),(year),(month))
2608    ///
2609    /// [Hive]: <https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=30151323#EnhancedAggregation,Cube,GroupingandRollup-GROUPINGSETSclause>
2610    GroupingSets(Expr),
2611}
2612
2613impl fmt::Display for GroupByWithModifier {
2614    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2615        match self {
2616            GroupByWithModifier::Rollup => write!(f, "WITH ROLLUP"),
2617            GroupByWithModifier::Cube => write!(f, "WITH CUBE"),
2618            GroupByWithModifier::Totals => write!(f, "WITH TOTALS"),
2619            GroupByWithModifier::GroupingSets(expr) => {
2620                write!(f, "{expr}")
2621            }
2622        }
2623    }
2624}
2625
2626#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2627#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2628#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2629pub enum GroupByExpr {
2630    /// ALL syntax of [Snowflake], [DuckDB] and [ClickHouse].
2631    ///
2632    /// [Snowflake]: <https://docs.snowflake.com/en/sql-reference/constructs/group-by#label-group-by-all-columns>
2633    /// [DuckDB]:  <https://duckdb.org/docs/sql/query_syntax/groupby.html>
2634    /// [ClickHouse]: <https://clickhouse.com/docs/en/sql-reference/statements/select/group-by#group-by-all>
2635    ///
2636    /// ClickHouse also supports WITH modifiers after GROUP BY ALL and expressions.
2637    ///
2638    /// [ClickHouse]: <https://clickhouse.com/docs/en/sql-reference/statements/select/group-by#rollup-modifier>
2639    All(Vec<GroupByWithModifier>),
2640
2641    /// Expressions
2642    Expressions(Vec<Expr>, Vec<GroupByWithModifier>),
2643}
2644
2645impl fmt::Display for GroupByExpr {
2646    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2647        match self {
2648            GroupByExpr::All(modifiers) => {
2649                write!(f, "GROUP BY ALL")?;
2650                if !modifiers.is_empty() {
2651                    write!(f, " {}", display_separated(modifiers, " "))?;
2652                }
2653                Ok(())
2654            }
2655            GroupByExpr::Expressions(col_names, modifiers) => {
2656                let col_names = display_comma_separated(col_names);
2657                write!(f, "GROUP BY {col_names}")?;
2658                if !modifiers.is_empty() {
2659                    write!(f, " {}", display_separated(modifiers, " "))?;
2660                }
2661                Ok(())
2662            }
2663        }
2664    }
2665}
2666
2667/// FORMAT identifier or FORMAT NULL clause, specific to ClickHouse.
2668///
2669/// [ClickHouse]: <https://clickhouse.com/docs/en/sql-reference/statements/select/format>
2670#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2671#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2672#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2673pub enum FormatClause {
2674    Identifier(Ident),
2675    Null,
2676}
2677
2678impl fmt::Display for FormatClause {
2679    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2680        match self {
2681            FormatClause::Identifier(ident) => write!(f, "FORMAT {}", ident),
2682            FormatClause::Null => write!(f, "FORMAT NULL"),
2683        }
2684    }
2685}
2686
2687/// FORMAT identifier in input context, specific to ClickHouse.
2688///
2689/// [ClickHouse]: <https://clickhouse.com/docs/en/interfaces/formats>
2690#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2691#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2692#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2693pub struct InputFormatClause {
2694    pub ident: Ident,
2695    pub values: Vec<Expr>,
2696}
2697
2698impl fmt::Display for InputFormatClause {
2699    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2700        write!(f, "FORMAT {}", self.ident)?;
2701
2702        if !self.values.is_empty() {
2703            write!(f, " {}", display_comma_separated(self.values.as_slice()))?;
2704        }
2705
2706        Ok(())
2707    }
2708}
2709
2710/// FOR XML or FOR JSON clause, specific to MSSQL
2711/// (formats the output of a query as XML or JSON)
2712#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2713#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2714#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2715pub enum ForClause {
2716    Browse,
2717    Json {
2718        for_json: ForJson,
2719        root: Option<String>,
2720        include_null_values: bool,
2721        without_array_wrapper: bool,
2722    },
2723    Xml {
2724        for_xml: ForXml,
2725        elements: bool,
2726        binary_base64: bool,
2727        root: Option<String>,
2728        r#type: bool,
2729    },
2730}
2731
2732impl fmt::Display for ForClause {
2733    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2734        match self {
2735            ForClause::Browse => write!(f, "FOR BROWSE"),
2736            ForClause::Json {
2737                for_json,
2738                root,
2739                include_null_values,
2740                without_array_wrapper,
2741            } => {
2742                write!(f, "FOR JSON ")?;
2743                write!(f, "{}", for_json)?;
2744                if let Some(root) = root {
2745                    write!(f, ", ROOT('{}')", root)?;
2746                }
2747                if *include_null_values {
2748                    write!(f, ", INCLUDE_NULL_VALUES")?;
2749                }
2750                if *without_array_wrapper {
2751                    write!(f, ", WITHOUT_ARRAY_WRAPPER")?;
2752                }
2753                Ok(())
2754            }
2755            ForClause::Xml {
2756                for_xml,
2757                elements,
2758                binary_base64,
2759                root,
2760                r#type,
2761            } => {
2762                write!(f, "FOR XML ")?;
2763                write!(f, "{}", for_xml)?;
2764                if *binary_base64 {
2765                    write!(f, ", BINARY BASE64")?;
2766                }
2767                if *r#type {
2768                    write!(f, ", TYPE")?;
2769                }
2770                if let Some(root) = root {
2771                    write!(f, ", ROOT('{}')", root)?;
2772                }
2773                if *elements {
2774                    write!(f, ", ELEMENTS")?;
2775                }
2776                Ok(())
2777            }
2778        }
2779    }
2780}
2781
2782#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2783#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2784#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2785pub enum ForXml {
2786    Raw(Option<String>),
2787    Auto,
2788    Explicit,
2789    Path(Option<String>),
2790}
2791
2792impl fmt::Display for ForXml {
2793    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2794        match self {
2795            ForXml::Raw(root) => {
2796                write!(f, "RAW")?;
2797                if let Some(root) = root {
2798                    write!(f, "('{}')", root)?;
2799                }
2800                Ok(())
2801            }
2802            ForXml::Auto => write!(f, "AUTO"),
2803            ForXml::Explicit => write!(f, "EXPLICIT"),
2804            ForXml::Path(root) => {
2805                write!(f, "PATH")?;
2806                if let Some(root) = root {
2807                    write!(f, "('{}')", root)?;
2808                }
2809                Ok(())
2810            }
2811        }
2812    }
2813}
2814
2815#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2816#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2817#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2818pub enum ForJson {
2819    Auto,
2820    Path,
2821}
2822
2823impl fmt::Display for ForJson {
2824    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2825        match self {
2826            ForJson::Auto => write!(f, "AUTO"),
2827            ForJson::Path => write!(f, "PATH"),
2828        }
2829    }
2830}
2831
2832/// A single column definition in MySQL's `JSON_TABLE` table valued function.
2833///
2834/// See
2835/// - [MySQL's JSON_TABLE documentation](https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html#function_json-table)
2836/// - [Oracle's JSON_TABLE documentation](https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/JSON_TABLE.html)
2837/// - [MariaDB's JSON_TABLE documentation](https://mariadb.com/kb/en/json_table/)
2838///
2839/// ```sql
2840/// SELECT *
2841/// FROM JSON_TABLE(
2842///     '["a", "b"]',
2843///     '$[*]' COLUMNS (
2844///         name FOR ORDINALITY,
2845///         value VARCHAR(20) PATH '$',
2846///         NESTED PATH '$[*]' COLUMNS (
2847///             value VARCHAR(20) PATH '$'
2848///         )
2849///     )
2850/// ) AS jt;
2851/// ```
2852#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2853#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2854#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2855pub enum JsonTableColumn {
2856    /// A named column with a JSON path
2857    Named(JsonTableNamedColumn),
2858    /// The FOR ORDINALITY column, which is a special column that returns the index of the current row in a JSON array.
2859    ForOrdinality(Ident),
2860    /// A set of nested columns, which extracts data from a nested JSON array.
2861    Nested(JsonTableNestedColumn),
2862}
2863
2864impl fmt::Display for JsonTableColumn {
2865    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2866        match self {
2867            JsonTableColumn::Named(json_table_named_column) => {
2868                write!(f, "{json_table_named_column}")
2869            }
2870            JsonTableColumn::ForOrdinality(ident) => write!(f, "{} FOR ORDINALITY", ident),
2871            JsonTableColumn::Nested(json_table_nested_column) => {
2872                write!(f, "{json_table_nested_column}")
2873            }
2874        }
2875    }
2876}
2877
2878/// A nested column in a JSON_TABLE column list
2879///
2880/// See <https://mariadb.com/kb/en/json_table/#nested-paths>
2881#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2882#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2883#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2884pub struct JsonTableNestedColumn {
2885    pub path: Value,
2886    pub columns: Vec<JsonTableColumn>,
2887}
2888
2889impl fmt::Display for JsonTableNestedColumn {
2890    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2891        write!(
2892            f,
2893            "NESTED PATH {} COLUMNS ({})",
2894            self.path,
2895            display_comma_separated(&self.columns)
2896        )
2897    }
2898}
2899
2900/// A single column definition in MySQL's `JSON_TABLE` table valued function.
2901///
2902/// See <https://mariadb.com/kb/en/json_table/#path-columns>
2903///
2904/// ```sql
2905///         value VARCHAR(20) PATH '$'
2906/// ```
2907#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2908#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2909#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2910pub struct JsonTableNamedColumn {
2911    /// The name of the column to be extracted.
2912    pub name: Ident,
2913    /// The type of the column to be extracted.
2914    pub r#type: DataType,
2915    /// The path to the column to be extracted. Must be a literal string.
2916    pub path: Value,
2917    /// true if the column is a boolean set to true if the given path exists
2918    pub exists: bool,
2919    /// The empty handling clause of the column
2920    pub on_empty: Option<JsonTableColumnErrorHandling>,
2921    /// The error handling clause of the column
2922    pub on_error: Option<JsonTableColumnErrorHandling>,
2923}
2924
2925impl fmt::Display for JsonTableNamedColumn {
2926    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2927        write!(
2928            f,
2929            "{} {}{} PATH {}",
2930            self.name,
2931            self.r#type,
2932            if self.exists { " EXISTS" } else { "" },
2933            self.path
2934        )?;
2935        if let Some(on_empty) = &self.on_empty {
2936            write!(f, " {} ON EMPTY", on_empty)?;
2937        }
2938        if let Some(on_error) = &self.on_error {
2939            write!(f, " {} ON ERROR", on_error)?;
2940        }
2941        Ok(())
2942    }
2943}
2944
2945/// Stores the error handling clause of a `JSON_TABLE` table valued function:
2946/// {NULL | DEFAULT json_string | ERROR} ON {ERROR | EMPTY }
2947#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2948#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2949#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2950pub enum JsonTableColumnErrorHandling {
2951    Null,
2952    Default(Value),
2953    Error,
2954}
2955
2956impl fmt::Display for JsonTableColumnErrorHandling {
2957    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2958        match self {
2959            JsonTableColumnErrorHandling::Null => write!(f, "NULL"),
2960            JsonTableColumnErrorHandling::Default(json_string) => {
2961                write!(f, "DEFAULT {}", json_string)
2962            }
2963            JsonTableColumnErrorHandling::Error => write!(f, "ERROR"),
2964        }
2965    }
2966}
2967
2968/// A single column definition in MSSQL's `OPENJSON WITH` clause.
2969///
2970/// ```sql
2971/// colName type [ column_path ] [ AS JSON ]
2972/// ```
2973///
2974/// Reference: <https://learn.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql?view=sql-server-ver16#syntax>
2975#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2976#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2977#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2978pub struct OpenJsonTableColumn {
2979    /// The name of the column to be extracted.
2980    pub name: Ident,
2981    /// The type of the column to be extracted.
2982    pub r#type: DataType,
2983    /// The path to the column to be extracted. Must be a literal string.
2984    pub path: Option<String>,
2985    /// The `AS JSON` option.
2986    pub as_json: bool,
2987}
2988
2989impl fmt::Display for OpenJsonTableColumn {
2990    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2991        write!(f, "{} {}", self.name, self.r#type)?;
2992        if let Some(path) = &self.path {
2993            write!(f, " '{}'", value::escape_single_quote_string(path))?;
2994        }
2995        if self.as_json {
2996            write!(f, " AS JSON")?;
2997        }
2998        Ok(())
2999    }
3000}
3001
3002/// BigQuery supports ValueTables which have 2 modes:
3003/// `SELECT AS STRUCT`
3004/// `SELECT AS VALUE`
3005/// <https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#value_tables>
3006#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3007#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3008#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3009pub enum ValueTableMode {
3010    AsStruct,
3011    AsValue,
3012}
3013
3014impl fmt::Display for ValueTableMode {
3015    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3016        match self {
3017            ValueTableMode::AsStruct => write!(f, "AS STRUCT"),
3018            ValueTableMode::AsValue => write!(f, "AS VALUE"),
3019        }
3020    }
3021}
3022
3023/// The `FROM` clause of an `UPDATE TABLE` statement
3024#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3025#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3026#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3027pub enum UpdateTableFromKind {
3028    /// Update Statement where the 'FROM' clause is before the 'SET' keyword (Supported by Snowflake)
3029    /// For Example: `UPDATE FROM t1 SET t1.name='aaa'`
3030    BeforeSet(Vec<TableWithJoins>),
3031    /// Update Statement where the 'FROM' clause is after the 'SET' keyword (Which is the standard way)
3032    /// For Example: `UPDATE SET t1.name='aaa' FROM t1`
3033    AfterSet(Vec<TableWithJoins>),
3034}