Skip to main content

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