sqlparser/ast/
mod.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//! SQL Abstract Syntax Tree (AST) types
19#[cfg(not(feature = "std"))]
20use alloc::{
21    boxed::Box,
22    format,
23    string::{String, ToString},
24    vec,
25    vec::Vec,
26};
27use helpers::{
28    attached_token::AttachedToken,
29    stmt_data_loading::{FileStagingCommand, StageLoadSelectItemKind},
30};
31
32use core::cmp::Ordering;
33use core::ops::Deref;
34use core::{
35    fmt::{self, Display},
36    hash,
37};
38
39#[cfg(feature = "serde")]
40use serde::{Deserialize, Serialize};
41
42#[cfg(feature = "visitor")]
43use sqlparser_derive::{Visit, VisitMut};
44
45use crate::{
46    display_utils::SpaceOrNewline,
47    tokenizer::{Span, Token},
48};
49use crate::{
50    display_utils::{Indent, NewLine},
51    keywords::Keyword,
52};
53
54pub use self::data_type::{
55    ArrayElemTypeDef, BinaryLength, CharLengthUnits, CharacterLength, DataType, EnumMember,
56    ExactNumberInfo, IntervalFields, StructBracketKind, TimezoneInfo,
57};
58pub use self::dcl::{
59    AlterRoleOperation, CreateRole, ResetConfig, RoleOption, SecondaryRoles, SetConfigValue, Use,
60};
61pub use self::ddl::{
62    Alignment, AlterColumnOperation, AlterConnectorOwner, AlterIndexOperation, AlterOperator,
63    AlterOperatorOperation, AlterPolicyOperation, AlterSchema, AlterSchemaOperation, AlterTable,
64    AlterTableAlgorithm, AlterTableLock, AlterTableOperation, AlterTableType, AlterType,
65    AlterTypeAddValue, AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename,
66    AlterTypeRenameValue, ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions,
67    ColumnPolicy, ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain,
68    CreateExtension, CreateFunction, CreateIndex, CreateOperator, CreateOperatorClass,
69    CreateOperatorFamily, CreateTable, CreateTrigger, CreateView, Deduplicate, DeferrableInitial,
70    DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily,
71    DropOperatorSignature, DropTrigger, ForValues, GeneratedAs, GeneratedExpressionMode,
72    IdentityParameters, IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind,
73    IdentityPropertyOrder, IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck,
74    NullsDistinctOption, OperatorArgTypes, OperatorClassItem, OperatorOption, OperatorPurpose,
75    Owner, Partition, PartitionBoundValue, ProcedureParam, ReferentialAction, RenameTableNameKind,
76    ReplicaIdentity, TagsColumnOption, TriggerObjectKind, Truncate,
77    UserDefinedTypeCompositeAttributeDef, UserDefinedTypeInternalLength,
78    UserDefinedTypeRangeOption, UserDefinedTypeRepresentation, UserDefinedTypeSqlDefinitionOption,
79    UserDefinedTypeStorage, ViewColumnDef,
80};
81pub use self::dml::{
82    Delete, Insert, Merge, MergeAction, MergeClause, MergeClauseKind, MergeInsertExpr,
83    MergeInsertKind, MergeUpdateExpr, OutputClause, Update,
84};
85pub use self::operator::{BinaryOperator, UnaryOperator};
86pub use self::query::{
87    AfterMatchSkip, ConnectBy, Cte, CteAsMaterialized, Distinct, EmptyMatchesMode,
88    ExceptSelectItem, ExcludeSelectItem, ExprWithAlias, ExprWithAliasAndOrderBy, Fetch, ForClause,
89    ForJson, ForXml, FormatClause, GroupByExpr, GroupByWithModifier, IdentWithAlias,
90    IlikeSelectItem, InputFormatClause, Interpolate, InterpolateExpr, Join, JoinConstraint,
91    JoinOperator, JsonTableColumn, JsonTableColumnErrorHandling, JsonTableNamedColumn,
92    JsonTableNestedColumn, LateralView, LimitClause, LockClause, LockType, MatchRecognizePattern,
93    MatchRecognizeSymbol, Measure, NamedWindowDefinition, NamedWindowExpr, NonBlock, Offset,
94    OffsetRows, OpenJsonTableColumn, OrderBy, OrderByExpr, OrderByKind, OrderByOptions,
95    PipeOperator, PivotValueSource, ProjectionSelect, Query, RenameSelectItem,
96    RepetitionQuantifier, ReplaceSelectElement, ReplaceSelectItem, RowsPerMatch, Select,
97    SelectFlavor, SelectInto, SelectItem, SelectItemQualifiedWildcardKind, SetExpr, SetOperator,
98    SetQuantifier, Setting, SymbolDefinition, Table, TableAlias, TableAliasColumnDef, TableFactor,
99    TableFunctionArgs, TableIndexHintForClause, TableIndexHintType, TableIndexHints,
100    TableIndexType, TableSample, TableSampleBucket, TableSampleKind, TableSampleMethod,
101    TableSampleModifier, TableSampleQuantity, TableSampleSeed, TableSampleSeedModifier,
102    TableSampleUnit, TableVersion, TableWithJoins, Top, TopQuantity, UpdateTableFromKind,
103    ValueTableMode, Values, WildcardAdditionalOptions, With, WithFill, XmlNamespaceDefinition,
104    XmlPassingArgument, XmlPassingClause, XmlTableColumn, XmlTableColumnOption,
105};
106
107pub use self::trigger::{
108    TriggerEvent, TriggerExecBody, TriggerExecBodyType, TriggerObject, TriggerPeriod,
109    TriggerReferencing, TriggerReferencingType,
110};
111
112pub use self::value::{
113    escape_double_quote_string, escape_quoted_string, DateTimeField, DollarQuotedString,
114    NormalizationForm, TrimWhereField, Value, ValueWithSpan,
115};
116
117use crate::ast::helpers::key_value_options::KeyValueOptions;
118use crate::ast::helpers::stmt_data_loading::StageParamsObject;
119
120#[cfg(feature = "visitor")]
121pub use visitor::*;
122
123pub use self::data_type::GeometricTypeKind;
124
125mod data_type;
126mod dcl;
127mod ddl;
128mod dml;
129pub mod helpers;
130pub mod table_constraints;
131pub use table_constraints::{
132    CheckConstraint, ForeignKeyConstraint, FullTextOrSpatialConstraint, IndexConstraint,
133    PrimaryKeyConstraint, TableConstraint, UniqueConstraint,
134};
135mod operator;
136mod query;
137mod spans;
138pub use spans::Spanned;
139
140mod trigger;
141mod value;
142
143#[cfg(feature = "visitor")]
144mod visitor;
145
146pub struct DisplaySeparated<'a, T>
147where
148    T: fmt::Display,
149{
150    slice: &'a [T],
151    sep: &'static str,
152}
153
154impl<T> fmt::Display for DisplaySeparated<'_, T>
155where
156    T: fmt::Display,
157{
158    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
159        let mut delim = "";
160        for t in self.slice {
161            f.write_str(delim)?;
162            delim = self.sep;
163            t.fmt(f)?;
164        }
165        Ok(())
166    }
167}
168
169pub(crate) fn display_separated<'a, T>(slice: &'a [T], sep: &'static str) -> DisplaySeparated<'a, T>
170where
171    T: fmt::Display,
172{
173    DisplaySeparated { slice, sep }
174}
175
176pub(crate) fn display_comma_separated<T>(slice: &[T]) -> DisplaySeparated<'_, T>
177where
178    T: fmt::Display,
179{
180    DisplaySeparated { slice, sep: ", " }
181}
182
183/// Writes the given statements to the formatter, each ending with
184/// a semicolon and space separated.
185fn format_statement_list(f: &mut fmt::Formatter, statements: &[Statement]) -> fmt::Result {
186    write!(f, "{}", display_separated(statements, "; "))?;
187    // We manually insert semicolon for the last statement,
188    // since display_separated doesn't handle that case.
189    write!(f, ";")
190}
191
192/// An identifier, decomposed into its value or character data and the quote style.
193#[derive(Debug, Clone)]
194#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
195#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
196pub struct Ident {
197    /// The value of the identifier without quotes.
198    pub value: String,
199    /// The starting quote if any. Valid quote characters are the single quote,
200    /// double quote, backtick, and opening square bracket.
201    pub quote_style: Option<char>,
202    /// The span of the identifier in the original SQL string.
203    pub span: Span,
204}
205
206impl PartialEq for Ident {
207    fn eq(&self, other: &Self) -> bool {
208        let Ident {
209            value,
210            quote_style,
211            // exhaustiveness check; we ignore spans in comparisons
212            span: _,
213        } = self;
214
215        value == &other.value && quote_style == &other.quote_style
216    }
217}
218
219impl core::hash::Hash for Ident {
220    fn hash<H: hash::Hasher>(&self, state: &mut H) {
221        let Ident {
222            value,
223            quote_style,
224            // exhaustiveness check; we ignore spans in hashes
225            span: _,
226        } = self;
227
228        value.hash(state);
229        quote_style.hash(state);
230    }
231}
232
233impl Eq for Ident {}
234
235impl PartialOrd for Ident {
236    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
237        Some(self.cmp(other))
238    }
239}
240
241impl Ord for Ident {
242    fn cmp(&self, other: &Self) -> Ordering {
243        let Ident {
244            value,
245            quote_style,
246            // exhaustiveness check; we ignore spans in ordering
247            span: _,
248        } = self;
249
250        let Ident {
251            value: other_value,
252            quote_style: other_quote_style,
253            // exhaustiveness check; we ignore spans in ordering
254            span: _,
255        } = other;
256
257        // First compare by value, then by quote_style
258        value
259            .cmp(other_value)
260            .then_with(|| quote_style.cmp(other_quote_style))
261    }
262}
263
264impl Ident {
265    /// Create a new identifier with the given value and no quotes and an empty span.
266    pub fn new<S>(value: S) -> Self
267    where
268        S: Into<String>,
269    {
270        Ident {
271            value: value.into(),
272            quote_style: None,
273            span: Span::empty(),
274        }
275    }
276
277    /// Create a new quoted identifier with the given quote and value. This function
278    /// panics if the given quote is not a valid quote character.
279    pub fn with_quote<S>(quote: char, value: S) -> Self
280    where
281        S: Into<String>,
282    {
283        assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
284        Ident {
285            value: value.into(),
286            quote_style: Some(quote),
287            span: Span::empty(),
288        }
289    }
290
291    pub fn with_span<S>(span: Span, value: S) -> Self
292    where
293        S: Into<String>,
294    {
295        Ident {
296            value: value.into(),
297            quote_style: None,
298            span,
299        }
300    }
301
302    pub fn with_quote_and_span<S>(quote: char, span: Span, value: S) -> Self
303    where
304        S: Into<String>,
305    {
306        assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
307        Ident {
308            value: value.into(),
309            quote_style: Some(quote),
310            span,
311        }
312    }
313}
314
315impl From<&str> for Ident {
316    fn from(value: &str) -> Self {
317        Ident {
318            value: value.to_string(),
319            quote_style: None,
320            span: Span::empty(),
321        }
322    }
323}
324
325impl fmt::Display for Ident {
326    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
327        match self.quote_style {
328            Some(q) if q == '"' || q == '\'' || q == '`' => {
329                let escaped = value::escape_quoted_string(&self.value, q);
330                write!(f, "{q}{escaped}{q}")
331            }
332            Some('[') => write!(f, "[{}]", self.value),
333            None => f.write_str(&self.value),
334            _ => panic!("unexpected quote style"),
335        }
336    }
337}
338
339/// A name of a table, view, custom type, etc., possibly multi-part, i.e. db.schema.obj
340#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
341#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
342#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
343pub struct ObjectName(pub Vec<ObjectNamePart>);
344
345impl From<Vec<Ident>> for ObjectName {
346    fn from(idents: Vec<Ident>) -> Self {
347        ObjectName(idents.into_iter().map(ObjectNamePart::Identifier).collect())
348    }
349}
350
351impl From<Ident> for ObjectName {
352    fn from(ident: Ident) -> Self {
353        ObjectName(vec![ObjectNamePart::Identifier(ident)])
354    }
355}
356
357impl fmt::Display for ObjectName {
358    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
359        write!(f, "{}", display_separated(&self.0, "."))
360    }
361}
362
363/// A single part of an ObjectName
364#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
365#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
366#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
367pub enum ObjectNamePart {
368    Identifier(Ident),
369    Function(ObjectNamePartFunction),
370}
371
372impl ObjectNamePart {
373    pub fn as_ident(&self) -> Option<&Ident> {
374        match self {
375            ObjectNamePart::Identifier(ident) => Some(ident),
376            ObjectNamePart::Function(_) => None,
377        }
378    }
379}
380
381impl fmt::Display for ObjectNamePart {
382    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
383        match self {
384            ObjectNamePart::Identifier(ident) => write!(f, "{ident}"),
385            ObjectNamePart::Function(func) => write!(f, "{func}"),
386        }
387    }
388}
389
390/// An object name part that consists of a function that dynamically
391/// constructs identifiers.
392///
393/// - [Snowflake](https://docs.snowflake.com/en/sql-reference/identifier-literal)
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 ObjectNamePartFunction {
398    pub name: Ident,
399    pub args: Vec<FunctionArg>,
400}
401
402impl fmt::Display for ObjectNamePartFunction {
403    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
404        write!(f, "{}(", self.name)?;
405        write!(f, "{})", display_comma_separated(&self.args))
406    }
407}
408
409/// Represents an Array Expression, either
410/// `ARRAY[..]`, or `[..]`
411#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
412#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
413#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
414pub struct Array {
415    /// The list of expressions between brackets
416    pub elem: Vec<Expr>,
417
418    /// `true` for  `ARRAY[..]`, `false` for `[..]`
419    pub named: bool,
420}
421
422impl fmt::Display for Array {
423    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
424        write!(
425            f,
426            "{}[{}]",
427            if self.named { "ARRAY" } else { "" },
428            display_comma_separated(&self.elem)
429        )
430    }
431}
432
433/// Represents an INTERVAL expression, roughly in the following format:
434/// `INTERVAL '<value>' [ <leading_field> [ (<leading_precision>) ] ]
435/// [ TO <last_field> [ (<fractional_seconds_precision>) ] ]`,
436/// e.g. `INTERVAL '123:45.67' MINUTE(3) TO SECOND(2)`.
437///
438/// The parser does not validate the `<value>`, nor does it ensure
439/// that the `<leading_field>` units >= the units in `<last_field>`,
440/// so the user will have to reject intervals like `HOUR TO YEAR`.
441#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
442#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
443#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
444pub struct Interval {
445    pub value: Box<Expr>,
446    pub leading_field: Option<DateTimeField>,
447    pub leading_precision: Option<u64>,
448    pub last_field: Option<DateTimeField>,
449    /// The seconds precision can be specified in SQL source as
450    /// `INTERVAL '__' SECOND(_, x)` (in which case the `leading_field`
451    /// will be `Second` and the `last_field` will be `None`),
452    /// or as `__ TO SECOND(x)`.
453    pub fractional_seconds_precision: Option<u64>,
454}
455
456impl fmt::Display for Interval {
457    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
458        let value = self.value.as_ref();
459        match (
460            &self.leading_field,
461            self.leading_precision,
462            self.fractional_seconds_precision,
463        ) {
464            (
465                Some(DateTimeField::Second),
466                Some(leading_precision),
467                Some(fractional_seconds_precision),
468            ) => {
469                // When the leading field is SECOND, the parser guarantees that
470                // the last field is None.
471                assert!(self.last_field.is_none());
472                write!(
473                    f,
474                    "INTERVAL {value} SECOND ({leading_precision}, {fractional_seconds_precision})"
475                )
476            }
477            _ => {
478                write!(f, "INTERVAL {value}")?;
479                if let Some(leading_field) = &self.leading_field {
480                    write!(f, " {leading_field}")?;
481                }
482                if let Some(leading_precision) = self.leading_precision {
483                    write!(f, " ({leading_precision})")?;
484                }
485                if let Some(last_field) = &self.last_field {
486                    write!(f, " TO {last_field}")?;
487                }
488                if let Some(fractional_seconds_precision) = self.fractional_seconds_precision {
489                    write!(f, " ({fractional_seconds_precision})")?;
490                }
491                Ok(())
492            }
493        }
494    }
495}
496
497/// A field definition within a struct
498///
499/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
500#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
501#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
502#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
503pub struct StructField {
504    pub field_name: Option<Ident>,
505    pub field_type: DataType,
506    /// Struct field options.
507    /// See [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#column_name_and_column_schema)
508    pub options: Option<Vec<SqlOption>>,
509}
510
511impl fmt::Display for StructField {
512    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
513        if let Some(name) = &self.field_name {
514            write!(f, "{name} {}", self.field_type)?;
515        } else {
516            write!(f, "{}", self.field_type)?;
517        }
518        if let Some(options) = &self.options {
519            write!(f, " OPTIONS({})", display_separated(options, ", "))
520        } else {
521            Ok(())
522        }
523    }
524}
525
526/// A field definition within a union
527///
528/// [DuckDB]: https://duckdb.org/docs/sql/data_types/union.html
529#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
530#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
531#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
532pub struct UnionField {
533    pub field_name: Ident,
534    pub field_type: DataType,
535}
536
537impl fmt::Display for UnionField {
538    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
539        write!(f, "{} {}", self.field_name, self.field_type)
540    }
541}
542
543/// A dictionary field within a dictionary.
544///
545/// [DuckDB]: https://duckdb.org/docs/sql/data_types/struct#creating-structs
546#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
547#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
548#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
549pub struct DictionaryField {
550    pub key: Ident,
551    pub value: Box<Expr>,
552}
553
554impl fmt::Display for DictionaryField {
555    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
556        write!(f, "{}: {}", self.key, self.value)
557    }
558}
559
560/// Represents a Map expression.
561#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
562#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
563#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
564pub struct Map {
565    pub entries: Vec<MapEntry>,
566}
567
568impl Display for Map {
569    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
570        write!(f, "MAP {{{}}}", display_comma_separated(&self.entries))
571    }
572}
573
574/// A map field within a map.
575///
576/// [DuckDB]: https://duckdb.org/docs/sql/data_types/map.html#creating-maps
577#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
578#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
579#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
580pub struct MapEntry {
581    pub key: Box<Expr>,
582    pub value: Box<Expr>,
583}
584
585impl fmt::Display for MapEntry {
586    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
587        write!(f, "{}: {}", self.key, self.value)
588    }
589}
590
591/// Options for `CAST` / `TRY_CAST`
592/// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax>
593#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
594#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
595#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
596pub enum CastFormat {
597    Value(Value),
598    ValueAtTimeZone(Value, Value),
599}
600
601/// An element of a JSON path.
602#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
603#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
604#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
605pub enum JsonPathElem {
606    /// Accesses an object field using dot notation, e.g. `obj:foo.bar.baz`.
607    ///
608    /// See <https://docs.snowflake.com/en/user-guide/querying-semistructured#dot-notation>.
609    Dot { key: String, quoted: bool },
610    /// Accesses an object field or array element using bracket notation,
611    /// e.g. `obj['foo']`.
612    ///
613    /// See <https://docs.snowflake.com/en/user-guide/querying-semistructured#bracket-notation>.
614    Bracket { key: Expr },
615}
616
617/// A JSON path.
618///
619/// See <https://docs.snowflake.com/en/user-guide/querying-semistructured>.
620/// See <https://docs.databricks.com/en/sql/language-manual/sql-ref-json-path-expression.html>.
621#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
622#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
623#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
624pub struct JsonPath {
625    pub path: Vec<JsonPathElem>,
626}
627
628impl fmt::Display for JsonPath {
629    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
630        for (i, elem) in self.path.iter().enumerate() {
631            match elem {
632                JsonPathElem::Dot { key, quoted } => {
633                    if i == 0 {
634                        write!(f, ":")?;
635                    } else {
636                        write!(f, ".")?;
637                    }
638
639                    if *quoted {
640                        write!(f, "\"{}\"", escape_double_quote_string(key))?;
641                    } else {
642                        write!(f, "{key}")?;
643                    }
644                }
645                JsonPathElem::Bracket { key } => {
646                    write!(f, "[{key}]")?;
647                }
648            }
649        }
650        Ok(())
651    }
652}
653
654/// The syntax used for in a cast expression.
655#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
656#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
657#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
658pub enum CastKind {
659    /// The standard SQL cast syntax, e.g. `CAST(<expr> as <datatype>)`
660    Cast,
661    /// A cast that returns `NULL` on failure, e.g. `TRY_CAST(<expr> as <datatype>)`.
662    ///
663    /// See <https://docs.snowflake.com/en/sql-reference/functions/try_cast>.
664    /// See <https://learn.microsoft.com/en-us/sql/t-sql/functions/try-cast-transact-sql>.
665    TryCast,
666    /// A cast that returns `NULL` on failure, bigQuery-specific ,  e.g. `SAFE_CAST(<expr> as <datatype>)`.
667    ///
668    /// See <https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#safe_casting>.
669    SafeCast,
670    /// `<expr> :: <datatype>`
671    DoubleColon,
672}
673
674/// `MATCH` type for constraint references
675///
676/// See: <https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-PARMS-REFERENCES>
677#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
678#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
679#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
680pub enum ConstraintReferenceMatchKind {
681    /// `MATCH FULL`
682    Full,
683    /// `MATCH PARTIAL`
684    Partial,
685    /// `MATCH SIMPLE`
686    Simple,
687}
688
689impl fmt::Display for ConstraintReferenceMatchKind {
690    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
691        match self {
692            Self::Full => write!(f, "MATCH FULL"),
693            Self::Partial => write!(f, "MATCH PARTIAL"),
694            Self::Simple => write!(f, "MATCH SIMPLE"),
695        }
696    }
697}
698
699/// `EXTRACT` syntax variants.
700///
701/// In Snowflake dialect, the `EXTRACT` expression can support either the `from` syntax
702/// or the comma syntax.
703///
704/// See <https://docs.snowflake.com/en/sql-reference/functions/extract>
705#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
706#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
707#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
708pub enum ExtractSyntax {
709    /// `EXTRACT( <date_or_time_part> FROM <date_or_time_expr> )`
710    From,
711    /// `EXTRACT( <date_or_time_part> , <date_or_timestamp_expr> )`
712    Comma,
713}
714
715/// The syntax used in a CEIL or FLOOR expression.
716///
717/// The `CEIL/FLOOR(<datetime value expression> TO <time unit>)` is an Amazon Kinesis Data Analytics extension.
718/// See <https://docs.aws.amazon.com/kinesisanalytics/latest/sqlref/sql-reference-ceil.html> for
719/// details.
720///
721/// Other dialects either support `CEIL/FLOOR( <expr> [, <scale>])` format or just
722/// `CEIL/FLOOR(<expr>)`.
723#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
724#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
725#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
726pub enum CeilFloorKind {
727    /// `CEIL( <expr> TO <DateTimeField>)`
728    DateTimeField(DateTimeField),
729    /// `CEIL( <expr> [, <scale>])`
730    Scale(Value),
731}
732
733/// A WHEN clause in a CASE expression containing both
734/// the condition and its corresponding result
735#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
736#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
737#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
738pub struct CaseWhen {
739    pub condition: Expr,
740    pub result: Expr,
741}
742
743impl fmt::Display for CaseWhen {
744    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
745        f.write_str("WHEN ")?;
746        self.condition.fmt(f)?;
747        f.write_str(" THEN")?;
748        SpaceOrNewline.fmt(f)?;
749        Indent(&self.result).fmt(f)?;
750        Ok(())
751    }
752}
753
754/// An SQL expression of any type.
755///
756/// # Semantics / Type Checking
757///
758/// The parser does not distinguish between expressions of different types
759/// (e.g. boolean vs string). The caller is responsible for detecting and
760/// validating types as necessary (for example  `WHERE 1` vs `SELECT 1=1`)
761/// See the [README.md] for more details.
762///
763/// [README.md]: https://github.com/apache/datafusion-sqlparser-rs/blob/main/README.md#syntax-vs-semantics
764///
765/// # Equality and Hashing Does not Include Source Locations
766///
767/// The `Expr` type implements `PartialEq` and `Eq` based on the semantic value
768/// of the expression (not bitwise comparison). This means that `Expr` instances
769/// that are semantically equivalent but have different spans (locations in the
770/// source tree) will compare as equal.
771#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
772#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
773#[cfg_attr(
774    feature = "visitor",
775    derive(Visit, VisitMut),
776    visit(with = "visit_expr")
777)]
778pub enum Expr {
779    /// Identifier e.g. table name or column name
780    Identifier(Ident),
781    /// Multi-part identifier, e.g. `table_alias.column` or `schema.table.col`
782    CompoundIdentifier(Vec<Ident>),
783    /// Multi-part expression access.
784    ///
785    /// This structure represents an access chain in structured / nested types
786    /// such as maps, arrays, and lists:
787    /// - Array
788    ///     - A 1-dim array `a[1]` will be represented like:
789    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript(1)]`
790    ///     - A 2-dim array `a[1][2]` will be represented like:
791    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript(1), Subscript(2)]`
792    /// - Map or Struct (Bracket-style)
793    ///     - A map `a['field1']` will be represented like:
794    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript('field')]`
795    ///     - A 2-dim map `a['field1']['field2']` will be represented like:
796    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript('field1'), Subscript('field2')]`
797    /// - Struct (Dot-style) (only effect when the chain contains both subscript and expr)
798    ///     - A struct access `a[field1].field2` will be represented like:
799    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript('field1'), Ident('field2')]`
800    /// - If a struct access likes `a.field1.field2`, it will be represented by CompoundIdentifier([a, field1, field2])
801    CompoundFieldAccess {
802        root: Box<Expr>,
803        access_chain: Vec<AccessExpr>,
804    },
805    /// Access data nested in a value containing semi-structured data, such as
806    /// the `VARIANT` type on Snowflake. for example `src:customer[0].name`.
807    ///
808    /// See <https://docs.snowflake.com/en/user-guide/querying-semistructured>.
809    /// See <https://docs.databricks.com/en/sql/language-manual/functions/colonsign.html>.
810    JsonAccess {
811        /// The value being queried.
812        value: Box<Expr>,
813        /// The path to the data to extract.
814        path: JsonPath,
815    },
816    /// `IS FALSE` operator
817    IsFalse(Box<Expr>),
818    /// `IS NOT FALSE` operator
819    IsNotFalse(Box<Expr>),
820    /// `IS TRUE` operator
821    IsTrue(Box<Expr>),
822    /// `IS NOT TRUE` operator
823    IsNotTrue(Box<Expr>),
824    /// `IS NULL` operator
825    IsNull(Box<Expr>),
826    /// `IS NOT NULL` operator
827    IsNotNull(Box<Expr>),
828    /// `IS UNKNOWN` operator
829    IsUnknown(Box<Expr>),
830    /// `IS NOT UNKNOWN` operator
831    IsNotUnknown(Box<Expr>),
832    /// `IS DISTINCT FROM` operator
833    IsDistinctFrom(Box<Expr>, Box<Expr>),
834    /// `IS NOT DISTINCT FROM` operator
835    IsNotDistinctFrom(Box<Expr>, Box<Expr>),
836    /// `<expr> IS [ NOT ] [ form ] NORMALIZED`
837    IsNormalized {
838        expr: Box<Expr>,
839        form: Option<NormalizationForm>,
840        negated: bool,
841    },
842    /// `[ NOT ] IN (val1, val2, ...)`
843    InList {
844        expr: Box<Expr>,
845        list: Vec<Expr>,
846        negated: bool,
847    },
848    /// `[ NOT ] IN (SELECT ...)`
849    InSubquery {
850        expr: Box<Expr>,
851        subquery: Box<Query>,
852        negated: bool,
853    },
854    /// `[ NOT ] IN UNNEST(array_expression)`
855    InUnnest {
856        expr: Box<Expr>,
857        array_expr: Box<Expr>,
858        negated: bool,
859    },
860    /// `<expr> [ NOT ] BETWEEN <low> AND <high>`
861    Between {
862        expr: Box<Expr>,
863        negated: bool,
864        low: Box<Expr>,
865        high: Box<Expr>,
866    },
867    /// Binary operation e.g. `1 + 1` or `foo > bar`
868    BinaryOp {
869        left: Box<Expr>,
870        op: BinaryOperator,
871        right: Box<Expr>,
872    },
873    /// `[NOT] LIKE <pattern> [ESCAPE <escape_character>]`
874    Like {
875        negated: bool,
876        // Snowflake supports the ANY keyword to match against a list of patterns
877        // https://docs.snowflake.com/en/sql-reference/functions/like_any
878        any: bool,
879        expr: Box<Expr>,
880        pattern: Box<Expr>,
881        escape_char: Option<Value>,
882    },
883    /// `ILIKE` (case-insensitive `LIKE`)
884    ILike {
885        negated: bool,
886        // Snowflake supports the ANY keyword to match against a list of patterns
887        // https://docs.snowflake.com/en/sql-reference/functions/like_any
888        any: bool,
889        expr: Box<Expr>,
890        pattern: Box<Expr>,
891        escape_char: Option<Value>,
892    },
893    /// SIMILAR TO regex
894    SimilarTo {
895        negated: bool,
896        expr: Box<Expr>,
897        pattern: Box<Expr>,
898        escape_char: Option<Value>,
899    },
900    /// MySQL: RLIKE regex or REGEXP regex
901    RLike {
902        negated: bool,
903        expr: Box<Expr>,
904        pattern: Box<Expr>,
905        // true for REGEXP, false for RLIKE (no difference in semantics)
906        regexp: bool,
907    },
908    /// `ANY` operation e.g. `foo > ANY(bar)`, comparison operator is one of `[=, >, <, =>, =<, !=]`
909    /// <https://docs.snowflake.com/en/sql-reference/operators-subquery#all-any>
910    AnyOp {
911        left: Box<Expr>,
912        compare_op: BinaryOperator,
913        right: Box<Expr>,
914        // ANY and SOME are synonymous: https://docs.cloudera.com/cdw-runtime/cloud/using-hiveql/topics/hive_comparison_predicates.html
915        is_some: bool,
916    },
917    /// `ALL` operation e.g. `foo > ALL(bar)`, comparison operator is one of `[=, >, <, =>, =<, !=]`
918    /// <https://docs.snowflake.com/en/sql-reference/operators-subquery#all-any>
919    AllOp {
920        left: Box<Expr>,
921        compare_op: BinaryOperator,
922        right: Box<Expr>,
923    },
924    /// Unary operation e.g. `NOT foo`
925    UnaryOp {
926        op: UnaryOperator,
927        expr: Box<Expr>,
928    },
929    /// CONVERT a value to a different data type or character encoding. e.g. `CONVERT(foo USING utf8mb4)`
930    Convert {
931        /// CONVERT (false) or TRY_CONVERT (true)
932        /// <https://learn.microsoft.com/en-us/sql/t-sql/functions/try-convert-transact-sql?view=sql-server-ver16>
933        is_try: bool,
934        /// The expression to convert
935        expr: Box<Expr>,
936        /// The target data type
937        data_type: Option<DataType>,
938        /// The target character encoding
939        charset: Option<ObjectName>,
940        /// whether the target comes before the expr (MSSQL syntax)
941        target_before_value: bool,
942        /// How to translate the expression.
943        ///
944        /// [MSSQL]: https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#style
945        styles: Vec<Expr>,
946    },
947    /// `CAST` an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))`
948    Cast {
949        kind: CastKind,
950        expr: Box<Expr>,
951        data_type: DataType,
952        /// Optional CAST(string_expression AS type FORMAT format_string_expression) as used by [BigQuery]
953        ///
954        /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax
955        format: Option<CastFormat>,
956    },
957    /// AT a timestamp to a different timezone e.g. `FROM_UNIXTIME(0) AT TIME ZONE 'UTC-06:00'`
958    AtTimeZone {
959        timestamp: Box<Expr>,
960        time_zone: Box<Expr>,
961    },
962    /// Extract a field from a timestamp e.g. `EXTRACT(MONTH FROM foo)`
963    /// Or `EXTRACT(MONTH, foo)`
964    ///
965    /// Syntax:
966    /// ```sql
967    /// EXTRACT(DateTimeField FROM <expr>) | EXTRACT(DateTimeField, <expr>)
968    /// ```
969    Extract {
970        field: DateTimeField,
971        syntax: ExtractSyntax,
972        expr: Box<Expr>,
973    },
974    /// ```sql
975    /// CEIL(<expr> [TO DateTimeField])
976    /// ```
977    /// ```sql
978    /// CEIL( <input_expr> [, <scale_expr> ] )
979    /// ```
980    Ceil {
981        expr: Box<Expr>,
982        field: CeilFloorKind,
983    },
984    /// ```sql
985    /// FLOOR(<expr> [TO DateTimeField])
986    /// ```
987    /// ```sql
988    /// FLOOR( <input_expr> [, <scale_expr> ] )
989    ///
990    Floor {
991        expr: Box<Expr>,
992        field: CeilFloorKind,
993    },
994    /// ```sql
995    /// POSITION(<expr> in <expr>)
996    /// ```
997    Position {
998        expr: Box<Expr>,
999        r#in: Box<Expr>,
1000    },
1001    /// ```sql
1002    /// SUBSTRING(<expr> [FROM <expr>] [FOR <expr>])
1003    /// ```
1004    /// or
1005    /// ```sql
1006    /// SUBSTRING(<expr>, <expr>, <expr>)
1007    /// ```
1008    Substring {
1009        expr: Box<Expr>,
1010        substring_from: Option<Box<Expr>>,
1011        substring_for: Option<Box<Expr>>,
1012
1013        /// false if the expression is represented using the `SUBSTRING(expr [FROM start] [FOR len])` syntax
1014        /// true if the expression is represented using the `SUBSTRING(expr, start, len)` syntax
1015        /// This flag is used for formatting.
1016        special: bool,
1017
1018        /// true if the expression is represented using the `SUBSTR` shorthand
1019        /// This flag is used for formatting.
1020        shorthand: bool,
1021    },
1022    /// ```sql
1023    /// TRIM([BOTH | LEADING | TRAILING] [<expr> FROM] <expr>)
1024    /// TRIM(<expr>)
1025    /// TRIM(<expr>, [, characters]) -- only Snowflake or Bigquery
1026    /// ```
1027    Trim {
1028        expr: Box<Expr>,
1029        // ([BOTH | LEADING | TRAILING]
1030        trim_where: Option<TrimWhereField>,
1031        trim_what: Option<Box<Expr>>,
1032        trim_characters: Option<Vec<Expr>>,
1033    },
1034    /// ```sql
1035    /// OVERLAY(<expr> PLACING <expr> FROM <expr>[ FOR <expr> ]
1036    /// ```
1037    Overlay {
1038        expr: Box<Expr>,
1039        overlay_what: Box<Expr>,
1040        overlay_from: Box<Expr>,
1041        overlay_for: Option<Box<Expr>>,
1042    },
1043    /// `expr COLLATE collation`
1044    Collate {
1045        expr: Box<Expr>,
1046        collation: ObjectName,
1047    },
1048    /// Nested expression e.g. `(foo > bar)` or `(1)`
1049    Nested(Box<Expr>),
1050    /// A literal value, such as string, number, date or NULL
1051    Value(ValueWithSpan),
1052    /// Prefixed expression, e.g. introducer strings, projection prefix
1053    /// <https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html>
1054    /// <https://docs.snowflake.com/en/sql-reference/constructs/connect-by>
1055    Prefixed {
1056        prefix: Ident,
1057        /// The value of the constant.
1058        /// Hint: you can unwrap the string value using `value.into_string()`.
1059        value: Box<Expr>,
1060    },
1061    /// A constant of form `<data_type> 'value'`.
1062    /// This can represent ANSI SQL `DATE`, `TIME`, and `TIMESTAMP` literals (such as `DATE '2020-01-01'`),
1063    /// as well as constants of other types (a non-standard PostgreSQL extension).
1064    TypedString(TypedString),
1065    /// Scalar function call e.g. `LEFT(foo, 5)`
1066    Function(Function),
1067    /// `CASE [<operand>] WHEN <condition> THEN <result> ... [ELSE <result>] END`
1068    ///
1069    /// Note we only recognize a complete single expression as `<condition>`,
1070    /// not `< 0` nor `1, 2, 3` as allowed in a `<simple when clause>` per
1071    /// <https://jakewheat.github.io/sql-overview/sql-2011-foundation-grammar.html#simple-when-clause>
1072    Case {
1073        case_token: AttachedToken,
1074        end_token: AttachedToken,
1075        operand: Option<Box<Expr>>,
1076        conditions: Vec<CaseWhen>,
1077        else_result: Option<Box<Expr>>,
1078    },
1079    /// An exists expression `[ NOT ] EXISTS(SELECT ...)`, used in expressions like
1080    /// `WHERE [ NOT ] EXISTS (SELECT ...)`.
1081    Exists {
1082        subquery: Box<Query>,
1083        negated: bool,
1084    },
1085    /// A parenthesized subquery `(SELECT ...)`, used in expression like
1086    /// `SELECT (subquery) AS x` or `WHERE (subquery) = x`
1087    Subquery(Box<Query>),
1088    /// The `GROUPING SETS` expr.
1089    GroupingSets(Vec<Vec<Expr>>),
1090    /// The `CUBE` expr.
1091    Cube(Vec<Vec<Expr>>),
1092    /// The `ROLLUP` expr.
1093    Rollup(Vec<Vec<Expr>>),
1094    /// ROW / TUPLE a single value, such as `SELECT (1, 2)`
1095    Tuple(Vec<Expr>),
1096    /// `Struct` literal expression
1097    /// Syntax:
1098    /// ```sql
1099    /// STRUCT<[field_name] field_type, ...>( expr1 [, ... ])
1100    ///
1101    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type)
1102    /// [Databricks](https://docs.databricks.com/en/sql/language-manual/functions/struct.html)
1103    /// ```
1104    Struct {
1105        /// Struct values.
1106        values: Vec<Expr>,
1107        /// Struct field definitions.
1108        fields: Vec<StructField>,
1109    },
1110    /// `BigQuery` specific: An named expression in a typeless struct [1]
1111    ///
1112    /// Syntax
1113    /// ```sql
1114    /// 1 AS A
1115    /// ```
1116    /// [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
1117    Named {
1118        expr: Box<Expr>,
1119        name: Ident,
1120    },
1121    /// `DuckDB` specific `Struct` literal expression [1]
1122    ///
1123    /// Syntax:
1124    /// ```sql
1125    /// syntax: {'field_name': expr1[, ... ]}
1126    /// ```
1127    /// [1]: https://duckdb.org/docs/sql/data_types/struct#creating-structs
1128    Dictionary(Vec<DictionaryField>),
1129    /// `DuckDB` specific `Map` literal expression [1]
1130    ///
1131    /// Syntax:
1132    /// ```sql
1133    /// syntax: Map {key1: value1[, ... ]}
1134    /// ```
1135    /// [1]: https://duckdb.org/docs/sql/data_types/map#creating-maps
1136    Map(Map),
1137    /// An array expression e.g. `ARRAY[1, 2]`
1138    Array(Array),
1139    /// An interval expression e.g. `INTERVAL '1' YEAR`
1140    Interval(Interval),
1141    /// `MySQL` specific text search function [(1)].
1142    ///
1143    /// Syntax:
1144    /// ```sql
1145    /// MATCH (<col>, <col>, ...) AGAINST (<expr> [<search modifier>])
1146    ///
1147    /// <col> = CompoundIdentifier
1148    /// <expr> = String literal
1149    /// ```
1150    /// [(1)]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html#function_match
1151    MatchAgainst {
1152        /// `(<col>, <col>, ...)`.
1153        columns: Vec<ObjectName>,
1154        /// `<expr>`.
1155        match_value: Value,
1156        /// `<search modifier>`
1157        opt_search_modifier: Option<SearchModifier>,
1158    },
1159    Wildcard(AttachedToken),
1160    /// Qualified wildcard, e.g. `alias.*` or `schema.table.*`.
1161    /// (Same caveats apply to `QualifiedWildcard` as to `Wildcard`.)
1162    QualifiedWildcard(ObjectName, AttachedToken),
1163    /// Some dialects support an older syntax for outer joins where columns are
1164    /// marked with the `(+)` operator in the WHERE clause, for example:
1165    ///
1166    /// ```sql
1167    /// SELECT t1.c1, t2.c2 FROM t1, t2 WHERE t1.c1 = t2.c2 (+)
1168    /// ```
1169    ///
1170    /// which is equivalent to
1171    ///
1172    /// ```sql
1173    /// SELECT t1.c1, t2.c2 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c2
1174    /// ```
1175    ///
1176    /// See <https://docs.snowflake.com/en/sql-reference/constructs/where#joins-in-the-where-clause>.
1177    OuterJoin(Box<Expr>),
1178    /// A reference to the prior level in a CONNECT BY clause.
1179    Prior(Box<Expr>),
1180    /// A lambda function.
1181    ///
1182    /// Syntax:
1183    /// ```plaintext
1184    /// param -> expr | (param1, ...) -> expr
1185    /// ```
1186    ///
1187    /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/functions#higher-order-functions---operator-and-lambdaparams-expr-function)
1188    /// [Databricks](https://docs.databricks.com/en/sql/language-manual/sql-ref-lambda-functions.html)
1189    /// [DuckDB](https://duckdb.org/docs/stable/sql/functions/lambda)
1190    Lambda(LambdaFunction),
1191    /// Checks membership of a value in a JSON array
1192    MemberOf(MemberOf),
1193}
1194
1195impl Expr {
1196    /// Creates a new [`Expr::Value`]
1197    pub fn value(value: impl Into<ValueWithSpan>) -> Self {
1198        Expr::Value(value.into())
1199    }
1200}
1201
1202/// The contents inside the `[` and `]` in a subscript expression.
1203#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1204#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1205#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1206pub enum Subscript {
1207    /// Accesses the element of the array at the given index.
1208    Index { index: Expr },
1209
1210    /// Accesses a slice of an array on PostgreSQL, e.g.
1211    ///
1212    /// ```plaintext
1213    /// => select (array[1,2,3,4,5,6])[2:5];
1214    /// -----------
1215    /// {2,3,4,5}
1216    /// ```
1217    ///
1218    /// The lower and/or upper bound can be omitted to slice from the start or
1219    /// end of the array respectively.
1220    ///
1221    /// See <https://www.postgresql.org/docs/current/arrays.html#ARRAYS-ACCESSING>.
1222    ///
1223    /// Also supports an optional "stride" as the last element (this is not
1224    /// supported by postgres), e.g.
1225    ///
1226    /// ```plaintext
1227    /// => select (array[1,2,3,4,5,6])[1:6:2];
1228    /// -----------
1229    /// {1,3,5}
1230    /// ```
1231    Slice {
1232        lower_bound: Option<Expr>,
1233        upper_bound: Option<Expr>,
1234        stride: Option<Expr>,
1235    },
1236}
1237
1238impl fmt::Display for Subscript {
1239    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1240        match self {
1241            Subscript::Index { index } => write!(f, "{index}"),
1242            Subscript::Slice {
1243                lower_bound,
1244                upper_bound,
1245                stride,
1246            } => {
1247                if let Some(lower) = lower_bound {
1248                    write!(f, "{lower}")?;
1249                }
1250                write!(f, ":")?;
1251                if let Some(upper) = upper_bound {
1252                    write!(f, "{upper}")?;
1253                }
1254                if let Some(stride) = stride {
1255                    write!(f, ":")?;
1256                    write!(f, "{stride}")?;
1257                }
1258                Ok(())
1259            }
1260        }
1261    }
1262}
1263
1264/// An element of a [`Expr::CompoundFieldAccess`].
1265/// It can be an expression or a subscript.
1266#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1267#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1268#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1269pub enum AccessExpr {
1270    /// Accesses a field using dot notation, e.g. `foo.bar.baz`.
1271    Dot(Expr),
1272    /// Accesses a field or array element using bracket notation, e.g. `foo['bar']`.
1273    Subscript(Subscript),
1274}
1275
1276impl fmt::Display for AccessExpr {
1277    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1278        match self {
1279            AccessExpr::Dot(expr) => write!(f, ".{expr}"),
1280            AccessExpr::Subscript(subscript) => write!(f, "[{subscript}]"),
1281        }
1282    }
1283}
1284
1285/// A lambda function.
1286#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1287#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1288#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1289pub struct LambdaFunction {
1290    /// The parameters to the lambda function.
1291    pub params: OneOrManyWithParens<Ident>,
1292    /// The body of the lambda function.
1293    pub body: Box<Expr>,
1294}
1295
1296impl fmt::Display for LambdaFunction {
1297    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1298        write!(f, "{} -> {}", self.params, self.body)
1299    }
1300}
1301
1302/// Encapsulates the common pattern in SQL where either one unparenthesized item
1303/// such as an identifier or expression is permitted, or multiple of the same
1304/// item in a parenthesized list. For accessing items regardless of the form,
1305/// `OneOrManyWithParens` implements `Deref<Target = [T]>` and `IntoIterator`,
1306/// so you can call slice methods on it and iterate over items
1307/// # Examples
1308/// Accessing as a slice:
1309/// ```
1310/// # use sqlparser::ast::OneOrManyWithParens;
1311/// let one = OneOrManyWithParens::One("a");
1312///
1313/// assert_eq!(one[0], "a");
1314/// assert_eq!(one.len(), 1);
1315/// ```
1316/// Iterating:
1317/// ```
1318/// # use sqlparser::ast::OneOrManyWithParens;
1319/// let one = OneOrManyWithParens::One("a");
1320/// let many = OneOrManyWithParens::Many(vec!["a", "b"]);
1321///
1322/// assert_eq!(one.into_iter().chain(many).collect::<Vec<_>>(), vec!["a", "a", "b"] );
1323/// ```
1324#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1325#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1326#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1327pub enum OneOrManyWithParens<T> {
1328    /// A single `T`, unparenthesized.
1329    One(T),
1330    /// One or more `T`s, parenthesized.
1331    Many(Vec<T>),
1332}
1333
1334impl<T> Deref for OneOrManyWithParens<T> {
1335    type Target = [T];
1336
1337    fn deref(&self) -> &[T] {
1338        match self {
1339            OneOrManyWithParens::One(one) => core::slice::from_ref(one),
1340            OneOrManyWithParens::Many(many) => many,
1341        }
1342    }
1343}
1344
1345impl<T> AsRef<[T]> for OneOrManyWithParens<T> {
1346    fn as_ref(&self) -> &[T] {
1347        self
1348    }
1349}
1350
1351impl<'a, T> IntoIterator for &'a OneOrManyWithParens<T> {
1352    type Item = &'a T;
1353    type IntoIter = core::slice::Iter<'a, T>;
1354
1355    fn into_iter(self) -> Self::IntoIter {
1356        self.iter()
1357    }
1358}
1359
1360/// Owned iterator implementation of `OneOrManyWithParens`
1361#[derive(Debug, Clone)]
1362pub struct OneOrManyWithParensIntoIter<T> {
1363    inner: OneOrManyWithParensIntoIterInner<T>,
1364}
1365
1366#[derive(Debug, Clone)]
1367enum OneOrManyWithParensIntoIterInner<T> {
1368    One(core::iter::Once<T>),
1369    Many(<Vec<T> as IntoIterator>::IntoIter),
1370}
1371
1372impl<T> core::iter::FusedIterator for OneOrManyWithParensIntoIter<T>
1373where
1374    core::iter::Once<T>: core::iter::FusedIterator,
1375    <Vec<T> as IntoIterator>::IntoIter: core::iter::FusedIterator,
1376{
1377}
1378
1379impl<T> core::iter::ExactSizeIterator for OneOrManyWithParensIntoIter<T>
1380where
1381    core::iter::Once<T>: core::iter::ExactSizeIterator,
1382    <Vec<T> as IntoIterator>::IntoIter: core::iter::ExactSizeIterator,
1383{
1384}
1385
1386impl<T> core::iter::Iterator for OneOrManyWithParensIntoIter<T> {
1387    type Item = T;
1388
1389    fn next(&mut self) -> Option<Self::Item> {
1390        match &mut self.inner {
1391            OneOrManyWithParensIntoIterInner::One(one) => one.next(),
1392            OneOrManyWithParensIntoIterInner::Many(many) => many.next(),
1393        }
1394    }
1395
1396    fn size_hint(&self) -> (usize, Option<usize>) {
1397        match &self.inner {
1398            OneOrManyWithParensIntoIterInner::One(one) => one.size_hint(),
1399            OneOrManyWithParensIntoIterInner::Many(many) => many.size_hint(),
1400        }
1401    }
1402
1403    fn count(self) -> usize
1404    where
1405        Self: Sized,
1406    {
1407        match self.inner {
1408            OneOrManyWithParensIntoIterInner::One(one) => one.count(),
1409            OneOrManyWithParensIntoIterInner::Many(many) => many.count(),
1410        }
1411    }
1412
1413    fn fold<B, F>(mut self, init: B, f: F) -> B
1414    where
1415        Self: Sized,
1416        F: FnMut(B, Self::Item) -> B,
1417    {
1418        match &mut self.inner {
1419            OneOrManyWithParensIntoIterInner::One(one) => one.fold(init, f),
1420            OneOrManyWithParensIntoIterInner::Many(many) => many.fold(init, f),
1421        }
1422    }
1423}
1424
1425impl<T> core::iter::DoubleEndedIterator for OneOrManyWithParensIntoIter<T> {
1426    fn next_back(&mut self) -> Option<Self::Item> {
1427        match &mut self.inner {
1428            OneOrManyWithParensIntoIterInner::One(one) => one.next_back(),
1429            OneOrManyWithParensIntoIterInner::Many(many) => many.next_back(),
1430        }
1431    }
1432}
1433
1434impl<T> IntoIterator for OneOrManyWithParens<T> {
1435    type Item = T;
1436
1437    type IntoIter = OneOrManyWithParensIntoIter<T>;
1438
1439    fn into_iter(self) -> Self::IntoIter {
1440        let inner = match self {
1441            OneOrManyWithParens::One(one) => {
1442                OneOrManyWithParensIntoIterInner::One(core::iter::once(one))
1443            }
1444            OneOrManyWithParens::Many(many) => {
1445                OneOrManyWithParensIntoIterInner::Many(many.into_iter())
1446            }
1447        };
1448
1449        OneOrManyWithParensIntoIter { inner }
1450    }
1451}
1452
1453impl<T> fmt::Display for OneOrManyWithParens<T>
1454where
1455    T: fmt::Display,
1456{
1457    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1458        match self {
1459            OneOrManyWithParens::One(value) => write!(f, "{value}"),
1460            OneOrManyWithParens::Many(values) => {
1461                write!(f, "({})", display_comma_separated(values))
1462            }
1463        }
1464    }
1465}
1466
1467impl fmt::Display for CastFormat {
1468    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1469        match self {
1470            CastFormat::Value(v) => write!(f, "{v}"),
1471            CastFormat::ValueAtTimeZone(v, tz) => write!(f, "{v} AT TIME ZONE {tz}"),
1472        }
1473    }
1474}
1475
1476impl fmt::Display for Expr {
1477    #[cfg_attr(feature = "recursive-protection", recursive::recursive)]
1478    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1479        match self {
1480            Expr::Identifier(s) => write!(f, "{s}"),
1481            Expr::Wildcard(_) => f.write_str("*"),
1482            Expr::QualifiedWildcard(prefix, _) => write!(f, "{prefix}.*"),
1483            Expr::CompoundIdentifier(s) => write!(f, "{}", display_separated(s, ".")),
1484            Expr::CompoundFieldAccess { root, access_chain } => {
1485                write!(f, "{root}")?;
1486                for field in access_chain {
1487                    write!(f, "{field}")?;
1488                }
1489                Ok(())
1490            }
1491            Expr::IsTrue(ast) => write!(f, "{ast} IS TRUE"),
1492            Expr::IsNotTrue(ast) => write!(f, "{ast} IS NOT TRUE"),
1493            Expr::IsFalse(ast) => write!(f, "{ast} IS FALSE"),
1494            Expr::IsNotFalse(ast) => write!(f, "{ast} IS NOT FALSE"),
1495            Expr::IsNull(ast) => write!(f, "{ast} IS NULL"),
1496            Expr::IsNotNull(ast) => write!(f, "{ast} IS NOT NULL"),
1497            Expr::IsUnknown(ast) => write!(f, "{ast} IS UNKNOWN"),
1498            Expr::IsNotUnknown(ast) => write!(f, "{ast} IS NOT UNKNOWN"),
1499            Expr::InList {
1500                expr,
1501                list,
1502                negated,
1503            } => write!(
1504                f,
1505                "{} {}IN ({})",
1506                expr,
1507                if *negated { "NOT " } else { "" },
1508                display_comma_separated(list)
1509            ),
1510            Expr::InSubquery {
1511                expr,
1512                subquery,
1513                negated,
1514            } => write!(
1515                f,
1516                "{} {}IN ({})",
1517                expr,
1518                if *negated { "NOT " } else { "" },
1519                subquery
1520            ),
1521            Expr::InUnnest {
1522                expr,
1523                array_expr,
1524                negated,
1525            } => write!(
1526                f,
1527                "{} {}IN UNNEST({})",
1528                expr,
1529                if *negated { "NOT " } else { "" },
1530                array_expr
1531            ),
1532            Expr::Between {
1533                expr,
1534                negated,
1535                low,
1536                high,
1537            } => write!(
1538                f,
1539                "{} {}BETWEEN {} AND {}",
1540                expr,
1541                if *negated { "NOT " } else { "" },
1542                low,
1543                high
1544            ),
1545            Expr::BinaryOp { left, op, right } => write!(f, "{left} {op} {right}"),
1546            Expr::Like {
1547                negated,
1548                expr,
1549                pattern,
1550                escape_char,
1551                any,
1552            } => match escape_char {
1553                Some(ch) => write!(
1554                    f,
1555                    "{} {}LIKE {}{} ESCAPE {}",
1556                    expr,
1557                    if *negated { "NOT " } else { "" },
1558                    if *any { "ANY " } else { "" },
1559                    pattern,
1560                    ch
1561                ),
1562                _ => write!(
1563                    f,
1564                    "{} {}LIKE {}{}",
1565                    expr,
1566                    if *negated { "NOT " } else { "" },
1567                    if *any { "ANY " } else { "" },
1568                    pattern
1569                ),
1570            },
1571            Expr::ILike {
1572                negated,
1573                expr,
1574                pattern,
1575                escape_char,
1576                any,
1577            } => match escape_char {
1578                Some(ch) => write!(
1579                    f,
1580                    "{} {}ILIKE {}{} ESCAPE {}",
1581                    expr,
1582                    if *negated { "NOT " } else { "" },
1583                    if *any { "ANY" } else { "" },
1584                    pattern,
1585                    ch
1586                ),
1587                _ => write!(
1588                    f,
1589                    "{} {}ILIKE {}{}",
1590                    expr,
1591                    if *negated { "NOT " } else { "" },
1592                    if *any { "ANY " } else { "" },
1593                    pattern
1594                ),
1595            },
1596            Expr::RLike {
1597                negated,
1598                expr,
1599                pattern,
1600                regexp,
1601            } => write!(
1602                f,
1603                "{} {}{} {}",
1604                expr,
1605                if *negated { "NOT " } else { "" },
1606                if *regexp { "REGEXP" } else { "RLIKE" },
1607                pattern
1608            ),
1609            Expr::IsNormalized {
1610                expr,
1611                form,
1612                negated,
1613            } => {
1614                let not_ = if *negated { "NOT " } else { "" };
1615                if form.is_none() {
1616                    write!(f, "{expr} IS {not_}NORMALIZED")
1617                } else {
1618                    write!(
1619                        f,
1620                        "{} IS {}{} NORMALIZED",
1621                        expr,
1622                        not_,
1623                        form.as_ref().unwrap()
1624                    )
1625                }
1626            }
1627            Expr::SimilarTo {
1628                negated,
1629                expr,
1630                pattern,
1631                escape_char,
1632            } => match escape_char {
1633                Some(ch) => write!(
1634                    f,
1635                    "{} {}SIMILAR TO {} ESCAPE {}",
1636                    expr,
1637                    if *negated { "NOT " } else { "" },
1638                    pattern,
1639                    ch
1640                ),
1641                _ => write!(
1642                    f,
1643                    "{} {}SIMILAR TO {}",
1644                    expr,
1645                    if *negated { "NOT " } else { "" },
1646                    pattern
1647                ),
1648            },
1649            Expr::AnyOp {
1650                left,
1651                compare_op,
1652                right,
1653                is_some,
1654            } => {
1655                let add_parens = !matches!(right.as_ref(), Expr::Subquery(_));
1656                write!(
1657                    f,
1658                    "{left} {compare_op} {}{}{right}{}",
1659                    if *is_some { "SOME" } else { "ANY" },
1660                    if add_parens { "(" } else { "" },
1661                    if add_parens { ")" } else { "" },
1662                )
1663            }
1664            Expr::AllOp {
1665                left,
1666                compare_op,
1667                right,
1668            } => {
1669                let add_parens = !matches!(right.as_ref(), Expr::Subquery(_));
1670                write!(
1671                    f,
1672                    "{left} {compare_op} ALL{}{right}{}",
1673                    if add_parens { "(" } else { "" },
1674                    if add_parens { ")" } else { "" },
1675                )
1676            }
1677            Expr::UnaryOp { op, expr } => {
1678                if op == &UnaryOperator::PGPostfixFactorial {
1679                    write!(f, "{expr}{op}")
1680                } else if matches!(
1681                    op,
1682                    UnaryOperator::Not
1683                        | UnaryOperator::Hash
1684                        | UnaryOperator::AtDashAt
1685                        | UnaryOperator::DoubleAt
1686                        | UnaryOperator::QuestionDash
1687                        | UnaryOperator::QuestionPipe
1688                ) {
1689                    write!(f, "{op} {expr}")
1690                } else {
1691                    write!(f, "{op}{expr}")
1692                }
1693            }
1694            Expr::Convert {
1695                is_try,
1696                expr,
1697                target_before_value,
1698                data_type,
1699                charset,
1700                styles,
1701            } => {
1702                write!(f, "{}CONVERT(", if *is_try { "TRY_" } else { "" })?;
1703                if let Some(data_type) = data_type {
1704                    if let Some(charset) = charset {
1705                        write!(f, "{expr}, {data_type} CHARACTER SET {charset}")
1706                    } else if *target_before_value {
1707                        write!(f, "{data_type}, {expr}")
1708                    } else {
1709                        write!(f, "{expr}, {data_type}")
1710                    }
1711                } else if let Some(charset) = charset {
1712                    write!(f, "{expr} USING {charset}")
1713                } else {
1714                    write!(f, "{expr}") // This should never happen
1715                }?;
1716                if !styles.is_empty() {
1717                    write!(f, ", {}", display_comma_separated(styles))?;
1718                }
1719                write!(f, ")")
1720            }
1721            Expr::Cast {
1722                kind,
1723                expr,
1724                data_type,
1725                format,
1726            } => match kind {
1727                CastKind::Cast => {
1728                    if let Some(format) = format {
1729                        write!(f, "CAST({expr} AS {data_type} FORMAT {format})")
1730                    } else {
1731                        write!(f, "CAST({expr} AS {data_type})")
1732                    }
1733                }
1734                CastKind::TryCast => {
1735                    if let Some(format) = format {
1736                        write!(f, "TRY_CAST({expr} AS {data_type} FORMAT {format})")
1737                    } else {
1738                        write!(f, "TRY_CAST({expr} AS {data_type})")
1739                    }
1740                }
1741                CastKind::SafeCast => {
1742                    if let Some(format) = format {
1743                        write!(f, "SAFE_CAST({expr} AS {data_type} FORMAT {format})")
1744                    } else {
1745                        write!(f, "SAFE_CAST({expr} AS {data_type})")
1746                    }
1747                }
1748                CastKind::DoubleColon => {
1749                    write!(f, "{expr}::{data_type}")
1750                }
1751            },
1752            Expr::Extract {
1753                field,
1754                syntax,
1755                expr,
1756            } => match syntax {
1757                ExtractSyntax::From => write!(f, "EXTRACT({field} FROM {expr})"),
1758                ExtractSyntax::Comma => write!(f, "EXTRACT({field}, {expr})"),
1759            },
1760            Expr::Ceil { expr, field } => match field {
1761                CeilFloorKind::DateTimeField(DateTimeField::NoDateTime) => {
1762                    write!(f, "CEIL({expr})")
1763                }
1764                CeilFloorKind::DateTimeField(dt_field) => write!(f, "CEIL({expr} TO {dt_field})"),
1765                CeilFloorKind::Scale(s) => write!(f, "CEIL({expr}, {s})"),
1766            },
1767            Expr::Floor { expr, field } => match field {
1768                CeilFloorKind::DateTimeField(DateTimeField::NoDateTime) => {
1769                    write!(f, "FLOOR({expr})")
1770                }
1771                CeilFloorKind::DateTimeField(dt_field) => write!(f, "FLOOR({expr} TO {dt_field})"),
1772                CeilFloorKind::Scale(s) => write!(f, "FLOOR({expr}, {s})"),
1773            },
1774            Expr::Position { expr, r#in } => write!(f, "POSITION({expr} IN {in})"),
1775            Expr::Collate { expr, collation } => write!(f, "{expr} COLLATE {collation}"),
1776            Expr::Nested(ast) => write!(f, "({ast})"),
1777            Expr::Value(v) => write!(f, "{v}"),
1778            Expr::Prefixed { prefix, value } => write!(f, "{prefix} {value}"),
1779            Expr::TypedString(ts) => ts.fmt(f),
1780            Expr::Function(fun) => fun.fmt(f),
1781            Expr::Case {
1782                case_token: _,
1783                end_token: _,
1784                operand,
1785                conditions,
1786                else_result,
1787            } => {
1788                f.write_str("CASE")?;
1789                if let Some(operand) = operand {
1790                    f.write_str(" ")?;
1791                    operand.fmt(f)?;
1792                }
1793                for when in conditions {
1794                    SpaceOrNewline.fmt(f)?;
1795                    Indent(when).fmt(f)?;
1796                }
1797                if let Some(else_result) = else_result {
1798                    SpaceOrNewline.fmt(f)?;
1799                    Indent("ELSE").fmt(f)?;
1800                    SpaceOrNewline.fmt(f)?;
1801                    Indent(Indent(else_result)).fmt(f)?;
1802                }
1803                SpaceOrNewline.fmt(f)?;
1804                f.write_str("END")
1805            }
1806            Expr::Exists { subquery, negated } => write!(
1807                f,
1808                "{}EXISTS ({})",
1809                if *negated { "NOT " } else { "" },
1810                subquery
1811            ),
1812            Expr::Subquery(s) => write!(f, "({s})"),
1813            Expr::GroupingSets(sets) => {
1814                write!(f, "GROUPING SETS (")?;
1815                let mut sep = "";
1816                for set in sets {
1817                    write!(f, "{sep}")?;
1818                    sep = ", ";
1819                    write!(f, "({})", display_comma_separated(set))?;
1820                }
1821                write!(f, ")")
1822            }
1823            Expr::Cube(sets) => {
1824                write!(f, "CUBE (")?;
1825                let mut sep = "";
1826                for set in sets {
1827                    write!(f, "{sep}")?;
1828                    sep = ", ";
1829                    if set.len() == 1 {
1830                        write!(f, "{}", set[0])?;
1831                    } else {
1832                        write!(f, "({})", display_comma_separated(set))?;
1833                    }
1834                }
1835                write!(f, ")")
1836            }
1837            Expr::Rollup(sets) => {
1838                write!(f, "ROLLUP (")?;
1839                let mut sep = "";
1840                for set in sets {
1841                    write!(f, "{sep}")?;
1842                    sep = ", ";
1843                    if set.len() == 1 {
1844                        write!(f, "{}", set[0])?;
1845                    } else {
1846                        write!(f, "({})", display_comma_separated(set))?;
1847                    }
1848                }
1849                write!(f, ")")
1850            }
1851            Expr::Substring {
1852                expr,
1853                substring_from,
1854                substring_for,
1855                special,
1856                shorthand,
1857            } => {
1858                f.write_str("SUBSTR")?;
1859                if !*shorthand {
1860                    f.write_str("ING")?;
1861                }
1862                write!(f, "({expr}")?;
1863                if let Some(from_part) = substring_from {
1864                    if *special {
1865                        write!(f, ", {from_part}")?;
1866                    } else {
1867                        write!(f, " FROM {from_part}")?;
1868                    }
1869                }
1870                if let Some(for_part) = substring_for {
1871                    if *special {
1872                        write!(f, ", {for_part}")?;
1873                    } else {
1874                        write!(f, " FOR {for_part}")?;
1875                    }
1876                }
1877
1878                write!(f, ")")
1879            }
1880            Expr::Overlay {
1881                expr,
1882                overlay_what,
1883                overlay_from,
1884                overlay_for,
1885            } => {
1886                write!(
1887                    f,
1888                    "OVERLAY({expr} PLACING {overlay_what} FROM {overlay_from}"
1889                )?;
1890                if let Some(for_part) = overlay_for {
1891                    write!(f, " FOR {for_part}")?;
1892                }
1893
1894                write!(f, ")")
1895            }
1896            Expr::IsDistinctFrom(a, b) => write!(f, "{a} IS DISTINCT FROM {b}"),
1897            Expr::IsNotDistinctFrom(a, b) => write!(f, "{a} IS NOT DISTINCT FROM {b}"),
1898            Expr::Trim {
1899                expr,
1900                trim_where,
1901                trim_what,
1902                trim_characters,
1903            } => {
1904                write!(f, "TRIM(")?;
1905                if let Some(ident) = trim_where {
1906                    write!(f, "{ident} ")?;
1907                }
1908                if let Some(trim_char) = trim_what {
1909                    write!(f, "{trim_char} FROM {expr}")?;
1910                } else {
1911                    write!(f, "{expr}")?;
1912                }
1913                if let Some(characters) = trim_characters {
1914                    write!(f, ", {}", display_comma_separated(characters))?;
1915                }
1916
1917                write!(f, ")")
1918            }
1919            Expr::Tuple(exprs) => {
1920                write!(f, "({})", display_comma_separated(exprs))
1921            }
1922            Expr::Struct { values, fields } => {
1923                if !fields.is_empty() {
1924                    write!(
1925                        f,
1926                        "STRUCT<{}>({})",
1927                        display_comma_separated(fields),
1928                        display_comma_separated(values)
1929                    )
1930                } else {
1931                    write!(f, "STRUCT({})", display_comma_separated(values))
1932                }
1933            }
1934            Expr::Named { expr, name } => {
1935                write!(f, "{expr} AS {name}")
1936            }
1937            Expr::Dictionary(fields) => {
1938                write!(f, "{{{}}}", display_comma_separated(fields))
1939            }
1940            Expr::Map(map) => {
1941                write!(f, "{map}")
1942            }
1943            Expr::Array(set) => {
1944                write!(f, "{set}")
1945            }
1946            Expr::JsonAccess { value, path } => {
1947                write!(f, "{value}{path}")
1948            }
1949            Expr::AtTimeZone {
1950                timestamp,
1951                time_zone,
1952            } => {
1953                write!(f, "{timestamp} AT TIME ZONE {time_zone}")
1954            }
1955            Expr::Interval(interval) => {
1956                write!(f, "{interval}")
1957            }
1958            Expr::MatchAgainst {
1959                columns,
1960                match_value: match_expr,
1961                opt_search_modifier,
1962            } => {
1963                write!(f, "MATCH ({}) AGAINST ", display_comma_separated(columns),)?;
1964
1965                if let Some(search_modifier) = opt_search_modifier {
1966                    write!(f, "({match_expr} {search_modifier})")?;
1967                } else {
1968                    write!(f, "({match_expr})")?;
1969                }
1970
1971                Ok(())
1972            }
1973            Expr::OuterJoin(expr) => {
1974                write!(f, "{expr} (+)")
1975            }
1976            Expr::Prior(expr) => write!(f, "PRIOR {expr}"),
1977            Expr::Lambda(lambda) => write!(f, "{lambda}"),
1978            Expr::MemberOf(member_of) => write!(f, "{member_of}"),
1979        }
1980    }
1981}
1982
1983#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1984#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1985#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1986pub enum WindowType {
1987    WindowSpec(WindowSpec),
1988    NamedWindow(Ident),
1989}
1990
1991impl Display for WindowType {
1992    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1993        match self {
1994            WindowType::WindowSpec(spec) => {
1995                f.write_str("(")?;
1996                NewLine.fmt(f)?;
1997                Indent(spec).fmt(f)?;
1998                NewLine.fmt(f)?;
1999                f.write_str(")")
2000            }
2001            WindowType::NamedWindow(name) => name.fmt(f),
2002        }
2003    }
2004}
2005
2006/// A window specification (i.e. `OVER ([window_name] PARTITION BY .. ORDER BY .. etc.)`)
2007#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2008#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2009#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2010pub struct WindowSpec {
2011    /// Optional window name.
2012    ///
2013    /// You can find it at least in [MySQL][1], [BigQuery][2], [PostgreSQL][3]
2014    ///
2015    /// [1]: https://dev.mysql.com/doc/refman/8.0/en/window-functions-named-windows.html
2016    /// [2]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
2017    /// [3]: https://www.postgresql.org/docs/current/sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS
2018    pub window_name: Option<Ident>,
2019    /// `OVER (PARTITION BY ...)`
2020    pub partition_by: Vec<Expr>,
2021    /// `OVER (ORDER BY ...)`
2022    pub order_by: Vec<OrderByExpr>,
2023    /// `OVER (window frame)`
2024    pub window_frame: Option<WindowFrame>,
2025}
2026
2027impl fmt::Display for WindowSpec {
2028    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2029        let mut is_first = true;
2030        if let Some(window_name) = &self.window_name {
2031            if !is_first {
2032                SpaceOrNewline.fmt(f)?;
2033            }
2034            is_first = false;
2035            write!(f, "{window_name}")?;
2036        }
2037        if !self.partition_by.is_empty() {
2038            if !is_first {
2039                SpaceOrNewline.fmt(f)?;
2040            }
2041            is_first = false;
2042            write!(
2043                f,
2044                "PARTITION BY {}",
2045                display_comma_separated(&self.partition_by)
2046            )?;
2047        }
2048        if !self.order_by.is_empty() {
2049            if !is_first {
2050                SpaceOrNewline.fmt(f)?;
2051            }
2052            is_first = false;
2053            write!(f, "ORDER BY {}", display_comma_separated(&self.order_by))?;
2054        }
2055        if let Some(window_frame) = &self.window_frame {
2056            if !is_first {
2057                SpaceOrNewline.fmt(f)?;
2058            }
2059            if let Some(end_bound) = &window_frame.end_bound {
2060                write!(
2061                    f,
2062                    "{} BETWEEN {} AND {}",
2063                    window_frame.units, window_frame.start_bound, end_bound
2064                )?;
2065            } else {
2066                write!(f, "{} {}", window_frame.units, window_frame.start_bound)?;
2067            }
2068        }
2069        Ok(())
2070    }
2071}
2072
2073/// Specifies the data processed by a window function, e.g.
2074/// `RANGE UNBOUNDED PRECEDING` or `ROWS BETWEEN 5 PRECEDING AND CURRENT ROW`.
2075///
2076/// Note: The parser does not validate the specified bounds; the caller should
2077/// reject invalid bounds like `ROWS UNBOUNDED FOLLOWING` before execution.
2078#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2079#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2080#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2081pub struct WindowFrame {
2082    pub units: WindowFrameUnits,
2083    pub start_bound: WindowFrameBound,
2084    /// The right bound of the `BETWEEN .. AND` clause. The end bound of `None`
2085    /// indicates the shorthand form (e.g. `ROWS 1 PRECEDING`), which must
2086    /// behave the same as `end_bound = WindowFrameBound::CurrentRow`.
2087    pub end_bound: Option<WindowFrameBound>,
2088    // TBD: EXCLUDE
2089}
2090
2091impl Default for WindowFrame {
2092    /// Returns default value for window frame
2093    ///
2094    /// See [this page](https://www.sqlite.org/windowfunctions.html#frame_specifications) for more details.
2095    fn default() -> Self {
2096        Self {
2097            units: WindowFrameUnits::Range,
2098            start_bound: WindowFrameBound::Preceding(None),
2099            end_bound: None,
2100        }
2101    }
2102}
2103
2104#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2105#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2106#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2107pub enum WindowFrameUnits {
2108    Rows,
2109    Range,
2110    Groups,
2111}
2112
2113impl fmt::Display for WindowFrameUnits {
2114    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2115        f.write_str(match self {
2116            WindowFrameUnits::Rows => "ROWS",
2117            WindowFrameUnits::Range => "RANGE",
2118            WindowFrameUnits::Groups => "GROUPS",
2119        })
2120    }
2121}
2122
2123/// Specifies Ignore / Respect NULL within window functions.
2124/// For example
2125/// `FIRST_VALUE(column2) IGNORE NULLS OVER (PARTITION BY column1)`
2126#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2127#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2128#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2129pub enum NullTreatment {
2130    IgnoreNulls,
2131    RespectNulls,
2132}
2133
2134impl fmt::Display for NullTreatment {
2135    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2136        f.write_str(match self {
2137            NullTreatment::IgnoreNulls => "IGNORE NULLS",
2138            NullTreatment::RespectNulls => "RESPECT NULLS",
2139        })
2140    }
2141}
2142
2143/// Specifies [WindowFrame]'s `start_bound` and `end_bound`
2144#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2145#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2146#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2147pub enum WindowFrameBound {
2148    /// `CURRENT ROW`
2149    CurrentRow,
2150    /// `<N> PRECEDING` or `UNBOUNDED PRECEDING`
2151    Preceding(Option<Box<Expr>>),
2152    /// `<N> FOLLOWING` or `UNBOUNDED FOLLOWING`.
2153    Following(Option<Box<Expr>>),
2154}
2155
2156impl fmt::Display for WindowFrameBound {
2157    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2158        match self {
2159            WindowFrameBound::CurrentRow => f.write_str("CURRENT ROW"),
2160            WindowFrameBound::Preceding(None) => f.write_str("UNBOUNDED PRECEDING"),
2161            WindowFrameBound::Following(None) => f.write_str("UNBOUNDED FOLLOWING"),
2162            WindowFrameBound::Preceding(Some(n)) => write!(f, "{n} PRECEDING"),
2163            WindowFrameBound::Following(Some(n)) => write!(f, "{n} FOLLOWING"),
2164        }
2165    }
2166}
2167
2168#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2170#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2171pub enum AddDropSync {
2172    ADD,
2173    DROP,
2174    SYNC,
2175}
2176
2177impl fmt::Display for AddDropSync {
2178    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2179        match self {
2180            AddDropSync::SYNC => f.write_str("SYNC PARTITIONS"),
2181            AddDropSync::DROP => f.write_str("DROP PARTITIONS"),
2182            AddDropSync::ADD => f.write_str("ADD PARTITIONS"),
2183        }
2184    }
2185}
2186
2187#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2188#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2189#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2190pub enum ShowCreateObject {
2191    Event,
2192    Function,
2193    Procedure,
2194    Table,
2195    Trigger,
2196    View,
2197}
2198
2199impl fmt::Display for ShowCreateObject {
2200    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2201        match self {
2202            ShowCreateObject::Event => f.write_str("EVENT"),
2203            ShowCreateObject::Function => f.write_str("FUNCTION"),
2204            ShowCreateObject::Procedure => f.write_str("PROCEDURE"),
2205            ShowCreateObject::Table => f.write_str("TABLE"),
2206            ShowCreateObject::Trigger => f.write_str("TRIGGER"),
2207            ShowCreateObject::View => f.write_str("VIEW"),
2208        }
2209    }
2210}
2211
2212#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2213#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2214#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2215pub enum CommentObject {
2216    Column,
2217    Table,
2218    Extension,
2219    Schema,
2220    Database,
2221    User,
2222    Role,
2223}
2224
2225impl fmt::Display for CommentObject {
2226    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2227        match self {
2228            CommentObject::Column => f.write_str("COLUMN"),
2229            CommentObject::Table => f.write_str("TABLE"),
2230            CommentObject::Extension => f.write_str("EXTENSION"),
2231            CommentObject::Schema => f.write_str("SCHEMA"),
2232            CommentObject::Database => f.write_str("DATABASE"),
2233            CommentObject::User => f.write_str("USER"),
2234            CommentObject::Role => f.write_str("ROLE"),
2235        }
2236    }
2237}
2238
2239#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2240#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2241#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2242pub enum Password {
2243    Password(Expr),
2244    NullPassword,
2245}
2246
2247/// A `CASE` statement.
2248///
2249/// Examples:
2250/// ```sql
2251/// CASE
2252///     WHEN EXISTS(SELECT 1)
2253///         THEN SELECT 1 FROM T;
2254///     WHEN EXISTS(SELECT 2)
2255///         THEN SELECT 1 FROM U;
2256///     ELSE
2257///         SELECT 1 FROM V;
2258/// END CASE;
2259/// ```
2260///
2261/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#case_search_expression)
2262/// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/case)
2263#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2264#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2265#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2266pub struct CaseStatement {
2267    /// The `CASE` token that starts the statement.
2268    pub case_token: AttachedToken,
2269    pub match_expr: Option<Expr>,
2270    pub when_blocks: Vec<ConditionalStatementBlock>,
2271    pub else_block: Option<ConditionalStatementBlock>,
2272    /// The last token of the statement (`END` or `CASE`).
2273    pub end_case_token: AttachedToken,
2274}
2275
2276impl fmt::Display for CaseStatement {
2277    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2278        let CaseStatement {
2279            case_token: _,
2280            match_expr,
2281            when_blocks,
2282            else_block,
2283            end_case_token: AttachedToken(end),
2284        } = self;
2285
2286        write!(f, "CASE")?;
2287
2288        if let Some(expr) = match_expr {
2289            write!(f, " {expr}")?;
2290        }
2291
2292        if !when_blocks.is_empty() {
2293            write!(f, " {}", display_separated(when_blocks, " "))?;
2294        }
2295
2296        if let Some(else_block) = else_block {
2297            write!(f, " {else_block}")?;
2298        }
2299
2300        write!(f, " END")?;
2301
2302        if let Token::Word(w) = &end.token {
2303            if w.keyword == Keyword::CASE {
2304                write!(f, " CASE")?;
2305            }
2306        }
2307
2308        Ok(())
2309    }
2310}
2311
2312/// An `IF` statement.
2313///
2314/// Example (BigQuery or Snowflake):
2315/// ```sql
2316/// IF TRUE THEN
2317///     SELECT 1;
2318///     SELECT 2;
2319/// ELSEIF TRUE THEN
2320///     SELECT 3;
2321/// ELSE
2322///     SELECT 4;
2323/// END IF
2324/// ```
2325/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#if)
2326/// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/if)
2327///
2328/// Example (MSSQL):
2329/// ```sql
2330/// IF 1=1 SELECT 1 ELSE SELECT 2
2331/// ```
2332/// [MSSQL](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/if-else-transact-sql?view=sql-server-ver16)
2333#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2334#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2335#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2336pub struct IfStatement {
2337    pub if_block: ConditionalStatementBlock,
2338    pub elseif_blocks: Vec<ConditionalStatementBlock>,
2339    pub else_block: Option<ConditionalStatementBlock>,
2340    pub end_token: Option<AttachedToken>,
2341}
2342
2343impl fmt::Display for IfStatement {
2344    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2345        let IfStatement {
2346            if_block,
2347            elseif_blocks,
2348            else_block,
2349            end_token,
2350        } = self;
2351
2352        write!(f, "{if_block}")?;
2353
2354        for elseif_block in elseif_blocks {
2355            write!(f, " {elseif_block}")?;
2356        }
2357
2358        if let Some(else_block) = else_block {
2359            write!(f, " {else_block}")?;
2360        }
2361
2362        if let Some(AttachedToken(end_token)) = end_token {
2363            write!(f, " END {end_token}")?;
2364        }
2365
2366        Ok(())
2367    }
2368}
2369
2370/// A `WHILE` statement.
2371///
2372/// Example:
2373/// ```sql
2374/// WHILE @@FETCH_STATUS = 0
2375/// BEGIN
2376///    FETCH NEXT FROM c1 INTO @var1, @var2;
2377/// END
2378/// ```
2379///
2380/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/while-transact-sql)
2381#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2382#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2383#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2384pub struct WhileStatement {
2385    pub while_block: ConditionalStatementBlock,
2386}
2387
2388impl fmt::Display for WhileStatement {
2389    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2390        let WhileStatement { while_block } = self;
2391        write!(f, "{while_block}")?;
2392        Ok(())
2393    }
2394}
2395
2396/// A block within a [Statement::Case] or [Statement::If] or [Statement::While]-like statement
2397///
2398/// Example 1:
2399/// ```sql
2400/// WHEN EXISTS(SELECT 1) THEN SELECT 1;
2401/// ```
2402///
2403/// Example 2:
2404/// ```sql
2405/// IF TRUE THEN SELECT 1; SELECT 2;
2406/// ```
2407///
2408/// Example 3:
2409/// ```sql
2410/// ELSE SELECT 1; SELECT 2;
2411/// ```
2412///
2413/// Example 4:
2414/// ```sql
2415/// WHILE @@FETCH_STATUS = 0
2416/// BEGIN
2417///    FETCH NEXT FROM c1 INTO @var1, @var2;
2418/// END
2419/// ```
2420#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2421#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2422#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2423pub struct ConditionalStatementBlock {
2424    pub start_token: AttachedToken,
2425    pub condition: Option<Expr>,
2426    pub then_token: Option<AttachedToken>,
2427    pub conditional_statements: ConditionalStatements,
2428}
2429
2430impl ConditionalStatementBlock {
2431    pub fn statements(&self) -> &Vec<Statement> {
2432        self.conditional_statements.statements()
2433    }
2434}
2435
2436impl fmt::Display for ConditionalStatementBlock {
2437    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2438        let ConditionalStatementBlock {
2439            start_token: AttachedToken(start_token),
2440            condition,
2441            then_token,
2442            conditional_statements,
2443        } = self;
2444
2445        write!(f, "{start_token}")?;
2446
2447        if let Some(condition) = condition {
2448            write!(f, " {condition}")?;
2449        }
2450
2451        if then_token.is_some() {
2452            write!(f, " THEN")?;
2453        }
2454
2455        if !conditional_statements.statements().is_empty() {
2456            write!(f, " {conditional_statements}")?;
2457        }
2458
2459        Ok(())
2460    }
2461}
2462
2463/// A list of statements in a [ConditionalStatementBlock].
2464#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2465#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2466#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2467pub enum ConditionalStatements {
2468    /// SELECT 1; SELECT 2; SELECT 3; ...
2469    Sequence { statements: Vec<Statement> },
2470    /// BEGIN SELECT 1; SELECT 2; SELECT 3; ... END
2471    BeginEnd(BeginEndStatements),
2472}
2473
2474impl ConditionalStatements {
2475    pub fn statements(&self) -> &Vec<Statement> {
2476        match self {
2477            ConditionalStatements::Sequence { statements } => statements,
2478            ConditionalStatements::BeginEnd(bes) => &bes.statements,
2479        }
2480    }
2481}
2482
2483impl fmt::Display for ConditionalStatements {
2484    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2485        match self {
2486            ConditionalStatements::Sequence { statements } => {
2487                if !statements.is_empty() {
2488                    format_statement_list(f, statements)?;
2489                }
2490                Ok(())
2491            }
2492            ConditionalStatements::BeginEnd(bes) => write!(f, "{bes}"),
2493        }
2494    }
2495}
2496
2497/// Represents a list of statements enclosed within `BEGIN` and `END` keywords.
2498/// Example:
2499/// ```sql
2500/// BEGIN
2501///     SELECT 1;
2502///     SELECT 2;
2503/// END
2504/// ```
2505#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2506#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2507#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2508pub struct BeginEndStatements {
2509    pub begin_token: AttachedToken,
2510    pub statements: Vec<Statement>,
2511    pub end_token: AttachedToken,
2512}
2513
2514impl fmt::Display for BeginEndStatements {
2515    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2516        let BeginEndStatements {
2517            begin_token: AttachedToken(begin_token),
2518            statements,
2519            end_token: AttachedToken(end_token),
2520        } = self;
2521
2522        if begin_token.token != Token::EOF {
2523            write!(f, "{begin_token} ")?;
2524        }
2525        if !statements.is_empty() {
2526            format_statement_list(f, statements)?;
2527        }
2528        if end_token.token != Token::EOF {
2529            write!(f, " {end_token}")?;
2530        }
2531        Ok(())
2532    }
2533}
2534
2535/// A `RAISE` statement.
2536///
2537/// Examples:
2538/// ```sql
2539/// RAISE USING MESSAGE = 'error';
2540///
2541/// RAISE myerror;
2542/// ```
2543///
2544/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#raise)
2545/// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/raise)
2546#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2547#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2548#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2549pub struct RaiseStatement {
2550    pub value: Option<RaiseStatementValue>,
2551}
2552
2553impl fmt::Display for RaiseStatement {
2554    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2555        let RaiseStatement { value } = self;
2556
2557        write!(f, "RAISE")?;
2558        if let Some(value) = value {
2559            write!(f, " {value}")?;
2560        }
2561
2562        Ok(())
2563    }
2564}
2565
2566/// Represents the error value of a [RaiseStatement].
2567#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2568#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2569#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2570pub enum RaiseStatementValue {
2571    /// `RAISE USING MESSAGE = 'error'`
2572    UsingMessage(Expr),
2573    /// `RAISE myerror`
2574    Expr(Expr),
2575}
2576
2577impl fmt::Display for RaiseStatementValue {
2578    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2579        match self {
2580            RaiseStatementValue::Expr(expr) => write!(f, "{expr}"),
2581            RaiseStatementValue::UsingMessage(expr) => write!(f, "USING MESSAGE = {expr}"),
2582        }
2583    }
2584}
2585
2586/// Represents an expression assignment within a variable `DECLARE` statement.
2587///
2588/// Examples:
2589/// ```sql
2590/// DECLARE variable_name := 42
2591/// DECLARE variable_name DEFAULT 42
2592/// ```
2593#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2594#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2595#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2596pub enum DeclareAssignment {
2597    /// Plain expression specified.
2598    Expr(Box<Expr>),
2599
2600    /// Expression assigned via the `DEFAULT` keyword
2601    Default(Box<Expr>),
2602
2603    /// Expression assigned via the `:=` syntax
2604    ///
2605    /// Example:
2606    /// ```sql
2607    /// DECLARE variable_name := 42;
2608    /// ```
2609    DuckAssignment(Box<Expr>),
2610
2611    /// Expression via the `FOR` keyword
2612    ///
2613    /// Example:
2614    /// ```sql
2615    /// DECLARE c1 CURSOR FOR res
2616    /// ```
2617    For(Box<Expr>),
2618
2619    /// Expression via the `=` syntax.
2620    ///
2621    /// Example:
2622    /// ```sql
2623    /// DECLARE @variable AS INT = 100
2624    /// ```
2625    MsSqlAssignment(Box<Expr>),
2626}
2627
2628impl fmt::Display for DeclareAssignment {
2629    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2630        match self {
2631            DeclareAssignment::Expr(expr) => {
2632                write!(f, "{expr}")
2633            }
2634            DeclareAssignment::Default(expr) => {
2635                write!(f, "DEFAULT {expr}")
2636            }
2637            DeclareAssignment::DuckAssignment(expr) => {
2638                write!(f, ":= {expr}")
2639            }
2640            DeclareAssignment::MsSqlAssignment(expr) => {
2641                write!(f, "= {expr}")
2642            }
2643            DeclareAssignment::For(expr) => {
2644                write!(f, "FOR {expr}")
2645            }
2646        }
2647    }
2648}
2649
2650/// Represents the type of a `DECLARE` statement.
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 enum DeclareType {
2655    /// Cursor variable type. e.g. [Snowflake] [PostgreSQL] [MsSql]
2656    ///
2657    /// [Snowflake]: https://docs.snowflake.com/en/developer-guide/snowflake-scripting/cursors#declaring-a-cursor
2658    /// [PostgreSQL]: https://www.postgresql.org/docs/current/plpgsql-cursors.html
2659    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-cursor-transact-sql
2660    Cursor,
2661
2662    /// Result set variable type. [Snowflake]
2663    ///
2664    /// Syntax:
2665    /// ```text
2666    /// <resultset_name> RESULTSET [ { DEFAULT | := } ( <query> ) ] ;
2667    /// ```
2668    /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare#resultset-declaration-syntax
2669    ResultSet,
2670
2671    /// Exception declaration syntax. [Snowflake]
2672    ///
2673    /// Syntax:
2674    /// ```text
2675    /// <exception_name> EXCEPTION [ ( <exception_number> , '<exception_message>' ) ] ;
2676    /// ```
2677    /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare#exception-declaration-syntax
2678    Exception,
2679}
2680
2681impl fmt::Display for DeclareType {
2682    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2683        match self {
2684            DeclareType::Cursor => {
2685                write!(f, "CURSOR")
2686            }
2687            DeclareType::ResultSet => {
2688                write!(f, "RESULTSET")
2689            }
2690            DeclareType::Exception => {
2691                write!(f, "EXCEPTION")
2692            }
2693        }
2694    }
2695}
2696
2697/// A `DECLARE` statement.
2698/// [PostgreSQL] [Snowflake] [BigQuery]
2699///
2700/// Examples:
2701/// ```sql
2702/// DECLARE variable_name := 42
2703/// DECLARE liahona CURSOR FOR SELECT * FROM films;
2704/// ```
2705///
2706/// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-declare.html
2707/// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare
2708/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#declare
2709#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2710#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2711#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2712pub struct Declare {
2713    /// The name(s) being declared.
2714    /// Example: `DECLARE a, b, c DEFAULT 42;
2715    pub names: Vec<Ident>,
2716    /// Data-type assigned to the declared variable.
2717    /// Example: `DECLARE x INT64 DEFAULT 42;
2718    pub data_type: Option<DataType>,
2719    /// Expression being assigned to the declared variable.
2720    pub assignment: Option<DeclareAssignment>,
2721    /// Represents the type of the declared variable.
2722    pub declare_type: Option<DeclareType>,
2723    /// Causes the cursor to return data in binary rather than in text format.
2724    pub binary: Option<bool>,
2725    /// None = Not specified
2726    /// Some(true) = INSENSITIVE
2727    /// Some(false) = ASENSITIVE
2728    pub sensitive: Option<bool>,
2729    /// None = Not specified
2730    /// Some(true) = SCROLL
2731    /// Some(false) = NO SCROLL
2732    pub scroll: Option<bool>,
2733    /// None = Not specified
2734    /// Some(true) = WITH HOLD, specifies that the cursor can continue to be used after the transaction that created it successfully commits
2735    /// Some(false) = WITHOUT HOLD, specifies that the cursor cannot be used outside of the transaction that created it
2736    pub hold: Option<bool>,
2737    /// `FOR <query>` clause in a CURSOR declaration.
2738    pub for_query: Option<Box<Query>>,
2739}
2740
2741impl fmt::Display for Declare {
2742    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2743        let Declare {
2744            names,
2745            data_type,
2746            assignment,
2747            declare_type,
2748            binary,
2749            sensitive,
2750            scroll,
2751            hold,
2752            for_query,
2753        } = self;
2754        write!(f, "{}", display_comma_separated(names))?;
2755
2756        if let Some(true) = binary {
2757            write!(f, " BINARY")?;
2758        }
2759
2760        if let Some(sensitive) = sensitive {
2761            if *sensitive {
2762                write!(f, " INSENSITIVE")?;
2763            } else {
2764                write!(f, " ASENSITIVE")?;
2765            }
2766        }
2767
2768        if let Some(scroll) = scroll {
2769            if *scroll {
2770                write!(f, " SCROLL")?;
2771            } else {
2772                write!(f, " NO SCROLL")?;
2773            }
2774        }
2775
2776        if let Some(declare_type) = declare_type {
2777            write!(f, " {declare_type}")?;
2778        }
2779
2780        if let Some(hold) = hold {
2781            if *hold {
2782                write!(f, " WITH HOLD")?;
2783            } else {
2784                write!(f, " WITHOUT HOLD")?;
2785            }
2786        }
2787
2788        if let Some(query) = for_query {
2789            write!(f, " FOR {query}")?;
2790        }
2791
2792        if let Some(data_type) = data_type {
2793            write!(f, " {data_type}")?;
2794        }
2795
2796        if let Some(expr) = assignment {
2797            write!(f, " {expr}")?;
2798        }
2799        Ok(())
2800    }
2801}
2802
2803/// Sql options of a `CREATE TABLE` statement.
2804#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2805#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2806#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2807pub enum CreateTableOptions {
2808    #[default]
2809    None,
2810    /// Options specified using the `WITH` keyword.
2811    /// e.g. `WITH (description = "123")`
2812    ///
2813    /// <https://www.postgresql.org/docs/current/sql-createtable.html>
2814    ///
2815    /// MSSQL supports more specific options that's not only key-value pairs.
2816    ///
2817    /// WITH (
2818    ///     DISTRIBUTION = ROUND_ROBIN,
2819    ///     CLUSTERED INDEX (column_a DESC, column_b)
2820    /// )
2821    ///
2822    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#syntax>
2823    With(Vec<SqlOption>),
2824    /// Options specified using the `OPTIONS` keyword.
2825    /// e.g. `OPTIONS(description = "123")`
2826    ///
2827    /// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list>
2828    Options(Vec<SqlOption>),
2829
2830    /// Plain options, options which are not part on any declerative statement e.g. WITH/OPTIONS/...
2831    /// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
2832    Plain(Vec<SqlOption>),
2833
2834    TableProperties(Vec<SqlOption>),
2835}
2836
2837impl fmt::Display for CreateTableOptions {
2838    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2839        match self {
2840            CreateTableOptions::With(with_options) => {
2841                write!(f, "WITH ({})", display_comma_separated(with_options))
2842            }
2843            CreateTableOptions::Options(options) => {
2844                write!(f, "OPTIONS({})", display_comma_separated(options))
2845            }
2846            CreateTableOptions::TableProperties(options) => {
2847                write!(f, "TBLPROPERTIES ({})", display_comma_separated(options))
2848            }
2849            CreateTableOptions::Plain(options) => {
2850                write!(f, "{}", display_separated(options, " "))
2851            }
2852            CreateTableOptions::None => Ok(()),
2853        }
2854    }
2855}
2856
2857/// A `FROM` clause within a `DELETE` statement.
2858///
2859/// Syntax
2860/// ```sql
2861/// [FROM] table
2862/// ```
2863#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2864#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2865#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2866pub enum FromTable {
2867    /// An explicit `FROM` keyword was specified.
2868    WithFromKeyword(Vec<TableWithJoins>),
2869    /// BigQuery: `FROM` keyword was omitted.
2870    /// <https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#delete_statement>
2871    WithoutKeyword(Vec<TableWithJoins>),
2872}
2873impl Display for FromTable {
2874    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2875        match self {
2876            FromTable::WithFromKeyword(tables) => {
2877                write!(f, "FROM {}", display_comma_separated(tables))
2878            }
2879            FromTable::WithoutKeyword(tables) => {
2880                write!(f, "{}", display_comma_separated(tables))
2881            }
2882        }
2883    }
2884}
2885
2886/// Policy type for a `CREATE POLICY` statement.
2887/// ```sql
2888/// AS [ PERMISSIVE | RESTRICTIVE ]
2889/// ```
2890/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)
2891#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2892#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2893#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2894pub enum CreatePolicyType {
2895    Permissive,
2896    Restrictive,
2897}
2898
2899/// Policy command for a `CREATE POLICY` statement.
2900/// ```sql
2901/// FOR [ALL | SELECT | INSERT | UPDATE | DELETE]
2902/// ```
2903/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)
2904#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2905#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2906#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2907pub enum CreatePolicyCommand {
2908    All,
2909    Select,
2910    Insert,
2911    Update,
2912    Delete,
2913}
2914
2915#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2916#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2917#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2918pub enum Set {
2919    /// SQL Standard-style
2920    /// SET a = 1;
2921    SingleAssignment {
2922        scope: Option<ContextModifier>,
2923        hivevar: bool,
2924        variable: ObjectName,
2925        values: Vec<Expr>,
2926    },
2927    /// Snowflake-style
2928    /// SET (a, b, ..) = (1, 2, ..);
2929    ParenthesizedAssignments {
2930        variables: Vec<ObjectName>,
2931        values: Vec<Expr>,
2932    },
2933    /// MySQL-style
2934    /// SET a = 1, b = 2, ..;
2935    MultipleAssignments { assignments: Vec<SetAssignment> },
2936    /// Session authorization for Postgres/Redshift
2937    ///
2938    /// ```sql
2939    /// SET SESSION AUTHORIZATION { user_name | DEFAULT }
2940    /// ```
2941    ///
2942    /// See <https://www.postgresql.org/docs/current/sql-set-session-authorization.html>
2943    /// See <https://docs.aws.amazon.com/redshift/latest/dg/r_SET_SESSION_AUTHORIZATION.html>
2944    SetSessionAuthorization(SetSessionAuthorizationParam),
2945    /// MS-SQL session
2946    ///
2947    /// See <https://learn.microsoft.com/en-us/sql/t-sql/statements/set-statements-transact-sql>
2948    SetSessionParam(SetSessionParamKind),
2949    /// ```sql
2950    /// SET [ SESSION | LOCAL ] ROLE role_name
2951    /// ```
2952    ///
2953    /// Sets session state. Examples: [ANSI][1], [Postgresql][2], [MySQL][3], and [Oracle][4]
2954    ///
2955    /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#set-role-statement
2956    /// [2]: https://www.postgresql.org/docs/14/sql-set-role.html
2957    /// [3]: https://dev.mysql.com/doc/refman/8.0/en/set-role.html
2958    /// [4]: https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_10004.htm
2959    SetRole {
2960        /// Non-ANSI optional identifier to inform if the role is defined inside the current session (`SESSION`) or transaction (`LOCAL`).
2961        context_modifier: Option<ContextModifier>,
2962        /// Role name. If NONE is specified, then the current role name is removed.
2963        role_name: Option<Ident>,
2964    },
2965    /// ```sql
2966    /// SET TIME ZONE <value>
2967    /// ```
2968    ///
2969    /// Note: this is a PostgreSQL-specific statements
2970    /// `SET TIME ZONE <value>` is an alias for `SET timezone TO <value>` in PostgreSQL
2971    /// However, we allow it for all dialects.
2972    SetTimeZone { local: bool, value: Expr },
2973    /// ```sql
2974    /// SET NAMES 'charset_name' [COLLATE 'collation_name']
2975    /// ```
2976    SetNames {
2977        charset_name: Ident,
2978        collation_name: Option<String>,
2979    },
2980    /// ```sql
2981    /// SET NAMES DEFAULT
2982    /// ```
2983    ///
2984    /// Note: this is a MySQL-specific statement.
2985    SetNamesDefault {},
2986    /// ```sql
2987    /// SET TRANSACTION ...
2988    /// ```
2989    SetTransaction {
2990        modes: Vec<TransactionMode>,
2991        snapshot: Option<Value>,
2992        session: bool,
2993    },
2994}
2995
2996impl Display for Set {
2997    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2998        match self {
2999            Self::ParenthesizedAssignments { variables, values } => write!(
3000                f,
3001                "SET ({}) = ({})",
3002                display_comma_separated(variables),
3003                display_comma_separated(values)
3004            ),
3005            Self::MultipleAssignments { assignments } => {
3006                write!(f, "SET {}", display_comma_separated(assignments))
3007            }
3008            Self::SetRole {
3009                context_modifier,
3010                role_name,
3011            } => {
3012                let role_name = role_name.clone().unwrap_or_else(|| Ident::new("NONE"));
3013                write!(
3014                    f,
3015                    "SET {modifier}ROLE {role_name}",
3016                    modifier = context_modifier.map(|m| format!("{m}")).unwrap_or_default()
3017                )
3018            }
3019            Self::SetSessionAuthorization(kind) => write!(f, "SET SESSION AUTHORIZATION {kind}"),
3020            Self::SetSessionParam(kind) => write!(f, "SET {kind}"),
3021            Self::SetTransaction {
3022                modes,
3023                snapshot,
3024                session,
3025            } => {
3026                if *session {
3027                    write!(f, "SET SESSION CHARACTERISTICS AS TRANSACTION")?;
3028                } else {
3029                    write!(f, "SET TRANSACTION")?;
3030                }
3031                if !modes.is_empty() {
3032                    write!(f, " {}", display_comma_separated(modes))?;
3033                }
3034                if let Some(snapshot_id) = snapshot {
3035                    write!(f, " SNAPSHOT {snapshot_id}")?;
3036                }
3037                Ok(())
3038            }
3039            Self::SetTimeZone { local, value } => {
3040                f.write_str("SET ")?;
3041                if *local {
3042                    f.write_str("LOCAL ")?;
3043                }
3044                write!(f, "TIME ZONE {value}")
3045            }
3046            Self::SetNames {
3047                charset_name,
3048                collation_name,
3049            } => {
3050                write!(f, "SET NAMES {charset_name}")?;
3051
3052                if let Some(collation) = collation_name {
3053                    f.write_str(" COLLATE ")?;
3054                    f.write_str(collation)?;
3055                };
3056
3057                Ok(())
3058            }
3059            Self::SetNamesDefault {} => {
3060                f.write_str("SET NAMES DEFAULT")?;
3061
3062                Ok(())
3063            }
3064            Set::SingleAssignment {
3065                scope,
3066                hivevar,
3067                variable,
3068                values,
3069            } => {
3070                write!(
3071                    f,
3072                    "SET {}{}{} = {}",
3073                    scope.map(|s| format!("{s}")).unwrap_or_default(),
3074                    if *hivevar { "HIVEVAR:" } else { "" },
3075                    variable,
3076                    display_comma_separated(values)
3077                )
3078            }
3079        }
3080    }
3081}
3082
3083/// A representation of a `WHEN` arm with all the identifiers catched and the statements to execute
3084/// for the arm.
3085///
3086/// Snowflake: <https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
3087/// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
3088#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3089#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3090#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3091pub struct ExceptionWhen {
3092    pub idents: Vec<Ident>,
3093    pub statements: Vec<Statement>,
3094}
3095
3096impl Display for ExceptionWhen {
3097    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3098        write!(
3099            f,
3100            "WHEN {idents} THEN",
3101            idents = display_separated(&self.idents, " OR ")
3102        )?;
3103
3104        if !self.statements.is_empty() {
3105            write!(f, " ")?;
3106            format_statement_list(f, &self.statements)?;
3107        }
3108
3109        Ok(())
3110    }
3111}
3112
3113/// ANALYZE TABLE statement (Hive-specific)
3114#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3115#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3116#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3117pub struct Analyze {
3118    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3119    pub table_name: ObjectName,
3120    pub partitions: Option<Vec<Expr>>,
3121    pub for_columns: bool,
3122    pub columns: Vec<Ident>,
3123    pub cache_metadata: bool,
3124    pub noscan: bool,
3125    pub compute_statistics: bool,
3126    pub has_table_keyword: bool,
3127}
3128
3129impl fmt::Display for Analyze {
3130    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3131        write!(
3132            f,
3133            "ANALYZE{}{table_name}",
3134            if self.has_table_keyword {
3135                " TABLE "
3136            } else {
3137                " "
3138            },
3139            table_name = self.table_name
3140        )?;
3141        if let Some(ref parts) = self.partitions {
3142            if !parts.is_empty() {
3143                write!(f, " PARTITION ({})", display_comma_separated(parts))?;
3144            }
3145        }
3146
3147        if self.compute_statistics {
3148            write!(f, " COMPUTE STATISTICS")?;
3149        }
3150        if self.noscan {
3151            write!(f, " NOSCAN")?;
3152        }
3153        if self.cache_metadata {
3154            write!(f, " CACHE METADATA")?;
3155        }
3156        if self.for_columns {
3157            write!(f, " FOR COLUMNS")?;
3158            if !self.columns.is_empty() {
3159                write!(f, " {}", display_comma_separated(&self.columns))?;
3160            }
3161        }
3162        Ok(())
3163    }
3164}
3165
3166/// A top-level statement (SELECT, INSERT, CREATE, etc.)
3167#[allow(clippy::large_enum_variant)]
3168#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3170#[cfg_attr(
3171    feature = "visitor",
3172    derive(Visit, VisitMut),
3173    visit(with = "visit_statement")
3174)]
3175pub enum Statement {
3176    /// ```sql
3177    /// ANALYZE
3178    /// ```
3179    /// Analyze (Hive)
3180    Analyze(Analyze),
3181    Set(Set),
3182    /// ```sql
3183    /// TRUNCATE
3184    /// ```
3185    /// Truncate (Hive)
3186    Truncate(Truncate),
3187    /// ```sql
3188    /// MSCK
3189    /// ```
3190    /// Msck (Hive)
3191    Msck(Msck),
3192    /// ```sql
3193    /// SELECT
3194    /// ```
3195    Query(Box<Query>),
3196    /// ```sql
3197    /// INSERT
3198    /// ```
3199    Insert(Insert),
3200    /// ```sql
3201    /// INSTALL
3202    /// ```
3203    Install {
3204        /// Only for DuckDB
3205        extension_name: Ident,
3206    },
3207    /// ```sql
3208    /// LOAD
3209    /// ```
3210    Load {
3211        /// Only for DuckDB
3212        extension_name: Ident,
3213    },
3214    // TODO: Support ROW FORMAT
3215    Directory {
3216        overwrite: bool,
3217        local: bool,
3218        path: String,
3219        file_format: Option<FileFormat>,
3220        source: Box<Query>,
3221    },
3222    /// A `CASE` statement.
3223    Case(CaseStatement),
3224    /// An `IF` statement.
3225    If(IfStatement),
3226    /// A `WHILE` statement.
3227    While(WhileStatement),
3228    /// A `RAISE` statement.
3229    Raise(RaiseStatement),
3230    /// ```sql
3231    /// CALL <function>
3232    /// ```
3233    Call(Function),
3234    /// ```sql
3235    /// COPY [TO | FROM] ...
3236    /// ```
3237    Copy {
3238        /// The source of 'COPY TO', or the target of 'COPY FROM'
3239        source: CopySource,
3240        /// If true, is a 'COPY TO' statement. If false is a 'COPY FROM'
3241        to: bool,
3242        /// The target of 'COPY TO', or the source of 'COPY FROM'
3243        target: CopyTarget,
3244        /// WITH options (from PostgreSQL version 9.0)
3245        options: Vec<CopyOption>,
3246        /// WITH options (before PostgreSQL version 9.0)
3247        legacy_options: Vec<CopyLegacyOption>,
3248        /// VALUES a vector of values to be copied
3249        values: Vec<Option<String>>,
3250    },
3251    /// ```sql
3252    /// COPY INTO <table> | <location>
3253    /// ```
3254    /// See:
3255    /// <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table>
3256    /// <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location>
3257    ///
3258    /// Copy Into syntax available for Snowflake is different than the one implemented in
3259    /// Postgres. Although they share common prefix, it is reasonable to implement them
3260    /// in different enums. This can be refactored later once custom dialects
3261    /// are allowed to have custom Statements.
3262    CopyIntoSnowflake {
3263        kind: CopyIntoSnowflakeKind,
3264        into: ObjectName,
3265        into_columns: Option<Vec<Ident>>,
3266        from_obj: Option<ObjectName>,
3267        from_obj_alias: Option<Ident>,
3268        stage_params: StageParamsObject,
3269        from_transformations: Option<Vec<StageLoadSelectItemKind>>,
3270        from_query: Option<Box<Query>>,
3271        files: Option<Vec<String>>,
3272        pattern: Option<String>,
3273        file_format: KeyValueOptions,
3274        copy_options: KeyValueOptions,
3275        validation_mode: Option<String>,
3276        partition: Option<Box<Expr>>,
3277    },
3278    /// ```sql
3279    /// OPEN cursor_name
3280    /// ```
3281    /// Opens a cursor.
3282    Open(OpenStatement),
3283    /// ```sql
3284    /// CLOSE
3285    /// ```
3286    /// Closes the portal underlying an open cursor.
3287    Close {
3288        /// Cursor name
3289        cursor: CloseCursor,
3290    },
3291    /// ```sql
3292    /// UPDATE
3293    /// ```
3294    Update(Update),
3295    /// ```sql
3296    /// DELETE
3297    /// ```
3298    Delete(Delete),
3299    /// ```sql
3300    /// CREATE VIEW
3301    /// ```
3302    CreateView(CreateView),
3303    /// ```sql
3304    /// CREATE TABLE
3305    /// ```
3306    CreateTable(CreateTable),
3307    /// ```sql
3308    /// CREATE VIRTUAL TABLE .. USING <module_name> (<module_args>)`
3309    /// ```
3310    /// Sqlite specific statement
3311    CreateVirtualTable {
3312        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3313        name: ObjectName,
3314        if_not_exists: bool,
3315        module_name: Ident,
3316        module_args: Vec<Ident>,
3317    },
3318    /// ```sql
3319    /// `CREATE INDEX`
3320    /// ```
3321    CreateIndex(CreateIndex),
3322    /// ```sql
3323    /// CREATE ROLE
3324    /// ```
3325    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createrole.html)
3326    CreateRole(CreateRole),
3327    /// ```sql
3328    /// CREATE SECRET
3329    /// ```
3330    /// See [DuckDB](https://duckdb.org/docs/sql/statements/create_secret.html)
3331    CreateSecret {
3332        or_replace: bool,
3333        temporary: Option<bool>,
3334        if_not_exists: bool,
3335        name: Option<Ident>,
3336        storage_specifier: Option<Ident>,
3337        secret_type: Ident,
3338        options: Vec<SecretOption>,
3339    },
3340    /// A `CREATE SERVER` statement.
3341    CreateServer(CreateServerStatement),
3342    /// ```sql
3343    /// CREATE POLICY
3344    /// ```
3345    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)
3346    CreatePolicy {
3347        name: Ident,
3348        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3349        table_name: ObjectName,
3350        policy_type: Option<CreatePolicyType>,
3351        command: Option<CreatePolicyCommand>,
3352        to: Option<Vec<Owner>>,
3353        using: Option<Expr>,
3354        with_check: Option<Expr>,
3355    },
3356    /// ```sql
3357    /// CREATE CONNECTOR
3358    /// ```
3359    /// See [Hive](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-CreateDataConnectorCreateConnector)
3360    CreateConnector(CreateConnector),
3361    /// ```sql
3362    /// CREATE OPERATOR
3363    /// ```
3364    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createoperator.html)
3365    CreateOperator(CreateOperator),
3366    /// ```sql
3367    /// CREATE OPERATOR FAMILY
3368    /// ```
3369    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopfamily.html)
3370    CreateOperatorFamily(CreateOperatorFamily),
3371    /// ```sql
3372    /// CREATE OPERATOR CLASS
3373    /// ```
3374    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopclass.html)
3375    CreateOperatorClass(CreateOperatorClass),
3376    /// ```sql
3377    /// ALTER TABLE
3378    /// ```
3379    AlterTable(AlterTable),
3380    /// ```sql
3381    /// ALTER SCHEMA
3382    /// ```
3383    /// See [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#alter_schema_collate_statement)
3384    AlterSchema(AlterSchema),
3385    /// ```sql
3386    /// ALTER INDEX
3387    /// ```
3388    AlterIndex {
3389        name: ObjectName,
3390        operation: AlterIndexOperation,
3391    },
3392    /// ```sql
3393    /// ALTER VIEW
3394    /// ```
3395    AlterView {
3396        /// View name
3397        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3398        name: ObjectName,
3399        columns: Vec<Ident>,
3400        query: Box<Query>,
3401        with_options: Vec<SqlOption>,
3402    },
3403    /// ```sql
3404    /// ALTER TYPE
3405    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-altertype.html)
3406    /// ```
3407    AlterType(AlterType),
3408    /// ```sql
3409    /// ALTER OPERATOR
3410    /// ```
3411    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteroperator.html)
3412    AlterOperator(AlterOperator),
3413    /// ```sql
3414    /// ALTER ROLE
3415    /// ```
3416    AlterRole {
3417        name: Ident,
3418        operation: AlterRoleOperation,
3419    },
3420    /// ```sql
3421    /// ALTER POLICY <NAME> ON <TABLE NAME> [<OPERATION>]
3422    /// ```
3423    /// (Postgresql-specific)
3424    AlterPolicy {
3425        name: Ident,
3426        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3427        table_name: ObjectName,
3428        operation: AlterPolicyOperation,
3429    },
3430    /// ```sql
3431    /// ALTER CONNECTOR connector_name SET DCPROPERTIES(property_name=property_value, ...);
3432    /// or
3433    /// ALTER CONNECTOR connector_name SET URL new_url;
3434    /// or
3435    /// ALTER CONNECTOR connector_name SET OWNER [USER|ROLE] user_or_role;
3436    /// ```
3437    /// (Hive-specific)
3438    AlterConnector {
3439        name: Ident,
3440        properties: Option<Vec<SqlOption>>,
3441        url: Option<String>,
3442        owner: Option<ddl::AlterConnectorOwner>,
3443    },
3444    /// ```sql
3445    /// ALTER SESSION SET sessionParam
3446    /// ALTER SESSION UNSET <param_name> [ , <param_name> , ... ]
3447    /// ```
3448    /// See <https://docs.snowflake.com/en/sql-reference/sql/alter-session>
3449    AlterSession {
3450        /// true is to set for the session parameters, false is to unset
3451        set: bool,
3452        /// The session parameters to set or unset
3453        session_params: KeyValueOptions,
3454    },
3455    /// ```sql
3456    /// ATTACH DATABASE 'path/to/file' AS alias
3457    /// ```
3458    /// (SQLite-specific)
3459    AttachDatabase {
3460        /// The name to bind to the newly attached database
3461        schema_name: Ident,
3462        /// An expression that indicates the path to the database file
3463        database_file_name: Expr,
3464        /// true if the syntax is 'ATTACH DATABASE', false if it's just 'ATTACH'
3465        database: bool,
3466    },
3467    /// (DuckDB-specific)
3468    /// ```sql
3469    /// ATTACH 'sqlite_file.db' AS sqlite_db (READ_ONLY, TYPE SQLITE);
3470    /// ```
3471    /// See <https://duckdb.org/docs/sql/statements/attach.html>
3472    AttachDuckDBDatabase {
3473        if_not_exists: bool,
3474        /// true if the syntax is 'ATTACH DATABASE', false if it's just 'ATTACH'
3475        database: bool,
3476        /// An expression that indicates the path to the database file
3477        database_path: Ident,
3478        database_alias: Option<Ident>,
3479        attach_options: Vec<AttachDuckDBDatabaseOption>,
3480    },
3481    /// (DuckDB-specific)
3482    /// ```sql
3483    /// DETACH db_alias;
3484    /// ```
3485    /// See <https://duckdb.org/docs/sql/statements/attach.html>
3486    DetachDuckDBDatabase {
3487        if_exists: bool,
3488        /// true if the syntax is 'DETACH DATABASE', false if it's just 'DETACH'
3489        database: bool,
3490        database_alias: Ident,
3491    },
3492    /// ```sql
3493    /// DROP [TABLE, VIEW, ...]
3494    /// ```
3495    Drop {
3496        /// The type of the object to drop: TABLE, VIEW, etc.
3497        object_type: ObjectType,
3498        /// An optional `IF EXISTS` clause. (Non-standard.)
3499        if_exists: bool,
3500        /// One or more objects to drop. (ANSI SQL requires exactly one.)
3501        names: Vec<ObjectName>,
3502        /// Whether `CASCADE` was specified. This will be `false` when
3503        /// `RESTRICT` or no drop behavior at all was specified.
3504        cascade: bool,
3505        /// Whether `RESTRICT` was specified. This will be `false` when
3506        /// `CASCADE` or no drop behavior at all was specified.
3507        restrict: bool,
3508        /// Hive allows you specify whether the table's stored data will be
3509        /// deleted along with the dropped table
3510        purge: bool,
3511        /// MySQL-specific "TEMPORARY" keyword
3512        temporary: bool,
3513        /// MySQL-specific drop index syntax, which requires table specification
3514        /// See <https://dev.mysql.com/doc/refman/8.4/en/drop-index.html>
3515        table: Option<ObjectName>,
3516    },
3517    /// ```sql
3518    /// DROP FUNCTION
3519    /// ```
3520    DropFunction(DropFunction),
3521    /// ```sql
3522    /// DROP DOMAIN
3523    /// ```
3524    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-dropdomain.html)
3525    ///
3526    /// DROP DOMAIN [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
3527    ///
3528    DropDomain(DropDomain),
3529    /// ```sql
3530    /// DROP PROCEDURE
3531    /// ```
3532    DropProcedure {
3533        if_exists: bool,
3534        /// One or more function to drop
3535        proc_desc: Vec<FunctionDesc>,
3536        /// `CASCADE` or `RESTRICT`
3537        drop_behavior: Option<DropBehavior>,
3538    },
3539    /// ```sql
3540    /// DROP SECRET
3541    /// ```
3542    DropSecret {
3543        if_exists: bool,
3544        temporary: Option<bool>,
3545        name: Ident,
3546        storage_specifier: Option<Ident>,
3547    },
3548    ///```sql
3549    /// DROP POLICY
3550    /// ```
3551    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-droppolicy.html)
3552    DropPolicy {
3553        if_exists: bool,
3554        name: Ident,
3555        table_name: ObjectName,
3556        drop_behavior: Option<DropBehavior>,
3557    },
3558    /// ```sql
3559    /// DROP CONNECTOR
3560    /// ```
3561    /// See [Hive](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-DropConnector)
3562    DropConnector {
3563        if_exists: bool,
3564        name: Ident,
3565    },
3566    /// ```sql
3567    /// DECLARE
3568    /// ```
3569    /// Declare Cursor Variables
3570    ///
3571    /// Note: this is a PostgreSQL-specific statement,
3572    /// but may also compatible with other SQL.
3573    Declare {
3574        stmts: Vec<Declare>,
3575    },
3576    /// ```sql
3577    /// CREATE EXTENSION [ IF NOT EXISTS ] extension_name
3578    ///     [ WITH ] [ SCHEMA schema_name ]
3579    ///              [ VERSION version ]
3580    ///              [ CASCADE ]
3581    /// ```
3582    ///
3583    /// Note: this is a PostgreSQL-specific statement,
3584    CreateExtension(CreateExtension),
3585    /// ```sql
3586    /// DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
3587    /// ```
3588    /// Note: this is a PostgreSQL-specific statement.
3589    /// <https://www.postgresql.org/docs/current/sql-dropextension.html>
3590    DropExtension(DropExtension),
3591    /// ```sql
3592    /// DROP OPERATOR [ IF EXISTS ] name ( { left_type | NONE } , right_type ) [, ...] [ CASCADE | RESTRICT ]
3593    /// ```
3594    /// Note: this is a PostgreSQL-specific statement.
3595    /// <https://www.postgresql.org/docs/current/sql-dropoperator.html>
3596    DropOperator(DropOperator),
3597    /// ```sql
3598    /// DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]
3599    /// ```
3600    /// Note: this is a PostgreSQL-specific statement.
3601    /// <https://www.postgresql.org/docs/current/sql-dropopfamily.html>
3602    DropOperatorFamily(DropOperatorFamily),
3603    /// ```sql
3604    /// DROP OPERATOR CLASS [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]
3605    /// ```
3606    /// Note: this is a PostgreSQL-specific statement.
3607    /// <https://www.postgresql.org/docs/current/sql-dropopclass.html>
3608    DropOperatorClass(DropOperatorClass),
3609    /// ```sql
3610    /// FETCH
3611    /// ```
3612    /// Retrieve rows from a query using a cursor
3613    ///
3614    /// Note: this is a PostgreSQL-specific statement,
3615    /// but may also compatible with other SQL.
3616    Fetch {
3617        /// Cursor name
3618        name: Ident,
3619        direction: FetchDirection,
3620        position: FetchPosition,
3621        /// Optional, It's possible to fetch rows form cursor to the table
3622        into: Option<ObjectName>,
3623    },
3624    /// ```sql
3625    /// FLUSH [NO_WRITE_TO_BINLOG | LOCAL] flush_option [, flush_option] ... | tables_option
3626    /// ```
3627    ///
3628    /// Note: this is a Mysql-specific statement,
3629    /// but may also compatible with other SQL.
3630    Flush {
3631        object_type: FlushType,
3632        location: Option<FlushLocation>,
3633        channel: Option<String>,
3634        read_lock: bool,
3635        export: bool,
3636        tables: Vec<ObjectName>,
3637    },
3638    /// ```sql
3639    /// DISCARD [ ALL | PLANS | SEQUENCES | TEMPORARY | TEMP ]
3640    /// ```
3641    ///
3642    /// Note: this is a PostgreSQL-specific statement,
3643    /// but may also compatible with other SQL.
3644    Discard {
3645        object_type: DiscardObject,
3646    },
3647    /// `SHOW FUNCTIONS`
3648    ///
3649    /// Note: this is a Presto-specific statement.
3650    ShowFunctions {
3651        filter: Option<ShowStatementFilter>,
3652    },
3653    /// ```sql
3654    /// SHOW <variable>
3655    /// ```
3656    ///
3657    /// Note: this is a PostgreSQL-specific statement.
3658    ShowVariable {
3659        variable: Vec<Ident>,
3660    },
3661    /// ```sql
3662    /// SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern' | WHERE expr]
3663    /// ```
3664    ///
3665    /// Note: this is a MySQL-specific statement.
3666    ShowStatus {
3667        filter: Option<ShowStatementFilter>,
3668        global: bool,
3669        session: bool,
3670    },
3671    /// ```sql
3672    /// SHOW VARIABLES
3673    /// ```
3674    ///
3675    /// Note: this is a MySQL-specific statement.
3676    ShowVariables {
3677        filter: Option<ShowStatementFilter>,
3678        global: bool,
3679        session: bool,
3680    },
3681    /// ```sql
3682    /// SHOW CREATE TABLE
3683    /// ```
3684    ///
3685    /// Note: this is a MySQL-specific statement.
3686    ShowCreate {
3687        obj_type: ShowCreateObject,
3688        obj_name: ObjectName,
3689    },
3690    /// ```sql
3691    /// SHOW COLUMNS
3692    /// ```
3693    ShowColumns {
3694        extended: bool,
3695        full: bool,
3696        show_options: ShowStatementOptions,
3697    },
3698    /// ```sql
3699    /// SHOW DATABASES
3700    /// ```
3701    ShowDatabases {
3702        terse: bool,
3703        history: bool,
3704        show_options: ShowStatementOptions,
3705    },
3706    /// ```sql
3707    /// SHOW SCHEMAS
3708    /// ```
3709    ShowSchemas {
3710        terse: bool,
3711        history: bool,
3712        show_options: ShowStatementOptions,
3713    },
3714    // ```sql
3715    // SHOW {CHARACTER SET | CHARSET}
3716    // ```
3717    // [MySQL]:
3718    // <https://dev.mysql.com/doc/refman/8.4/en/show.html#:~:text=SHOW%20%7BCHARACTER%20SET%20%7C%20CHARSET%7D%20%5Blike_or_where%5D>
3719    ShowCharset(ShowCharset),
3720    /// ```sql
3721    /// SHOW OBJECTS LIKE 'line%' IN mydb.public
3722    /// ```
3723    /// Snowflake-specific statement
3724    /// <https://docs.snowflake.com/en/sql-reference/sql/show-objects>
3725    ShowObjects(ShowObjects),
3726    /// ```sql
3727    /// SHOW TABLES
3728    /// ```
3729    ShowTables {
3730        terse: bool,
3731        history: bool,
3732        extended: bool,
3733        full: bool,
3734        external: bool,
3735        show_options: ShowStatementOptions,
3736    },
3737    /// ```sql
3738    /// SHOW VIEWS
3739    /// ```
3740    ShowViews {
3741        terse: bool,
3742        materialized: bool,
3743        show_options: ShowStatementOptions,
3744    },
3745    /// ```sql
3746    /// SHOW COLLATION
3747    /// ```
3748    ///
3749    /// Note: this is a MySQL-specific statement.
3750    ShowCollation {
3751        filter: Option<ShowStatementFilter>,
3752    },
3753    /// ```sql
3754    /// `USE ...`
3755    /// ```
3756    Use(Use),
3757    /// ```sql
3758    /// START  [ TRANSACTION | WORK ] | START TRANSACTION } ...
3759    /// ```
3760    /// If `begin` is false.
3761    ///
3762    /// ```sql
3763    /// `BEGIN  [ TRANSACTION | WORK ] | START TRANSACTION } ...`
3764    /// ```
3765    /// If `begin` is true
3766    StartTransaction {
3767        modes: Vec<TransactionMode>,
3768        begin: bool,
3769        transaction: Option<BeginTransactionKind>,
3770        modifier: Option<TransactionModifier>,
3771        /// List of statements belonging to the `BEGIN` block.
3772        /// Example:
3773        /// ```sql
3774        /// BEGIN
3775        ///     SELECT 1;
3776        ///     SELECT 2;
3777        /// END;
3778        /// ```
3779        statements: Vec<Statement>,
3780        /// Exception handling with exception clauses.
3781        /// Example:
3782        /// ```sql
3783        /// EXCEPTION
3784        ///     WHEN EXCEPTION_1 THEN
3785        ///         SELECT 2;
3786        ///     WHEN EXCEPTION_2 OR EXCEPTION_3 THEN
3787        ///         SELECT 3;
3788        ///     WHEN OTHER THEN
3789        ///         SELECT 4;
3790        /// ```
3791        /// <https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
3792        /// <https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
3793        exception: Option<Vec<ExceptionWhen>>,
3794        /// TRUE if the statement has an `END` keyword.
3795        has_end_keyword: bool,
3796    },
3797    /// ```sql
3798    /// COMMENT ON ...
3799    /// ```
3800    ///
3801    /// Note: this is a PostgreSQL-specific statement.
3802    Comment {
3803        object_type: CommentObject,
3804        object_name: ObjectName,
3805        comment: Option<String>,
3806        /// An optional `IF EXISTS` clause. (Non-standard.)
3807        /// See <https://docs.snowflake.com/en/sql-reference/sql/comment>
3808        if_exists: bool,
3809    },
3810    /// ```sql
3811    /// COMMIT [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]
3812    /// ```
3813    /// If `end` is false
3814    ///
3815    /// ```sql
3816    /// END [ TRY | CATCH ]
3817    /// ```
3818    /// If `end` is true
3819    Commit {
3820        chain: bool,
3821        end: bool,
3822        modifier: Option<TransactionModifier>,
3823    },
3824    /// ```sql
3825    /// ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ] [ TO [ SAVEPOINT ] savepoint_name ]
3826    /// ```
3827    Rollback {
3828        chain: bool,
3829        savepoint: Option<Ident>,
3830    },
3831    /// ```sql
3832    /// CREATE SCHEMA
3833    /// ```
3834    CreateSchema {
3835        /// `<schema name> | AUTHORIZATION <schema authorization identifier>  | <schema name>  AUTHORIZATION <schema authorization identifier>`
3836        schema_name: SchemaName,
3837        if_not_exists: bool,
3838        /// Schema properties.
3839        ///
3840        /// ```sql
3841        /// CREATE SCHEMA myschema WITH (key1='value1');
3842        /// ```
3843        ///
3844        /// [Trino](https://trino.io/docs/current/sql/create-schema.html)
3845        with: Option<Vec<SqlOption>>,
3846        /// Schema options.
3847        ///
3848        /// ```sql
3849        /// CREATE SCHEMA myschema OPTIONS(key1='value1');
3850        /// ```
3851        ///
3852        /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_schema_statement)
3853        options: Option<Vec<SqlOption>>,
3854        /// Default collation specification for the schema.
3855        ///
3856        /// ```sql
3857        /// CREATE SCHEMA myschema DEFAULT COLLATE 'und:ci';
3858        /// ```
3859        ///
3860        /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_schema_statement)
3861        default_collate_spec: Option<Expr>,
3862        /// Clones a schema
3863        ///
3864        /// ```sql
3865        /// CREATE SCHEMA myschema CLONE otherschema
3866        /// ```
3867        ///
3868        /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-clone#databases-schemas)
3869        clone: Option<ObjectName>,
3870    },
3871    /// ```sql
3872    /// CREATE DATABASE
3873    /// ```
3874    /// See:
3875    /// <https://docs.snowflake.com/en/sql-reference/sql/create-database>
3876    CreateDatabase {
3877        db_name: ObjectName,
3878        if_not_exists: bool,
3879        location: Option<String>,
3880        managed_location: Option<String>,
3881        or_replace: bool,
3882        transient: bool,
3883        clone: Option<ObjectName>,
3884        data_retention_time_in_days: Option<u64>,
3885        max_data_extension_time_in_days: Option<u64>,
3886        external_volume: Option<String>,
3887        catalog: Option<String>,
3888        replace_invalid_characters: Option<bool>,
3889        default_ddl_collation: Option<String>,
3890        storage_serialization_policy: Option<StorageSerializationPolicy>,
3891        comment: Option<String>,
3892        catalog_sync: Option<String>,
3893        catalog_sync_namespace_mode: Option<CatalogSyncNamespaceMode>,
3894        catalog_sync_namespace_flatten_delimiter: Option<String>,
3895        with_tags: Option<Vec<Tag>>,
3896        with_contacts: Option<Vec<ContactEntry>>,
3897    },
3898    /// ```sql
3899    /// CREATE FUNCTION
3900    /// ```
3901    ///
3902    /// Supported variants:
3903    /// 1. [Hive](https://cwiki.apache.org/confluence/display/hive/languagemanual+ddl#LanguageManualDDL-Create/Drop/ReloadFunction)
3904    /// 2. [PostgreSQL](https://www.postgresql.org/docs/15/sql-createfunction.html)
3905    /// 3. [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_function_statement)
3906    /// 4. [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql)
3907    CreateFunction(CreateFunction),
3908    /// CREATE TRIGGER statement. See struct [CreateTrigger] for details.
3909    CreateTrigger(CreateTrigger),
3910    /// DROP TRIGGER statement. See struct [DropTrigger] for details.
3911    DropTrigger(DropTrigger),
3912    /// ```sql
3913    /// CREATE PROCEDURE
3914    /// ```
3915    CreateProcedure {
3916        or_alter: bool,
3917        name: ObjectName,
3918        params: Option<Vec<ProcedureParam>>,
3919        language: Option<Ident>,
3920        body: ConditionalStatements,
3921    },
3922    /// ```sql
3923    /// CREATE MACRO
3924    /// ```
3925    ///
3926    /// Supported variants:
3927    /// 1. [DuckDB](https://duckdb.org/docs/sql/statements/create_macro)
3928    CreateMacro {
3929        or_replace: bool,
3930        temporary: bool,
3931        name: ObjectName,
3932        args: Option<Vec<MacroArg>>,
3933        definition: MacroDefinition,
3934    },
3935    /// ```sql
3936    /// CREATE STAGE
3937    /// ```
3938    /// See <https://docs.snowflake.com/en/sql-reference/sql/create-stage>
3939    CreateStage {
3940        or_replace: bool,
3941        temporary: bool,
3942        if_not_exists: bool,
3943        name: ObjectName,
3944        stage_params: StageParamsObject,
3945        directory_table_params: KeyValueOptions,
3946        file_format: KeyValueOptions,
3947        copy_options: KeyValueOptions,
3948        comment: Option<String>,
3949    },
3950    /// ```sql
3951    /// ASSERT <condition> [AS <message>]
3952    /// ```
3953    Assert {
3954        condition: Expr,
3955        message: Option<Expr>,
3956    },
3957    /// ```sql
3958    /// GRANT privileges ON objects TO grantees
3959    /// ```
3960    Grant {
3961        privileges: Privileges,
3962        objects: Option<GrantObjects>,
3963        grantees: Vec<Grantee>,
3964        with_grant_option: bool,
3965        as_grantor: Option<Ident>,
3966        granted_by: Option<Ident>,
3967        current_grants: Option<CurrentGrantsKind>,
3968    },
3969    /// ```sql
3970    /// DENY privileges ON object TO grantees
3971    /// ```
3972    Deny(DenyStatement),
3973    /// ```sql
3974    /// REVOKE privileges ON objects FROM grantees
3975    /// ```
3976    Revoke {
3977        privileges: Privileges,
3978        objects: Option<GrantObjects>,
3979        grantees: Vec<Grantee>,
3980        granted_by: Option<Ident>,
3981        cascade: Option<CascadeOption>,
3982    },
3983    /// ```sql
3984    /// DEALLOCATE [ PREPARE ] { name | ALL }
3985    /// ```
3986    ///
3987    /// Note: this is a PostgreSQL-specific statement.
3988    Deallocate {
3989        name: Ident,
3990        prepare: bool,
3991    },
3992    /// ```sql
3993    /// An `EXECUTE` statement
3994    /// ```
3995    ///
3996    /// Postgres: <https://www.postgresql.org/docs/current/sql-execute.html>
3997    /// MSSQL: <https://learn.microsoft.com/en-us/sql/relational-databases/stored-procedures/execute-a-stored-procedure>
3998    /// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#execute_immediate>
3999    /// Snowflake: <https://docs.snowflake.com/en/sql-reference/sql/execute-immediate>
4000    Execute {
4001        name: Option<ObjectName>,
4002        parameters: Vec<Expr>,
4003        has_parentheses: bool,
4004        /// Is this an `EXECUTE IMMEDIATE`
4005        immediate: bool,
4006        into: Vec<Ident>,
4007        using: Vec<ExprWithAlias>,
4008        /// Whether the last parameter is the return value of the procedure
4009        /// MSSQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver17#output>
4010        output: bool,
4011        /// Whether to invoke the procedure with the default parameter values
4012        /// MSSQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver17#default>
4013        default: bool,
4014    },
4015    /// ```sql
4016    /// PREPARE name [ ( data_type [, ...] ) ] AS statement
4017    /// ```
4018    ///
4019    /// Note: this is a PostgreSQL-specific statement.
4020    Prepare {
4021        name: Ident,
4022        data_types: Vec<DataType>,
4023        statement: Box<Statement>,
4024    },
4025    /// ```sql
4026    /// KILL [CONNECTION | QUERY | MUTATION]
4027    /// ```
4028    ///
4029    /// See <https://clickhouse.com/docs/en/sql-reference/statements/kill/>
4030    /// See <https://dev.mysql.com/doc/refman/8.0/en/kill.html>
4031    Kill {
4032        modifier: Option<KillType>,
4033        // processlist_id
4034        id: u64,
4035    },
4036    /// ```sql
4037    /// [EXPLAIN | DESC | DESCRIBE] TABLE
4038    /// ```
4039    /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/explain.html>
4040    ExplainTable {
4041        /// `EXPLAIN | DESC | DESCRIBE`
4042        describe_alias: DescribeAlias,
4043        /// Hive style `FORMATTED | EXTENDED`
4044        hive_format: Option<HiveDescribeFormat>,
4045        /// Snowflake and ClickHouse support `DESC|DESCRIBE TABLE <table_name>` syntax
4046        ///
4047        /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/desc-table.html)
4048        /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/describe-table)
4049        has_table_keyword: bool,
4050        /// Table name
4051        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
4052        table_name: ObjectName,
4053    },
4054    /// ```sql
4055    /// [EXPLAIN | DESC | DESCRIBE]  <statement>
4056    /// ```
4057    Explain {
4058        /// `EXPLAIN | DESC | DESCRIBE`
4059        describe_alias: DescribeAlias,
4060        /// Carry out the command and show actual run times and other statistics.
4061        analyze: bool,
4062        // Display additional information regarding the plan.
4063        verbose: bool,
4064        /// `EXPLAIN QUERY PLAN`
4065        /// Display the query plan without running the query.
4066        ///
4067        /// [SQLite](https://sqlite.org/lang_explain.html)
4068        query_plan: bool,
4069        /// `EXPLAIN ESTIMATE`
4070        /// [Clickhouse](https://clickhouse.com/docs/en/sql-reference/statements/explain#explain-estimate)
4071        estimate: bool,
4072        /// A SQL query that specifies what to explain
4073        statement: Box<Statement>,
4074        /// Optional output format of explain
4075        format: Option<AnalyzeFormatKind>,
4076        /// Postgres style utility options, `(analyze, verbose true)`
4077        options: Option<Vec<UtilityOption>>,
4078    },
4079    /// ```sql
4080    /// SAVEPOINT
4081    /// ```
4082    /// Define a new savepoint within the current transaction
4083    Savepoint {
4084        name: Ident,
4085    },
4086    /// ```sql
4087    /// RELEASE [ SAVEPOINT ] savepoint_name
4088    /// ```
4089    ReleaseSavepoint {
4090        name: Ident,
4091    },
4092    /// A `MERGE` statement.
4093    ///
4094    /// ```sql
4095    /// MERGE INTO <target_table> USING <source> ON <join_expr> { matchedClause | notMatchedClause } [ ... ]
4096    /// ```
4097    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/merge)
4098    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
4099    /// [MSSQL](https://learn.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver16)
4100    Merge(Merge),
4101    /// ```sql
4102    /// CACHE [ FLAG ] TABLE <table_name> [ OPTIONS('K1' = 'V1', 'K2' = V2) ] [ AS ] [ <query> ]
4103    /// ```
4104    ///
4105    /// See [Spark SQL docs] for more details.
4106    ///
4107    /// [Spark SQL docs]: https://docs.databricks.com/spark/latest/spark-sql/language-manual/sql-ref-syntax-aux-cache-cache-table.html
4108    Cache {
4109        /// Table flag
4110        table_flag: Option<ObjectName>,
4111        /// Table name
4112        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
4113        table_name: ObjectName,
4114        has_as: bool,
4115        /// Table confs
4116        options: Vec<SqlOption>,
4117        /// Cache table as a Query
4118        query: Option<Box<Query>>,
4119    },
4120    /// ```sql
4121    /// UNCACHE TABLE [ IF EXISTS ]  <table_name>
4122    /// ```
4123    UNCache {
4124        /// Table name
4125        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
4126        table_name: ObjectName,
4127        if_exists: bool,
4128    },
4129    /// ```sql
4130    /// CREATE [ { TEMPORARY | TEMP } ] SEQUENCE [ IF NOT EXISTS ] <sequence_name>
4131    /// ```
4132    /// Define a new sequence:
4133    CreateSequence {
4134        temporary: bool,
4135        if_not_exists: bool,
4136        name: ObjectName,
4137        data_type: Option<DataType>,
4138        sequence_options: Vec<SequenceOptions>,
4139        owned_by: Option<ObjectName>,
4140    },
4141    /// A `CREATE DOMAIN` statement.
4142    CreateDomain(CreateDomain),
4143    /// ```sql
4144    /// CREATE TYPE <name>
4145    /// ```
4146    CreateType {
4147        name: ObjectName,
4148        representation: Option<UserDefinedTypeRepresentation>,
4149    },
4150    /// ```sql
4151    /// PRAGMA <schema-name>.<pragma-name> = <pragma-value>
4152    /// ```
4153    Pragma {
4154        name: ObjectName,
4155        value: Option<Value>,
4156        is_eq: bool,
4157    },
4158    /// ```sql
4159    /// LOCK TABLES <table_name> [READ [LOCAL] | [LOW_PRIORITY] WRITE]
4160    /// ```
4161    /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html>
4162    LockTables {
4163        tables: Vec<LockTable>,
4164    },
4165    /// ```sql
4166    /// UNLOCK TABLES
4167    /// ```
4168    /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html>
4169    UnlockTables,
4170    /// Unloads the result of a query to file
4171    ///
4172    /// [Athena](https://docs.aws.amazon.com/athena/latest/ug/unload.html):
4173    /// ```sql
4174    /// UNLOAD(statement) TO <destination> [ WITH options ]
4175    /// ```
4176    ///
4177    /// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD.html):
4178    /// ```sql
4179    /// UNLOAD('statement') TO <destination> [ OPTIONS ]
4180    /// ```
4181    Unload {
4182        query: Option<Box<Query>>,
4183        query_text: Option<String>,
4184        to: Ident,
4185        auth: Option<IamRoleKind>,
4186        with: Vec<SqlOption>,
4187        options: Vec<CopyLegacyOption>,
4188    },
4189    /// ```sql
4190    /// OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition | PARTITION ID 'partition_id'] [FINAL] [DEDUPLICATE [BY expression]]
4191    /// ```
4192    ///
4193    /// See ClickHouse <https://clickhouse.com/docs/en/sql-reference/statements/optimize>
4194    OptimizeTable {
4195        name: ObjectName,
4196        on_cluster: Option<Ident>,
4197        partition: Option<Partition>,
4198        include_final: bool,
4199        deduplicate: Option<Deduplicate>,
4200    },
4201    /// ```sql
4202    /// LISTEN
4203    /// ```
4204    /// listen for a notification channel
4205    ///
4206    /// See Postgres <https://www.postgresql.org/docs/current/sql-listen.html>
4207    LISTEN {
4208        channel: Ident,
4209    },
4210    /// ```sql
4211    /// UNLISTEN
4212    /// ```
4213    /// stop listening for a notification
4214    ///
4215    /// See Postgres <https://www.postgresql.org/docs/current/sql-unlisten.html>
4216    UNLISTEN {
4217        channel: Ident,
4218    },
4219    /// ```sql
4220    /// NOTIFY channel [ , payload ]
4221    /// ```
4222    /// send a notification event together with an optional "payload" string to channel
4223    ///
4224    /// See Postgres <https://www.postgresql.org/docs/current/sql-notify.html>
4225    NOTIFY {
4226        channel: Ident,
4227        payload: Option<String>,
4228    },
4229    /// ```sql
4230    /// LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename
4231    /// [PARTITION (partcol1=val1, partcol2=val2 ...)]
4232    /// [INPUTFORMAT 'inputformat' SERDE 'serde']
4233    /// ```
4234    /// Loading files into tables
4235    ///
4236    /// See Hive <https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362036#LanguageManualDML-Loadingfilesintotables>
4237    LoadData {
4238        local: bool,
4239        inpath: String,
4240        overwrite: bool,
4241        table_name: ObjectName,
4242        partitioned: Option<Vec<Expr>>,
4243        table_format: Option<HiveLoadDataFormat>,
4244    },
4245    /// ```sql
4246    /// Rename TABLE tbl_name TO new_tbl_name[, tbl_name2 TO new_tbl_name2] ...
4247    /// ```
4248    /// Renames one or more tables
4249    ///
4250    /// See Mysql <https://dev.mysql.com/doc/refman/9.1/en/rename-table.html>
4251    RenameTable(Vec<RenameTable>),
4252    /// Snowflake `LIST`
4253    /// See: <https://docs.snowflake.com/en/sql-reference/sql/list>
4254    List(FileStagingCommand),
4255    /// Snowflake `REMOVE`
4256    /// See: <https://docs.snowflake.com/en/sql-reference/sql/remove>
4257    Remove(FileStagingCommand),
4258    /// RaiseError (MSSQL)
4259    /// RAISERROR ( { msg_id | msg_str | @local_variable }
4260    /// { , severity , state }
4261    /// [ , argument [ , ...n ] ] )
4262    /// [ WITH option [ , ...n ] ]
4263    /// See <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/raiserror-transact-sql?view=sql-server-ver16>
4264    RaisError {
4265        message: Box<Expr>,
4266        severity: Box<Expr>,
4267        state: Box<Expr>,
4268        arguments: Vec<Expr>,
4269        options: Vec<RaisErrorOption>,
4270    },
4271    /// ```sql
4272    /// PRINT msg_str | @local_variable | string_expr
4273    /// ```
4274    ///
4275    /// See: <https://learn.microsoft.com/en-us/sql/t-sql/statements/print-transact-sql>
4276    Print(PrintStatement),
4277    /// ```sql
4278    /// RETURN [ expression ]
4279    /// ```
4280    ///
4281    /// See [ReturnStatement]
4282    Return(ReturnStatement),
4283    /// Export data statement
4284    ///
4285    /// Example:
4286    /// ```sql
4287    /// EXPORT DATA OPTIONS(uri='gs://bucket/folder/*', format='PARQUET', overwrite=true) AS
4288    /// SELECT field1, field2 FROM mydataset.table1 ORDER BY field1 LIMIT 10
4289    /// ```
4290    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/export-statements)
4291    ExportData(ExportData),
4292    /// ```sql
4293    /// CREATE [OR REPLACE] USER <user> [IF NOT EXISTS]
4294    /// ```
4295    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-user)
4296    CreateUser(CreateUser),
4297    /// ```sql
4298    /// ALTER USER \[ IF EXISTS \] \[ <name> \]
4299    /// ```
4300    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/alter-user)
4301    AlterUser(AlterUser),
4302    /// Re-sorts rows and reclaims space in either a specified table or all tables in the current database
4303    ///
4304    /// ```sql
4305    /// VACUUM tbl
4306    /// ```
4307    /// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)
4308    Vacuum(VacuumStatement),
4309    /// Restore the value of a run-time parameter to the default value.
4310    ///
4311    /// ```sql
4312    /// RESET configuration_parameter;
4313    /// RESET ALL;
4314    /// ```
4315    /// [PostgreSQL](https://www.postgresql.org/docs/current/sql-reset.html)
4316    Reset(ResetStatement),
4317}
4318
4319impl From<Analyze> for Statement {
4320    fn from(analyze: Analyze) -> Self {
4321        Statement::Analyze(analyze)
4322    }
4323}
4324
4325impl From<ddl::Truncate> for Statement {
4326    fn from(truncate: ddl::Truncate) -> Self {
4327        Statement::Truncate(truncate)
4328    }
4329}
4330
4331impl From<ddl::Msck> for Statement {
4332    fn from(msck: ddl::Msck) -> Self {
4333        Statement::Msck(msck)
4334    }
4335}
4336
4337/// ```sql
4338/// {COPY | REVOKE} CURRENT GRANTS
4339/// ```
4340///
4341/// - [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/grant-ownership#optional-parameters)
4342#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4343#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4344#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4345pub enum CurrentGrantsKind {
4346    CopyCurrentGrants,
4347    RevokeCurrentGrants,
4348}
4349
4350impl fmt::Display for CurrentGrantsKind {
4351    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4352        match self {
4353            CurrentGrantsKind::CopyCurrentGrants => write!(f, "COPY CURRENT GRANTS"),
4354            CurrentGrantsKind::RevokeCurrentGrants => write!(f, "REVOKE CURRENT GRANTS"),
4355        }
4356    }
4357}
4358
4359#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4360#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4361#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4362pub enum RaisErrorOption {
4363    Log,
4364    NoWait,
4365    SetError,
4366}
4367
4368impl fmt::Display for RaisErrorOption {
4369    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4370        match self {
4371            RaisErrorOption::Log => write!(f, "LOG"),
4372            RaisErrorOption::NoWait => write!(f, "NOWAIT"),
4373            RaisErrorOption::SetError => write!(f, "SETERROR"),
4374        }
4375    }
4376}
4377
4378impl fmt::Display for Statement {
4379    /// Formats a SQL statement with support for pretty printing.
4380    ///
4381    /// When using the alternate flag (`{:#}`), the statement will be formatted with proper
4382    /// indentation and line breaks. For example:
4383    ///
4384    /// ```
4385    /// # use sqlparser::dialect::GenericDialect;
4386    /// # use sqlparser::parser::Parser;
4387    /// let sql = "SELECT a, b FROM table_1";
4388    /// let ast = Parser::parse_sql(&GenericDialect, sql).unwrap();
4389    ///
4390    /// // Regular formatting
4391    /// assert_eq!(format!("{}", ast[0]), "SELECT a, b FROM table_1");
4392    ///
4393    /// // Pretty printing
4394    /// assert_eq!(format!("{:#}", ast[0]),
4395    /// r#"SELECT
4396    ///   a,
4397    ///   b
4398    /// FROM
4399    ///   table_1"#);
4400    /// ```
4401    // Clippy thinks this function is too complicated, but it is painful to
4402    // split up without extracting structs for each `Statement` variant.
4403    #[allow(clippy::cognitive_complexity)]
4404    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4405        match self {
4406            Statement::Flush {
4407                object_type,
4408                location,
4409                channel,
4410                read_lock,
4411                export,
4412                tables,
4413            } => {
4414                write!(f, "FLUSH")?;
4415                if let Some(location) = location {
4416                    f.write_str(" ")?;
4417                    location.fmt(f)?;
4418                }
4419                write!(f, " {object_type}")?;
4420
4421                if let Some(channel) = channel {
4422                    write!(f, " FOR CHANNEL {channel}")?;
4423                }
4424
4425                write!(
4426                    f,
4427                    "{tables}{read}{export}",
4428                    tables = if !tables.is_empty() {
4429                        " ".to_string() + &display_comma_separated(tables).to_string()
4430                    } else {
4431                        "".to_string()
4432                    },
4433                    export = if *export { " FOR EXPORT" } else { "" },
4434                    read = if *read_lock { " WITH READ LOCK" } else { "" }
4435                )
4436            }
4437            Statement::Kill { modifier, id } => {
4438                write!(f, "KILL ")?;
4439
4440                if let Some(m) = modifier {
4441                    write!(f, "{m} ")?;
4442                }
4443
4444                write!(f, "{id}")
4445            }
4446            Statement::ExplainTable {
4447                describe_alias,
4448                hive_format,
4449                has_table_keyword,
4450                table_name,
4451            } => {
4452                write!(f, "{describe_alias} ")?;
4453
4454                if let Some(format) = hive_format {
4455                    write!(f, "{format} ")?;
4456                }
4457                if *has_table_keyword {
4458                    write!(f, "TABLE ")?;
4459                }
4460
4461                write!(f, "{table_name}")
4462            }
4463            Statement::Explain {
4464                describe_alias,
4465                verbose,
4466                analyze,
4467                query_plan,
4468                estimate,
4469                statement,
4470                format,
4471                options,
4472            } => {
4473                write!(f, "{describe_alias} ")?;
4474
4475                if *query_plan {
4476                    write!(f, "QUERY PLAN ")?;
4477                }
4478                if *analyze {
4479                    write!(f, "ANALYZE ")?;
4480                }
4481                if *estimate {
4482                    write!(f, "ESTIMATE ")?;
4483                }
4484
4485                if *verbose {
4486                    write!(f, "VERBOSE ")?;
4487                }
4488
4489                if let Some(format) = format {
4490                    write!(f, "{format} ")?;
4491                }
4492
4493                if let Some(options) = options {
4494                    write!(f, "({}) ", display_comma_separated(options))?;
4495                }
4496
4497                write!(f, "{statement}")
4498            }
4499            Statement::Query(s) => s.fmt(f),
4500            Statement::Declare { stmts } => {
4501                write!(f, "DECLARE ")?;
4502                write!(f, "{}", display_separated(stmts, "; "))
4503            }
4504            Statement::Fetch {
4505                name,
4506                direction,
4507                position,
4508                into,
4509            } => {
4510                write!(f, "FETCH {direction} {position} {name}")?;
4511
4512                if let Some(into) = into {
4513                    write!(f, " INTO {into}")?;
4514                }
4515
4516                Ok(())
4517            }
4518            Statement::Directory {
4519                overwrite,
4520                local,
4521                path,
4522                file_format,
4523                source,
4524            } => {
4525                write!(
4526                    f,
4527                    "INSERT{overwrite}{local} DIRECTORY '{path}'",
4528                    overwrite = if *overwrite { " OVERWRITE" } else { "" },
4529                    local = if *local { " LOCAL" } else { "" },
4530                    path = path
4531                )?;
4532                if let Some(ref ff) = file_format {
4533                    write!(f, " STORED AS {ff}")?
4534                }
4535                write!(f, " {source}")
4536            }
4537            Statement::Msck(msck) => msck.fmt(f),
4538            Statement::Truncate(truncate) => truncate.fmt(f),
4539            Statement::Case(stmt) => {
4540                write!(f, "{stmt}")
4541            }
4542            Statement::If(stmt) => {
4543                write!(f, "{stmt}")
4544            }
4545            Statement::While(stmt) => {
4546                write!(f, "{stmt}")
4547            }
4548            Statement::Raise(stmt) => {
4549                write!(f, "{stmt}")
4550            }
4551            Statement::AttachDatabase {
4552                schema_name,
4553                database_file_name,
4554                database,
4555            } => {
4556                let keyword = if *database { "DATABASE " } else { "" };
4557                write!(f, "ATTACH {keyword}{database_file_name} AS {schema_name}")
4558            }
4559            Statement::AttachDuckDBDatabase {
4560                if_not_exists,
4561                database,
4562                database_path,
4563                database_alias,
4564                attach_options,
4565            } => {
4566                write!(
4567                    f,
4568                    "ATTACH{database}{if_not_exists} {database_path}",
4569                    database = if *database { " DATABASE" } else { "" },
4570                    if_not_exists = if *if_not_exists { " IF NOT EXISTS" } else { "" },
4571                )?;
4572                if let Some(alias) = database_alias {
4573                    write!(f, " AS {alias}")?;
4574                }
4575                if !attach_options.is_empty() {
4576                    write!(f, " ({})", display_comma_separated(attach_options))?;
4577                }
4578                Ok(())
4579            }
4580            Statement::DetachDuckDBDatabase {
4581                if_exists,
4582                database,
4583                database_alias,
4584            } => {
4585                write!(
4586                    f,
4587                    "DETACH{database}{if_exists} {database_alias}",
4588                    database = if *database { " DATABASE" } else { "" },
4589                    if_exists = if *if_exists { " IF EXISTS" } else { "" },
4590                )?;
4591                Ok(())
4592            }
4593            Statement::Analyze(analyze) => analyze.fmt(f),
4594            Statement::Insert(insert) => insert.fmt(f),
4595            Statement::Install {
4596                extension_name: name,
4597            } => write!(f, "INSTALL {name}"),
4598
4599            Statement::Load {
4600                extension_name: name,
4601            } => write!(f, "LOAD {name}"),
4602
4603            Statement::Call(function) => write!(f, "CALL {function}"),
4604
4605            Statement::Copy {
4606                source,
4607                to,
4608                target,
4609                options,
4610                legacy_options,
4611                values,
4612            } => {
4613                write!(f, "COPY")?;
4614                match source {
4615                    CopySource::Query(query) => write!(f, " ({query})")?,
4616                    CopySource::Table {
4617                        table_name,
4618                        columns,
4619                    } => {
4620                        write!(f, " {table_name}")?;
4621                        if !columns.is_empty() {
4622                            write!(f, " ({})", display_comma_separated(columns))?;
4623                        }
4624                    }
4625                }
4626                write!(f, " {} {}", if *to { "TO" } else { "FROM" }, target)?;
4627                if !options.is_empty() {
4628                    write!(f, " ({})", display_comma_separated(options))?;
4629                }
4630                if !legacy_options.is_empty() {
4631                    write!(f, " {}", display_separated(legacy_options, " "))?;
4632                }
4633                if !values.is_empty() {
4634                    writeln!(f, ";")?;
4635                    let mut delim = "";
4636                    for v in values {
4637                        write!(f, "{delim}")?;
4638                        delim = "\t";
4639                        if let Some(v) = v {
4640                            write!(f, "{v}")?;
4641                        } else {
4642                            write!(f, "\\N")?;
4643                        }
4644                    }
4645                    write!(f, "\n\\.")?;
4646                }
4647                Ok(())
4648            }
4649            Statement::Update(update) => update.fmt(f),
4650            Statement::Delete(delete) => delete.fmt(f),
4651            Statement::Open(open) => open.fmt(f),
4652            Statement::Close { cursor } => {
4653                write!(f, "CLOSE {cursor}")?;
4654
4655                Ok(())
4656            }
4657            Statement::CreateDatabase {
4658                db_name,
4659                if_not_exists,
4660                location,
4661                managed_location,
4662                or_replace,
4663                transient,
4664                clone,
4665                data_retention_time_in_days,
4666                max_data_extension_time_in_days,
4667                external_volume,
4668                catalog,
4669                replace_invalid_characters,
4670                default_ddl_collation,
4671                storage_serialization_policy,
4672                comment,
4673                catalog_sync,
4674                catalog_sync_namespace_mode,
4675                catalog_sync_namespace_flatten_delimiter,
4676                with_tags,
4677                with_contacts,
4678            } => {
4679                write!(
4680                    f,
4681                    "CREATE {or_replace}{transient}DATABASE {if_not_exists}{name}",
4682                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
4683                    transient = if *transient { "TRANSIENT " } else { "" },
4684                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
4685                    name = db_name,
4686                )?;
4687
4688                if let Some(l) = location {
4689                    write!(f, " LOCATION '{l}'")?;
4690                }
4691                if let Some(ml) = managed_location {
4692                    write!(f, " MANAGEDLOCATION '{ml}'")?;
4693                }
4694                if let Some(clone) = clone {
4695                    write!(f, " CLONE {clone}")?;
4696                }
4697
4698                if let Some(value) = data_retention_time_in_days {
4699                    write!(f, " DATA_RETENTION_TIME_IN_DAYS = {value}")?;
4700                }
4701
4702                if let Some(value) = max_data_extension_time_in_days {
4703                    write!(f, " MAX_DATA_EXTENSION_TIME_IN_DAYS = {value}")?;
4704                }
4705
4706                if let Some(vol) = external_volume {
4707                    write!(f, " EXTERNAL_VOLUME = '{vol}'")?;
4708                }
4709
4710                if let Some(cat) = catalog {
4711                    write!(f, " CATALOG = '{cat}'")?;
4712                }
4713
4714                if let Some(true) = replace_invalid_characters {
4715                    write!(f, " REPLACE_INVALID_CHARACTERS = TRUE")?;
4716                } else if let Some(false) = replace_invalid_characters {
4717                    write!(f, " REPLACE_INVALID_CHARACTERS = FALSE")?;
4718                }
4719
4720                if let Some(collation) = default_ddl_collation {
4721                    write!(f, " DEFAULT_DDL_COLLATION = '{collation}'")?;
4722                }
4723
4724                if let Some(policy) = storage_serialization_policy {
4725                    write!(f, " STORAGE_SERIALIZATION_POLICY = {policy}")?;
4726                }
4727
4728                if let Some(comment) = comment {
4729                    write!(f, " COMMENT = '{comment}'")?;
4730                }
4731
4732                if let Some(sync) = catalog_sync {
4733                    write!(f, " CATALOG_SYNC = '{sync}'")?;
4734                }
4735
4736                if let Some(mode) = catalog_sync_namespace_mode {
4737                    write!(f, " CATALOG_SYNC_NAMESPACE_MODE = {mode}")?;
4738                }
4739
4740                if let Some(delim) = catalog_sync_namespace_flatten_delimiter {
4741                    write!(f, " CATALOG_SYNC_NAMESPACE_FLATTEN_DELIMITER = '{delim}'")?;
4742                }
4743
4744                if let Some(tags) = with_tags {
4745                    write!(f, " WITH TAG ({})", display_comma_separated(tags))?;
4746                }
4747
4748                if let Some(contacts) = with_contacts {
4749                    write!(f, " WITH CONTACT ({})", display_comma_separated(contacts))?;
4750                }
4751                Ok(())
4752            }
4753            Statement::CreateFunction(create_function) => create_function.fmt(f),
4754            Statement::CreateDomain(create_domain) => create_domain.fmt(f),
4755            Statement::CreateTrigger(create_trigger) => create_trigger.fmt(f),
4756            Statement::DropTrigger(drop_trigger) => drop_trigger.fmt(f),
4757            Statement::CreateProcedure {
4758                name,
4759                or_alter,
4760                params,
4761                language,
4762                body,
4763            } => {
4764                write!(
4765                    f,
4766                    "CREATE {or_alter}PROCEDURE {name}",
4767                    or_alter = if *or_alter { "OR ALTER " } else { "" },
4768                    name = name
4769                )?;
4770
4771                if let Some(p) = params {
4772                    if !p.is_empty() {
4773                        write!(f, " ({})", display_comma_separated(p))?;
4774                    }
4775                }
4776
4777                if let Some(language) = language {
4778                    write!(f, " LANGUAGE {language}")?;
4779                }
4780
4781                write!(f, " AS {body}")
4782            }
4783            Statement::CreateMacro {
4784                or_replace,
4785                temporary,
4786                name,
4787                args,
4788                definition,
4789            } => {
4790                write!(
4791                    f,
4792                    "CREATE {or_replace}{temp}MACRO {name}",
4793                    temp = if *temporary { "TEMPORARY " } else { "" },
4794                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
4795                )?;
4796                if let Some(args) = args {
4797                    write!(f, "({})", display_comma_separated(args))?;
4798                }
4799                match definition {
4800                    MacroDefinition::Expr(expr) => write!(f, " AS {expr}")?,
4801                    MacroDefinition::Table(query) => write!(f, " AS TABLE {query}")?,
4802                }
4803                Ok(())
4804            }
4805            Statement::CreateView(create_view) => create_view.fmt(f),
4806            Statement::CreateTable(create_table) => create_table.fmt(f),
4807            Statement::LoadData {
4808                local,
4809                inpath,
4810                overwrite,
4811                table_name,
4812                partitioned,
4813                table_format,
4814            } => {
4815                write!(
4816                    f,
4817                    "LOAD DATA {local}INPATH '{inpath}' {overwrite}INTO TABLE {table_name}",
4818                    local = if *local { "LOCAL " } else { "" },
4819                    inpath = inpath,
4820                    overwrite = if *overwrite { "OVERWRITE " } else { "" },
4821                    table_name = table_name,
4822                )?;
4823                if let Some(ref parts) = &partitioned {
4824                    if !parts.is_empty() {
4825                        write!(f, " PARTITION ({})", display_comma_separated(parts))?;
4826                    }
4827                }
4828                if let Some(HiveLoadDataFormat {
4829                    serde,
4830                    input_format,
4831                }) = &table_format
4832                {
4833                    write!(f, " INPUTFORMAT {input_format} SERDE {serde}")?;
4834                }
4835                Ok(())
4836            }
4837            Statement::CreateVirtualTable {
4838                name,
4839                if_not_exists,
4840                module_name,
4841                module_args,
4842            } => {
4843                write!(
4844                    f,
4845                    "CREATE VIRTUAL TABLE {if_not_exists}{name} USING {module_name}",
4846                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
4847                    name = name,
4848                    module_name = module_name
4849                )?;
4850                if !module_args.is_empty() {
4851                    write!(f, " ({})", display_comma_separated(module_args))?;
4852                }
4853                Ok(())
4854            }
4855            Statement::CreateIndex(create_index) => create_index.fmt(f),
4856            Statement::CreateExtension(create_extension) => write!(f, "{create_extension}"),
4857            Statement::DropExtension(drop_extension) => write!(f, "{drop_extension}"),
4858            Statement::DropOperator(drop_operator) => write!(f, "{drop_operator}"),
4859            Statement::DropOperatorFamily(drop_operator_family) => {
4860                write!(f, "{drop_operator_family}")
4861            }
4862            Statement::DropOperatorClass(drop_operator_class) => {
4863                write!(f, "{drop_operator_class}")
4864            }
4865            Statement::CreateRole(create_role) => write!(f, "{create_role}"),
4866            Statement::CreateSecret {
4867                or_replace,
4868                temporary,
4869                if_not_exists,
4870                name,
4871                storage_specifier,
4872                secret_type,
4873                options,
4874            } => {
4875                write!(
4876                    f,
4877                    "CREATE {or_replace}",
4878                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
4879                )?;
4880                if let Some(t) = temporary {
4881                    write!(f, "{}", if *t { "TEMPORARY " } else { "PERSISTENT " })?;
4882                }
4883                write!(
4884                    f,
4885                    "SECRET {if_not_exists}",
4886                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
4887                )?;
4888                if let Some(n) = name {
4889                    write!(f, "{n} ")?;
4890                };
4891                if let Some(s) = storage_specifier {
4892                    write!(f, "IN {s} ")?;
4893                }
4894                write!(f, "( TYPE {secret_type}",)?;
4895                if !options.is_empty() {
4896                    write!(f, ", {o}", o = display_comma_separated(options))?;
4897                }
4898                write!(f, " )")?;
4899                Ok(())
4900            }
4901            Statement::CreateServer(stmt) => {
4902                write!(f, "{stmt}")
4903            }
4904            Statement::CreatePolicy {
4905                name,
4906                table_name,
4907                policy_type,
4908                command,
4909                to,
4910                using,
4911                with_check,
4912            } => {
4913                write!(f, "CREATE POLICY {name} ON {table_name}")?;
4914
4915                if let Some(policy_type) = policy_type {
4916                    match policy_type {
4917                        CreatePolicyType::Permissive => write!(f, " AS PERMISSIVE")?,
4918                        CreatePolicyType::Restrictive => write!(f, " AS RESTRICTIVE")?,
4919                    }
4920                }
4921
4922                if let Some(command) = command {
4923                    match command {
4924                        CreatePolicyCommand::All => write!(f, " FOR ALL")?,
4925                        CreatePolicyCommand::Select => write!(f, " FOR SELECT")?,
4926                        CreatePolicyCommand::Insert => write!(f, " FOR INSERT")?,
4927                        CreatePolicyCommand::Update => write!(f, " FOR UPDATE")?,
4928                        CreatePolicyCommand::Delete => write!(f, " FOR DELETE")?,
4929                    }
4930                }
4931
4932                if let Some(to) = to {
4933                    write!(f, " TO {}", display_comma_separated(to))?;
4934                }
4935
4936                if let Some(using) = using {
4937                    write!(f, " USING ({using})")?;
4938                }
4939
4940                if let Some(with_check) = with_check {
4941                    write!(f, " WITH CHECK ({with_check})")?;
4942                }
4943
4944                Ok(())
4945            }
4946            Statement::CreateConnector(create_connector) => create_connector.fmt(f),
4947            Statement::CreateOperator(create_operator) => create_operator.fmt(f),
4948            Statement::CreateOperatorFamily(create_operator_family) => {
4949                create_operator_family.fmt(f)
4950            }
4951            Statement::CreateOperatorClass(create_operator_class) => create_operator_class.fmt(f),
4952            Statement::AlterTable(alter_table) => write!(f, "{alter_table}"),
4953            Statement::AlterIndex { name, operation } => {
4954                write!(f, "ALTER INDEX {name} {operation}")
4955            }
4956            Statement::AlterView {
4957                name,
4958                columns,
4959                query,
4960                with_options,
4961            } => {
4962                write!(f, "ALTER VIEW {name}")?;
4963                if !with_options.is_empty() {
4964                    write!(f, " WITH ({})", display_comma_separated(with_options))?;
4965                }
4966                if !columns.is_empty() {
4967                    write!(f, " ({})", display_comma_separated(columns))?;
4968                }
4969                write!(f, " AS {query}")
4970            }
4971            Statement::AlterType(AlterType { name, operation }) => {
4972                write!(f, "ALTER TYPE {name} {operation}")
4973            }
4974            Statement::AlterOperator(alter_operator) => write!(f, "{alter_operator}"),
4975            Statement::AlterRole { name, operation } => {
4976                write!(f, "ALTER ROLE {name} {operation}")
4977            }
4978            Statement::AlterPolicy {
4979                name,
4980                table_name,
4981                operation,
4982            } => {
4983                write!(f, "ALTER POLICY {name} ON {table_name}{operation}")
4984            }
4985            Statement::AlterConnector {
4986                name,
4987                properties,
4988                url,
4989                owner,
4990            } => {
4991                write!(f, "ALTER CONNECTOR {name}")?;
4992                if let Some(properties) = properties {
4993                    write!(
4994                        f,
4995                        " SET DCPROPERTIES({})",
4996                        display_comma_separated(properties)
4997                    )?;
4998                }
4999                if let Some(url) = url {
5000                    write!(f, " SET URL '{url}'")?;
5001                }
5002                if let Some(owner) = owner {
5003                    write!(f, " SET OWNER {owner}")?;
5004                }
5005                Ok(())
5006            }
5007            Statement::AlterSession {
5008                set,
5009                session_params,
5010            } => {
5011                write!(
5012                    f,
5013                    "ALTER SESSION {set}",
5014                    set = if *set { "SET" } else { "UNSET" }
5015                )?;
5016                if !session_params.options.is_empty() {
5017                    if *set {
5018                        write!(f, " {session_params}")?;
5019                    } else {
5020                        let options = session_params
5021                            .options
5022                            .iter()
5023                            .map(|p| p.option_name.clone())
5024                            .collect::<Vec<_>>();
5025                        write!(f, " {}", display_separated(&options, ", "))?;
5026                    }
5027                }
5028                Ok(())
5029            }
5030            Statement::Drop {
5031                object_type,
5032                if_exists,
5033                names,
5034                cascade,
5035                restrict,
5036                purge,
5037                temporary,
5038                table,
5039            } => {
5040                write!(
5041                    f,
5042                    "DROP {}{}{} {}{}{}{}",
5043                    if *temporary { "TEMPORARY " } else { "" },
5044                    object_type,
5045                    if *if_exists { " IF EXISTS" } else { "" },
5046                    display_comma_separated(names),
5047                    if *cascade { " CASCADE" } else { "" },
5048                    if *restrict { " RESTRICT" } else { "" },
5049                    if *purge { " PURGE" } else { "" },
5050                )?;
5051                if let Some(table_name) = table.as_ref() {
5052                    write!(f, " ON {table_name}")?;
5053                };
5054                Ok(())
5055            }
5056            Statement::DropFunction(drop_function) => write!(f, "{drop_function}"),
5057            Statement::DropDomain(DropDomain {
5058                if_exists,
5059                name,
5060                drop_behavior,
5061            }) => {
5062                write!(
5063                    f,
5064                    "DROP DOMAIN{} {name}",
5065                    if *if_exists { " IF EXISTS" } else { "" },
5066                )?;
5067                if let Some(op) = drop_behavior {
5068                    write!(f, " {op}")?;
5069                }
5070                Ok(())
5071            }
5072            Statement::DropProcedure {
5073                if_exists,
5074                proc_desc,
5075                drop_behavior,
5076            } => {
5077                write!(
5078                    f,
5079                    "DROP PROCEDURE{} {}",
5080                    if *if_exists { " IF EXISTS" } else { "" },
5081                    display_comma_separated(proc_desc),
5082                )?;
5083                if let Some(op) = drop_behavior {
5084                    write!(f, " {op}")?;
5085                }
5086                Ok(())
5087            }
5088            Statement::DropSecret {
5089                if_exists,
5090                temporary,
5091                name,
5092                storage_specifier,
5093            } => {
5094                write!(f, "DROP ")?;
5095                if let Some(t) = temporary {
5096                    write!(f, "{}", if *t { "TEMPORARY " } else { "PERSISTENT " })?;
5097                }
5098                write!(
5099                    f,
5100                    "SECRET {if_exists}{name}",
5101                    if_exists = if *if_exists { "IF EXISTS " } else { "" },
5102                )?;
5103                if let Some(s) = storage_specifier {
5104                    write!(f, " FROM {s}")?;
5105                }
5106                Ok(())
5107            }
5108            Statement::DropPolicy {
5109                if_exists,
5110                name,
5111                table_name,
5112                drop_behavior,
5113            } => {
5114                write!(f, "DROP POLICY")?;
5115                if *if_exists {
5116                    write!(f, " IF EXISTS")?;
5117                }
5118                write!(f, " {name} ON {table_name}")?;
5119                if let Some(drop_behavior) = drop_behavior {
5120                    write!(f, " {drop_behavior}")?;
5121                }
5122                Ok(())
5123            }
5124            Statement::DropConnector { if_exists, name } => {
5125                write!(
5126                    f,
5127                    "DROP CONNECTOR {if_exists}{name}",
5128                    if_exists = if *if_exists { "IF EXISTS " } else { "" }
5129                )?;
5130                Ok(())
5131            }
5132            Statement::Discard { object_type } => {
5133                write!(f, "DISCARD {object_type}")?;
5134                Ok(())
5135            }
5136            Self::Set(set) => write!(f, "{set}"),
5137            Statement::ShowVariable { variable } => {
5138                write!(f, "SHOW")?;
5139                if !variable.is_empty() {
5140                    write!(f, " {}", display_separated(variable, " "))?;
5141                }
5142                Ok(())
5143            }
5144            Statement::ShowStatus {
5145                filter,
5146                global,
5147                session,
5148            } => {
5149                write!(f, "SHOW")?;
5150                if *global {
5151                    write!(f, " GLOBAL")?;
5152                }
5153                if *session {
5154                    write!(f, " SESSION")?;
5155                }
5156                write!(f, " STATUS")?;
5157                if filter.is_some() {
5158                    write!(f, " {}", filter.as_ref().unwrap())?;
5159                }
5160                Ok(())
5161            }
5162            Statement::ShowVariables {
5163                filter,
5164                global,
5165                session,
5166            } => {
5167                write!(f, "SHOW")?;
5168                if *global {
5169                    write!(f, " GLOBAL")?;
5170                }
5171                if *session {
5172                    write!(f, " SESSION")?;
5173                }
5174                write!(f, " VARIABLES")?;
5175                if filter.is_some() {
5176                    write!(f, " {}", filter.as_ref().unwrap())?;
5177                }
5178                Ok(())
5179            }
5180            Statement::ShowCreate { obj_type, obj_name } => {
5181                write!(f, "SHOW CREATE {obj_type} {obj_name}",)?;
5182                Ok(())
5183            }
5184            Statement::ShowColumns {
5185                extended,
5186                full,
5187                show_options,
5188            } => {
5189                write!(
5190                    f,
5191                    "SHOW {extended}{full}COLUMNS{show_options}",
5192                    extended = if *extended { "EXTENDED " } else { "" },
5193                    full = if *full { "FULL " } else { "" },
5194                )?;
5195                Ok(())
5196            }
5197            Statement::ShowDatabases {
5198                terse,
5199                history,
5200                show_options,
5201            } => {
5202                write!(
5203                    f,
5204                    "SHOW {terse}DATABASES{history}{show_options}",
5205                    terse = if *terse { "TERSE " } else { "" },
5206                    history = if *history { " HISTORY" } else { "" },
5207                )?;
5208                Ok(())
5209            }
5210            Statement::ShowSchemas {
5211                terse,
5212                history,
5213                show_options,
5214            } => {
5215                write!(
5216                    f,
5217                    "SHOW {terse}SCHEMAS{history}{show_options}",
5218                    terse = if *terse { "TERSE " } else { "" },
5219                    history = if *history { " HISTORY" } else { "" },
5220                )?;
5221                Ok(())
5222            }
5223            Statement::ShowObjects(ShowObjects {
5224                terse,
5225                show_options,
5226            }) => {
5227                write!(
5228                    f,
5229                    "SHOW {terse}OBJECTS{show_options}",
5230                    terse = if *terse { "TERSE " } else { "" },
5231                )?;
5232                Ok(())
5233            }
5234            Statement::ShowTables {
5235                terse,
5236                history,
5237                extended,
5238                full,
5239                external,
5240                show_options,
5241            } => {
5242                write!(
5243                    f,
5244                    "SHOW {terse}{extended}{full}{external}TABLES{history}{show_options}",
5245                    terse = if *terse { "TERSE " } else { "" },
5246                    extended = if *extended { "EXTENDED " } else { "" },
5247                    full = if *full { "FULL " } else { "" },
5248                    external = if *external { "EXTERNAL " } else { "" },
5249                    history = if *history { " HISTORY" } else { "" },
5250                )?;
5251                Ok(())
5252            }
5253            Statement::ShowViews {
5254                terse,
5255                materialized,
5256                show_options,
5257            } => {
5258                write!(
5259                    f,
5260                    "SHOW {terse}{materialized}VIEWS{show_options}",
5261                    terse = if *terse { "TERSE " } else { "" },
5262                    materialized = if *materialized { "MATERIALIZED " } else { "" }
5263                )?;
5264                Ok(())
5265            }
5266            Statement::ShowFunctions { filter } => {
5267                write!(f, "SHOW FUNCTIONS")?;
5268                if let Some(filter) = filter {
5269                    write!(f, " {filter}")?;
5270                }
5271                Ok(())
5272            }
5273            Statement::Use(use_expr) => use_expr.fmt(f),
5274            Statement::ShowCollation { filter } => {
5275                write!(f, "SHOW COLLATION")?;
5276                if let Some(filter) = filter {
5277                    write!(f, " {filter}")?;
5278                }
5279                Ok(())
5280            }
5281            Statement::ShowCharset(show_stm) => show_stm.fmt(f),
5282            Statement::StartTransaction {
5283                modes,
5284                begin: syntax_begin,
5285                transaction,
5286                modifier,
5287                statements,
5288                exception,
5289                has_end_keyword,
5290            } => {
5291                if *syntax_begin {
5292                    if let Some(modifier) = *modifier {
5293                        write!(f, "BEGIN {modifier}")?;
5294                    } else {
5295                        write!(f, "BEGIN")?;
5296                    }
5297                } else {
5298                    write!(f, "START")?;
5299                }
5300                if let Some(transaction) = transaction {
5301                    write!(f, " {transaction}")?;
5302                }
5303                if !modes.is_empty() {
5304                    write!(f, " {}", display_comma_separated(modes))?;
5305                }
5306                if !statements.is_empty() {
5307                    write!(f, " ")?;
5308                    format_statement_list(f, statements)?;
5309                }
5310                if let Some(exception_when) = exception {
5311                    write!(f, " EXCEPTION")?;
5312                    for when in exception_when {
5313                        write!(f, " {when}")?;
5314                    }
5315                }
5316                if *has_end_keyword {
5317                    write!(f, " END")?;
5318                }
5319                Ok(())
5320            }
5321            Statement::Commit {
5322                chain,
5323                end: end_syntax,
5324                modifier,
5325            } => {
5326                if *end_syntax {
5327                    write!(f, "END")?;
5328                    if let Some(modifier) = *modifier {
5329                        write!(f, " {modifier}")?;
5330                    }
5331                    if *chain {
5332                        write!(f, " AND CHAIN")?;
5333                    }
5334                } else {
5335                    write!(f, "COMMIT{}", if *chain { " AND CHAIN" } else { "" })?;
5336                }
5337                Ok(())
5338            }
5339            Statement::Rollback { chain, savepoint } => {
5340                write!(f, "ROLLBACK")?;
5341
5342                if *chain {
5343                    write!(f, " AND CHAIN")?;
5344                }
5345
5346                if let Some(savepoint) = savepoint {
5347                    write!(f, " TO SAVEPOINT {savepoint}")?;
5348                }
5349
5350                Ok(())
5351            }
5352            Statement::CreateSchema {
5353                schema_name,
5354                if_not_exists,
5355                with,
5356                options,
5357                default_collate_spec,
5358                clone,
5359            } => {
5360                write!(
5361                    f,
5362                    "CREATE SCHEMA {if_not_exists}{name}",
5363                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5364                    name = schema_name
5365                )?;
5366
5367                if let Some(collate) = default_collate_spec {
5368                    write!(f, " DEFAULT COLLATE {collate}")?;
5369                }
5370
5371                if let Some(with) = with {
5372                    write!(f, " WITH ({})", display_comma_separated(with))?;
5373                }
5374
5375                if let Some(options) = options {
5376                    write!(f, " OPTIONS({})", display_comma_separated(options))?;
5377                }
5378
5379                if let Some(clone) = clone {
5380                    write!(f, " CLONE {clone}")?;
5381                }
5382                Ok(())
5383            }
5384            Statement::Assert { condition, message } => {
5385                write!(f, "ASSERT {condition}")?;
5386                if let Some(m) = message {
5387                    write!(f, " AS {m}")?;
5388                }
5389                Ok(())
5390            }
5391            Statement::Grant {
5392                privileges,
5393                objects,
5394                grantees,
5395                with_grant_option,
5396                as_grantor,
5397                granted_by,
5398                current_grants,
5399            } => {
5400                write!(f, "GRANT {privileges} ")?;
5401                if let Some(objects) = objects {
5402                    write!(f, "ON {objects} ")?;
5403                }
5404                write!(f, "TO {}", display_comma_separated(grantees))?;
5405                if *with_grant_option {
5406                    write!(f, " WITH GRANT OPTION")?;
5407                }
5408                if let Some(current_grants) = current_grants {
5409                    write!(f, " {current_grants}")?;
5410                }
5411                if let Some(grantor) = as_grantor {
5412                    write!(f, " AS {grantor}")?;
5413                }
5414                if let Some(grantor) = granted_by {
5415                    write!(f, " GRANTED BY {grantor}")?;
5416                }
5417                Ok(())
5418            }
5419            Statement::Deny(s) => write!(f, "{s}"),
5420            Statement::Revoke {
5421                privileges,
5422                objects,
5423                grantees,
5424                granted_by,
5425                cascade,
5426            } => {
5427                write!(f, "REVOKE {privileges} ")?;
5428                if let Some(objects) = objects {
5429                    write!(f, "ON {objects} ")?;
5430                }
5431                write!(f, "FROM {}", display_comma_separated(grantees))?;
5432                if let Some(grantor) = granted_by {
5433                    write!(f, " GRANTED BY {grantor}")?;
5434                }
5435                if let Some(cascade) = cascade {
5436                    write!(f, " {cascade}")?;
5437                }
5438                Ok(())
5439            }
5440            Statement::Deallocate { name, prepare } => write!(
5441                f,
5442                "DEALLOCATE {prepare}{name}",
5443                prepare = if *prepare { "PREPARE " } else { "" },
5444                name = name,
5445            ),
5446            Statement::Execute {
5447                name,
5448                parameters,
5449                has_parentheses,
5450                immediate,
5451                into,
5452                using,
5453                output,
5454                default,
5455            } => {
5456                let (open, close) = if *has_parentheses {
5457                    ("(", ")")
5458                } else {
5459                    (if parameters.is_empty() { "" } else { " " }, "")
5460                };
5461                write!(f, "EXECUTE")?;
5462                if *immediate {
5463                    write!(f, " IMMEDIATE")?;
5464                }
5465                if let Some(name) = name {
5466                    write!(f, " {name}")?;
5467                }
5468                write!(f, "{open}{}{close}", display_comma_separated(parameters),)?;
5469                if !into.is_empty() {
5470                    write!(f, " INTO {}", display_comma_separated(into))?;
5471                }
5472                if !using.is_empty() {
5473                    write!(f, " USING {}", display_comma_separated(using))?;
5474                };
5475                if *output {
5476                    write!(f, " OUTPUT")?;
5477                }
5478                if *default {
5479                    write!(f, " DEFAULT")?;
5480                }
5481                Ok(())
5482            }
5483            Statement::Prepare {
5484                name,
5485                data_types,
5486                statement,
5487            } => {
5488                write!(f, "PREPARE {name} ")?;
5489                if !data_types.is_empty() {
5490                    write!(f, "({}) ", display_comma_separated(data_types))?;
5491                }
5492                write!(f, "AS {statement}")
5493            }
5494            Statement::Comment {
5495                object_type,
5496                object_name,
5497                comment,
5498                if_exists,
5499            } => {
5500                write!(f, "COMMENT ")?;
5501                if *if_exists {
5502                    write!(f, "IF EXISTS ")?
5503                };
5504                write!(f, "ON {object_type} {object_name} IS ")?;
5505                if let Some(c) = comment {
5506                    write!(f, "'{c}'")
5507                } else {
5508                    write!(f, "NULL")
5509                }
5510            }
5511            Statement::Savepoint { name } => {
5512                write!(f, "SAVEPOINT ")?;
5513                write!(f, "{name}")
5514            }
5515            Statement::ReleaseSavepoint { name } => {
5516                write!(f, "RELEASE SAVEPOINT {name}")
5517            }
5518            Statement::Merge(merge) => merge.fmt(f),
5519            Statement::Cache {
5520                table_name,
5521                table_flag,
5522                has_as,
5523                options,
5524                query,
5525            } => {
5526                if let Some(table_flag) = table_flag {
5527                    write!(f, "CACHE {table_flag} TABLE {table_name}")?;
5528                } else {
5529                    write!(f, "CACHE TABLE {table_name}")?;
5530                }
5531
5532                if !options.is_empty() {
5533                    write!(f, " OPTIONS({})", display_comma_separated(options))?;
5534                }
5535
5536                match (*has_as, query) {
5537                    (true, Some(query)) => write!(f, " AS {query}"),
5538                    (true, None) => f.write_str(" AS"),
5539                    (false, Some(query)) => write!(f, " {query}"),
5540                    (false, None) => Ok(()),
5541                }
5542            }
5543            Statement::UNCache {
5544                table_name,
5545                if_exists,
5546            } => {
5547                if *if_exists {
5548                    write!(f, "UNCACHE TABLE IF EXISTS {table_name}")
5549                } else {
5550                    write!(f, "UNCACHE TABLE {table_name}")
5551                }
5552            }
5553            Statement::CreateSequence {
5554                temporary,
5555                if_not_exists,
5556                name,
5557                data_type,
5558                sequence_options,
5559                owned_by,
5560            } => {
5561                let as_type: String = if let Some(dt) = data_type.as_ref() {
5562                    //Cannot use format!(" AS {}", dt), due to format! is not available in --target thumbv6m-none-eabi
5563                    // " AS ".to_owned() + &dt.to_string()
5564                    [" AS ", &dt.to_string()].concat()
5565                } else {
5566                    "".to_string()
5567                };
5568                write!(
5569                    f,
5570                    "CREATE {temporary}SEQUENCE {if_not_exists}{name}{as_type}",
5571                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5572                    temporary = if *temporary { "TEMPORARY " } else { "" },
5573                    name = name,
5574                    as_type = as_type
5575                )?;
5576                for sequence_option in sequence_options {
5577                    write!(f, "{sequence_option}")?;
5578                }
5579                if let Some(ob) = owned_by.as_ref() {
5580                    write!(f, " OWNED BY {ob}")?;
5581                }
5582                write!(f, "")
5583            }
5584            Statement::CreateStage {
5585                or_replace,
5586                temporary,
5587                if_not_exists,
5588                name,
5589                stage_params,
5590                directory_table_params,
5591                file_format,
5592                copy_options,
5593                comment,
5594                ..
5595            } => {
5596                write!(
5597                    f,
5598                    "CREATE {or_replace}{temp}STAGE {if_not_exists}{name}{stage_params}",
5599                    temp = if *temporary { "TEMPORARY " } else { "" },
5600                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
5601                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5602                )?;
5603                if !directory_table_params.options.is_empty() {
5604                    write!(f, " DIRECTORY=({directory_table_params})")?;
5605                }
5606                if !file_format.options.is_empty() {
5607                    write!(f, " FILE_FORMAT=({file_format})")?;
5608                }
5609                if !copy_options.options.is_empty() {
5610                    write!(f, " COPY_OPTIONS=({copy_options})")?;
5611                }
5612                if comment.is_some() {
5613                    write!(f, " COMMENT='{}'", comment.as_ref().unwrap())?;
5614                }
5615                Ok(())
5616            }
5617            Statement::CopyIntoSnowflake {
5618                kind,
5619                into,
5620                into_columns,
5621                from_obj,
5622                from_obj_alias,
5623                stage_params,
5624                from_transformations,
5625                from_query,
5626                files,
5627                pattern,
5628                file_format,
5629                copy_options,
5630                validation_mode,
5631                partition,
5632            } => {
5633                write!(f, "COPY INTO {into}")?;
5634                if let Some(into_columns) = into_columns {
5635                    write!(f, " ({})", display_comma_separated(into_columns))?;
5636                }
5637                if let Some(from_transformations) = from_transformations {
5638                    // Data load with transformation
5639                    if let Some(from_stage) = from_obj {
5640                        write!(
5641                            f,
5642                            " FROM (SELECT {} FROM {}{}",
5643                            display_separated(from_transformations, ", "),
5644                            from_stage,
5645                            stage_params
5646                        )?;
5647                    }
5648                    if let Some(from_obj_alias) = from_obj_alias {
5649                        write!(f, " AS {from_obj_alias}")?;
5650                    }
5651                    write!(f, ")")?;
5652                } else if let Some(from_obj) = from_obj {
5653                    // Standard data load
5654                    write!(f, " FROM {from_obj}{stage_params}")?;
5655                    if let Some(from_obj_alias) = from_obj_alias {
5656                        write!(f, " AS {from_obj_alias}")?;
5657                    }
5658                } else if let Some(from_query) = from_query {
5659                    // Data unload from query
5660                    write!(f, " FROM ({from_query})")?;
5661                }
5662
5663                if let Some(files) = files {
5664                    write!(f, " FILES = ('{}')", display_separated(files, "', '"))?;
5665                }
5666                if let Some(pattern) = pattern {
5667                    write!(f, " PATTERN = '{pattern}'")?;
5668                }
5669                if let Some(partition) = partition {
5670                    write!(f, " PARTITION BY {partition}")?;
5671                }
5672                if !file_format.options.is_empty() {
5673                    write!(f, " FILE_FORMAT=({file_format})")?;
5674                }
5675                if !copy_options.options.is_empty() {
5676                    match kind {
5677                        CopyIntoSnowflakeKind::Table => {
5678                            write!(f, " COPY_OPTIONS=({copy_options})")?
5679                        }
5680                        CopyIntoSnowflakeKind::Location => write!(f, " {copy_options}")?,
5681                    }
5682                }
5683                if let Some(validation_mode) = validation_mode {
5684                    write!(f, " VALIDATION_MODE = {validation_mode}")?;
5685                }
5686                Ok(())
5687            }
5688            Statement::CreateType {
5689                name,
5690                representation,
5691            } => {
5692                write!(f, "CREATE TYPE {name}")?;
5693                if let Some(repr) = representation {
5694                    write!(f, " {repr}")?;
5695                }
5696                Ok(())
5697            }
5698            Statement::Pragma { name, value, is_eq } => {
5699                write!(f, "PRAGMA {name}")?;
5700                if value.is_some() {
5701                    let val = value.as_ref().unwrap();
5702                    if *is_eq {
5703                        write!(f, " = {val}")?;
5704                    } else {
5705                        write!(f, "({val})")?;
5706                    }
5707                }
5708                Ok(())
5709            }
5710            Statement::LockTables { tables } => {
5711                write!(f, "LOCK TABLES {}", display_comma_separated(tables))
5712            }
5713            Statement::UnlockTables => {
5714                write!(f, "UNLOCK TABLES")
5715            }
5716            Statement::Unload {
5717                query,
5718                query_text,
5719                to,
5720                auth,
5721                with,
5722                options,
5723            } => {
5724                write!(f, "UNLOAD(")?;
5725                if let Some(query) = query {
5726                    write!(f, "{query}")?;
5727                }
5728                if let Some(query_text) = query_text {
5729                    write!(f, "'{query_text}'")?;
5730                }
5731                write!(f, ") TO {to}")?;
5732                if let Some(auth) = auth {
5733                    write!(f, " IAM_ROLE {auth}")?;
5734                }
5735                if !with.is_empty() {
5736                    write!(f, " WITH ({})", display_comma_separated(with))?;
5737                }
5738                if !options.is_empty() {
5739                    write!(f, " {}", display_separated(options, " "))?;
5740                }
5741                Ok(())
5742            }
5743            Statement::OptimizeTable {
5744                name,
5745                on_cluster,
5746                partition,
5747                include_final,
5748                deduplicate,
5749            } => {
5750                write!(f, "OPTIMIZE TABLE {name}")?;
5751                if let Some(on_cluster) = on_cluster {
5752                    write!(f, " ON CLUSTER {on_cluster}")?;
5753                }
5754                if let Some(partition) = partition {
5755                    write!(f, " {partition}")?;
5756                }
5757                if *include_final {
5758                    write!(f, " FINAL")?;
5759                }
5760                if let Some(deduplicate) = deduplicate {
5761                    write!(f, " {deduplicate}")?;
5762                }
5763                Ok(())
5764            }
5765            Statement::LISTEN { channel } => {
5766                write!(f, "LISTEN {channel}")?;
5767                Ok(())
5768            }
5769            Statement::UNLISTEN { channel } => {
5770                write!(f, "UNLISTEN {channel}")?;
5771                Ok(())
5772            }
5773            Statement::NOTIFY { channel, payload } => {
5774                write!(f, "NOTIFY {channel}")?;
5775                if let Some(payload) = payload {
5776                    write!(f, ", '{payload}'")?;
5777                }
5778                Ok(())
5779            }
5780            Statement::RenameTable(rename_tables) => {
5781                write!(f, "RENAME TABLE {}", display_comma_separated(rename_tables))
5782            }
5783            Statement::RaisError {
5784                message,
5785                severity,
5786                state,
5787                arguments,
5788                options,
5789            } => {
5790                write!(f, "RAISERROR({message}, {severity}, {state}")?;
5791                if !arguments.is_empty() {
5792                    write!(f, ", {}", display_comma_separated(arguments))?;
5793                }
5794                write!(f, ")")?;
5795                if !options.is_empty() {
5796                    write!(f, " WITH {}", display_comma_separated(options))?;
5797                }
5798                Ok(())
5799            }
5800            Statement::Print(s) => write!(f, "{s}"),
5801            Statement::Return(r) => write!(f, "{r}"),
5802            Statement::List(command) => write!(f, "LIST {command}"),
5803            Statement::Remove(command) => write!(f, "REMOVE {command}"),
5804            Statement::ExportData(e) => write!(f, "{e}"),
5805            Statement::CreateUser(s) => write!(f, "{s}"),
5806            Statement::AlterSchema(s) => write!(f, "{s}"),
5807            Statement::Vacuum(s) => write!(f, "{s}"),
5808            Statement::AlterUser(s) => write!(f, "{s}"),
5809            Statement::Reset(s) => write!(f, "{s}"),
5810        }
5811    }
5812}
5813
5814/// Can use to describe options in create sequence or table column type identity
5815/// ```sql
5816/// [ INCREMENT [ BY ] increment ]
5817///     [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
5818///     [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
5819/// ```
5820#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5821#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5822#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5823pub enum SequenceOptions {
5824    IncrementBy(Expr, bool),
5825    MinValue(Option<Expr>),
5826    MaxValue(Option<Expr>),
5827    StartWith(Expr, bool),
5828    Cache(Expr),
5829    Cycle(bool),
5830}
5831
5832impl fmt::Display for SequenceOptions {
5833    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5834        match self {
5835            SequenceOptions::IncrementBy(increment, by) => {
5836                write!(
5837                    f,
5838                    " INCREMENT{by} {increment}",
5839                    by = if *by { " BY" } else { "" },
5840                    increment = increment
5841                )
5842            }
5843            SequenceOptions::MinValue(Some(expr)) => {
5844                write!(f, " MINVALUE {expr}")
5845            }
5846            SequenceOptions::MinValue(None) => {
5847                write!(f, " NO MINVALUE")
5848            }
5849            SequenceOptions::MaxValue(Some(expr)) => {
5850                write!(f, " MAXVALUE {expr}")
5851            }
5852            SequenceOptions::MaxValue(None) => {
5853                write!(f, " NO MAXVALUE")
5854            }
5855            SequenceOptions::StartWith(start, with) => {
5856                write!(
5857                    f,
5858                    " START{with} {start}",
5859                    with = if *with { " WITH" } else { "" },
5860                    start = start
5861                )
5862            }
5863            SequenceOptions::Cache(cache) => {
5864                write!(f, " CACHE {}", *cache)
5865            }
5866            SequenceOptions::Cycle(no) => {
5867                write!(f, " {}CYCLE", if *no { "NO " } else { "" })
5868            }
5869        }
5870    }
5871}
5872
5873/// Assignment for a `SET` statement (name [=|TO] value)
5874#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5875#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5876#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5877pub struct SetAssignment {
5878    pub scope: Option<ContextModifier>,
5879    pub name: ObjectName,
5880    pub value: Expr,
5881}
5882
5883impl fmt::Display for SetAssignment {
5884    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5885        write!(
5886            f,
5887            "{}{} = {}",
5888            self.scope.map(|s| format!("{s}")).unwrap_or_default(),
5889            self.name,
5890            self.value
5891        )
5892    }
5893}
5894
5895/// Target of a `TRUNCATE TABLE` command
5896///
5897/// Note this is its own struct because `visit_relation` requires an `ObjectName` (not a `Vec<ObjectName>`)
5898#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5899#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5900#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5901pub struct TruncateTableTarget {
5902    /// name of the table being truncated
5903    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
5904    pub name: ObjectName,
5905    /// Postgres-specific option
5906    /// [ TRUNCATE TABLE ONLY ]
5907    /// <https://www.postgresql.org/docs/current/sql-truncate.html>
5908    pub only: bool,
5909}
5910
5911impl fmt::Display for TruncateTableTarget {
5912    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5913        if self.only {
5914            write!(f, "ONLY ")?;
5915        };
5916        write!(f, "{}", self.name)
5917    }
5918}
5919
5920/// PostgreSQL identity option for TRUNCATE table
5921/// [ RESTART IDENTITY | CONTINUE IDENTITY ]
5922#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5923#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5924#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5925pub enum TruncateIdentityOption {
5926    Restart,
5927    Continue,
5928}
5929
5930/// Cascade/restrict option for Postgres TRUNCATE table, MySQL GRANT/REVOKE, etc.
5931/// [ CASCADE | RESTRICT ]
5932#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5933#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5934#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5935pub enum CascadeOption {
5936    Cascade,
5937    Restrict,
5938}
5939
5940impl Display for CascadeOption {
5941    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5942        match self {
5943            CascadeOption::Cascade => write!(f, "CASCADE"),
5944            CascadeOption::Restrict => write!(f, "RESTRICT"),
5945        }
5946    }
5947}
5948
5949/// Transaction started with [ TRANSACTION | WORK ]
5950#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5951#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5952#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5953pub enum BeginTransactionKind {
5954    Transaction,
5955    Work,
5956}
5957
5958impl Display for BeginTransactionKind {
5959    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5960        match self {
5961            BeginTransactionKind::Transaction => write!(f, "TRANSACTION"),
5962            BeginTransactionKind::Work => write!(f, "WORK"),
5963        }
5964    }
5965}
5966
5967/// Can use to describe options in  create sequence or table column type identity
5968/// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
5969#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5970#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5971#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5972pub enum MinMaxValue {
5973    // clause is not specified
5974    Empty,
5975    // NO MINVALUE/NO MAXVALUE
5976    None,
5977    // MINVALUE <expr> / MAXVALUE <expr>
5978    Some(Expr),
5979}
5980
5981#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5982#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5983#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5984#[non_exhaustive]
5985pub enum OnInsert {
5986    /// ON DUPLICATE KEY UPDATE (MySQL when the key already exists, then execute an update instead)
5987    DuplicateKeyUpdate(Vec<Assignment>),
5988    /// ON CONFLICT is a PostgreSQL and Sqlite extension
5989    OnConflict(OnConflict),
5990}
5991
5992#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5993#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5994#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5995pub struct InsertAliases {
5996    pub row_alias: ObjectName,
5997    pub col_aliases: Option<Vec<Ident>>,
5998}
5999
6000#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6001#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6002#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6003pub struct OnConflict {
6004    pub conflict_target: Option<ConflictTarget>,
6005    pub action: OnConflictAction,
6006}
6007#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6008#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6009#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6010pub enum ConflictTarget {
6011    Columns(Vec<Ident>),
6012    OnConstraint(ObjectName),
6013}
6014#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6015#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6016#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6017pub enum OnConflictAction {
6018    DoNothing,
6019    DoUpdate(DoUpdate),
6020}
6021
6022#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6023#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6024#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6025pub struct DoUpdate {
6026    /// Column assignments
6027    pub assignments: Vec<Assignment>,
6028    /// WHERE
6029    pub selection: Option<Expr>,
6030}
6031
6032impl fmt::Display for OnInsert {
6033    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6034        match self {
6035            Self::DuplicateKeyUpdate(expr) => write!(
6036                f,
6037                " ON DUPLICATE KEY UPDATE {}",
6038                display_comma_separated(expr)
6039            ),
6040            Self::OnConflict(o) => write!(f, "{o}"),
6041        }
6042    }
6043}
6044impl fmt::Display for OnConflict {
6045    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6046        write!(f, " ON CONFLICT")?;
6047        if let Some(target) = &self.conflict_target {
6048            write!(f, "{target}")?;
6049        }
6050        write!(f, " {}", self.action)
6051    }
6052}
6053impl fmt::Display for ConflictTarget {
6054    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6055        match self {
6056            ConflictTarget::Columns(cols) => write!(f, "({})", display_comma_separated(cols)),
6057            ConflictTarget::OnConstraint(name) => write!(f, " ON CONSTRAINT {name}"),
6058        }
6059    }
6060}
6061impl fmt::Display for OnConflictAction {
6062    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6063        match self {
6064            Self::DoNothing => write!(f, "DO NOTHING"),
6065            Self::DoUpdate(do_update) => {
6066                write!(f, "DO UPDATE")?;
6067                if !do_update.assignments.is_empty() {
6068                    write!(
6069                        f,
6070                        " SET {}",
6071                        display_comma_separated(&do_update.assignments)
6072                    )?;
6073                }
6074                if let Some(selection) = &do_update.selection {
6075                    write!(f, " WHERE {selection}")?;
6076                }
6077                Ok(())
6078            }
6079        }
6080    }
6081}
6082
6083/// Privileges granted in a GRANT statement or revoked in a REVOKE statement.
6084#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6085#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6086#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6087pub enum Privileges {
6088    /// All privileges applicable to the object type
6089    All {
6090        /// Optional keyword from the spec, ignored in practice
6091        with_privileges_keyword: bool,
6092    },
6093    /// Specific privileges (e.g. `SELECT`, `INSERT`)
6094    Actions(Vec<Action>),
6095}
6096
6097impl fmt::Display for Privileges {
6098    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6099        match self {
6100            Privileges::All {
6101                with_privileges_keyword,
6102            } => {
6103                write!(
6104                    f,
6105                    "ALL{}",
6106                    if *with_privileges_keyword {
6107                        " PRIVILEGES"
6108                    } else {
6109                        ""
6110                    }
6111                )
6112            }
6113            Privileges::Actions(actions) => {
6114                write!(f, "{}", display_comma_separated(actions))
6115            }
6116        }
6117    }
6118}
6119
6120/// Specific direction for FETCH statement
6121#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6122#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6123#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6124pub enum FetchDirection {
6125    Count { limit: Value },
6126    Next,
6127    Prior,
6128    First,
6129    Last,
6130    Absolute { limit: Value },
6131    Relative { limit: Value },
6132    All,
6133    // FORWARD
6134    // FORWARD count
6135    Forward { limit: Option<Value> },
6136    ForwardAll,
6137    // BACKWARD
6138    // BACKWARD count
6139    Backward { limit: Option<Value> },
6140    BackwardAll,
6141}
6142
6143impl fmt::Display for FetchDirection {
6144    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6145        match self {
6146            FetchDirection::Count { limit } => f.write_str(&limit.to_string())?,
6147            FetchDirection::Next => f.write_str("NEXT")?,
6148            FetchDirection::Prior => f.write_str("PRIOR")?,
6149            FetchDirection::First => f.write_str("FIRST")?,
6150            FetchDirection::Last => f.write_str("LAST")?,
6151            FetchDirection::Absolute { limit } => {
6152                f.write_str("ABSOLUTE ")?;
6153                f.write_str(&limit.to_string())?;
6154            }
6155            FetchDirection::Relative { limit } => {
6156                f.write_str("RELATIVE ")?;
6157                f.write_str(&limit.to_string())?;
6158            }
6159            FetchDirection::All => f.write_str("ALL")?,
6160            FetchDirection::Forward { limit } => {
6161                f.write_str("FORWARD")?;
6162
6163                if let Some(l) = limit {
6164                    f.write_str(" ")?;
6165                    f.write_str(&l.to_string())?;
6166                }
6167            }
6168            FetchDirection::ForwardAll => f.write_str("FORWARD ALL")?,
6169            FetchDirection::Backward { limit } => {
6170                f.write_str("BACKWARD")?;
6171
6172                if let Some(l) = limit {
6173                    f.write_str(" ")?;
6174                    f.write_str(&l.to_string())?;
6175                }
6176            }
6177            FetchDirection::BackwardAll => f.write_str("BACKWARD ALL")?,
6178        };
6179
6180        Ok(())
6181    }
6182}
6183
6184/// The "position" for a FETCH statement.
6185///
6186/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/fetch-transact-sql)
6187#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6188#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6189#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6190pub enum FetchPosition {
6191    From,
6192    In,
6193}
6194
6195impl fmt::Display for FetchPosition {
6196    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6197        match self {
6198            FetchPosition::From => f.write_str("FROM")?,
6199            FetchPosition::In => f.write_str("IN")?,
6200        };
6201
6202        Ok(())
6203    }
6204}
6205
6206/// A privilege on a database object (table, sequence, etc.).
6207#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6208#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6209#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6210pub enum Action {
6211    AddSearchOptimization,
6212    Apply {
6213        apply_type: ActionApplyType,
6214    },
6215    ApplyBudget,
6216    AttachListing,
6217    AttachPolicy,
6218    Audit,
6219    BindServiceEndpoint,
6220    Connect,
6221    Create {
6222        obj_type: Option<ActionCreateObjectType>,
6223    },
6224    DatabaseRole {
6225        role: ObjectName,
6226    },
6227    Delete,
6228    Drop,
6229    EvolveSchema,
6230    Exec {
6231        obj_type: Option<ActionExecuteObjectType>,
6232    },
6233    Execute {
6234        obj_type: Option<ActionExecuteObjectType>,
6235    },
6236    Failover,
6237    ImportedPrivileges,
6238    ImportShare,
6239    Insert {
6240        columns: Option<Vec<Ident>>,
6241    },
6242    Manage {
6243        manage_type: ActionManageType,
6244    },
6245    ManageReleases,
6246    ManageVersions,
6247    Modify {
6248        modify_type: Option<ActionModifyType>,
6249    },
6250    Monitor {
6251        monitor_type: Option<ActionMonitorType>,
6252    },
6253    Operate,
6254    OverrideShareRestrictions,
6255    Ownership,
6256    PurchaseDataExchangeListing,
6257    Read,
6258    ReadSession,
6259    References {
6260        columns: Option<Vec<Ident>>,
6261    },
6262    Replicate,
6263    ResolveAll,
6264    Role {
6265        role: ObjectName,
6266    },
6267    Select {
6268        columns: Option<Vec<Ident>>,
6269    },
6270    Temporary,
6271    Trigger,
6272    Truncate,
6273    Update {
6274        columns: Option<Vec<Ident>>,
6275    },
6276    Usage,
6277}
6278
6279impl fmt::Display for Action {
6280    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6281        match self {
6282            Action::AddSearchOptimization => f.write_str("ADD SEARCH OPTIMIZATION")?,
6283            Action::Apply { apply_type } => write!(f, "APPLY {apply_type}")?,
6284            Action::ApplyBudget => f.write_str("APPLYBUDGET")?,
6285            Action::AttachListing => f.write_str("ATTACH LISTING")?,
6286            Action::AttachPolicy => f.write_str("ATTACH POLICY")?,
6287            Action::Audit => f.write_str("AUDIT")?,
6288            Action::BindServiceEndpoint => f.write_str("BIND SERVICE ENDPOINT")?,
6289            Action::Connect => f.write_str("CONNECT")?,
6290            Action::Create { obj_type } => {
6291                f.write_str("CREATE")?;
6292                if let Some(obj_type) = obj_type {
6293                    write!(f, " {obj_type}")?
6294                }
6295            }
6296            Action::DatabaseRole { role } => write!(f, "DATABASE ROLE {role}")?,
6297            Action::Delete => f.write_str("DELETE")?,
6298            Action::Drop => f.write_str("DROP")?,
6299            Action::EvolveSchema => f.write_str("EVOLVE SCHEMA")?,
6300            Action::Exec { obj_type } => {
6301                f.write_str("EXEC")?;
6302                if let Some(obj_type) = obj_type {
6303                    write!(f, " {obj_type}")?
6304                }
6305            }
6306            Action::Execute { obj_type } => {
6307                f.write_str("EXECUTE")?;
6308                if let Some(obj_type) = obj_type {
6309                    write!(f, " {obj_type}")?
6310                }
6311            }
6312            Action::Failover => f.write_str("FAILOVER")?,
6313            Action::ImportedPrivileges => f.write_str("IMPORTED PRIVILEGES")?,
6314            Action::ImportShare => f.write_str("IMPORT SHARE")?,
6315            Action::Insert { .. } => f.write_str("INSERT")?,
6316            Action::Manage { manage_type } => write!(f, "MANAGE {manage_type}")?,
6317            Action::ManageReleases => f.write_str("MANAGE RELEASES")?,
6318            Action::ManageVersions => f.write_str("MANAGE VERSIONS")?,
6319            Action::Modify { modify_type } => {
6320                write!(f, "MODIFY")?;
6321                if let Some(modify_type) = modify_type {
6322                    write!(f, " {modify_type}")?;
6323                }
6324            }
6325            Action::Monitor { monitor_type } => {
6326                write!(f, "MONITOR")?;
6327                if let Some(monitor_type) = monitor_type {
6328                    write!(f, " {monitor_type}")?
6329                }
6330            }
6331            Action::Operate => f.write_str("OPERATE")?,
6332            Action::OverrideShareRestrictions => f.write_str("OVERRIDE SHARE RESTRICTIONS")?,
6333            Action::Ownership => f.write_str("OWNERSHIP")?,
6334            Action::PurchaseDataExchangeListing => f.write_str("PURCHASE DATA EXCHANGE LISTING")?,
6335            Action::Read => f.write_str("READ")?,
6336            Action::ReadSession => f.write_str("READ SESSION")?,
6337            Action::References { .. } => f.write_str("REFERENCES")?,
6338            Action::Replicate => f.write_str("REPLICATE")?,
6339            Action::ResolveAll => f.write_str("RESOLVE ALL")?,
6340            Action::Role { role } => write!(f, "ROLE {role}")?,
6341            Action::Select { .. } => f.write_str("SELECT")?,
6342            Action::Temporary => f.write_str("TEMPORARY")?,
6343            Action::Trigger => f.write_str("TRIGGER")?,
6344            Action::Truncate => f.write_str("TRUNCATE")?,
6345            Action::Update { .. } => f.write_str("UPDATE")?,
6346            Action::Usage => f.write_str("USAGE")?,
6347        };
6348        match self {
6349            Action::Insert { columns }
6350            | Action::References { columns }
6351            | Action::Select { columns }
6352            | Action::Update { columns } => {
6353                if let Some(columns) = columns {
6354                    write!(f, " ({})", display_comma_separated(columns))?;
6355                }
6356            }
6357            _ => (),
6358        };
6359        Ok(())
6360    }
6361}
6362
6363#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6364#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6365#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6366/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6367/// under `globalPrivileges` in the `CREATE` privilege.
6368pub enum ActionCreateObjectType {
6369    Account,
6370    Application,
6371    ApplicationPackage,
6372    ComputePool,
6373    DataExchangeListing,
6374    Database,
6375    ExternalVolume,
6376    FailoverGroup,
6377    Integration,
6378    NetworkPolicy,
6379    OrganiationListing,
6380    ReplicationGroup,
6381    Role,
6382    Schema,
6383    Share,
6384    User,
6385    Warehouse,
6386}
6387
6388impl fmt::Display for ActionCreateObjectType {
6389    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6390        match self {
6391            ActionCreateObjectType::Account => write!(f, "ACCOUNT"),
6392            ActionCreateObjectType::Application => write!(f, "APPLICATION"),
6393            ActionCreateObjectType::ApplicationPackage => write!(f, "APPLICATION PACKAGE"),
6394            ActionCreateObjectType::ComputePool => write!(f, "COMPUTE POOL"),
6395            ActionCreateObjectType::DataExchangeListing => write!(f, "DATA EXCHANGE LISTING"),
6396            ActionCreateObjectType::Database => write!(f, "DATABASE"),
6397            ActionCreateObjectType::ExternalVolume => write!(f, "EXTERNAL VOLUME"),
6398            ActionCreateObjectType::FailoverGroup => write!(f, "FAILOVER GROUP"),
6399            ActionCreateObjectType::Integration => write!(f, "INTEGRATION"),
6400            ActionCreateObjectType::NetworkPolicy => write!(f, "NETWORK POLICY"),
6401            ActionCreateObjectType::OrganiationListing => write!(f, "ORGANIZATION LISTING"),
6402            ActionCreateObjectType::ReplicationGroup => write!(f, "REPLICATION GROUP"),
6403            ActionCreateObjectType::Role => write!(f, "ROLE"),
6404            ActionCreateObjectType::Schema => write!(f, "SCHEMA"),
6405            ActionCreateObjectType::Share => write!(f, "SHARE"),
6406            ActionCreateObjectType::User => write!(f, "USER"),
6407            ActionCreateObjectType::Warehouse => write!(f, "WAREHOUSE"),
6408        }
6409    }
6410}
6411
6412#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6413#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6414#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6415/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6416/// under `globalPrivileges` in the `APPLY` privilege.
6417pub enum ActionApplyType {
6418    AggregationPolicy,
6419    AuthenticationPolicy,
6420    JoinPolicy,
6421    MaskingPolicy,
6422    PackagesPolicy,
6423    PasswordPolicy,
6424    ProjectionPolicy,
6425    RowAccessPolicy,
6426    SessionPolicy,
6427    Tag,
6428}
6429
6430impl fmt::Display for ActionApplyType {
6431    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6432        match self {
6433            ActionApplyType::AggregationPolicy => write!(f, "AGGREGATION POLICY"),
6434            ActionApplyType::AuthenticationPolicy => write!(f, "AUTHENTICATION POLICY"),
6435            ActionApplyType::JoinPolicy => write!(f, "JOIN POLICY"),
6436            ActionApplyType::MaskingPolicy => write!(f, "MASKING POLICY"),
6437            ActionApplyType::PackagesPolicy => write!(f, "PACKAGES POLICY"),
6438            ActionApplyType::PasswordPolicy => write!(f, "PASSWORD POLICY"),
6439            ActionApplyType::ProjectionPolicy => write!(f, "PROJECTION POLICY"),
6440            ActionApplyType::RowAccessPolicy => write!(f, "ROW ACCESS POLICY"),
6441            ActionApplyType::SessionPolicy => write!(f, "SESSION POLICY"),
6442            ActionApplyType::Tag => write!(f, "TAG"),
6443        }
6444    }
6445}
6446
6447#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6448#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6449#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6450/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6451/// under `globalPrivileges` in the `EXECUTE` privilege.
6452pub enum ActionExecuteObjectType {
6453    Alert,
6454    DataMetricFunction,
6455    ManagedAlert,
6456    ManagedTask,
6457    Task,
6458}
6459
6460impl fmt::Display for ActionExecuteObjectType {
6461    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6462        match self {
6463            ActionExecuteObjectType::Alert => write!(f, "ALERT"),
6464            ActionExecuteObjectType::DataMetricFunction => write!(f, "DATA METRIC FUNCTION"),
6465            ActionExecuteObjectType::ManagedAlert => write!(f, "MANAGED ALERT"),
6466            ActionExecuteObjectType::ManagedTask => write!(f, "MANAGED TASK"),
6467            ActionExecuteObjectType::Task => write!(f, "TASK"),
6468        }
6469    }
6470}
6471
6472#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6473#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6474#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6475/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6476/// under `globalPrivileges` in the `MANAGE` privilege.
6477pub enum ActionManageType {
6478    AccountSupportCases,
6479    EventSharing,
6480    Grants,
6481    ListingAutoFulfillment,
6482    OrganizationSupportCases,
6483    UserSupportCases,
6484    Warehouses,
6485}
6486
6487impl fmt::Display for ActionManageType {
6488    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6489        match self {
6490            ActionManageType::AccountSupportCases => write!(f, "ACCOUNT SUPPORT CASES"),
6491            ActionManageType::EventSharing => write!(f, "EVENT SHARING"),
6492            ActionManageType::Grants => write!(f, "GRANTS"),
6493            ActionManageType::ListingAutoFulfillment => write!(f, "LISTING AUTO FULFILLMENT"),
6494            ActionManageType::OrganizationSupportCases => write!(f, "ORGANIZATION SUPPORT CASES"),
6495            ActionManageType::UserSupportCases => write!(f, "USER SUPPORT CASES"),
6496            ActionManageType::Warehouses => write!(f, "WAREHOUSES"),
6497        }
6498    }
6499}
6500
6501#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6502#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6503#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6504/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6505/// under `globalPrivileges` in the `MODIFY` privilege.
6506pub enum ActionModifyType {
6507    LogLevel,
6508    TraceLevel,
6509    SessionLogLevel,
6510    SessionTraceLevel,
6511}
6512
6513impl fmt::Display for ActionModifyType {
6514    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6515        match self {
6516            ActionModifyType::LogLevel => write!(f, "LOG LEVEL"),
6517            ActionModifyType::TraceLevel => write!(f, "TRACE LEVEL"),
6518            ActionModifyType::SessionLogLevel => write!(f, "SESSION LOG LEVEL"),
6519            ActionModifyType::SessionTraceLevel => write!(f, "SESSION TRACE LEVEL"),
6520        }
6521    }
6522}
6523
6524#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6525#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6526#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6527/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6528/// under `globalPrivileges` in the `MONITOR` privilege.
6529pub enum ActionMonitorType {
6530    Execution,
6531    Security,
6532    Usage,
6533}
6534
6535impl fmt::Display for ActionMonitorType {
6536    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6537        match self {
6538            ActionMonitorType::Execution => write!(f, "EXECUTION"),
6539            ActionMonitorType::Security => write!(f, "SECURITY"),
6540            ActionMonitorType::Usage => write!(f, "USAGE"),
6541        }
6542    }
6543}
6544
6545/// The principal that receives the privileges
6546#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6547#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6548#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6549pub struct Grantee {
6550    pub grantee_type: GranteesType,
6551    pub name: Option<GranteeName>,
6552}
6553
6554impl fmt::Display for Grantee {
6555    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6556        match self.grantee_type {
6557            GranteesType::Role => {
6558                write!(f, "ROLE ")?;
6559            }
6560            GranteesType::Share => {
6561                write!(f, "SHARE ")?;
6562            }
6563            GranteesType::User => {
6564                write!(f, "USER ")?;
6565            }
6566            GranteesType::Group => {
6567                write!(f, "GROUP ")?;
6568            }
6569            GranteesType::Public => {
6570                write!(f, "PUBLIC ")?;
6571            }
6572            GranteesType::DatabaseRole => {
6573                write!(f, "DATABASE ROLE ")?;
6574            }
6575            GranteesType::Application => {
6576                write!(f, "APPLICATION ")?;
6577            }
6578            GranteesType::ApplicationRole => {
6579                write!(f, "APPLICATION ROLE ")?;
6580            }
6581            GranteesType::None => (),
6582        }
6583        if let Some(ref name) = self.name {
6584            name.fmt(f)?;
6585        }
6586        Ok(())
6587    }
6588}
6589
6590#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6591#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6592#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6593pub enum GranteesType {
6594    Role,
6595    Share,
6596    User,
6597    Group,
6598    Public,
6599    DatabaseRole,
6600    Application,
6601    ApplicationRole,
6602    None,
6603}
6604
6605/// Users/roles designated in a GRANT/REVOKE
6606#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6607#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6608#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6609pub enum GranteeName {
6610    /// A bare identifier
6611    ObjectName(ObjectName),
6612    /// A MySQL user/host pair such as 'root'@'%'
6613    UserHost { user: Ident, host: Ident },
6614}
6615
6616impl fmt::Display for GranteeName {
6617    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6618        match self {
6619            GranteeName::ObjectName(name) => name.fmt(f),
6620            GranteeName::UserHost { user, host } => {
6621                write!(f, "{user}@{host}")
6622            }
6623        }
6624    }
6625}
6626
6627/// Objects on which privileges are granted in a GRANT statement.
6628#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6629#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6630#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6631pub enum GrantObjects {
6632    /// Grant privileges on `ALL SEQUENCES IN SCHEMA <schema_name> [, ...]`
6633    AllSequencesInSchema { schemas: Vec<ObjectName> },
6634    /// Grant privileges on `ALL TABLES IN SCHEMA <schema_name> [, ...]`
6635    AllTablesInSchema { schemas: Vec<ObjectName> },
6636    /// Grant privileges on `ALL VIEWS IN SCHEMA <schema_name> [, ...]`
6637    AllViewsInSchema { schemas: Vec<ObjectName> },
6638    /// Grant privileges on `ALL MATERIALIZED VIEWS IN SCHEMA <schema_name> [, ...]`
6639    AllMaterializedViewsInSchema { schemas: Vec<ObjectName> },
6640    /// Grant privileges on `ALL EXTERNAL TABLES IN SCHEMA <schema_name> [, ...]`
6641    AllExternalTablesInSchema { schemas: Vec<ObjectName> },
6642    /// Grant privileges on `ALL FUNCTIONS IN SCHEMA <schema_name> [, ...]`
6643    AllFunctionsInSchema { schemas: Vec<ObjectName> },
6644    /// Grant privileges on `FUTURE SCHEMAS IN DATABASE <database_name> [, ...]`
6645    FutureSchemasInDatabase { databases: Vec<ObjectName> },
6646    /// Grant privileges on `FUTURE TABLES IN SCHEMA <schema_name> [, ...]`
6647    FutureTablesInSchema { schemas: Vec<ObjectName> },
6648    /// Grant privileges on `FUTURE VIEWS IN SCHEMA <schema_name> [, ...]`
6649    FutureViewsInSchema { schemas: Vec<ObjectName> },
6650    /// Grant privileges on `FUTURE EXTERNAL TABLES IN SCHEMA <schema_name> [, ...]`
6651    FutureExternalTablesInSchema { schemas: Vec<ObjectName> },
6652    /// Grant privileges on `FUTURE MATERIALIZED VIEWS IN SCHEMA <schema_name> [, ...]`
6653    FutureMaterializedViewsInSchema { schemas: Vec<ObjectName> },
6654    /// Grant privileges on `FUTURE SEQUENCES IN SCHEMA <schema_name> [, ...]`
6655    FutureSequencesInSchema { schemas: Vec<ObjectName> },
6656    /// Grant privileges on specific databases
6657    Databases(Vec<ObjectName>),
6658    /// Grant privileges on specific schemas
6659    Schemas(Vec<ObjectName>),
6660    /// Grant privileges on specific sequences
6661    Sequences(Vec<ObjectName>),
6662    /// Grant privileges on specific tables
6663    Tables(Vec<ObjectName>),
6664    /// Grant privileges on specific views
6665    Views(Vec<ObjectName>),
6666    /// Grant privileges on specific warehouses
6667    Warehouses(Vec<ObjectName>),
6668    /// Grant privileges on specific integrations
6669    Integrations(Vec<ObjectName>),
6670    /// Grant privileges on resource monitors
6671    ResourceMonitors(Vec<ObjectName>),
6672    /// Grant privileges on users
6673    Users(Vec<ObjectName>),
6674    /// Grant privileges on compute pools
6675    ComputePools(Vec<ObjectName>),
6676    /// Grant privileges on connections
6677    Connections(Vec<ObjectName>),
6678    /// Grant privileges on failover groups
6679    FailoverGroup(Vec<ObjectName>),
6680    /// Grant privileges on replication group
6681    ReplicationGroup(Vec<ObjectName>),
6682    /// Grant privileges on external volumes
6683    ExternalVolumes(Vec<ObjectName>),
6684    /// Grant privileges on a procedure. In dialects that
6685    /// support overloading, the argument types must be specified.
6686    ///
6687    /// For example:
6688    /// `GRANT USAGE ON PROCEDURE foo(varchar) TO ROLE role1`
6689    Procedure {
6690        name: ObjectName,
6691        arg_types: Vec<DataType>,
6692    },
6693
6694    /// Grant privileges on a function. In dialects that
6695    /// support overloading, the argument types must be specified.
6696    ///
6697    /// For example:
6698    /// `GRANT USAGE ON FUNCTION foo(varchar) TO ROLE role1`
6699    Function {
6700        name: ObjectName,
6701        arg_types: Vec<DataType>,
6702    },
6703}
6704
6705impl fmt::Display for GrantObjects {
6706    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6707        match self {
6708            GrantObjects::Sequences(sequences) => {
6709                write!(f, "SEQUENCE {}", display_comma_separated(sequences))
6710            }
6711            GrantObjects::Databases(databases) => {
6712                write!(f, "DATABASE {}", display_comma_separated(databases))
6713            }
6714            GrantObjects::Schemas(schemas) => {
6715                write!(f, "SCHEMA {}", display_comma_separated(schemas))
6716            }
6717            GrantObjects::Tables(tables) => {
6718                write!(f, "{}", display_comma_separated(tables))
6719            }
6720            GrantObjects::Views(views) => {
6721                write!(f, "VIEW {}", display_comma_separated(views))
6722            }
6723            GrantObjects::Warehouses(warehouses) => {
6724                write!(f, "WAREHOUSE {}", display_comma_separated(warehouses))
6725            }
6726            GrantObjects::Integrations(integrations) => {
6727                write!(f, "INTEGRATION {}", display_comma_separated(integrations))
6728            }
6729            GrantObjects::AllSequencesInSchema { schemas } => {
6730                write!(
6731                    f,
6732                    "ALL SEQUENCES IN SCHEMA {}",
6733                    display_comma_separated(schemas)
6734                )
6735            }
6736            GrantObjects::AllTablesInSchema { schemas } => {
6737                write!(
6738                    f,
6739                    "ALL TABLES IN SCHEMA {}",
6740                    display_comma_separated(schemas)
6741                )
6742            }
6743            GrantObjects::AllExternalTablesInSchema { schemas } => {
6744                write!(
6745                    f,
6746                    "ALL EXTERNAL TABLES IN SCHEMA {}",
6747                    display_comma_separated(schemas)
6748                )
6749            }
6750            GrantObjects::AllViewsInSchema { schemas } => {
6751                write!(
6752                    f,
6753                    "ALL VIEWS IN SCHEMA {}",
6754                    display_comma_separated(schemas)
6755                )
6756            }
6757            GrantObjects::AllMaterializedViewsInSchema { schemas } => {
6758                write!(
6759                    f,
6760                    "ALL MATERIALIZED VIEWS IN SCHEMA {}",
6761                    display_comma_separated(schemas)
6762                )
6763            }
6764            GrantObjects::AllFunctionsInSchema { schemas } => {
6765                write!(
6766                    f,
6767                    "ALL FUNCTIONS IN SCHEMA {}",
6768                    display_comma_separated(schemas)
6769                )
6770            }
6771            GrantObjects::FutureSchemasInDatabase { databases } => {
6772                write!(
6773                    f,
6774                    "FUTURE SCHEMAS IN DATABASE {}",
6775                    display_comma_separated(databases)
6776                )
6777            }
6778            GrantObjects::FutureTablesInSchema { schemas } => {
6779                write!(
6780                    f,
6781                    "FUTURE TABLES IN SCHEMA {}",
6782                    display_comma_separated(schemas)
6783                )
6784            }
6785            GrantObjects::FutureExternalTablesInSchema { schemas } => {
6786                write!(
6787                    f,
6788                    "FUTURE EXTERNAL TABLES IN SCHEMA {}",
6789                    display_comma_separated(schemas)
6790                )
6791            }
6792            GrantObjects::FutureViewsInSchema { schemas } => {
6793                write!(
6794                    f,
6795                    "FUTURE VIEWS IN SCHEMA {}",
6796                    display_comma_separated(schemas)
6797                )
6798            }
6799            GrantObjects::FutureMaterializedViewsInSchema { schemas } => {
6800                write!(
6801                    f,
6802                    "FUTURE MATERIALIZED VIEWS IN SCHEMA {}",
6803                    display_comma_separated(schemas)
6804                )
6805            }
6806            GrantObjects::FutureSequencesInSchema { schemas } => {
6807                write!(
6808                    f,
6809                    "FUTURE SEQUENCES IN SCHEMA {}",
6810                    display_comma_separated(schemas)
6811                )
6812            }
6813            GrantObjects::ResourceMonitors(objects) => {
6814                write!(f, "RESOURCE MONITOR {}", display_comma_separated(objects))
6815            }
6816            GrantObjects::Users(objects) => {
6817                write!(f, "USER {}", display_comma_separated(objects))
6818            }
6819            GrantObjects::ComputePools(objects) => {
6820                write!(f, "COMPUTE POOL {}", display_comma_separated(objects))
6821            }
6822            GrantObjects::Connections(objects) => {
6823                write!(f, "CONNECTION {}", display_comma_separated(objects))
6824            }
6825            GrantObjects::FailoverGroup(objects) => {
6826                write!(f, "FAILOVER GROUP {}", display_comma_separated(objects))
6827            }
6828            GrantObjects::ReplicationGroup(objects) => {
6829                write!(f, "REPLICATION GROUP {}", display_comma_separated(objects))
6830            }
6831            GrantObjects::ExternalVolumes(objects) => {
6832                write!(f, "EXTERNAL VOLUME {}", display_comma_separated(objects))
6833            }
6834            GrantObjects::Procedure { name, arg_types } => {
6835                write!(f, "PROCEDURE {name}")?;
6836                if !arg_types.is_empty() {
6837                    write!(f, "({})", display_comma_separated(arg_types))?;
6838                }
6839                Ok(())
6840            }
6841            GrantObjects::Function { name, arg_types } => {
6842                write!(f, "FUNCTION {name}")?;
6843                if !arg_types.is_empty() {
6844                    write!(f, "({})", display_comma_separated(arg_types))?;
6845                }
6846                Ok(())
6847            }
6848        }
6849    }
6850}
6851
6852/// A `DENY` statement
6853///
6854/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/deny-transact-sql)
6855#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6856#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6857#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6858pub struct DenyStatement {
6859    pub privileges: Privileges,
6860    pub objects: GrantObjects,
6861    pub grantees: Vec<Grantee>,
6862    pub granted_by: Option<Ident>,
6863    pub cascade: Option<CascadeOption>,
6864}
6865
6866impl fmt::Display for DenyStatement {
6867    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6868        write!(f, "DENY {}", self.privileges)?;
6869        write!(f, " ON {}", self.objects)?;
6870        if !self.grantees.is_empty() {
6871            write!(f, " TO {}", display_comma_separated(&self.grantees))?;
6872        }
6873        if let Some(cascade) = &self.cascade {
6874            write!(f, " {cascade}")?;
6875        }
6876        if let Some(granted_by) = &self.granted_by {
6877            write!(f, " AS {granted_by}")?;
6878        }
6879        Ok(())
6880    }
6881}
6882
6883/// SQL assignment `foo = expr` as used in SQLUpdate
6884#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6885#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6886#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6887pub struct Assignment {
6888    pub target: AssignmentTarget,
6889    pub value: Expr,
6890}
6891
6892impl fmt::Display for Assignment {
6893    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6894        write!(f, "{} = {}", self.target, self.value)
6895    }
6896}
6897
6898/// Left-hand side of an assignment in an UPDATE statement,
6899/// e.g. `foo` in `foo = 5` (ColumnName assignment) or
6900/// `(a, b)` in `(a, b) = (1, 2)` (Tuple assignment).
6901#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6902#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6903#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6904pub enum AssignmentTarget {
6905    /// A single column
6906    ColumnName(ObjectName),
6907    /// A tuple of columns
6908    Tuple(Vec<ObjectName>),
6909}
6910
6911impl fmt::Display for AssignmentTarget {
6912    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6913        match self {
6914            AssignmentTarget::ColumnName(column) => write!(f, "{column}"),
6915            AssignmentTarget::Tuple(columns) => write!(f, "({})", display_comma_separated(columns)),
6916        }
6917    }
6918}
6919
6920#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6921#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6922#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6923pub enum FunctionArgExpr {
6924    Expr(Expr),
6925    /// Qualified wildcard, e.g. `alias.*` or `schema.table.*`.
6926    QualifiedWildcard(ObjectName),
6927    /// An unqualified `*`
6928    Wildcard,
6929}
6930
6931impl From<Expr> for FunctionArgExpr {
6932    fn from(wildcard_expr: Expr) -> Self {
6933        match wildcard_expr {
6934            Expr::QualifiedWildcard(prefix, _) => Self::QualifiedWildcard(prefix),
6935            Expr::Wildcard(_) => Self::Wildcard,
6936            expr => Self::Expr(expr),
6937        }
6938    }
6939}
6940
6941impl fmt::Display for FunctionArgExpr {
6942    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6943        match self {
6944            FunctionArgExpr::Expr(expr) => write!(f, "{expr}"),
6945            FunctionArgExpr::QualifiedWildcard(prefix) => write!(f, "{prefix}.*"),
6946            FunctionArgExpr::Wildcard => f.write_str("*"),
6947        }
6948    }
6949}
6950
6951#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6952#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6953#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6954/// Operator used to separate function arguments
6955pub enum FunctionArgOperator {
6956    /// function(arg1 = value1)
6957    Equals,
6958    /// function(arg1 => value1)
6959    RightArrow,
6960    /// function(arg1 := value1)
6961    Assignment,
6962    /// function(arg1 : value1)
6963    Colon,
6964    /// function(arg1 VALUE value1)
6965    Value,
6966}
6967
6968impl fmt::Display for FunctionArgOperator {
6969    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6970        match self {
6971            FunctionArgOperator::Equals => f.write_str("="),
6972            FunctionArgOperator::RightArrow => f.write_str("=>"),
6973            FunctionArgOperator::Assignment => f.write_str(":="),
6974            FunctionArgOperator::Colon => f.write_str(":"),
6975            FunctionArgOperator::Value => f.write_str("VALUE"),
6976        }
6977    }
6978}
6979
6980#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6981#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6982#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6983pub enum FunctionArg {
6984    /// `name` is identifier
6985    ///
6986    /// Enabled when `Dialect::supports_named_fn_args_with_expr_name` returns 'false'
6987    Named {
6988        name: Ident,
6989        arg: FunctionArgExpr,
6990        operator: FunctionArgOperator,
6991    },
6992    /// `name` is arbitrary expression
6993    ///
6994    /// Enabled when `Dialect::supports_named_fn_args_with_expr_name` returns 'true'
6995    ExprNamed {
6996        name: Expr,
6997        arg: FunctionArgExpr,
6998        operator: FunctionArgOperator,
6999    },
7000    Unnamed(FunctionArgExpr),
7001}
7002
7003impl fmt::Display for FunctionArg {
7004    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7005        match self {
7006            FunctionArg::Named {
7007                name,
7008                arg,
7009                operator,
7010            } => write!(f, "{name} {operator} {arg}"),
7011            FunctionArg::ExprNamed {
7012                name,
7013                arg,
7014                operator,
7015            } => write!(f, "{name} {operator} {arg}"),
7016            FunctionArg::Unnamed(unnamed_arg) => write!(f, "{unnamed_arg}"),
7017        }
7018    }
7019}
7020
7021#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7022#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7023#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7024pub enum CloseCursor {
7025    All,
7026    Specific { name: Ident },
7027}
7028
7029impl fmt::Display for CloseCursor {
7030    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7031        match self {
7032            CloseCursor::All => write!(f, "ALL"),
7033            CloseCursor::Specific { name } => write!(f, "{name}"),
7034        }
7035    }
7036}
7037
7038/// A Drop Domain statement
7039#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7040#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7041#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7042pub struct DropDomain {
7043    /// Whether to drop the domain if it exists
7044    pub if_exists: bool,
7045    /// The name of the domain to drop
7046    pub name: ObjectName,
7047    /// The behavior to apply when dropping the domain
7048    pub drop_behavior: Option<DropBehavior>,
7049}
7050
7051/// A constant of form `<data_type> 'value'`.
7052/// This can represent ANSI SQL `DATE`, `TIME`, and `TIMESTAMP` literals (such as `DATE '2020-01-01'`),
7053/// as well as constants of other types (a non-standard PostgreSQL extension).
7054#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7055#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7056#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7057pub struct TypedString {
7058    pub data_type: DataType,
7059    /// The value of the constant.
7060    /// Hint: you can unwrap the string value using `value.into_string()`.
7061    pub value: ValueWithSpan,
7062    /// Flags whether this TypedString uses the [ODBC syntax].
7063    ///
7064    /// Example:
7065    /// ```sql
7066    /// -- An ODBC date literal:
7067    /// SELECT {d '2025-07-16'}
7068    /// -- This is equivalent to the standard ANSI SQL literal:
7069    /// SELECT DATE '2025-07-16'
7070    ///
7071    /// [ODBC syntax]: https://learn.microsoft.com/en-us/sql/odbc/reference/develop-app/date-time-and-timestamp-literals?view=sql-server-2017
7072    pub uses_odbc_syntax: bool,
7073}
7074
7075impl fmt::Display for TypedString {
7076    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7077        let data_type = &self.data_type;
7078        let value = &self.value;
7079        match self.uses_odbc_syntax {
7080            false => {
7081                write!(f, "{data_type}")?;
7082                write!(f, " {value}")
7083            }
7084            true => {
7085                let prefix = match data_type {
7086                    DataType::Date => "d",
7087                    DataType::Time(..) => "t",
7088                    DataType::Timestamp(..) => "ts",
7089                    _ => "?",
7090                };
7091                write!(f, "{{{prefix} {value}}}")
7092            }
7093        }
7094    }
7095}
7096
7097/// A function call
7098#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7099#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7100#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7101pub struct Function {
7102    pub name: ObjectName,
7103    /// Flags whether this function call uses the [ODBC syntax].
7104    ///
7105    /// Example:
7106    /// ```sql
7107    /// SELECT {fn CONCAT('foo', 'bar')}
7108    /// ```
7109    ///
7110    /// [ODBC syntax]: https://learn.microsoft.com/en-us/sql/odbc/reference/develop-app/scalar-function-calls?view=sql-server-2017
7111    pub uses_odbc_syntax: bool,
7112    /// The parameters to the function, including any options specified within the
7113    /// delimiting parentheses.
7114    ///
7115    /// Example:
7116    /// ```plaintext
7117    /// HISTOGRAM(0.5, 0.6)(x, y)
7118    /// ```
7119    ///
7120    /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/aggregate-functions/parametric-functions)
7121    pub parameters: FunctionArguments,
7122    /// The arguments to the function, including any options specified within the
7123    /// delimiting parentheses.
7124    pub args: FunctionArguments,
7125    /// e.g. `x > 5` in `COUNT(x) FILTER (WHERE x > 5)`
7126    pub filter: Option<Box<Expr>>,
7127    /// Indicates how `NULL`s should be handled in the calculation.
7128    ///
7129    /// Example:
7130    /// ```plaintext
7131    /// FIRST_VALUE( <expr> ) [ { IGNORE | RESPECT } NULLS ] OVER ...
7132    /// ```
7133    ///
7134    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/functions/first_value)
7135    pub null_treatment: Option<NullTreatment>,
7136    /// The `OVER` clause, indicating a window function call.
7137    pub over: Option<WindowType>,
7138    /// A clause used with certain aggregate functions to control the ordering
7139    /// within grouped sets before the function is applied.
7140    ///
7141    /// Syntax:
7142    /// ```plaintext
7143    /// <aggregate_function>(expression) WITHIN GROUP (ORDER BY key [ASC | DESC], ...)
7144    /// ```
7145    pub within_group: Vec<OrderByExpr>,
7146}
7147
7148impl fmt::Display for Function {
7149    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7150        if self.uses_odbc_syntax {
7151            write!(f, "{{fn ")?;
7152        }
7153
7154        write!(f, "{}{}{}", self.name, self.parameters, self.args)?;
7155
7156        if !self.within_group.is_empty() {
7157            write!(
7158                f,
7159                " WITHIN GROUP (ORDER BY {})",
7160                display_comma_separated(&self.within_group)
7161            )?;
7162        }
7163
7164        if let Some(filter_cond) = &self.filter {
7165            write!(f, " FILTER (WHERE {filter_cond})")?;
7166        }
7167
7168        if let Some(null_treatment) = &self.null_treatment {
7169            write!(f, " {null_treatment}")?;
7170        }
7171
7172        if let Some(o) = &self.over {
7173            f.write_str(" OVER ")?;
7174            o.fmt(f)?;
7175        }
7176
7177        if self.uses_odbc_syntax {
7178            write!(f, "}}")?;
7179        }
7180
7181        Ok(())
7182    }
7183}
7184
7185/// The arguments passed to a function call.
7186#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7187#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7188#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7189pub enum FunctionArguments {
7190    /// Used for special functions like `CURRENT_TIMESTAMP` that are invoked
7191    /// without parentheses.
7192    None,
7193    /// On some dialects, a subquery can be passed without surrounding
7194    /// parentheses if it's the sole argument to the function.
7195    Subquery(Box<Query>),
7196    /// A normal function argument list, including any clauses within it such as
7197    /// `DISTINCT` or `ORDER BY`.
7198    List(FunctionArgumentList),
7199}
7200
7201impl fmt::Display for FunctionArguments {
7202    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7203        match self {
7204            FunctionArguments::None => Ok(()),
7205            FunctionArguments::Subquery(query) => write!(f, "({query})"),
7206            FunctionArguments::List(args) => write!(f, "({args})"),
7207        }
7208    }
7209}
7210
7211/// This represents everything inside the parentheses when calling a function.
7212#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7213#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7214#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7215pub struct FunctionArgumentList {
7216    /// `[ ALL | DISTINCT ]`
7217    pub duplicate_treatment: Option<DuplicateTreatment>,
7218    /// The function arguments.
7219    pub args: Vec<FunctionArg>,
7220    /// Additional clauses specified within the argument list.
7221    pub clauses: Vec<FunctionArgumentClause>,
7222}
7223
7224impl fmt::Display for FunctionArgumentList {
7225    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7226        if let Some(duplicate_treatment) = self.duplicate_treatment {
7227            write!(f, "{duplicate_treatment} ")?;
7228        }
7229        write!(f, "{}", display_comma_separated(&self.args))?;
7230        if !self.clauses.is_empty() {
7231            if !self.args.is_empty() {
7232                write!(f, " ")?;
7233            }
7234            write!(f, "{}", display_separated(&self.clauses, " "))?;
7235        }
7236        Ok(())
7237    }
7238}
7239
7240#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7241#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7242#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7243pub enum FunctionArgumentClause {
7244    /// Indicates how `NULL`s should be handled in the calculation, e.g. in `FIRST_VALUE` on [BigQuery].
7245    ///
7246    /// Syntax:
7247    /// ```plaintext
7248    /// { IGNORE | RESPECT } NULLS ]
7249    /// ```
7250    ///
7251    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#first_value
7252    IgnoreOrRespectNulls(NullTreatment),
7253    /// Specifies the the ordering for some ordered set aggregates, e.g. `ARRAY_AGG` on [BigQuery].
7254    ///
7255    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#array_agg
7256    OrderBy(Vec<OrderByExpr>),
7257    /// Specifies a limit for the `ARRAY_AGG` and `ARRAY_CONCAT_AGG` functions on BigQuery.
7258    Limit(Expr),
7259    /// Specifies the behavior on overflow of the `LISTAGG` function.
7260    ///
7261    /// See <https://trino.io/docs/current/functions/aggregate.html>.
7262    OnOverflow(ListAggOnOverflow),
7263    /// Specifies a minimum or maximum bound on the input to [`ANY_VALUE`] on BigQuery.
7264    ///
7265    /// Syntax:
7266    /// ```plaintext
7267    /// HAVING { MAX | MIN } expression
7268    /// ```
7269    ///
7270    /// [`ANY_VALUE`]: https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#any_value
7271    Having(HavingBound),
7272    /// The `SEPARATOR` clause to the [`GROUP_CONCAT`] function in MySQL.
7273    ///
7274    /// [`GROUP_CONCAT`]: https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat
7275    Separator(Value),
7276    /// The `ON NULL` clause for some JSON functions.
7277    ///
7278    /// [MSSQL `JSON_ARRAY`](https://learn.microsoft.com/en-us/sql/t-sql/functions/json-array-transact-sql?view=sql-server-ver16)
7279    /// [MSSQL `JSON_OBJECT`](https://learn.microsoft.com/en-us/sql/t-sql/functions/json-object-transact-sql?view=sql-server-ver16>)
7280    /// [PostgreSQL JSON functions](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSON-PROCESSING)
7281    JsonNullClause(JsonNullClause),
7282    /// The `RETURNING` clause for some JSON functions in PostgreSQL
7283    ///
7284    /// [`JSON_OBJECT`](https://www.postgresql.org/docs/current/functions-json.html#:~:text=json_object)
7285    JsonReturningClause(JsonReturningClause),
7286}
7287
7288impl fmt::Display for FunctionArgumentClause {
7289    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7290        match self {
7291            FunctionArgumentClause::IgnoreOrRespectNulls(null_treatment) => {
7292                write!(f, "{null_treatment}")
7293            }
7294            FunctionArgumentClause::OrderBy(order_by) => {
7295                write!(f, "ORDER BY {}", display_comma_separated(order_by))
7296            }
7297            FunctionArgumentClause::Limit(limit) => write!(f, "LIMIT {limit}"),
7298            FunctionArgumentClause::OnOverflow(on_overflow) => write!(f, "{on_overflow}"),
7299            FunctionArgumentClause::Having(bound) => write!(f, "{bound}"),
7300            FunctionArgumentClause::Separator(sep) => write!(f, "SEPARATOR {sep}"),
7301            FunctionArgumentClause::JsonNullClause(null_clause) => write!(f, "{null_clause}"),
7302            FunctionArgumentClause::JsonReturningClause(returning_clause) => {
7303                write!(f, "{returning_clause}")
7304            }
7305        }
7306    }
7307}
7308
7309/// A method call
7310#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7311#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7312#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7313pub struct Method {
7314    pub expr: Box<Expr>,
7315    // always non-empty
7316    pub method_chain: Vec<Function>,
7317}
7318
7319impl fmt::Display for Method {
7320    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7321        write!(
7322            f,
7323            "{}.{}",
7324            self.expr,
7325            display_separated(&self.method_chain, ".")
7326        )
7327    }
7328}
7329
7330#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7331#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7332#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7333pub enum DuplicateTreatment {
7334    /// Perform the calculation only unique values.
7335    Distinct,
7336    /// Retain all duplicate values (the default).
7337    All,
7338}
7339
7340impl fmt::Display for DuplicateTreatment {
7341    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7342        match self {
7343            DuplicateTreatment::Distinct => write!(f, "DISTINCT"),
7344            DuplicateTreatment::All => write!(f, "ALL"),
7345        }
7346    }
7347}
7348
7349#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7350#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7351#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7352pub enum AnalyzeFormatKind {
7353    /// e.g. `EXPLAIN ANALYZE FORMAT JSON SELECT * FROM tbl`
7354    Keyword(AnalyzeFormat),
7355    /// e.g. `EXPLAIN ANALYZE FORMAT=JSON SELECT * FROM tbl`
7356    Assignment(AnalyzeFormat),
7357}
7358
7359impl fmt::Display for AnalyzeFormatKind {
7360    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7361        match self {
7362            AnalyzeFormatKind::Keyword(format) => write!(f, "FORMAT {format}"),
7363            AnalyzeFormatKind::Assignment(format) => write!(f, "FORMAT={format}"),
7364        }
7365    }
7366}
7367
7368#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7369#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7370#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7371pub enum AnalyzeFormat {
7372    TEXT,
7373    GRAPHVIZ,
7374    JSON,
7375    TRADITIONAL,
7376    TREE,
7377}
7378
7379impl fmt::Display for AnalyzeFormat {
7380    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7381        f.write_str(match self {
7382            AnalyzeFormat::TEXT => "TEXT",
7383            AnalyzeFormat::GRAPHVIZ => "GRAPHVIZ",
7384            AnalyzeFormat::JSON => "JSON",
7385            AnalyzeFormat::TRADITIONAL => "TRADITIONAL",
7386            AnalyzeFormat::TREE => "TREE",
7387        })
7388    }
7389}
7390
7391/// External table's available file format
7392#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7393#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7394#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7395pub enum FileFormat {
7396    TEXTFILE,
7397    SEQUENCEFILE,
7398    ORC,
7399    PARQUET,
7400    AVRO,
7401    RCFILE,
7402    JSONFILE,
7403}
7404
7405impl fmt::Display for FileFormat {
7406    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7407        use self::FileFormat::*;
7408        f.write_str(match self {
7409            TEXTFILE => "TEXTFILE",
7410            SEQUENCEFILE => "SEQUENCEFILE",
7411            ORC => "ORC",
7412            PARQUET => "PARQUET",
7413            AVRO => "AVRO",
7414            RCFILE => "RCFILE",
7415            JSONFILE => "JSONFILE",
7416        })
7417    }
7418}
7419
7420/// The `ON OVERFLOW` clause of a LISTAGG invocation
7421#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7422#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7423#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7424pub enum ListAggOnOverflow {
7425    /// `ON OVERFLOW ERROR`
7426    Error,
7427
7428    /// `ON OVERFLOW TRUNCATE [ <filler> ] WITH[OUT] COUNT`
7429    Truncate {
7430        filler: Option<Box<Expr>>,
7431        with_count: bool,
7432    },
7433}
7434
7435impl fmt::Display for ListAggOnOverflow {
7436    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7437        write!(f, "ON OVERFLOW")?;
7438        match self {
7439            ListAggOnOverflow::Error => write!(f, " ERROR"),
7440            ListAggOnOverflow::Truncate { filler, with_count } => {
7441                write!(f, " TRUNCATE")?;
7442                if let Some(filler) = filler {
7443                    write!(f, " {filler}")?;
7444                }
7445                if *with_count {
7446                    write!(f, " WITH")?;
7447                } else {
7448                    write!(f, " WITHOUT")?;
7449                }
7450                write!(f, " COUNT")
7451            }
7452        }
7453    }
7454}
7455
7456/// The `HAVING` clause in a call to `ANY_VALUE` on BigQuery.
7457#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7458#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7459#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7460pub struct HavingBound(pub HavingBoundKind, pub Expr);
7461
7462impl fmt::Display for HavingBound {
7463    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7464        write!(f, "HAVING {} {}", self.0, self.1)
7465    }
7466}
7467
7468#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7469#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7470#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7471pub enum HavingBoundKind {
7472    Min,
7473    Max,
7474}
7475
7476impl fmt::Display for HavingBoundKind {
7477    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7478        match self {
7479            HavingBoundKind::Min => write!(f, "MIN"),
7480            HavingBoundKind::Max => write!(f, "MAX"),
7481        }
7482    }
7483}
7484
7485#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7486#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7487#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7488pub enum ObjectType {
7489    Table,
7490    View,
7491    MaterializedView,
7492    Index,
7493    Schema,
7494    Database,
7495    Role,
7496    Sequence,
7497    Stage,
7498    Type,
7499    User,
7500    Stream,
7501}
7502
7503impl fmt::Display for ObjectType {
7504    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7505        f.write_str(match self {
7506            ObjectType::Table => "TABLE",
7507            ObjectType::View => "VIEW",
7508            ObjectType::MaterializedView => "MATERIALIZED VIEW",
7509            ObjectType::Index => "INDEX",
7510            ObjectType::Schema => "SCHEMA",
7511            ObjectType::Database => "DATABASE",
7512            ObjectType::Role => "ROLE",
7513            ObjectType::Sequence => "SEQUENCE",
7514            ObjectType::Stage => "STAGE",
7515            ObjectType::Type => "TYPE",
7516            ObjectType::User => "USER",
7517            ObjectType::Stream => "STREAM",
7518        })
7519    }
7520}
7521
7522#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7523#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7524#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7525pub enum KillType {
7526    Connection,
7527    Query,
7528    Mutation,
7529}
7530
7531impl fmt::Display for KillType {
7532    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7533        f.write_str(match self {
7534            // MySQL
7535            KillType::Connection => "CONNECTION",
7536            KillType::Query => "QUERY",
7537            // Clickhouse supports Mutation
7538            KillType::Mutation => "MUTATION",
7539        })
7540    }
7541}
7542
7543#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7544#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7545#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7546pub enum HiveDistributionStyle {
7547    PARTITIONED {
7548        columns: Vec<ColumnDef>,
7549    },
7550    SKEWED {
7551        columns: Vec<ColumnDef>,
7552        on: Vec<ColumnDef>,
7553        stored_as_directories: bool,
7554    },
7555    NONE,
7556}
7557
7558#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7559#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7560#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7561pub enum HiveRowFormat {
7562    SERDE { class: String },
7563    DELIMITED { delimiters: Vec<HiveRowDelimiter> },
7564}
7565
7566#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7567#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7568#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7569pub struct HiveLoadDataFormat {
7570    pub serde: Expr,
7571    pub input_format: Expr,
7572}
7573
7574#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7575#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7576#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7577pub struct HiveRowDelimiter {
7578    pub delimiter: HiveDelimiter,
7579    pub char: Ident,
7580}
7581
7582impl fmt::Display for HiveRowDelimiter {
7583    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7584        write!(f, "{} ", self.delimiter)?;
7585        write!(f, "{}", self.char)
7586    }
7587}
7588
7589#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7590#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7591#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7592pub enum HiveDelimiter {
7593    FieldsTerminatedBy,
7594    FieldsEscapedBy,
7595    CollectionItemsTerminatedBy,
7596    MapKeysTerminatedBy,
7597    LinesTerminatedBy,
7598    NullDefinedAs,
7599}
7600
7601impl fmt::Display for HiveDelimiter {
7602    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7603        use HiveDelimiter::*;
7604        f.write_str(match self {
7605            FieldsTerminatedBy => "FIELDS TERMINATED BY",
7606            FieldsEscapedBy => "ESCAPED BY",
7607            CollectionItemsTerminatedBy => "COLLECTION ITEMS TERMINATED BY",
7608            MapKeysTerminatedBy => "MAP KEYS TERMINATED BY",
7609            LinesTerminatedBy => "LINES TERMINATED BY",
7610            NullDefinedAs => "NULL DEFINED AS",
7611        })
7612    }
7613}
7614
7615#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7616#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7617#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7618pub enum HiveDescribeFormat {
7619    Extended,
7620    Formatted,
7621}
7622
7623impl fmt::Display for HiveDescribeFormat {
7624    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7625        use HiveDescribeFormat::*;
7626        f.write_str(match self {
7627            Extended => "EXTENDED",
7628            Formatted => "FORMATTED",
7629        })
7630    }
7631}
7632
7633#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7634#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7635#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7636pub enum DescribeAlias {
7637    Describe,
7638    Explain,
7639    Desc,
7640}
7641
7642impl fmt::Display for DescribeAlias {
7643    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7644        use DescribeAlias::*;
7645        f.write_str(match self {
7646            Describe => "DESCRIBE",
7647            Explain => "EXPLAIN",
7648            Desc => "DESC",
7649        })
7650    }
7651}
7652
7653#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7654#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7655#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7656#[allow(clippy::large_enum_variant)]
7657pub enum HiveIOFormat {
7658    IOF {
7659        input_format: Expr,
7660        output_format: Expr,
7661    },
7662    FileFormat {
7663        format: FileFormat,
7664    },
7665}
7666
7667#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
7668#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7669#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7670pub struct HiveFormat {
7671    pub row_format: Option<HiveRowFormat>,
7672    pub serde_properties: Option<Vec<SqlOption>>,
7673    pub storage: Option<HiveIOFormat>,
7674    pub location: Option<String>,
7675}
7676
7677#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7678#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7679#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7680pub struct ClusteredIndex {
7681    pub name: Ident,
7682    pub asc: Option<bool>,
7683}
7684
7685impl fmt::Display for ClusteredIndex {
7686    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7687        write!(f, "{}", self.name)?;
7688        match self.asc {
7689            Some(true) => write!(f, " ASC"),
7690            Some(false) => write!(f, " DESC"),
7691            _ => Ok(()),
7692        }
7693    }
7694}
7695
7696#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7697#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7698#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7699pub enum TableOptionsClustered {
7700    ColumnstoreIndex,
7701    ColumnstoreIndexOrder(Vec<Ident>),
7702    Index(Vec<ClusteredIndex>),
7703}
7704
7705impl fmt::Display for TableOptionsClustered {
7706    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7707        match self {
7708            TableOptionsClustered::ColumnstoreIndex => {
7709                write!(f, "CLUSTERED COLUMNSTORE INDEX")
7710            }
7711            TableOptionsClustered::ColumnstoreIndexOrder(values) => {
7712                write!(
7713                    f,
7714                    "CLUSTERED COLUMNSTORE INDEX ORDER ({})",
7715                    display_comma_separated(values)
7716                )
7717            }
7718            TableOptionsClustered::Index(values) => {
7719                write!(f, "CLUSTERED INDEX ({})", display_comma_separated(values))
7720            }
7721        }
7722    }
7723}
7724
7725/// Specifies which partition the boundary values on table partitioning belongs to.
7726#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7727#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7728#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7729pub enum PartitionRangeDirection {
7730    Left,
7731    Right,
7732}
7733
7734#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7735#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7736#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7737pub enum SqlOption {
7738    /// Clustered represents the clustered version of table storage for MSSQL.
7739    ///
7740    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#TableOptions>
7741    Clustered(TableOptionsClustered),
7742    /// Single identifier options, e.g. `HEAP` for MSSQL.
7743    ///
7744    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#TableOptions>
7745    Ident(Ident),
7746    /// Any option that consists of a key value pair where the value is an expression. e.g.
7747    ///
7748    ///   WITH(DISTRIBUTION = ROUND_ROBIN)
7749    KeyValue { key: Ident, value: Expr },
7750    /// One or more table partitions and represents which partition the boundary values belong to,
7751    /// e.g.
7752    ///
7753    ///   PARTITION (id RANGE LEFT FOR VALUES (10, 20, 30, 40))
7754    ///
7755    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#TablePartitionOptions>
7756    Partition {
7757        column_name: Ident,
7758        range_direction: Option<PartitionRangeDirection>,
7759        for_values: Vec<Expr>,
7760    },
7761    /// Comment parameter (supports `=` and no `=` syntax)
7762    Comment(CommentDef),
7763    /// MySQL TableSpace option
7764    /// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
7765    TableSpace(TablespaceOption),
7766    /// An option representing a key value pair, where the value is a parenthesized list and with an optional name
7767    /// e.g.
7768    ///
7769    ///   UNION  = (tbl_name\[,tbl_name\]...) <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
7770    ///   ENGINE = ReplicatedMergeTree('/table_name','{replica}', ver) <https://clickhouse.com/docs/engines/table-engines/mergetree-family/replication>
7771    ///   ENGINE = SummingMergeTree(\[columns\]) <https://clickhouse.com/docs/engines/table-engines/mergetree-family/summingmergetree>
7772    NamedParenthesizedList(NamedParenthesizedList),
7773}
7774
7775impl fmt::Display for SqlOption {
7776    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7777        match self {
7778            SqlOption::Clustered(c) => write!(f, "{c}"),
7779            SqlOption::Ident(ident) => {
7780                write!(f, "{ident}")
7781            }
7782            SqlOption::KeyValue { key: name, value } => {
7783                write!(f, "{name} = {value}")
7784            }
7785            SqlOption::Partition {
7786                column_name,
7787                range_direction,
7788                for_values,
7789            } => {
7790                let direction = match range_direction {
7791                    Some(PartitionRangeDirection::Left) => " LEFT",
7792                    Some(PartitionRangeDirection::Right) => " RIGHT",
7793                    None => "",
7794                };
7795
7796                write!(
7797                    f,
7798                    "PARTITION ({} RANGE{} FOR VALUES ({}))",
7799                    column_name,
7800                    direction,
7801                    display_comma_separated(for_values)
7802                )
7803            }
7804            SqlOption::TableSpace(tablespace_option) => {
7805                write!(f, "TABLESPACE {}", tablespace_option.name)?;
7806                match tablespace_option.storage {
7807                    Some(StorageType::Disk) => write!(f, " STORAGE DISK"),
7808                    Some(StorageType::Memory) => write!(f, " STORAGE MEMORY"),
7809                    None => Ok(()),
7810                }
7811            }
7812            SqlOption::Comment(comment) => match comment {
7813                CommentDef::WithEq(comment) => {
7814                    write!(f, "COMMENT = '{comment}'")
7815                }
7816                CommentDef::WithoutEq(comment) => {
7817                    write!(f, "COMMENT '{comment}'")
7818                }
7819            },
7820            SqlOption::NamedParenthesizedList(value) => {
7821                write!(f, "{} = ", value.key)?;
7822                if let Some(key) = &value.name {
7823                    write!(f, "{key}")?;
7824                }
7825                if !value.values.is_empty() {
7826                    write!(f, "({})", display_comma_separated(&value.values))?
7827                }
7828                Ok(())
7829            }
7830        }
7831    }
7832}
7833
7834#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
7835#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7836#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7837pub enum StorageType {
7838    Disk,
7839    Memory,
7840}
7841
7842#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
7843#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7844#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7845/// MySql TableSpace option
7846/// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
7847pub struct TablespaceOption {
7848    pub name: String,
7849    pub storage: Option<StorageType>,
7850}
7851
7852#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7853#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7854#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7855pub struct SecretOption {
7856    pub key: Ident,
7857    pub value: Ident,
7858}
7859
7860impl fmt::Display for SecretOption {
7861    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7862        write!(f, "{} {}", self.key, self.value)
7863    }
7864}
7865
7866/// A `CREATE SERVER` statement.
7867///
7868/// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-createserver.html)
7869#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7870#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7871#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7872pub struct CreateServerStatement {
7873    pub name: ObjectName,
7874    pub if_not_exists: bool,
7875    pub server_type: Option<Ident>,
7876    pub version: Option<Ident>,
7877    pub foreign_data_wrapper: ObjectName,
7878    pub options: Option<Vec<CreateServerOption>>,
7879}
7880
7881impl fmt::Display for CreateServerStatement {
7882    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7883        let CreateServerStatement {
7884            name,
7885            if_not_exists,
7886            server_type,
7887            version,
7888            foreign_data_wrapper,
7889            options,
7890        } = self;
7891
7892        write!(
7893            f,
7894            "CREATE SERVER {if_not_exists}{name} ",
7895            if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
7896        )?;
7897
7898        if let Some(st) = server_type {
7899            write!(f, "TYPE {st} ")?;
7900        }
7901
7902        if let Some(v) = version {
7903            write!(f, "VERSION {v} ")?;
7904        }
7905
7906        write!(f, "FOREIGN DATA WRAPPER {foreign_data_wrapper}")?;
7907
7908        if let Some(o) = options {
7909            write!(f, " OPTIONS ({o})", o = display_comma_separated(o))?;
7910        }
7911
7912        Ok(())
7913    }
7914}
7915
7916#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7917#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7918#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7919pub struct CreateServerOption {
7920    pub key: Ident,
7921    pub value: Ident,
7922}
7923
7924impl fmt::Display for CreateServerOption {
7925    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7926        write!(f, "{} {}", self.key, self.value)
7927    }
7928}
7929
7930#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7931#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7932#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7933pub enum AttachDuckDBDatabaseOption {
7934    ReadOnly(Option<bool>),
7935    Type(Ident),
7936}
7937
7938impl fmt::Display for AttachDuckDBDatabaseOption {
7939    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7940        match self {
7941            AttachDuckDBDatabaseOption::ReadOnly(Some(true)) => write!(f, "READ_ONLY true"),
7942            AttachDuckDBDatabaseOption::ReadOnly(Some(false)) => write!(f, "READ_ONLY false"),
7943            AttachDuckDBDatabaseOption::ReadOnly(None) => write!(f, "READ_ONLY"),
7944            AttachDuckDBDatabaseOption::Type(t) => write!(f, "TYPE {t}"),
7945        }
7946    }
7947}
7948
7949#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7950#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7951#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7952pub enum TransactionMode {
7953    AccessMode(TransactionAccessMode),
7954    IsolationLevel(TransactionIsolationLevel),
7955}
7956
7957impl fmt::Display for TransactionMode {
7958    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7959        use TransactionMode::*;
7960        match self {
7961            AccessMode(access_mode) => write!(f, "{access_mode}"),
7962            IsolationLevel(iso_level) => write!(f, "ISOLATION LEVEL {iso_level}"),
7963        }
7964    }
7965}
7966
7967#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7968#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7969#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7970pub enum TransactionAccessMode {
7971    ReadOnly,
7972    ReadWrite,
7973}
7974
7975impl fmt::Display for TransactionAccessMode {
7976    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7977        use TransactionAccessMode::*;
7978        f.write_str(match self {
7979            ReadOnly => "READ ONLY",
7980            ReadWrite => "READ WRITE",
7981        })
7982    }
7983}
7984
7985#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7986#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7987#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7988pub enum TransactionIsolationLevel {
7989    ReadUncommitted,
7990    ReadCommitted,
7991    RepeatableRead,
7992    Serializable,
7993    Snapshot,
7994}
7995
7996impl fmt::Display for TransactionIsolationLevel {
7997    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7998        use TransactionIsolationLevel::*;
7999        f.write_str(match self {
8000            ReadUncommitted => "READ UNCOMMITTED",
8001            ReadCommitted => "READ COMMITTED",
8002            RepeatableRead => "REPEATABLE READ",
8003            Serializable => "SERIALIZABLE",
8004            Snapshot => "SNAPSHOT",
8005        })
8006    }
8007}
8008
8009/// Modifier for the transaction in the `BEGIN` syntax
8010///
8011/// SQLite: <https://sqlite.org/lang_transaction.html>
8012/// MS-SQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql>
8013#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8014#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8015#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8016pub enum TransactionModifier {
8017    Deferred,
8018    Immediate,
8019    Exclusive,
8020    Try,
8021    Catch,
8022}
8023
8024impl fmt::Display for TransactionModifier {
8025    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8026        use TransactionModifier::*;
8027        f.write_str(match self {
8028            Deferred => "DEFERRED",
8029            Immediate => "IMMEDIATE",
8030            Exclusive => "EXCLUSIVE",
8031            Try => "TRY",
8032            Catch => "CATCH",
8033        })
8034    }
8035}
8036
8037#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8038#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8039#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8040pub enum ShowStatementFilter {
8041    Like(String),
8042    ILike(String),
8043    Where(Expr),
8044    NoKeyword(String),
8045}
8046
8047impl fmt::Display for ShowStatementFilter {
8048    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8049        use ShowStatementFilter::*;
8050        match self {
8051            Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
8052            ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
8053            Where(expr) => write!(f, "WHERE {expr}"),
8054            NoKeyword(pattern) => write!(f, "'{}'", value::escape_single_quote_string(pattern)),
8055        }
8056    }
8057}
8058
8059#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8060#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8061#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8062pub enum ShowStatementInClause {
8063    IN,
8064    FROM,
8065}
8066
8067impl fmt::Display for ShowStatementInClause {
8068    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8069        use ShowStatementInClause::*;
8070        match self {
8071            FROM => write!(f, "FROM"),
8072            IN => write!(f, "IN"),
8073        }
8074    }
8075}
8076
8077/// Sqlite specific syntax
8078///
8079/// See [Sqlite documentation](https://sqlite.org/lang_conflict.html)
8080/// for more details.
8081#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8082#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8083#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8084pub enum SqliteOnConflict {
8085    Rollback,
8086    Abort,
8087    Fail,
8088    Ignore,
8089    Replace,
8090}
8091
8092impl fmt::Display for SqliteOnConflict {
8093    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8094        use SqliteOnConflict::*;
8095        match self {
8096            Rollback => write!(f, "OR ROLLBACK"),
8097            Abort => write!(f, "OR ABORT"),
8098            Fail => write!(f, "OR FAIL"),
8099            Ignore => write!(f, "OR IGNORE"),
8100            Replace => write!(f, "OR REPLACE"),
8101        }
8102    }
8103}
8104
8105/// Mysql specific syntax
8106///
8107/// See [Mysql documentation](https://dev.mysql.com/doc/refman/8.0/en/replace.html)
8108/// See [Mysql documentation](https://dev.mysql.com/doc/refman/8.0/en/insert.html)
8109/// for more details.
8110#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8111#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8112#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8113pub enum MysqlInsertPriority {
8114    LowPriority,
8115    Delayed,
8116    HighPriority,
8117}
8118
8119impl fmt::Display for crate::ast::MysqlInsertPriority {
8120    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8121        use MysqlInsertPriority::*;
8122        match self {
8123            LowPriority => write!(f, "LOW_PRIORITY"),
8124            Delayed => write!(f, "DELAYED"),
8125            HighPriority => write!(f, "HIGH_PRIORITY"),
8126        }
8127    }
8128}
8129
8130#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8131#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8132#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8133pub enum CopySource {
8134    Table {
8135        /// The name of the table to copy from.
8136        table_name: ObjectName,
8137        /// A list of column names to copy. Empty list means that all columns
8138        /// are copied.
8139        columns: Vec<Ident>,
8140    },
8141    Query(Box<Query>),
8142}
8143
8144#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8145#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8146#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8147pub enum CopyTarget {
8148    Stdin,
8149    Stdout,
8150    File {
8151        /// The path name of the input or output file.
8152        filename: String,
8153    },
8154    Program {
8155        /// A command to execute
8156        command: String,
8157    },
8158}
8159
8160impl fmt::Display for CopyTarget {
8161    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8162        use CopyTarget::*;
8163        match self {
8164            Stdin => write!(f, "STDIN"),
8165            Stdout => write!(f, "STDOUT"),
8166            File { filename } => write!(f, "'{}'", value::escape_single_quote_string(filename)),
8167            Program { command } => write!(
8168                f,
8169                "PROGRAM '{}'",
8170                value::escape_single_quote_string(command)
8171            ),
8172        }
8173    }
8174}
8175
8176#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8177#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8178#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8179pub enum OnCommit {
8180    DeleteRows,
8181    PreserveRows,
8182    Drop,
8183}
8184
8185/// An option in `COPY` statement.
8186///
8187/// <https://www.postgresql.org/docs/14/sql-copy.html>
8188#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8189#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8190#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8191pub enum CopyOption {
8192    /// FORMAT format_name
8193    Format(Ident),
8194    /// FREEZE \[ boolean \]
8195    Freeze(bool),
8196    /// DELIMITER 'delimiter_character'
8197    Delimiter(char),
8198    /// NULL 'null_string'
8199    Null(String),
8200    /// HEADER \[ boolean \]
8201    Header(bool),
8202    /// QUOTE 'quote_character'
8203    Quote(char),
8204    /// ESCAPE 'escape_character'
8205    Escape(char),
8206    /// FORCE_QUOTE { ( column_name [, ...] ) | * }
8207    ForceQuote(Vec<Ident>),
8208    /// FORCE_NOT_NULL ( column_name [, ...] )
8209    ForceNotNull(Vec<Ident>),
8210    /// FORCE_NULL ( column_name [, ...] )
8211    ForceNull(Vec<Ident>),
8212    /// ENCODING 'encoding_name'
8213    Encoding(String),
8214}
8215
8216impl fmt::Display for CopyOption {
8217    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8218        use CopyOption::*;
8219        match self {
8220            Format(name) => write!(f, "FORMAT {name}"),
8221            Freeze(true) => write!(f, "FREEZE"),
8222            Freeze(false) => write!(f, "FREEZE FALSE"),
8223            Delimiter(char) => write!(f, "DELIMITER '{char}'"),
8224            Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
8225            Header(true) => write!(f, "HEADER"),
8226            Header(false) => write!(f, "HEADER FALSE"),
8227            Quote(char) => write!(f, "QUOTE '{char}'"),
8228            Escape(char) => write!(f, "ESCAPE '{char}'"),
8229            ForceQuote(columns) => write!(f, "FORCE_QUOTE ({})", display_comma_separated(columns)),
8230            ForceNotNull(columns) => {
8231                write!(f, "FORCE_NOT_NULL ({})", display_comma_separated(columns))
8232            }
8233            ForceNull(columns) => write!(f, "FORCE_NULL ({})", display_comma_separated(columns)),
8234            Encoding(name) => write!(f, "ENCODING '{}'", value::escape_single_quote_string(name)),
8235        }
8236    }
8237}
8238
8239/// An option in `COPY` statement before PostgreSQL version 9.0.
8240///
8241/// [PostgreSQL](https://www.postgresql.org/docs/8.4/sql-copy.html)
8242/// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_COPY-alphabetical-parm-list.html)
8243#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8244#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8245#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8246pub enum CopyLegacyOption {
8247    /// ACCEPTANYDATE
8248    AcceptAnyDate,
8249    /// ACCEPTINVCHARS
8250    AcceptInvChars(Option<String>),
8251    /// ADDQUOTES
8252    AddQuotes,
8253    /// ALLOWOVERWRITE
8254    AllowOverwrite,
8255    /// BINARY
8256    Binary,
8257    /// BLANKSASNULL
8258    BlankAsNull,
8259    /// BZIP2
8260    Bzip2,
8261    /// CLEANPATH
8262    CleanPath,
8263    /// COMPUPDATE [ PRESET | { ON | TRUE } | { OFF | FALSE } ]
8264    CompUpdate { preset: bool, enabled: Option<bool> },
8265    /// CSV ...
8266    Csv(Vec<CopyLegacyCsvOption>),
8267    /// DATEFORMAT \[ AS \] {'dateformat_string' | 'auto' }
8268    DateFormat(Option<String>),
8269    /// DELIMITER \[ AS \] 'delimiter_character'
8270    Delimiter(char),
8271    /// EMPTYASNULL
8272    EmptyAsNull,
8273    /// ENCRYPTED \[ AUTO \]
8274    Encrypted { auto: bool },
8275    /// ESCAPE
8276    Escape,
8277    /// EXTENSION 'extension-name'
8278    Extension(String),
8279    /// FIXEDWIDTH \[ AS \] 'fixedwidth-spec'
8280    FixedWidth(String),
8281    /// GZIP
8282    Gzip,
8283    /// HEADER
8284    Header,
8285    /// IAM_ROLE { DEFAULT | 'arn:aws:iam::123456789:role/role1' }
8286    IamRole(IamRoleKind),
8287    /// IGNOREHEADER \[ AS \] number_rows
8288    IgnoreHeader(u64),
8289    /// JSON
8290    Json,
8291    /// MANIFEST \[ VERBOSE \]
8292    Manifest { verbose: bool },
8293    /// MAXFILESIZE \[ AS \] max-size \[ MB | GB \]
8294    MaxFileSize(FileSize),
8295    /// NULL \[ AS \] 'null_string'
8296    Null(String),
8297    /// PARALLEL [ { ON | TRUE } | { OFF | FALSE } ]
8298    Parallel(Option<bool>),
8299    /// PARQUET
8300    Parquet,
8301    /// PARTITION BY ( column_name [, ... ] ) \[ INCLUDE \]
8302    PartitionBy(UnloadPartitionBy),
8303    /// REGION \[ AS \] 'aws-region' }
8304    Region(String),
8305    /// REMOVEQUOTES
8306    RemoveQuotes,
8307    /// ROWGROUPSIZE \[ AS \] size \[ MB | GB \]
8308    RowGroupSize(FileSize),
8309    /// STATUPDATE [ { ON | TRUE } | { OFF | FALSE } ]
8310    StatUpdate(Option<bool>),
8311    /// TIMEFORMAT \[ AS \] {'timeformat_string' | 'auto' | 'epochsecs' | 'epochmillisecs' }
8312    TimeFormat(Option<String>),
8313    /// TRUNCATECOLUMNS
8314    TruncateColumns,
8315    /// ZSTD
8316    Zstd,
8317}
8318
8319impl fmt::Display for CopyLegacyOption {
8320    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8321        use CopyLegacyOption::*;
8322        match self {
8323            AcceptAnyDate => write!(f, "ACCEPTANYDATE"),
8324            AcceptInvChars(ch) => {
8325                write!(f, "ACCEPTINVCHARS")?;
8326                if let Some(ch) = ch {
8327                    write!(f, " '{}'", value::escape_single_quote_string(ch))?;
8328                }
8329                Ok(())
8330            }
8331            AddQuotes => write!(f, "ADDQUOTES"),
8332            AllowOverwrite => write!(f, "ALLOWOVERWRITE"),
8333            Binary => write!(f, "BINARY"),
8334            BlankAsNull => write!(f, "BLANKSASNULL"),
8335            Bzip2 => write!(f, "BZIP2"),
8336            CleanPath => write!(f, "CLEANPATH"),
8337            CompUpdate { preset, enabled } => {
8338                write!(f, "COMPUPDATE")?;
8339                if *preset {
8340                    write!(f, " PRESET")?;
8341                } else if let Some(enabled) = enabled {
8342                    write!(
8343                        f,
8344                        "{}",
8345                        match enabled {
8346                            true => " TRUE",
8347                            false => " FALSE",
8348                        }
8349                    )?;
8350                }
8351                Ok(())
8352            }
8353            Csv(opts) => {
8354                write!(f, "CSV")?;
8355                if !opts.is_empty() {
8356                    write!(f, " {}", display_separated(opts, " "))?;
8357                }
8358                Ok(())
8359            }
8360            DateFormat(fmt) => {
8361                write!(f, "DATEFORMAT")?;
8362                if let Some(fmt) = fmt {
8363                    write!(f, " '{}'", value::escape_single_quote_string(fmt))?;
8364                }
8365                Ok(())
8366            }
8367            Delimiter(char) => write!(f, "DELIMITER '{char}'"),
8368            EmptyAsNull => write!(f, "EMPTYASNULL"),
8369            Encrypted { auto } => write!(f, "ENCRYPTED{}", if *auto { " AUTO" } else { "" }),
8370            Escape => write!(f, "ESCAPE"),
8371            Extension(ext) => write!(f, "EXTENSION '{}'", value::escape_single_quote_string(ext)),
8372            FixedWidth(spec) => write!(
8373                f,
8374                "FIXEDWIDTH '{}'",
8375                value::escape_single_quote_string(spec)
8376            ),
8377            Gzip => write!(f, "GZIP"),
8378            Header => write!(f, "HEADER"),
8379            IamRole(role) => write!(f, "IAM_ROLE {role}"),
8380            IgnoreHeader(num_rows) => write!(f, "IGNOREHEADER {num_rows}"),
8381            Json => write!(f, "JSON"),
8382            Manifest { verbose } => write!(f, "MANIFEST{}", if *verbose { " VERBOSE" } else { "" }),
8383            MaxFileSize(file_size) => write!(f, "MAXFILESIZE {file_size}"),
8384            Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
8385            Parallel(enabled) => {
8386                write!(
8387                    f,
8388                    "PARALLEL{}",
8389                    match enabled {
8390                        Some(true) => " TRUE",
8391                        Some(false) => " FALSE",
8392                        _ => "",
8393                    }
8394                )
8395            }
8396            Parquet => write!(f, "PARQUET"),
8397            PartitionBy(p) => write!(f, "{p}"),
8398            Region(region) => write!(f, "REGION '{}'", value::escape_single_quote_string(region)),
8399            RemoveQuotes => write!(f, "REMOVEQUOTES"),
8400            RowGroupSize(file_size) => write!(f, "ROWGROUPSIZE {file_size}"),
8401            StatUpdate(enabled) => {
8402                write!(
8403                    f,
8404                    "STATUPDATE{}",
8405                    match enabled {
8406                        Some(true) => " TRUE",
8407                        Some(false) => " FALSE",
8408                        _ => "",
8409                    }
8410                )
8411            }
8412            TimeFormat(fmt) => {
8413                write!(f, "TIMEFORMAT")?;
8414                if let Some(fmt) = fmt {
8415                    write!(f, " '{}'", value::escape_single_quote_string(fmt))?;
8416                }
8417                Ok(())
8418            }
8419            TruncateColumns => write!(f, "TRUNCATECOLUMNS"),
8420            Zstd => write!(f, "ZSTD"),
8421        }
8422    }
8423}
8424
8425/// ```sql
8426/// SIZE \[ MB | GB \]
8427/// ```
8428#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8429#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8430#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8431pub struct FileSize {
8432    pub size: Value,
8433    pub unit: Option<FileSizeUnit>,
8434}
8435
8436impl fmt::Display for FileSize {
8437    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8438        write!(f, "{}", self.size)?;
8439        if let Some(unit) = &self.unit {
8440            write!(f, " {unit}")?;
8441        }
8442        Ok(())
8443    }
8444}
8445
8446#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8447#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8448#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8449pub enum FileSizeUnit {
8450    MB,
8451    GB,
8452}
8453
8454impl fmt::Display for FileSizeUnit {
8455    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8456        match self {
8457            FileSizeUnit::MB => write!(f, "MB"),
8458            FileSizeUnit::GB => write!(f, "GB"),
8459        }
8460    }
8461}
8462
8463/// Specifies the partition keys for the unload operation
8464///
8465/// ```sql
8466/// PARTITION BY ( column_name [, ... ] ) [ INCLUDE ]
8467/// ```
8468#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8469#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8470#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8471pub struct UnloadPartitionBy {
8472    pub columns: Vec<Ident>,
8473    pub include: bool,
8474}
8475
8476impl fmt::Display for UnloadPartitionBy {
8477    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8478        write!(
8479            f,
8480            "PARTITION BY ({}){}",
8481            display_comma_separated(&self.columns),
8482            if self.include { " INCLUDE" } else { "" }
8483        )
8484    }
8485}
8486
8487/// An `IAM_ROLE` option in the AWS ecosystem
8488///
8489/// [Redshift COPY](https://docs.aws.amazon.com/redshift/latest/dg/copy-parameters-authorization.html#copy-iam-role)
8490#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8491#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8492#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8493pub enum IamRoleKind {
8494    /// Default role
8495    Default,
8496    /// Specific role ARN, for example: `arn:aws:iam::123456789:role/role1`
8497    Arn(String),
8498}
8499
8500impl fmt::Display for IamRoleKind {
8501    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8502        match self {
8503            IamRoleKind::Default => write!(f, "DEFAULT"),
8504            IamRoleKind::Arn(arn) => write!(f, "'{arn}'"),
8505        }
8506    }
8507}
8508
8509/// A `CSV` option in `COPY` statement before PostgreSQL version 9.0.
8510///
8511/// <https://www.postgresql.org/docs/8.4/sql-copy.html>
8512#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8513#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8514#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8515pub enum CopyLegacyCsvOption {
8516    /// HEADER
8517    Header,
8518    /// QUOTE \[ AS \] 'quote_character'
8519    Quote(char),
8520    /// ESCAPE \[ AS \] 'escape_character'
8521    Escape(char),
8522    /// FORCE QUOTE { column_name [, ...] | * }
8523    ForceQuote(Vec<Ident>),
8524    /// FORCE NOT NULL column_name [, ...]
8525    ForceNotNull(Vec<Ident>),
8526}
8527
8528impl fmt::Display for CopyLegacyCsvOption {
8529    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8530        use CopyLegacyCsvOption::*;
8531        match self {
8532            Header => write!(f, "HEADER"),
8533            Quote(char) => write!(f, "QUOTE '{char}'"),
8534            Escape(char) => write!(f, "ESCAPE '{char}'"),
8535            ForceQuote(columns) => write!(f, "FORCE QUOTE {}", display_comma_separated(columns)),
8536            ForceNotNull(columns) => {
8537                write!(f, "FORCE NOT NULL {}", display_comma_separated(columns))
8538            }
8539        }
8540    }
8541}
8542
8543#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8544#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8545#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8546pub enum DiscardObject {
8547    ALL,
8548    PLANS,
8549    SEQUENCES,
8550    TEMP,
8551}
8552
8553impl fmt::Display for DiscardObject {
8554    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8555        match self {
8556            DiscardObject::ALL => f.write_str("ALL"),
8557            DiscardObject::PLANS => f.write_str("PLANS"),
8558            DiscardObject::SEQUENCES => f.write_str("SEQUENCES"),
8559            DiscardObject::TEMP => f.write_str("TEMP"),
8560        }
8561    }
8562}
8563
8564#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8565#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8566#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8567pub enum FlushType {
8568    BinaryLogs,
8569    EngineLogs,
8570    ErrorLogs,
8571    GeneralLogs,
8572    Hosts,
8573    Logs,
8574    Privileges,
8575    OptimizerCosts,
8576    RelayLogs,
8577    SlowLogs,
8578    Status,
8579    UserResources,
8580    Tables,
8581}
8582
8583impl fmt::Display for FlushType {
8584    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8585        match self {
8586            FlushType::BinaryLogs => f.write_str("BINARY LOGS"),
8587            FlushType::EngineLogs => f.write_str("ENGINE LOGS"),
8588            FlushType::ErrorLogs => f.write_str("ERROR LOGS"),
8589            FlushType::GeneralLogs => f.write_str("GENERAL LOGS"),
8590            FlushType::Hosts => f.write_str("HOSTS"),
8591            FlushType::Logs => f.write_str("LOGS"),
8592            FlushType::Privileges => f.write_str("PRIVILEGES"),
8593            FlushType::OptimizerCosts => f.write_str("OPTIMIZER_COSTS"),
8594            FlushType::RelayLogs => f.write_str("RELAY LOGS"),
8595            FlushType::SlowLogs => f.write_str("SLOW LOGS"),
8596            FlushType::Status => f.write_str("STATUS"),
8597            FlushType::UserResources => f.write_str("USER_RESOURCES"),
8598            FlushType::Tables => f.write_str("TABLES"),
8599        }
8600    }
8601}
8602
8603#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8604#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8605#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8606pub enum FlushLocation {
8607    NoWriteToBinlog,
8608    Local,
8609}
8610
8611impl fmt::Display for FlushLocation {
8612    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8613        match self {
8614            FlushLocation::NoWriteToBinlog => f.write_str("NO_WRITE_TO_BINLOG"),
8615            FlushLocation::Local => f.write_str("LOCAL"),
8616        }
8617    }
8618}
8619
8620/// Optional context modifier for statements that can be or `LOCAL`, `GLOBAL`, or `SESSION`.
8621#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8622#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8623#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8624pub enum ContextModifier {
8625    /// `LOCAL` identifier, usually related to transactional states.
8626    Local,
8627    /// `SESSION` identifier
8628    Session,
8629    /// `GLOBAL` identifier
8630    Global,
8631}
8632
8633impl fmt::Display for ContextModifier {
8634    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8635        match self {
8636            Self::Local => {
8637                write!(f, "LOCAL ")
8638            }
8639            Self::Session => {
8640                write!(f, "SESSION ")
8641            }
8642            Self::Global => {
8643                write!(f, "GLOBAL ")
8644            }
8645        }
8646    }
8647}
8648
8649/// Function describe in DROP FUNCTION.
8650#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8651#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8652pub enum DropFunctionOption {
8653    Restrict,
8654    Cascade,
8655}
8656
8657impl fmt::Display for DropFunctionOption {
8658    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8659        match self {
8660            DropFunctionOption::Restrict => write!(f, "RESTRICT "),
8661            DropFunctionOption::Cascade => write!(f, "CASCADE  "),
8662        }
8663    }
8664}
8665
8666/// Generic function description for DROP FUNCTION and CREATE TRIGGER.
8667#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8668#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8669#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8670pub struct FunctionDesc {
8671    pub name: ObjectName,
8672    pub args: Option<Vec<OperateFunctionArg>>,
8673}
8674
8675impl fmt::Display for FunctionDesc {
8676    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8677        write!(f, "{}", self.name)?;
8678        if let Some(args) = &self.args {
8679            write!(f, "({})", display_comma_separated(args))?;
8680        }
8681        Ok(())
8682    }
8683}
8684
8685/// Function argument in CREATE OR DROP FUNCTION.
8686#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8687#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8688#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8689pub struct OperateFunctionArg {
8690    pub mode: Option<ArgMode>,
8691    pub name: Option<Ident>,
8692    pub data_type: DataType,
8693    pub default_expr: Option<Expr>,
8694}
8695
8696impl OperateFunctionArg {
8697    /// Returns an unnamed argument.
8698    pub fn unnamed(data_type: DataType) -> Self {
8699        Self {
8700            mode: None,
8701            name: None,
8702            data_type,
8703            default_expr: None,
8704        }
8705    }
8706
8707    /// Returns an argument with name.
8708    pub fn with_name(name: &str, data_type: DataType) -> Self {
8709        Self {
8710            mode: None,
8711            name: Some(name.into()),
8712            data_type,
8713            default_expr: None,
8714        }
8715    }
8716}
8717
8718impl fmt::Display for OperateFunctionArg {
8719    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8720        if let Some(mode) = &self.mode {
8721            write!(f, "{mode} ")?;
8722        }
8723        if let Some(name) = &self.name {
8724            write!(f, "{name} ")?;
8725        }
8726        write!(f, "{}", self.data_type)?;
8727        if let Some(default_expr) = &self.default_expr {
8728            write!(f, " = {default_expr}")?;
8729        }
8730        Ok(())
8731    }
8732}
8733
8734/// The mode of an argument in CREATE FUNCTION.
8735#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8736#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8737#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8738pub enum ArgMode {
8739    In,
8740    Out,
8741    InOut,
8742}
8743
8744impl fmt::Display for ArgMode {
8745    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8746        match self {
8747            ArgMode::In => write!(f, "IN"),
8748            ArgMode::Out => write!(f, "OUT"),
8749            ArgMode::InOut => write!(f, "INOUT"),
8750        }
8751    }
8752}
8753
8754/// These attributes inform the query optimizer about the behavior of the function.
8755#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8756#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8757#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8758pub enum FunctionBehavior {
8759    Immutable,
8760    Stable,
8761    Volatile,
8762}
8763
8764impl fmt::Display for FunctionBehavior {
8765    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8766        match self {
8767            FunctionBehavior::Immutable => write!(f, "IMMUTABLE"),
8768            FunctionBehavior::Stable => write!(f, "STABLE"),
8769            FunctionBehavior::Volatile => write!(f, "VOLATILE"),
8770        }
8771    }
8772}
8773
8774/// Specifies whether the function is SECURITY DEFINER or SECURITY INVOKER.
8775#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8776#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8777#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8778pub enum FunctionSecurity {
8779    Definer,
8780    Invoker,
8781}
8782
8783impl fmt::Display for FunctionSecurity {
8784    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8785        match self {
8786            FunctionSecurity::Definer => write!(f, "SECURITY DEFINER"),
8787            FunctionSecurity::Invoker => write!(f, "SECURITY INVOKER"),
8788        }
8789    }
8790}
8791
8792/// Value for a SET configuration parameter in a CREATE FUNCTION statement.
8793///
8794/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
8795#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8796#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8797#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8798pub enum FunctionSetValue {
8799    /// SET param = value1, value2, ...
8800    Values(Vec<Expr>),
8801    /// SET param FROM CURRENT
8802    FromCurrent,
8803}
8804
8805/// A SET configuration_parameter clause in a CREATE FUNCTION statement.
8806///
8807/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
8808#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8809#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8810#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8811pub struct FunctionDefinitionSetParam {
8812    pub name: Ident,
8813    pub value: FunctionSetValue,
8814}
8815
8816impl fmt::Display for FunctionDefinitionSetParam {
8817    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8818        write!(f, "SET {} ", self.name)?;
8819        match &self.value {
8820            FunctionSetValue::Values(values) => {
8821                write!(f, "= {}", display_comma_separated(values))
8822            }
8823            FunctionSetValue::FromCurrent => write!(f, "FROM CURRENT"),
8824        }
8825    }
8826}
8827
8828/// These attributes describe the behavior of the function when called with a null argument.
8829#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8830#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8831#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8832pub enum FunctionCalledOnNull {
8833    CalledOnNullInput,
8834    ReturnsNullOnNullInput,
8835    Strict,
8836}
8837
8838impl fmt::Display for FunctionCalledOnNull {
8839    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8840        match self {
8841            FunctionCalledOnNull::CalledOnNullInput => write!(f, "CALLED ON NULL INPUT"),
8842            FunctionCalledOnNull::ReturnsNullOnNullInput => write!(f, "RETURNS NULL ON NULL INPUT"),
8843            FunctionCalledOnNull::Strict => write!(f, "STRICT"),
8844        }
8845    }
8846}
8847
8848/// If it is safe for PostgreSQL to call the function from multiple threads at once
8849#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8850#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8851#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8852pub enum FunctionParallel {
8853    Unsafe,
8854    Restricted,
8855    Safe,
8856}
8857
8858impl fmt::Display for FunctionParallel {
8859    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8860        match self {
8861            FunctionParallel::Unsafe => write!(f, "PARALLEL UNSAFE"),
8862            FunctionParallel::Restricted => write!(f, "PARALLEL RESTRICTED"),
8863            FunctionParallel::Safe => write!(f, "PARALLEL SAFE"),
8864        }
8865    }
8866}
8867
8868/// [BigQuery] Determinism specifier used in a UDF definition.
8869///
8870/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
8871#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8872#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8873#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8874pub enum FunctionDeterminismSpecifier {
8875    Deterministic,
8876    NotDeterministic,
8877}
8878
8879impl fmt::Display for FunctionDeterminismSpecifier {
8880    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8881        match self {
8882            FunctionDeterminismSpecifier::Deterministic => {
8883                write!(f, "DETERMINISTIC")
8884            }
8885            FunctionDeterminismSpecifier::NotDeterministic => {
8886                write!(f, "NOT DETERMINISTIC")
8887            }
8888        }
8889    }
8890}
8891
8892/// Represent the expression body of a `CREATE FUNCTION` statement as well as
8893/// where within the statement, the body shows up.
8894///
8895/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
8896/// [PostgreSQL]: https://www.postgresql.org/docs/15/sql-createfunction.html
8897/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
8898#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8899#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8900#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8901pub enum CreateFunctionBody {
8902    /// A function body expression using the 'AS' keyword and shows up
8903    /// before any `OPTIONS` clause.
8904    ///
8905    /// Example:
8906    /// ```sql
8907    /// CREATE FUNCTION myfunc(x FLOAT64, y FLOAT64) RETURNS FLOAT64
8908    /// AS (x * y)
8909    /// OPTIONS(description="desc");
8910    /// ```
8911    ///
8912    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
8913    /// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
8914    AsBeforeOptions {
8915        /// The primary expression.
8916        body: Expr,
8917        /// Link symbol if the primary expression contains the name of shared library file.
8918        ///
8919        /// Example:
8920        /// ```sql
8921        /// CREATE FUNCTION cas_in(input cstring) RETURNS cas
8922        /// AS 'MODULE_PATHNAME', 'cas_in_wrapper'
8923        /// ```
8924        /// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
8925        link_symbol: Option<Expr>,
8926    },
8927    /// A function body expression using the 'AS' keyword and shows up
8928    /// after any `OPTIONS` clause.
8929    ///
8930    /// Example:
8931    /// ```sql
8932    /// CREATE FUNCTION myfunc(x FLOAT64, y FLOAT64) RETURNS FLOAT64
8933    /// OPTIONS(description="desc")
8934    /// AS (x * y);
8935    /// ```
8936    ///
8937    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
8938    AsAfterOptions(Expr),
8939    /// Function body with statements before the `RETURN` keyword.
8940    ///
8941    /// Example:
8942    /// ```sql
8943    /// CREATE FUNCTION my_scalar_udf(a INT, b INT)
8944    /// RETURNS INT
8945    /// AS
8946    /// BEGIN
8947    ///     DECLARE c INT;
8948    ///     SET c = a + b;
8949    ///     RETURN c;
8950    /// END
8951    /// ```
8952    ///
8953    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
8954    AsBeginEnd(BeginEndStatements),
8955    /// Function body expression using the 'RETURN' keyword.
8956    ///
8957    /// Example:
8958    /// ```sql
8959    /// CREATE FUNCTION myfunc(a INTEGER, IN b INTEGER = 1) RETURNS INTEGER
8960    /// LANGUAGE SQL
8961    /// RETURN a + b;
8962    /// ```
8963    ///
8964    /// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
8965    Return(Expr),
8966
8967    /// Function body expression using the 'AS RETURN' keywords
8968    ///
8969    /// Example:
8970    /// ```sql
8971    /// CREATE FUNCTION myfunc(a INT, b INT)
8972    /// RETURNS TABLE
8973    /// AS RETURN (SELECT a + b AS sum);
8974    /// ```
8975    ///
8976    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
8977    AsReturnExpr(Expr),
8978
8979    /// Function body expression using the 'AS RETURN' keywords, with an un-parenthesized SELECT query
8980    ///
8981    /// Example:
8982    /// ```sql
8983    /// CREATE FUNCTION myfunc(a INT, b INT)
8984    /// RETURNS TABLE
8985    /// AS RETURN SELECT a + b AS sum;
8986    /// ```
8987    ///
8988    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql?view=sql-server-ver16#select_stmt
8989    AsReturnSelect(Select),
8990}
8991
8992#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8993#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8994#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8995pub enum CreateFunctionUsing {
8996    Jar(String),
8997    File(String),
8998    Archive(String),
8999}
9000
9001impl fmt::Display for CreateFunctionUsing {
9002    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9003        write!(f, "USING ")?;
9004        match self {
9005            CreateFunctionUsing::Jar(uri) => write!(f, "JAR '{uri}'"),
9006            CreateFunctionUsing::File(uri) => write!(f, "FILE '{uri}'"),
9007            CreateFunctionUsing::Archive(uri) => write!(f, "ARCHIVE '{uri}'"),
9008        }
9009    }
9010}
9011
9012/// `NAME = <EXPR>` arguments for DuckDB macros
9013///
9014/// See [Create Macro - DuckDB](https://duckdb.org/docs/sql/statements/create_macro)
9015/// for more details
9016#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9017#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9018#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9019pub struct MacroArg {
9020    pub name: Ident,
9021    pub default_expr: Option<Expr>,
9022}
9023
9024impl MacroArg {
9025    /// Returns an argument with name.
9026    pub fn new(name: &str) -> Self {
9027        Self {
9028            name: name.into(),
9029            default_expr: None,
9030        }
9031    }
9032}
9033
9034impl fmt::Display for MacroArg {
9035    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9036        write!(f, "{}", self.name)?;
9037        if let Some(default_expr) = &self.default_expr {
9038            write!(f, " := {default_expr}")?;
9039        }
9040        Ok(())
9041    }
9042}
9043
9044#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9045#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9046#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9047pub enum MacroDefinition {
9048    Expr(Expr),
9049    Table(Box<Query>),
9050}
9051
9052impl fmt::Display for MacroDefinition {
9053    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9054        match self {
9055            MacroDefinition::Expr(expr) => write!(f, "{expr}")?,
9056            MacroDefinition::Table(query) => write!(f, "{query}")?,
9057        }
9058        Ok(())
9059    }
9060}
9061
9062/// Schema possible naming variants ([1]).
9063///
9064/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#schema-definition
9065#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9066#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9067#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9068pub enum SchemaName {
9069    /// Only schema name specified: `<schema name>`.
9070    Simple(ObjectName),
9071    /// Only authorization identifier specified: `AUTHORIZATION <schema authorization identifier>`.
9072    UnnamedAuthorization(Ident),
9073    /// Both schema name and authorization identifier specified: `<schema name>  AUTHORIZATION <schema authorization identifier>`.
9074    NamedAuthorization(ObjectName, Ident),
9075}
9076
9077impl fmt::Display for SchemaName {
9078    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9079        match self {
9080            SchemaName::Simple(name) => {
9081                write!(f, "{name}")
9082            }
9083            SchemaName::UnnamedAuthorization(authorization) => {
9084                write!(f, "AUTHORIZATION {authorization}")
9085            }
9086            SchemaName::NamedAuthorization(name, authorization) => {
9087                write!(f, "{name} AUTHORIZATION {authorization}")
9088            }
9089        }
9090    }
9091}
9092
9093/// Fulltext search modifiers ([1]).
9094///
9095/// [1]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html#function_match
9096#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9097#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9098#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9099pub enum SearchModifier {
9100    /// `IN NATURAL LANGUAGE MODE`.
9101    InNaturalLanguageMode,
9102    /// `IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION`.
9103    InNaturalLanguageModeWithQueryExpansion,
9104    ///`IN BOOLEAN MODE`.
9105    InBooleanMode,
9106    ///`WITH QUERY EXPANSION`.
9107    WithQueryExpansion,
9108}
9109
9110impl fmt::Display for SearchModifier {
9111    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9112        match self {
9113            Self::InNaturalLanguageMode => {
9114                write!(f, "IN NATURAL LANGUAGE MODE")?;
9115            }
9116            Self::InNaturalLanguageModeWithQueryExpansion => {
9117                write!(f, "IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION")?;
9118            }
9119            Self::InBooleanMode => {
9120                write!(f, "IN BOOLEAN MODE")?;
9121            }
9122            Self::WithQueryExpansion => {
9123                write!(f, "WITH QUERY EXPANSION")?;
9124            }
9125        }
9126
9127        Ok(())
9128    }
9129}
9130
9131#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9132#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9133#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9134pub struct LockTable {
9135    pub table: Ident,
9136    pub alias: Option<Ident>,
9137    pub lock_type: LockTableType,
9138}
9139
9140impl fmt::Display for LockTable {
9141    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9142        let Self {
9143            table: tbl_name,
9144            alias,
9145            lock_type,
9146        } = self;
9147
9148        write!(f, "{tbl_name} ")?;
9149        if let Some(alias) = alias {
9150            write!(f, "AS {alias} ")?;
9151        }
9152        write!(f, "{lock_type}")?;
9153        Ok(())
9154    }
9155}
9156
9157#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9158#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9159#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9160pub enum LockTableType {
9161    Read { local: bool },
9162    Write { low_priority: bool },
9163}
9164
9165impl fmt::Display for LockTableType {
9166    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9167        match self {
9168            Self::Read { local } => {
9169                write!(f, "READ")?;
9170                if *local {
9171                    write!(f, " LOCAL")?;
9172                }
9173            }
9174            Self::Write { low_priority } => {
9175                if *low_priority {
9176                    write!(f, "LOW_PRIORITY ")?;
9177                }
9178                write!(f, "WRITE")?;
9179            }
9180        }
9181
9182        Ok(())
9183    }
9184}
9185
9186#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9187#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9188#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9189pub struct HiveSetLocation {
9190    pub has_set: bool,
9191    pub location: Ident,
9192}
9193
9194impl fmt::Display for HiveSetLocation {
9195    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9196        if self.has_set {
9197            write!(f, "SET ")?;
9198        }
9199        write!(f, "LOCATION {}", self.location)
9200    }
9201}
9202
9203/// MySQL `ALTER TABLE` only  [FIRST | AFTER column_name]
9204#[allow(clippy::large_enum_variant)]
9205#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9206#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9207#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9208pub enum MySQLColumnPosition {
9209    First,
9210    After(Ident),
9211}
9212
9213impl Display for MySQLColumnPosition {
9214    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9215        match self {
9216            MySQLColumnPosition::First => write!(f, "FIRST"),
9217            MySQLColumnPosition::After(ident) => {
9218                let column_name = &ident.value;
9219                write!(f, "AFTER {column_name}")
9220            }
9221        }
9222    }
9223}
9224
9225/// MySQL `CREATE VIEW` algorithm parameter: [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
9226#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9227#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9228#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9229pub enum CreateViewAlgorithm {
9230    Undefined,
9231    Merge,
9232    TempTable,
9233}
9234
9235impl Display for CreateViewAlgorithm {
9236    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9237        match self {
9238            CreateViewAlgorithm::Undefined => write!(f, "UNDEFINED"),
9239            CreateViewAlgorithm::Merge => write!(f, "MERGE"),
9240            CreateViewAlgorithm::TempTable => write!(f, "TEMPTABLE"),
9241        }
9242    }
9243}
9244/// MySQL `CREATE VIEW` security parameter: [SQL SECURITY { DEFINER | INVOKER }]
9245#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9246#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9247#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9248pub enum CreateViewSecurity {
9249    Definer,
9250    Invoker,
9251}
9252
9253impl Display for CreateViewSecurity {
9254    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9255        match self {
9256            CreateViewSecurity::Definer => write!(f, "DEFINER"),
9257            CreateViewSecurity::Invoker => write!(f, "INVOKER"),
9258        }
9259    }
9260}
9261
9262/// [MySQL] `CREATE VIEW` additional parameters
9263///
9264/// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/create-view.html
9265#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9267#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9268pub struct CreateViewParams {
9269    pub algorithm: Option<CreateViewAlgorithm>,
9270    pub definer: Option<GranteeName>,
9271    pub security: Option<CreateViewSecurity>,
9272}
9273
9274impl Display for CreateViewParams {
9275    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9276        let CreateViewParams {
9277            algorithm,
9278            definer,
9279            security,
9280        } = self;
9281        if let Some(algorithm) = algorithm {
9282            write!(f, "ALGORITHM = {algorithm} ")?;
9283        }
9284        if let Some(definers) = definer {
9285            write!(f, "DEFINER = {definers} ")?;
9286        }
9287        if let Some(security) = security {
9288            write!(f, "SQL SECURITY {security} ")?;
9289        }
9290        Ok(())
9291    }
9292}
9293
9294#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9295#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9296#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9297/// Key/Value, where the value is a (optionally named) list of identifiers
9298///
9299/// ```sql
9300/// UNION = (tbl_name[,tbl_name]...)
9301/// ENGINE = ReplicatedMergeTree('/table_name','{replica}', ver)
9302/// ENGINE = SummingMergeTree([columns])
9303/// ```
9304pub struct NamedParenthesizedList {
9305    pub key: Ident,
9306    pub name: Option<Ident>,
9307    pub values: Vec<Ident>,
9308}
9309
9310/// Snowflake `WITH ROW ACCESS POLICY policy_name ON (identifier, ...)`
9311///
9312/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
9313/// <https://docs.snowflake.com/en/user-guide/security-row-intro>
9314#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9315#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9316#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9317pub struct RowAccessPolicy {
9318    pub policy: ObjectName,
9319    pub on: Vec<Ident>,
9320}
9321
9322impl RowAccessPolicy {
9323    pub fn new(policy: ObjectName, on: Vec<Ident>) -> Self {
9324        Self { policy, on }
9325    }
9326}
9327
9328impl Display for RowAccessPolicy {
9329    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9330        write!(
9331            f,
9332            "WITH ROW ACCESS POLICY {} ON ({})",
9333            self.policy,
9334            display_comma_separated(self.on.as_slice())
9335        )
9336    }
9337}
9338
9339/// Snowflake `WITH TAG ( tag_name = '<tag_value>', ...)`
9340///
9341/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
9342#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9343#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9344#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9345pub struct Tag {
9346    pub key: ObjectName,
9347    pub value: String,
9348}
9349
9350impl Tag {
9351    pub fn new(key: ObjectName, value: String) -> Self {
9352        Self { key, value }
9353    }
9354}
9355
9356impl Display for Tag {
9357    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9358        write!(f, "{}='{}'", self.key, self.value)
9359    }
9360}
9361
9362/// Snowflake `WITH CONTACT ( purpose = contact [ , purpose = contact ...] )`
9363///
9364/// <https://docs.snowflake.com/en/sql-reference/sql/create-database>
9365#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9366#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9367#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9368pub struct ContactEntry {
9369    pub purpose: String,
9370    pub contact: String,
9371}
9372
9373impl Display for ContactEntry {
9374    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9375        write!(f, "{} = {}", self.purpose, self.contact)
9376    }
9377}
9378
9379/// Helper to indicate if a comment includes the `=` in the display form
9380#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9381#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9382#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9383pub enum CommentDef {
9384    /// Includes `=` when printing the comment, as `COMMENT = 'comment'`
9385    /// Does not include `=` when printing the comment, as `COMMENT 'comment'`
9386    WithEq(String),
9387    WithoutEq(String),
9388}
9389
9390impl Display for CommentDef {
9391    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9392        match self {
9393            CommentDef::WithEq(comment) | CommentDef::WithoutEq(comment) => write!(f, "{comment}"),
9394        }
9395    }
9396}
9397
9398/// Helper to indicate if a collection should be wrapped by a symbol in the display form
9399///
9400/// [`Display`] is implemented for every [`Vec<T>`] where `T: Display`.
9401/// The string output is a comma separated list for the vec items
9402///
9403/// # Examples
9404/// ```
9405/// # use sqlparser::ast::WrappedCollection;
9406/// let items = WrappedCollection::Parentheses(vec!["one", "two", "three"]);
9407/// assert_eq!("(one, two, three)", items.to_string());
9408///
9409/// let items = WrappedCollection::NoWrapping(vec!["one", "two", "three"]);
9410/// assert_eq!("one, two, three", items.to_string());
9411/// ```
9412#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9413#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9414#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9415pub enum WrappedCollection<T> {
9416    /// Print the collection without wrapping symbols, as `item, item, item`
9417    NoWrapping(T),
9418    /// Wraps the collection in Parentheses, as `(item, item, item)`
9419    Parentheses(T),
9420}
9421
9422impl<T> Display for WrappedCollection<Vec<T>>
9423where
9424    T: Display,
9425{
9426    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9427        match self {
9428            WrappedCollection::NoWrapping(inner) => {
9429                write!(f, "{}", display_comma_separated(inner.as_slice()))
9430            }
9431            WrappedCollection::Parentheses(inner) => {
9432                write!(f, "({})", display_comma_separated(inner.as_slice()))
9433            }
9434        }
9435    }
9436}
9437
9438/// Represents a single PostgreSQL utility option.
9439///
9440/// A utility option is a key-value pair where the key is an identifier (IDENT) and the value
9441/// can be one of the following:
9442/// - A number with an optional sign (`+` or `-`). Example: `+10`, `-10.2`, `3`
9443/// - A non-keyword string. Example: `option1`, `'option2'`, `"option3"`
9444/// - keyword: `TRUE`, `FALSE`, `ON` (`off` is also accept).
9445/// - Empty. Example: `ANALYZE` (identifier only)
9446///
9447/// Utility options are used in various PostgreSQL DDL statements, including statements such as
9448/// `CLUSTER`, `EXPLAIN`, `VACUUM`, and `REINDEX`. These statements format options as `( option [, ...] )`.
9449///
9450/// [CLUSTER](https://www.postgresql.org/docs/current/sql-cluster.html)
9451/// [EXPLAIN](https://www.postgresql.org/docs/current/sql-explain.html)
9452/// [VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html)
9453/// [REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html)
9454///
9455/// For example, the `EXPLAIN` AND `VACUUM` statements with options might look like this:
9456/// ```sql
9457/// EXPLAIN (ANALYZE, VERBOSE TRUE, FORMAT TEXT) SELECT * FROM my_table;
9458///
9459/// VACUUM (VERBOSE, ANALYZE ON, PARALLEL 10) my_table;
9460/// ```
9461#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9462#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9463#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9464pub struct UtilityOption {
9465    pub name: Ident,
9466    pub arg: Option<Expr>,
9467}
9468
9469impl Display for UtilityOption {
9470    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9471        if let Some(ref arg) = self.arg {
9472            write!(f, "{} {}", self.name, arg)
9473        } else {
9474            write!(f, "{}", self.name)
9475        }
9476    }
9477}
9478
9479/// Represents the different options available for `SHOW`
9480/// statements to filter the results. Example from Snowflake:
9481/// <https://docs.snowflake.com/en/sql-reference/sql/show-tables>
9482#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9483#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9484#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9485pub struct ShowStatementOptions {
9486    pub show_in: Option<ShowStatementIn>,
9487    pub starts_with: Option<Value>,
9488    pub limit: Option<Expr>,
9489    pub limit_from: Option<Value>,
9490    pub filter_position: Option<ShowStatementFilterPosition>,
9491}
9492
9493impl Display for ShowStatementOptions {
9494    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9495        let (like_in_infix, like_in_suffix) = match &self.filter_position {
9496            Some(ShowStatementFilterPosition::Infix(filter)) => {
9497                (format!(" {filter}"), "".to_string())
9498            }
9499            Some(ShowStatementFilterPosition::Suffix(filter)) => {
9500                ("".to_string(), format!(" {filter}"))
9501            }
9502            None => ("".to_string(), "".to_string()),
9503        };
9504        write!(
9505            f,
9506            "{like_in_infix}{show_in}{starts_with}{limit}{from}{like_in_suffix}",
9507            show_in = match &self.show_in {
9508                Some(i) => format!(" {i}"),
9509                None => String::new(),
9510            },
9511            starts_with = match &self.starts_with {
9512                Some(s) => format!(" STARTS WITH {s}"),
9513                None => String::new(),
9514            },
9515            limit = match &self.limit {
9516                Some(l) => format!(" LIMIT {l}"),
9517                None => String::new(),
9518            },
9519            from = match &self.limit_from {
9520                Some(f) => format!(" FROM {f}"),
9521                None => String::new(),
9522            }
9523        )?;
9524        Ok(())
9525    }
9526}
9527
9528#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9529#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9530#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9531pub enum ShowStatementFilterPosition {
9532    Infix(ShowStatementFilter), // For example: SHOW COLUMNS LIKE '%name%' IN TABLE tbl
9533    Suffix(ShowStatementFilter), // For example: SHOW COLUMNS IN tbl LIKE '%name%'
9534}
9535
9536#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9537#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9538#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9539pub enum ShowStatementInParentType {
9540    Account,
9541    Database,
9542    Schema,
9543    Table,
9544    View,
9545}
9546
9547impl fmt::Display for ShowStatementInParentType {
9548    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9549        match self {
9550            ShowStatementInParentType::Account => write!(f, "ACCOUNT"),
9551            ShowStatementInParentType::Database => write!(f, "DATABASE"),
9552            ShowStatementInParentType::Schema => write!(f, "SCHEMA"),
9553            ShowStatementInParentType::Table => write!(f, "TABLE"),
9554            ShowStatementInParentType::View => write!(f, "VIEW"),
9555        }
9556    }
9557}
9558
9559#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9560#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9561#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9562pub struct ShowStatementIn {
9563    pub clause: ShowStatementInClause,
9564    pub parent_type: Option<ShowStatementInParentType>,
9565    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
9566    pub parent_name: Option<ObjectName>,
9567}
9568
9569impl fmt::Display for ShowStatementIn {
9570    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9571        write!(f, "{}", self.clause)?;
9572        if let Some(parent_type) = &self.parent_type {
9573            write!(f, " {parent_type}")?;
9574        }
9575        if let Some(parent_name) = &self.parent_name {
9576            write!(f, " {parent_name}")?;
9577        }
9578        Ok(())
9579    }
9580}
9581
9582/// A Show Charset statement
9583#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9584#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9585#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9586pub struct ShowCharset {
9587    /// The statement can be written as `SHOW CHARSET` or `SHOW CHARACTER SET`
9588    /// true means CHARSET was used and false means CHARACTER SET was used
9589    pub is_shorthand: bool,
9590    pub filter: Option<ShowStatementFilter>,
9591}
9592
9593impl fmt::Display for ShowCharset {
9594    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9595        write!(f, "SHOW")?;
9596        if self.is_shorthand {
9597            write!(f, " CHARSET")?;
9598        } else {
9599            write!(f, " CHARACTER SET")?;
9600        }
9601        if let Some(filter) = &self.filter {
9602            write!(f, " {filter}")?;
9603        }
9604        Ok(())
9605    }
9606}
9607
9608#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9609#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9610#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9611pub struct ShowObjects {
9612    pub terse: bool,
9613    pub show_options: ShowStatementOptions,
9614}
9615
9616/// MSSQL's json null clause
9617///
9618/// ```plaintext
9619/// <json_null_clause> ::=
9620///       NULL ON NULL
9621///     | ABSENT ON NULL
9622/// ```
9623///
9624/// <https://learn.microsoft.com/en-us/sql/t-sql/functions/json-object-transact-sql?view=sql-server-ver16#json_null_clause>
9625#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9626#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9627#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9628pub enum JsonNullClause {
9629    NullOnNull,
9630    AbsentOnNull,
9631}
9632
9633impl Display for JsonNullClause {
9634    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9635        match self {
9636            JsonNullClause::NullOnNull => write!(f, "NULL ON NULL"),
9637            JsonNullClause::AbsentOnNull => write!(f, "ABSENT ON NULL"),
9638        }
9639    }
9640}
9641
9642/// PostgreSQL JSON function RETURNING clause
9643///
9644/// Example:
9645/// ```sql
9646/// JSON_OBJECT('a': 1 RETURNING jsonb)
9647/// ```
9648#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9649#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9650#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9651pub struct JsonReturningClause {
9652    pub data_type: DataType,
9653}
9654
9655impl Display for JsonReturningClause {
9656    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9657        write!(f, "RETURNING {}", self.data_type)
9658    }
9659}
9660
9661/// rename object definition
9662#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9663#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9664#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9665pub struct RenameTable {
9666    pub old_name: ObjectName,
9667    pub new_name: ObjectName,
9668}
9669
9670impl fmt::Display for RenameTable {
9671    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9672        write!(f, "{} TO {}", self.old_name, self.new_name)?;
9673        Ok(())
9674    }
9675}
9676
9677/// Represents the referenced table in an `INSERT INTO` statement
9678#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9679#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9680#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9681pub enum TableObject {
9682    /// Table specified by name.
9683    /// Example:
9684    /// ```sql
9685    /// INSERT INTO my_table
9686    /// ```
9687    TableName(#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] ObjectName),
9688
9689    /// Table specified as a function.
9690    /// Example:
9691    /// ```sql
9692    /// INSERT INTO TABLE FUNCTION remote('localhost', default.simple_table)
9693    /// ```
9694    /// [Clickhouse](https://clickhouse.com/docs/en/sql-reference/table-functions)
9695    TableFunction(Function),
9696}
9697
9698impl fmt::Display for TableObject {
9699    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9700        match self {
9701            Self::TableName(table_name) => write!(f, "{table_name}"),
9702            Self::TableFunction(func) => write!(f, "FUNCTION {func}"),
9703        }
9704    }
9705}
9706
9707/// Represents a SET SESSION AUTHORIZATION statement
9708#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9709#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9710#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9711pub struct SetSessionAuthorizationParam {
9712    pub scope: ContextModifier,
9713    pub kind: SetSessionAuthorizationParamKind,
9714}
9715
9716impl fmt::Display for SetSessionAuthorizationParam {
9717    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9718        write!(f, "{}", self.kind)
9719    }
9720}
9721
9722/// Represents the parameter kind for SET SESSION AUTHORIZATION
9723#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9724#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9725#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9726pub enum SetSessionAuthorizationParamKind {
9727    /// Default authorization
9728    Default,
9729
9730    /// User name
9731    User(Ident),
9732}
9733
9734impl fmt::Display for SetSessionAuthorizationParamKind {
9735    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9736        match self {
9737            SetSessionAuthorizationParamKind::Default => write!(f, "DEFAULT"),
9738            SetSessionAuthorizationParamKind::User(name) => write!(f, "{}", name),
9739        }
9740    }
9741}
9742
9743#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9744#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9745#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9746pub enum SetSessionParamKind {
9747    Generic(SetSessionParamGeneric),
9748    IdentityInsert(SetSessionParamIdentityInsert),
9749    Offsets(SetSessionParamOffsets),
9750    Statistics(SetSessionParamStatistics),
9751}
9752
9753impl fmt::Display for SetSessionParamKind {
9754    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9755        match self {
9756            SetSessionParamKind::Generic(x) => write!(f, "{x}"),
9757            SetSessionParamKind::IdentityInsert(x) => write!(f, "{x}"),
9758            SetSessionParamKind::Offsets(x) => write!(f, "{x}"),
9759            SetSessionParamKind::Statistics(x) => write!(f, "{x}"),
9760        }
9761    }
9762}
9763
9764#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9765#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9766#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9767pub struct SetSessionParamGeneric {
9768    pub names: Vec<String>,
9769    pub value: String,
9770}
9771
9772impl fmt::Display for SetSessionParamGeneric {
9773    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9774        write!(f, "{} {}", display_comma_separated(&self.names), self.value)
9775    }
9776}
9777
9778#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9779#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9780#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9781pub struct SetSessionParamIdentityInsert {
9782    pub obj: ObjectName,
9783    pub value: SessionParamValue,
9784}
9785
9786impl fmt::Display for SetSessionParamIdentityInsert {
9787    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9788        write!(f, "IDENTITY_INSERT {} {}", self.obj, self.value)
9789    }
9790}
9791
9792#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9793#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9794#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9795pub struct SetSessionParamOffsets {
9796    pub keywords: Vec<String>,
9797    pub value: SessionParamValue,
9798}
9799
9800impl fmt::Display for SetSessionParamOffsets {
9801    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9802        write!(
9803            f,
9804            "OFFSETS {} {}",
9805            display_comma_separated(&self.keywords),
9806            self.value
9807        )
9808    }
9809}
9810
9811#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9812#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9813#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9814pub struct SetSessionParamStatistics {
9815    pub topic: SessionParamStatsTopic,
9816    pub value: SessionParamValue,
9817}
9818
9819impl fmt::Display for SetSessionParamStatistics {
9820    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9821        write!(f, "STATISTICS {} {}", self.topic, self.value)
9822    }
9823}
9824
9825#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9826#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9827#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9828pub enum SessionParamStatsTopic {
9829    IO,
9830    Profile,
9831    Time,
9832    Xml,
9833}
9834
9835impl fmt::Display for SessionParamStatsTopic {
9836    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9837        match self {
9838            SessionParamStatsTopic::IO => write!(f, "IO"),
9839            SessionParamStatsTopic::Profile => write!(f, "PROFILE"),
9840            SessionParamStatsTopic::Time => write!(f, "TIME"),
9841            SessionParamStatsTopic::Xml => write!(f, "XML"),
9842        }
9843    }
9844}
9845
9846#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9847#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9848#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9849pub enum SessionParamValue {
9850    On,
9851    Off,
9852}
9853
9854impl fmt::Display for SessionParamValue {
9855    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9856        match self {
9857            SessionParamValue::On => write!(f, "ON"),
9858            SessionParamValue::Off => write!(f, "OFF"),
9859        }
9860    }
9861}
9862
9863/// Snowflake StorageSerializationPolicy for Iceberg Tables
9864/// ```sql
9865/// [ STORAGE_SERIALIZATION_POLICY = { COMPATIBLE | OPTIMIZED } ]
9866/// ```
9867///
9868/// <https://docs.snowflake.com/en/sql-reference/sql/create-iceberg-table>
9869#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9870#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9871#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9872pub enum StorageSerializationPolicy {
9873    Compatible,
9874    Optimized,
9875}
9876
9877impl Display for StorageSerializationPolicy {
9878    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9879        match self {
9880            StorageSerializationPolicy::Compatible => write!(f, "COMPATIBLE"),
9881            StorageSerializationPolicy::Optimized => write!(f, "OPTIMIZED"),
9882        }
9883    }
9884}
9885
9886/// Snowflake CatalogSyncNamespaceMode
9887/// ```sql
9888/// [ CATALOG_SYNC_NAMESPACE_MODE = { NEST | FLATTEN } ]
9889/// ```
9890///
9891/// <https://docs.snowflake.com/en/sql-reference/sql/create-database>
9892#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9893#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9894#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9895pub enum CatalogSyncNamespaceMode {
9896    Nest,
9897    Flatten,
9898}
9899
9900impl Display for CatalogSyncNamespaceMode {
9901    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9902        match self {
9903            CatalogSyncNamespaceMode::Nest => write!(f, "NEST"),
9904            CatalogSyncNamespaceMode::Flatten => write!(f, "FLATTEN"),
9905        }
9906    }
9907}
9908
9909/// Variants of the Snowflake `COPY INTO` statement
9910#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9911#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9912#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9913pub enum CopyIntoSnowflakeKind {
9914    /// Loads data from files to a table
9915    /// See: <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table>
9916    Table,
9917    /// Unloads data from a table or query to external files
9918    /// See: <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location>
9919    Location,
9920}
9921
9922#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9923#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9924#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9925pub struct PrintStatement {
9926    pub message: Box<Expr>,
9927}
9928
9929impl fmt::Display for PrintStatement {
9930    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9931        write!(f, "PRINT {}", self.message)
9932    }
9933}
9934
9935/// Represents a `Return` statement.
9936///
9937/// [MsSql triggers](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql)
9938/// [MsSql functions](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql)
9939#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9940#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9941#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9942pub struct ReturnStatement {
9943    pub value: Option<ReturnStatementValue>,
9944}
9945
9946impl fmt::Display for ReturnStatement {
9947    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9948        match &self.value {
9949            Some(ReturnStatementValue::Expr(expr)) => write!(f, "RETURN {expr}"),
9950            None => write!(f, "RETURN"),
9951        }
9952    }
9953}
9954
9955/// Variants of a `RETURN` statement
9956#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9957#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9958#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9959pub enum ReturnStatementValue {
9960    Expr(Expr),
9961}
9962
9963/// Represents an `OPEN` statement.
9964#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9965#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9966#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9967pub struct OpenStatement {
9968    /// Cursor name
9969    pub cursor_name: Ident,
9970}
9971
9972impl fmt::Display for OpenStatement {
9973    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9974        write!(f, "OPEN {}", self.cursor_name)
9975    }
9976}
9977
9978/// Specifies Include / Exclude NULL within UNPIVOT command.
9979/// For example
9980/// `UNPIVOT (column1 FOR new_column IN (col3, col4, col5, col6))`
9981#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9982#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9983#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9984pub enum NullInclusion {
9985    IncludeNulls,
9986    ExcludeNulls,
9987}
9988
9989impl fmt::Display for NullInclusion {
9990    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9991        match self {
9992            NullInclusion::IncludeNulls => write!(f, "INCLUDE NULLS"),
9993            NullInclusion::ExcludeNulls => write!(f, "EXCLUDE NULLS"),
9994        }
9995    }
9996}
9997
9998/// Checks membership of a value in a JSON array
9999///
10000/// Syntax:
10001/// ```sql
10002/// <value> MEMBER OF(<array>)
10003/// ```
10004/// [MySQL](https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#operator_member-of)
10005#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10006#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10007#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10008pub struct MemberOf {
10009    pub value: Box<Expr>,
10010    pub array: Box<Expr>,
10011}
10012
10013impl fmt::Display for MemberOf {
10014    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10015        write!(f, "{} MEMBER OF({})", self.value, self.array)
10016    }
10017}
10018
10019#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10020#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10021#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10022pub struct ExportData {
10023    pub options: Vec<SqlOption>,
10024    pub query: Box<Query>,
10025    pub connection: Option<ObjectName>,
10026}
10027
10028impl fmt::Display for ExportData {
10029    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10030        if let Some(connection) = &self.connection {
10031            write!(
10032                f,
10033                "EXPORT DATA WITH CONNECTION {connection} OPTIONS({}) AS {}",
10034                display_comma_separated(&self.options),
10035                self.query
10036            )
10037        } else {
10038            write!(
10039                f,
10040                "EXPORT DATA OPTIONS({}) AS {}",
10041                display_comma_separated(&self.options),
10042                self.query
10043            )
10044        }
10045    }
10046}
10047/// Creates a user
10048///
10049/// Syntax:
10050/// ```sql
10051/// CREATE [OR REPLACE] USER [IF NOT EXISTS] <name> [OPTIONS]
10052/// ```
10053///
10054/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-user)
10055#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10056#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10057#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10058pub struct CreateUser {
10059    pub or_replace: bool,
10060    pub if_not_exists: bool,
10061    pub name: Ident,
10062    pub options: KeyValueOptions,
10063    pub with_tags: bool,
10064    pub tags: KeyValueOptions,
10065}
10066
10067impl fmt::Display for CreateUser {
10068    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10069        write!(f, "CREATE")?;
10070        if self.or_replace {
10071            write!(f, " OR REPLACE")?;
10072        }
10073        write!(f, " USER")?;
10074        if self.if_not_exists {
10075            write!(f, " IF NOT EXISTS")?;
10076        }
10077        write!(f, " {}", self.name)?;
10078        if !self.options.options.is_empty() {
10079            write!(f, " {}", self.options)?;
10080        }
10081        if !self.tags.options.is_empty() {
10082            if self.with_tags {
10083                write!(f, " WITH")?;
10084            }
10085            write!(f, " TAG ({})", self.tags)?;
10086        }
10087        Ok(())
10088    }
10089}
10090
10091/// Modifies the properties of a user
10092///
10093/// Syntax:
10094/// ```sql
10095/// ALTER USER [ IF EXISTS ] [ <name> ] [ OPTIONS ]
10096/// ```
10097///
10098/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/alter-user)
10099#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10100#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10101#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10102pub struct AlterUser {
10103    pub if_exists: bool,
10104    pub name: Ident,
10105    /// The following fields are Snowflake-specific: <https://docs.snowflake.com/en/sql-reference/sql/alter-user#syntax>
10106    pub rename_to: Option<Ident>,
10107    pub reset_password: bool,
10108    pub abort_all_queries: bool,
10109    pub add_role_delegation: Option<AlterUserAddRoleDelegation>,
10110    pub remove_role_delegation: Option<AlterUserRemoveRoleDelegation>,
10111    pub enroll_mfa: bool,
10112    pub set_default_mfa_method: Option<MfaMethodKind>,
10113    pub remove_mfa_method: Option<MfaMethodKind>,
10114    pub modify_mfa_method: Option<AlterUserModifyMfaMethod>,
10115    pub add_mfa_method_otp: Option<AlterUserAddMfaMethodOtp>,
10116    pub set_policy: Option<AlterUserSetPolicy>,
10117    pub unset_policy: Option<UserPolicyKind>,
10118    pub set_tag: KeyValueOptions,
10119    pub unset_tag: Vec<String>,
10120    pub set_props: KeyValueOptions,
10121    pub unset_props: Vec<String>,
10122}
10123
10124/// ```sql
10125/// ALTER USER [ IF EXISTS ] [ <name> ] ADD DELEGATED AUTHORIZATION OF ROLE <role_name> TO SECURITY INTEGRATION <integration_name>
10126/// ```
10127#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10128#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10129#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10130pub struct AlterUserAddRoleDelegation {
10131    pub role: Ident,
10132    pub integration: Ident,
10133}
10134
10135/// ```sql
10136/// ALTER USER [ IF EXISTS ] [ <name> ] REMOVE DELEGATED { AUTHORIZATION OF ROLE <role_name> | AUTHORIZATIONS } FROM SECURITY INTEGRATION <integration_name>
10137/// ```
10138#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10139#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10140#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10141pub struct AlterUserRemoveRoleDelegation {
10142    pub role: Option<Ident>,
10143    pub integration: Ident,
10144}
10145
10146/// ```sql
10147/// ADD MFA METHOD OTP [ COUNT = number ]
10148/// ```
10149#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10150#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10151#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10152pub struct AlterUserAddMfaMethodOtp {
10153    pub count: Option<Value>,
10154}
10155
10156/// ```sql
10157/// ALTER USER [ IF EXISTS ] [ <name> ] MODIFY MFA METHOD <mfa_method> SET COMMENT = '<string>'
10158/// ```
10159#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10160#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10161#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10162pub struct AlterUserModifyMfaMethod {
10163    pub method: MfaMethodKind,
10164    pub comment: String,
10165}
10166
10167/// Types of MFA methods
10168#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10170#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10171pub enum MfaMethodKind {
10172    PassKey,
10173    Totp,
10174    Duo,
10175}
10176
10177impl fmt::Display for MfaMethodKind {
10178    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10179        match self {
10180            MfaMethodKind::PassKey => write!(f, "PASSKEY"),
10181            MfaMethodKind::Totp => write!(f, "TOTP"),
10182            MfaMethodKind::Duo => write!(f, "DUO"),
10183        }
10184    }
10185}
10186
10187/// ```sql
10188/// ALTER USER [ IF EXISTS ] [ <name> ] SET { AUTHENTICATION | PASSWORD | SESSION } POLICY <policy_name>
10189/// ```
10190#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10191#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10192#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10193pub struct AlterUserSetPolicy {
10194    pub policy_kind: UserPolicyKind,
10195    pub policy: Ident,
10196}
10197
10198/// Types of user-based policies
10199#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10200#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10201#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10202pub enum UserPolicyKind {
10203    Authentication,
10204    Password,
10205    Session,
10206}
10207
10208impl fmt::Display for UserPolicyKind {
10209    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10210        match self {
10211            UserPolicyKind::Authentication => write!(f, "AUTHENTICATION"),
10212            UserPolicyKind::Password => write!(f, "PASSWORD"),
10213            UserPolicyKind::Session => write!(f, "SESSION"),
10214        }
10215    }
10216}
10217
10218impl fmt::Display for AlterUser {
10219    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10220        write!(f, "ALTER")?;
10221        write!(f, " USER")?;
10222        if self.if_exists {
10223            write!(f, " IF EXISTS")?;
10224        }
10225        write!(f, " {}", self.name)?;
10226        if let Some(new_name) = &self.rename_to {
10227            write!(f, " RENAME TO {new_name}")?;
10228        }
10229        if self.reset_password {
10230            write!(f, " RESET PASSWORD")?;
10231        }
10232        if self.abort_all_queries {
10233            write!(f, " ABORT ALL QUERIES")?;
10234        }
10235        if let Some(role_delegation) = &self.add_role_delegation {
10236            let role = &role_delegation.role;
10237            let integration = &role_delegation.integration;
10238            write!(
10239                f,
10240                " ADD DELEGATED AUTHORIZATION OF ROLE {role} TO SECURITY INTEGRATION {integration}"
10241            )?;
10242        }
10243        if let Some(role_delegation) = &self.remove_role_delegation {
10244            write!(f, " REMOVE DELEGATED")?;
10245            match &role_delegation.role {
10246                Some(role) => write!(f, " AUTHORIZATION OF ROLE {role}")?,
10247                None => write!(f, " AUTHORIZATIONS")?,
10248            }
10249            let integration = &role_delegation.integration;
10250            write!(f, " FROM SECURITY INTEGRATION {integration}")?;
10251        }
10252        if self.enroll_mfa {
10253            write!(f, " ENROLL MFA")?;
10254        }
10255        if let Some(method) = &self.set_default_mfa_method {
10256            write!(f, " SET DEFAULT_MFA_METHOD {method}")?
10257        }
10258        if let Some(method) = &self.remove_mfa_method {
10259            write!(f, " REMOVE MFA METHOD {method}")?;
10260        }
10261        if let Some(modify) = &self.modify_mfa_method {
10262            let method = &modify.method;
10263            let comment = &modify.comment;
10264            write!(
10265                f,
10266                " MODIFY MFA METHOD {method} SET COMMENT '{}'",
10267                value::escape_single_quote_string(comment)
10268            )?;
10269        }
10270        if let Some(add_mfa_method_otp) = &self.add_mfa_method_otp {
10271            write!(f, " ADD MFA METHOD OTP")?;
10272            if let Some(count) = &add_mfa_method_otp.count {
10273                write!(f, " COUNT = {count}")?;
10274            }
10275        }
10276        if let Some(policy) = &self.set_policy {
10277            let policy_kind = &policy.policy_kind;
10278            let name = &policy.policy;
10279            write!(f, " SET {policy_kind} POLICY {name}")?;
10280        }
10281        if let Some(policy_kind) = &self.unset_policy {
10282            write!(f, " UNSET {policy_kind} POLICY")?;
10283        }
10284        if !self.set_tag.options.is_empty() {
10285            write!(f, " SET TAG {}", self.set_tag)?;
10286        }
10287        if !self.unset_tag.is_empty() {
10288            write!(f, " UNSET TAG {}", display_comma_separated(&self.unset_tag))?;
10289        }
10290        let has_props = !self.set_props.options.is_empty();
10291        if has_props {
10292            write!(f, " SET")?;
10293            write!(f, " {}", &self.set_props)?;
10294        }
10295        if !self.unset_props.is_empty() {
10296            write!(f, " UNSET {}", display_comma_separated(&self.unset_props))?;
10297        }
10298        Ok(())
10299    }
10300}
10301
10302/// Specifies how to create a new table based on an existing table's schema.
10303/// '''sql
10304/// CREATE TABLE new LIKE old ...
10305/// '''
10306#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10307#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10308#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10309pub enum CreateTableLikeKind {
10310    /// '''sql
10311    /// CREATE TABLE new (LIKE old ...)
10312    /// '''
10313    /// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html)
10314    Parenthesized(CreateTableLike),
10315    /// '''sql
10316    /// CREATE TABLE new LIKE old ...
10317    /// '''
10318    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-table#label-create-table-like)
10319    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_like)
10320    Plain(CreateTableLike),
10321}
10322
10323#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10324#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10325#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10326pub enum CreateTableLikeDefaults {
10327    Including,
10328    Excluding,
10329}
10330
10331impl fmt::Display for CreateTableLikeDefaults {
10332    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10333        match self {
10334            CreateTableLikeDefaults::Including => write!(f, "INCLUDING DEFAULTS"),
10335            CreateTableLikeDefaults::Excluding => write!(f, "EXCLUDING DEFAULTS"),
10336        }
10337    }
10338}
10339
10340#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10341#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10342#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10343pub struct CreateTableLike {
10344    pub name: ObjectName,
10345    pub defaults: Option<CreateTableLikeDefaults>,
10346}
10347
10348impl fmt::Display for CreateTableLike {
10349    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10350        write!(f, "LIKE {}", self.name)?;
10351        if let Some(defaults) = &self.defaults {
10352            write!(f, " {defaults}")?;
10353        }
10354        Ok(())
10355    }
10356}
10357
10358/// Specifies the refresh mode for the dynamic table.
10359///
10360/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table)
10361#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10362#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10363#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10364pub enum RefreshModeKind {
10365    Auto,
10366    Full,
10367    Incremental,
10368}
10369
10370impl fmt::Display for RefreshModeKind {
10371    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10372        match self {
10373            RefreshModeKind::Auto => write!(f, "AUTO"),
10374            RefreshModeKind::Full => write!(f, "FULL"),
10375            RefreshModeKind::Incremental => write!(f, "INCREMENTAL"),
10376        }
10377    }
10378}
10379
10380/// Specifies the behavior of the initial refresh of the dynamic table.
10381///
10382/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table)
10383#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10384#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10385#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10386pub enum InitializeKind {
10387    OnCreate,
10388    OnSchedule,
10389}
10390
10391impl fmt::Display for InitializeKind {
10392    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10393        match self {
10394            InitializeKind::OnCreate => write!(f, "ON_CREATE"),
10395            InitializeKind::OnSchedule => write!(f, "ON_SCHEDULE"),
10396        }
10397    }
10398}
10399
10400/// Re-sorts rows and reclaims space in either a specified table or all tables in the current database
10401///
10402/// '''sql
10403/// VACUUM [ FULL | SORT ONLY | DELETE ONLY | REINDEX | RECLUSTER ] [ \[ table_name \] [ TO threshold PERCENT ] \[ BOOST \] ]
10404/// '''
10405/// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)
10406#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10407#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10408#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10409pub struct VacuumStatement {
10410    pub full: bool,
10411    pub sort_only: bool,
10412    pub delete_only: bool,
10413    pub reindex: bool,
10414    pub recluster: bool,
10415    pub table_name: Option<ObjectName>,
10416    pub threshold: Option<Value>,
10417    pub boost: bool,
10418}
10419
10420impl fmt::Display for VacuumStatement {
10421    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10422        write!(
10423            f,
10424            "VACUUM{}{}{}{}{}",
10425            if self.full { " FULL" } else { "" },
10426            if self.sort_only { " SORT ONLY" } else { "" },
10427            if self.delete_only { " DELETE ONLY" } else { "" },
10428            if self.reindex { " REINDEX" } else { "" },
10429            if self.recluster { " RECLUSTER" } else { "" },
10430        )?;
10431        if let Some(table_name) = &self.table_name {
10432            write!(f, " {table_name}")?;
10433        }
10434        if let Some(threshold) = &self.threshold {
10435            write!(f, " TO {threshold} PERCENT")?;
10436        }
10437        if self.boost {
10438            write!(f, " BOOST")?;
10439        }
10440        Ok(())
10441    }
10442}
10443
10444/// Variants of the RESET statement
10445#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10446#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10447#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10448pub enum Reset {
10449    /// Resets all session parameters to their default values.
10450    ALL,
10451
10452    /// Resets a specific session parameter to its default value.
10453    ConfigurationParameter(ObjectName),
10454}
10455
10456/// Resets a session parameter to its default value.
10457/// ```sql
10458/// RESET { ALL | <configuration_parameter> }
10459/// ```
10460#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10461#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10462#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10463pub struct ResetStatement {
10464    pub reset: Reset,
10465}
10466
10467impl fmt::Display for ResetStatement {
10468    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10469        match &self.reset {
10470            Reset::ALL => write!(f, "RESET ALL"),
10471            Reset::ConfigurationParameter(param) => write!(f, "RESET {}", param),
10472        }
10473    }
10474}
10475
10476impl From<Set> for Statement {
10477    fn from(s: Set) -> Self {
10478        Self::Set(s)
10479    }
10480}
10481
10482impl From<Query> for Statement {
10483    fn from(q: Query) -> Self {
10484        Box::new(q).into()
10485    }
10486}
10487
10488impl From<Box<Query>> for Statement {
10489    fn from(q: Box<Query>) -> Self {
10490        Self::Query(q)
10491    }
10492}
10493
10494impl From<Insert> for Statement {
10495    fn from(i: Insert) -> Self {
10496        Self::Insert(i)
10497    }
10498}
10499
10500impl From<Update> for Statement {
10501    fn from(u: Update) -> Self {
10502        Self::Update(u)
10503    }
10504}
10505
10506impl From<CreateView> for Statement {
10507    fn from(cv: CreateView) -> Self {
10508        Self::CreateView(cv)
10509    }
10510}
10511
10512impl From<CreateRole> for Statement {
10513    fn from(cr: CreateRole) -> Self {
10514        Self::CreateRole(cr)
10515    }
10516}
10517
10518impl From<AlterTable> for Statement {
10519    fn from(at: AlterTable) -> Self {
10520        Self::AlterTable(at)
10521    }
10522}
10523
10524impl From<DropFunction> for Statement {
10525    fn from(df: DropFunction) -> Self {
10526        Self::DropFunction(df)
10527    }
10528}
10529
10530impl From<CreateExtension> for Statement {
10531    fn from(ce: CreateExtension) -> Self {
10532        Self::CreateExtension(ce)
10533    }
10534}
10535
10536impl From<DropExtension> for Statement {
10537    fn from(de: DropExtension) -> Self {
10538        Self::DropExtension(de)
10539    }
10540}
10541
10542impl From<CaseStatement> for Statement {
10543    fn from(c: CaseStatement) -> Self {
10544        Self::Case(c)
10545    }
10546}
10547
10548impl From<IfStatement> for Statement {
10549    fn from(i: IfStatement) -> Self {
10550        Self::If(i)
10551    }
10552}
10553
10554impl From<WhileStatement> for Statement {
10555    fn from(w: WhileStatement) -> Self {
10556        Self::While(w)
10557    }
10558}
10559
10560impl From<RaiseStatement> for Statement {
10561    fn from(r: RaiseStatement) -> Self {
10562        Self::Raise(r)
10563    }
10564}
10565
10566impl From<Function> for Statement {
10567    fn from(f: Function) -> Self {
10568        Self::Call(f)
10569    }
10570}
10571
10572impl From<OpenStatement> for Statement {
10573    fn from(o: OpenStatement) -> Self {
10574        Self::Open(o)
10575    }
10576}
10577
10578impl From<Delete> for Statement {
10579    fn from(d: Delete) -> Self {
10580        Self::Delete(d)
10581    }
10582}
10583
10584impl From<CreateTable> for Statement {
10585    fn from(c: CreateTable) -> Self {
10586        Self::CreateTable(c)
10587    }
10588}
10589
10590impl From<CreateIndex> for Statement {
10591    fn from(c: CreateIndex) -> Self {
10592        Self::CreateIndex(c)
10593    }
10594}
10595
10596impl From<CreateServerStatement> for Statement {
10597    fn from(c: CreateServerStatement) -> Self {
10598        Self::CreateServer(c)
10599    }
10600}
10601
10602impl From<CreateConnector> for Statement {
10603    fn from(c: CreateConnector) -> Self {
10604        Self::CreateConnector(c)
10605    }
10606}
10607
10608impl From<AlterSchema> for Statement {
10609    fn from(a: AlterSchema) -> Self {
10610        Self::AlterSchema(a)
10611    }
10612}
10613
10614impl From<AlterType> for Statement {
10615    fn from(a: AlterType) -> Self {
10616        Self::AlterType(a)
10617    }
10618}
10619
10620impl From<DropDomain> for Statement {
10621    fn from(d: DropDomain) -> Self {
10622        Self::DropDomain(d)
10623    }
10624}
10625
10626impl From<ShowCharset> for Statement {
10627    fn from(s: ShowCharset) -> Self {
10628        Self::ShowCharset(s)
10629    }
10630}
10631
10632impl From<ShowObjects> for Statement {
10633    fn from(s: ShowObjects) -> Self {
10634        Self::ShowObjects(s)
10635    }
10636}
10637
10638impl From<Use> for Statement {
10639    fn from(u: Use) -> Self {
10640        Self::Use(u)
10641    }
10642}
10643
10644impl From<CreateFunction> for Statement {
10645    fn from(c: CreateFunction) -> Self {
10646        Self::CreateFunction(c)
10647    }
10648}
10649
10650impl From<CreateTrigger> for Statement {
10651    fn from(c: CreateTrigger) -> Self {
10652        Self::CreateTrigger(c)
10653    }
10654}
10655
10656impl From<DropTrigger> for Statement {
10657    fn from(d: DropTrigger) -> Self {
10658        Self::DropTrigger(d)
10659    }
10660}
10661
10662impl From<DenyStatement> for Statement {
10663    fn from(d: DenyStatement) -> Self {
10664        Self::Deny(d)
10665    }
10666}
10667
10668impl From<CreateDomain> for Statement {
10669    fn from(c: CreateDomain) -> Self {
10670        Self::CreateDomain(c)
10671    }
10672}
10673
10674impl From<RenameTable> for Statement {
10675    fn from(r: RenameTable) -> Self {
10676        vec![r].into()
10677    }
10678}
10679
10680impl From<Vec<RenameTable>> for Statement {
10681    fn from(r: Vec<RenameTable>) -> Self {
10682        Self::RenameTable(r)
10683    }
10684}
10685
10686impl From<PrintStatement> for Statement {
10687    fn from(p: PrintStatement) -> Self {
10688        Self::Print(p)
10689    }
10690}
10691
10692impl From<ReturnStatement> for Statement {
10693    fn from(r: ReturnStatement) -> Self {
10694        Self::Return(r)
10695    }
10696}
10697
10698impl From<ExportData> for Statement {
10699    fn from(e: ExportData) -> Self {
10700        Self::ExportData(e)
10701    }
10702}
10703
10704impl From<CreateUser> for Statement {
10705    fn from(c: CreateUser) -> Self {
10706        Self::CreateUser(c)
10707    }
10708}
10709
10710impl From<VacuumStatement> for Statement {
10711    fn from(v: VacuumStatement) -> Self {
10712        Self::Vacuum(v)
10713    }
10714}
10715
10716impl From<ResetStatement> for Statement {
10717    fn from(r: ResetStatement) -> Self {
10718        Self::Reset(r)
10719    }
10720}
10721
10722#[cfg(test)]
10723mod tests {
10724    use crate::tokenizer::Location;
10725
10726    use super::*;
10727
10728    #[test]
10729    fn test_window_frame_default() {
10730        let window_frame = WindowFrame::default();
10731        assert_eq!(WindowFrameBound::Preceding(None), window_frame.start_bound);
10732    }
10733
10734    #[test]
10735    fn test_grouping_sets_display() {
10736        // a and b in different group
10737        let grouping_sets = Expr::GroupingSets(vec![
10738            vec![Expr::Identifier(Ident::new("a"))],
10739            vec![Expr::Identifier(Ident::new("b"))],
10740        ]);
10741        assert_eq!("GROUPING SETS ((a), (b))", format!("{grouping_sets}"));
10742
10743        // a and b in the same group
10744        let grouping_sets = Expr::GroupingSets(vec![vec![
10745            Expr::Identifier(Ident::new("a")),
10746            Expr::Identifier(Ident::new("b")),
10747        ]]);
10748        assert_eq!("GROUPING SETS ((a, b))", format!("{grouping_sets}"));
10749
10750        // (a, b) and (c, d) in different group
10751        let grouping_sets = Expr::GroupingSets(vec![
10752            vec![
10753                Expr::Identifier(Ident::new("a")),
10754                Expr::Identifier(Ident::new("b")),
10755            ],
10756            vec![
10757                Expr::Identifier(Ident::new("c")),
10758                Expr::Identifier(Ident::new("d")),
10759            ],
10760        ]);
10761        assert_eq!("GROUPING SETS ((a, b), (c, d))", format!("{grouping_sets}"));
10762    }
10763
10764    #[test]
10765    fn test_rollup_display() {
10766        let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new("a"))]]);
10767        assert_eq!("ROLLUP (a)", format!("{rollup}"));
10768
10769        let rollup = Expr::Rollup(vec![vec![
10770            Expr::Identifier(Ident::new("a")),
10771            Expr::Identifier(Ident::new("b")),
10772        ]]);
10773        assert_eq!("ROLLUP ((a, b))", format!("{rollup}"));
10774
10775        let rollup = Expr::Rollup(vec![
10776            vec![Expr::Identifier(Ident::new("a"))],
10777            vec![Expr::Identifier(Ident::new("b"))],
10778        ]);
10779        assert_eq!("ROLLUP (a, b)", format!("{rollup}"));
10780
10781        let rollup = Expr::Rollup(vec![
10782            vec![Expr::Identifier(Ident::new("a"))],
10783            vec![
10784                Expr::Identifier(Ident::new("b")),
10785                Expr::Identifier(Ident::new("c")),
10786            ],
10787            vec![Expr::Identifier(Ident::new("d"))],
10788        ]);
10789        assert_eq!("ROLLUP (a, (b, c), d)", format!("{rollup}"));
10790    }
10791
10792    #[test]
10793    fn test_cube_display() {
10794        let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new("a"))]]);
10795        assert_eq!("CUBE (a)", format!("{cube}"));
10796
10797        let cube = Expr::Cube(vec![vec![
10798            Expr::Identifier(Ident::new("a")),
10799            Expr::Identifier(Ident::new("b")),
10800        ]]);
10801        assert_eq!("CUBE ((a, b))", format!("{cube}"));
10802
10803        let cube = Expr::Cube(vec![
10804            vec![Expr::Identifier(Ident::new("a"))],
10805            vec![Expr::Identifier(Ident::new("b"))],
10806        ]);
10807        assert_eq!("CUBE (a, b)", format!("{cube}"));
10808
10809        let cube = Expr::Cube(vec![
10810            vec![Expr::Identifier(Ident::new("a"))],
10811            vec![
10812                Expr::Identifier(Ident::new("b")),
10813                Expr::Identifier(Ident::new("c")),
10814            ],
10815            vec![Expr::Identifier(Ident::new("d"))],
10816        ]);
10817        assert_eq!("CUBE (a, (b, c), d)", format!("{cube}"));
10818    }
10819
10820    #[test]
10821    fn test_interval_display() {
10822        let interval = Expr::Interval(Interval {
10823            value: Box::new(Expr::Value(
10824                Value::SingleQuotedString(String::from("123:45.67")).with_empty_span(),
10825            )),
10826            leading_field: Some(DateTimeField::Minute),
10827            leading_precision: Some(10),
10828            last_field: Some(DateTimeField::Second),
10829            fractional_seconds_precision: Some(9),
10830        });
10831        assert_eq!(
10832            "INTERVAL '123:45.67' MINUTE (10) TO SECOND (9)",
10833            format!("{interval}"),
10834        );
10835
10836        let interval = Expr::Interval(Interval {
10837            value: Box::new(Expr::Value(
10838                Value::SingleQuotedString(String::from("5")).with_empty_span(),
10839            )),
10840            leading_field: Some(DateTimeField::Second),
10841            leading_precision: Some(1),
10842            last_field: None,
10843            fractional_seconds_precision: Some(3),
10844        });
10845        assert_eq!("INTERVAL '5' SECOND (1, 3)", format!("{interval}"));
10846    }
10847
10848    #[test]
10849    fn test_one_or_many_with_parens_deref() {
10850        use core::ops::Index;
10851
10852        let one = OneOrManyWithParens::One("a");
10853
10854        assert_eq!(one.deref(), &["a"]);
10855        assert_eq!(<OneOrManyWithParens<_> as Deref>::deref(&one), &["a"]);
10856
10857        assert_eq!(one[0], "a");
10858        assert_eq!(one.index(0), &"a");
10859        assert_eq!(
10860            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&one, 0),
10861            &"a"
10862        );
10863
10864        assert_eq!(one.len(), 1);
10865        assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&one), 1);
10866
10867        let many1 = OneOrManyWithParens::Many(vec!["b"]);
10868
10869        assert_eq!(many1.deref(), &["b"]);
10870        assert_eq!(<OneOrManyWithParens<_> as Deref>::deref(&many1), &["b"]);
10871
10872        assert_eq!(many1[0], "b");
10873        assert_eq!(many1.index(0), &"b");
10874        assert_eq!(
10875            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many1, 0),
10876            &"b"
10877        );
10878
10879        assert_eq!(many1.len(), 1);
10880        assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&many1), 1);
10881
10882        let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
10883
10884        assert_eq!(many2.deref(), &["c", "d"]);
10885        assert_eq!(
10886            <OneOrManyWithParens<_> as Deref>::deref(&many2),
10887            &["c", "d"]
10888        );
10889
10890        assert_eq!(many2[0], "c");
10891        assert_eq!(many2.index(0), &"c");
10892        assert_eq!(
10893            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many2, 0),
10894            &"c"
10895        );
10896
10897        assert_eq!(many2[1], "d");
10898        assert_eq!(many2.index(1), &"d");
10899        assert_eq!(
10900            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many2, 1),
10901            &"d"
10902        );
10903
10904        assert_eq!(many2.len(), 2);
10905        assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&many2), 2);
10906    }
10907
10908    #[test]
10909    fn test_one_or_many_with_parens_as_ref() {
10910        let one = OneOrManyWithParens::One("a");
10911
10912        assert_eq!(one.as_ref(), &["a"]);
10913        assert_eq!(<OneOrManyWithParens<_> as AsRef<_>>::as_ref(&one), &["a"]);
10914
10915        let many1 = OneOrManyWithParens::Many(vec!["b"]);
10916
10917        assert_eq!(many1.as_ref(), &["b"]);
10918        assert_eq!(<OneOrManyWithParens<_> as AsRef<_>>::as_ref(&many1), &["b"]);
10919
10920        let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
10921
10922        assert_eq!(many2.as_ref(), &["c", "d"]);
10923        assert_eq!(
10924            <OneOrManyWithParens<_> as AsRef<_>>::as_ref(&many2),
10925            &["c", "d"]
10926        );
10927    }
10928
10929    #[test]
10930    fn test_one_or_many_with_parens_ref_into_iter() {
10931        let one = OneOrManyWithParens::One("a");
10932
10933        assert_eq!(Vec::from_iter(&one), vec![&"a"]);
10934
10935        let many1 = OneOrManyWithParens::Many(vec!["b"]);
10936
10937        assert_eq!(Vec::from_iter(&many1), vec![&"b"]);
10938
10939        let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
10940
10941        assert_eq!(Vec::from_iter(&many2), vec![&"c", &"d"]);
10942    }
10943
10944    #[test]
10945    fn test_one_or_many_with_parens_value_into_iter() {
10946        use core::iter::once;
10947
10948        //tests that our iterator implemented methods behaves exactly as it's inner iterator, at every step up to n calls to next/next_back
10949        fn test_steps<I>(ours: OneOrManyWithParens<usize>, inner: I, n: usize)
10950        where
10951            I: IntoIterator<Item = usize, IntoIter: DoubleEndedIterator + Clone> + Clone,
10952        {
10953            fn checks<I>(ours: OneOrManyWithParensIntoIter<usize>, inner: I)
10954            where
10955                I: Iterator<Item = usize> + Clone + DoubleEndedIterator,
10956            {
10957                assert_eq!(ours.size_hint(), inner.size_hint());
10958                assert_eq!(ours.clone().count(), inner.clone().count());
10959
10960                assert_eq!(
10961                    ours.clone().fold(1, |a, v| a + v),
10962                    inner.clone().fold(1, |a, v| a + v)
10963                );
10964
10965                assert_eq!(Vec::from_iter(ours.clone()), Vec::from_iter(inner.clone()));
10966                assert_eq!(
10967                    Vec::from_iter(ours.clone().rev()),
10968                    Vec::from_iter(inner.clone().rev())
10969                );
10970            }
10971
10972            let mut ours_next = ours.clone().into_iter();
10973            let mut inner_next = inner.clone().into_iter();
10974
10975            for _ in 0..n {
10976                checks(ours_next.clone(), inner_next.clone());
10977
10978                assert_eq!(ours_next.next(), inner_next.next());
10979            }
10980
10981            let mut ours_next_back = ours.clone().into_iter();
10982            let mut inner_next_back = inner.clone().into_iter();
10983
10984            for _ in 0..n {
10985                checks(ours_next_back.clone(), inner_next_back.clone());
10986
10987                assert_eq!(ours_next_back.next_back(), inner_next_back.next_back());
10988            }
10989
10990            let mut ours_mixed = ours.clone().into_iter();
10991            let mut inner_mixed = inner.clone().into_iter();
10992
10993            for i in 0..n {
10994                checks(ours_mixed.clone(), inner_mixed.clone());
10995
10996                if i % 2 == 0 {
10997                    assert_eq!(ours_mixed.next_back(), inner_mixed.next_back());
10998                } else {
10999                    assert_eq!(ours_mixed.next(), inner_mixed.next());
11000                }
11001            }
11002
11003            let mut ours_mixed2 = ours.into_iter();
11004            let mut inner_mixed2 = inner.into_iter();
11005
11006            for i in 0..n {
11007                checks(ours_mixed2.clone(), inner_mixed2.clone());
11008
11009                if i % 2 == 0 {
11010                    assert_eq!(ours_mixed2.next(), inner_mixed2.next());
11011                } else {
11012                    assert_eq!(ours_mixed2.next_back(), inner_mixed2.next_back());
11013                }
11014            }
11015        }
11016
11017        test_steps(OneOrManyWithParens::One(1), once(1), 3);
11018        test_steps(OneOrManyWithParens::Many(vec![2]), vec![2], 3);
11019        test_steps(OneOrManyWithParens::Many(vec![3, 4]), vec![3, 4], 4);
11020    }
11021
11022    // Tests that the position in the code of an `Ident` does not affect its
11023    // ordering.
11024    #[test]
11025    fn test_ident_ord() {
11026        let mut a = Ident::with_span(Span::new(Location::new(1, 1), Location::new(1, 1)), "a");
11027        let mut b = Ident::with_span(Span::new(Location::new(2, 2), Location::new(2, 2)), "b");
11028
11029        assert!(a < b);
11030        std::mem::swap(&mut a.span, &mut b.span);
11031        assert!(a < b);
11032    }
11033}