Skip to main content

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, ExclusionConstraint, ExclusionElement, ForeignKeyConstraint,
133    FullTextOrSpatialConstraint, IndexConstraint, PrimaryKeyConstraint, TableConstraint,
134    UniqueConstraint,
135};
136mod operator;
137mod query;
138mod spans;
139pub use spans::Spanned;
140
141mod trigger;
142mod value;
143
144#[cfg(feature = "visitor")]
145mod visitor;
146
147pub struct DisplaySeparated<'a, T>
148where
149    T: fmt::Display,
150{
151    slice: &'a [T],
152    sep: &'static str,
153}
154
155impl<T> fmt::Display for DisplaySeparated<'_, T>
156where
157    T: fmt::Display,
158{
159    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
160        let mut delim = "";
161        for t in self.slice {
162            f.write_str(delim)?;
163            delim = self.sep;
164            t.fmt(f)?;
165        }
166        Ok(())
167    }
168}
169
170pub(crate) fn display_separated<'a, T>(slice: &'a [T], sep: &'static str) -> DisplaySeparated<'a, T>
171where
172    T: fmt::Display,
173{
174    DisplaySeparated { slice, sep }
175}
176
177pub(crate) fn display_comma_separated<T>(slice: &[T]) -> DisplaySeparated<'_, T>
178where
179    T: fmt::Display,
180{
181    DisplaySeparated { slice, sep: ", " }
182}
183
184/// Writes the given statements to the formatter, each ending with
185/// a semicolon and space separated.
186fn format_statement_list(f: &mut fmt::Formatter, statements: &[Statement]) -> fmt::Result {
187    write!(f, "{}", display_separated(statements, "; "))?;
188    // We manually insert semicolon for the last statement,
189    // since display_separated doesn't handle that case.
190    write!(f, ";")
191}
192
193/// An identifier, decomposed into its value or character data and the quote style.
194#[derive(Debug, Clone)]
195#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
196#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
197pub struct Ident {
198    /// The value of the identifier without quotes.
199    pub value: String,
200    /// The starting quote if any. Valid quote characters are the single quote,
201    /// double quote, backtick, and opening square bracket.
202    pub quote_style: Option<char>,
203    /// The span of the identifier in the original SQL string.
204    pub span: Span,
205}
206
207impl PartialEq for Ident {
208    fn eq(&self, other: &Self) -> bool {
209        let Ident {
210            value,
211            quote_style,
212            // exhaustiveness check; we ignore spans in comparisons
213            span: _,
214        } = self;
215
216        value == &other.value && quote_style == &other.quote_style
217    }
218}
219
220impl core::hash::Hash for Ident {
221    fn hash<H: hash::Hasher>(&self, state: &mut H) {
222        let Ident {
223            value,
224            quote_style,
225            // exhaustiveness check; we ignore spans in hashes
226            span: _,
227        } = self;
228
229        value.hash(state);
230        quote_style.hash(state);
231    }
232}
233
234impl Eq for Ident {}
235
236impl PartialOrd for Ident {
237    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
238        Some(self.cmp(other))
239    }
240}
241
242impl Ord for Ident {
243    fn cmp(&self, other: &Self) -> Ordering {
244        let Ident {
245            value,
246            quote_style,
247            // exhaustiveness check; we ignore spans in ordering
248            span: _,
249        } = self;
250
251        let Ident {
252            value: other_value,
253            quote_style: other_quote_style,
254            // exhaustiveness check; we ignore spans in ordering
255            span: _,
256        } = other;
257
258        // First compare by value, then by quote_style
259        value
260            .cmp(other_value)
261            .then_with(|| quote_style.cmp(other_quote_style))
262    }
263}
264
265impl Ident {
266    /// Create a new identifier with the given value and no quotes and an empty span.
267    pub fn new<S>(value: S) -> Self
268    where
269        S: Into<String>,
270    {
271        Ident {
272            value: value.into(),
273            quote_style: None,
274            span: Span::empty(),
275        }
276    }
277
278    /// Create a new quoted identifier with the given quote and value. This function
279    /// panics if the given quote is not a valid quote character.
280    pub fn with_quote<S>(quote: char, value: S) -> Self
281    where
282        S: Into<String>,
283    {
284        assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
285        Ident {
286            value: value.into(),
287            quote_style: Some(quote),
288            span: Span::empty(),
289        }
290    }
291
292    pub fn with_span<S>(span: Span, value: S) -> Self
293    where
294        S: Into<String>,
295    {
296        Ident {
297            value: value.into(),
298            quote_style: None,
299            span,
300        }
301    }
302
303    pub fn with_quote_and_span<S>(quote: char, span: Span, value: S) -> Self
304    where
305        S: Into<String>,
306    {
307        assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
308        Ident {
309            value: value.into(),
310            quote_style: Some(quote),
311            span,
312        }
313    }
314}
315
316impl From<&str> for Ident {
317    fn from(value: &str) -> Self {
318        Ident {
319            value: value.to_string(),
320            quote_style: None,
321            span: Span::empty(),
322        }
323    }
324}
325
326impl fmt::Display for Ident {
327    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
328        match self.quote_style {
329            Some(q) if q == '"' || q == '\'' || q == '`' => {
330                let escaped = value::escape_quoted_string(&self.value, q);
331                write!(f, "{q}{escaped}{q}")
332            }
333            Some('[') => write!(f, "[{}]", self.value),
334            None => f.write_str(&self.value),
335            _ => panic!("unexpected quote style"),
336        }
337    }
338}
339
340/// A name of a table, view, custom type, etc., possibly multi-part, i.e. db.schema.obj
341#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
342#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
343#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
344pub struct ObjectName(pub Vec<ObjectNamePart>);
345
346impl From<Vec<Ident>> for ObjectName {
347    fn from(idents: Vec<Ident>) -> Self {
348        ObjectName(idents.into_iter().map(ObjectNamePart::Identifier).collect())
349    }
350}
351
352impl From<Ident> for ObjectName {
353    fn from(ident: Ident) -> Self {
354        ObjectName(vec![ObjectNamePart::Identifier(ident)])
355    }
356}
357
358impl fmt::Display for ObjectName {
359    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
360        write!(f, "{}", display_separated(&self.0, "."))
361    }
362}
363
364/// A single part of an ObjectName
365#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
366#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
367#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
368pub enum ObjectNamePart {
369    Identifier(Ident),
370    Function(ObjectNamePartFunction),
371}
372
373impl ObjectNamePart {
374    pub fn as_ident(&self) -> Option<&Ident> {
375        match self {
376            ObjectNamePart::Identifier(ident) => Some(ident),
377            ObjectNamePart::Function(_) => None,
378        }
379    }
380}
381
382impl fmt::Display for ObjectNamePart {
383    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
384        match self {
385            ObjectNamePart::Identifier(ident) => write!(f, "{ident}"),
386            ObjectNamePart::Function(func) => write!(f, "{func}"),
387        }
388    }
389}
390
391/// An object name part that consists of a function that dynamically
392/// constructs identifiers.
393///
394/// - [Snowflake](https://docs.snowflake.com/en/sql-reference/identifier-literal)
395#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
396#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
397#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
398pub struct ObjectNamePartFunction {
399    pub name: Ident,
400    pub args: Vec<FunctionArg>,
401}
402
403impl fmt::Display for ObjectNamePartFunction {
404    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
405        write!(f, "{}(", self.name)?;
406        write!(f, "{})", display_comma_separated(&self.args))
407    }
408}
409
410/// Represents an Array Expression, either
411/// `ARRAY[..]`, or `[..]`
412#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
413#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
414#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
415pub struct Array {
416    /// The list of expressions between brackets
417    pub elem: Vec<Expr>,
418
419    /// `true` for  `ARRAY[..]`, `false` for `[..]`
420    pub named: bool,
421}
422
423impl fmt::Display for Array {
424    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
425        write!(
426            f,
427            "{}[{}]",
428            if self.named { "ARRAY" } else { "" },
429            display_comma_separated(&self.elem)
430        )
431    }
432}
433
434/// Represents an INTERVAL expression, roughly in the following format:
435/// `INTERVAL '<value>' [ <leading_field> [ (<leading_precision>) ] ]
436/// [ TO <last_field> [ (<fractional_seconds_precision>) ] ]`,
437/// e.g. `INTERVAL '123:45.67' MINUTE(3) TO SECOND(2)`.
438///
439/// The parser does not validate the `<value>`, nor does it ensure
440/// that the `<leading_field>` units >= the units in `<last_field>`,
441/// so the user will have to reject intervals like `HOUR TO YEAR`.
442#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
443#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
444#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
445pub struct Interval {
446    pub value: Box<Expr>,
447    pub leading_field: Option<DateTimeField>,
448    pub leading_precision: Option<u64>,
449    pub last_field: Option<DateTimeField>,
450    /// The seconds precision can be specified in SQL source as
451    /// `INTERVAL '__' SECOND(_, x)` (in which case the `leading_field`
452    /// will be `Second` and the `last_field` will be `None`),
453    /// or as `__ TO SECOND(x)`.
454    pub fractional_seconds_precision: Option<u64>,
455}
456
457impl fmt::Display for Interval {
458    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
459        let value = self.value.as_ref();
460        match (
461            &self.leading_field,
462            self.leading_precision,
463            self.fractional_seconds_precision,
464        ) {
465            (
466                Some(DateTimeField::Second),
467                Some(leading_precision),
468                Some(fractional_seconds_precision),
469            ) => {
470                // When the leading field is SECOND, the parser guarantees that
471                // the last field is None.
472                assert!(self.last_field.is_none());
473                write!(
474                    f,
475                    "INTERVAL {value} SECOND ({leading_precision}, {fractional_seconds_precision})"
476                )
477            }
478            _ => {
479                write!(f, "INTERVAL {value}")?;
480                if let Some(leading_field) = &self.leading_field {
481                    write!(f, " {leading_field}")?;
482                }
483                if let Some(leading_precision) = self.leading_precision {
484                    write!(f, " ({leading_precision})")?;
485                }
486                if let Some(last_field) = &self.last_field {
487                    write!(f, " TO {last_field}")?;
488                }
489                if let Some(fractional_seconds_precision) = self.fractional_seconds_precision {
490                    write!(f, " ({fractional_seconds_precision})")?;
491                }
492                Ok(())
493            }
494        }
495    }
496}
497
498/// A field definition within a struct
499///
500/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
501#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
502#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
503#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
504pub struct StructField {
505    pub field_name: Option<Ident>,
506    pub field_type: DataType,
507    /// Struct field options.
508    /// See [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#column_name_and_column_schema)
509    pub options: Option<Vec<SqlOption>>,
510}
511
512impl fmt::Display for StructField {
513    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
514        if let Some(name) = &self.field_name {
515            write!(f, "{name} {}", self.field_type)?;
516        } else {
517            write!(f, "{}", self.field_type)?;
518        }
519        if let Some(options) = &self.options {
520            write!(f, " OPTIONS({})", display_separated(options, ", "))
521        } else {
522            Ok(())
523        }
524    }
525}
526
527/// A field definition within a union
528///
529/// [DuckDB]: https://duckdb.org/docs/sql/data_types/union.html
530#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
531#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
532#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
533pub struct UnionField {
534    pub field_name: Ident,
535    pub field_type: DataType,
536}
537
538impl fmt::Display for UnionField {
539    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
540        write!(f, "{} {}", self.field_name, self.field_type)
541    }
542}
543
544/// A dictionary field within a dictionary.
545///
546/// [DuckDB]: https://duckdb.org/docs/sql/data_types/struct#creating-structs
547#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
548#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
549#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
550pub struct DictionaryField {
551    pub key: Ident,
552    pub value: Box<Expr>,
553}
554
555impl fmt::Display for DictionaryField {
556    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
557        write!(f, "{}: {}", self.key, self.value)
558    }
559}
560
561/// Represents a Map expression.
562#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
563#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
564#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
565pub struct Map {
566    pub entries: Vec<MapEntry>,
567}
568
569impl Display for Map {
570    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
571        write!(f, "MAP {{{}}}", display_comma_separated(&self.entries))
572    }
573}
574
575/// A map field within a map.
576///
577/// [DuckDB]: https://duckdb.org/docs/sql/data_types/map.html#creating-maps
578#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
579#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
580#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
581pub struct MapEntry {
582    pub key: Box<Expr>,
583    pub value: Box<Expr>,
584}
585
586impl fmt::Display for MapEntry {
587    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
588        write!(f, "{}: {}", self.key, self.value)
589    }
590}
591
592/// Options for `CAST` / `TRY_CAST`
593/// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax>
594#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
595#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
596#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
597pub enum CastFormat {
598    Value(Value),
599    ValueAtTimeZone(Value, Value),
600}
601
602/// An element of a JSON path.
603#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
604#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
605#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
606pub enum JsonPathElem {
607    /// Accesses an object field using dot notation, e.g. `obj:foo.bar.baz`.
608    ///
609    /// See <https://docs.snowflake.com/en/user-guide/querying-semistructured#dot-notation>.
610    Dot { key: String, quoted: bool },
611    /// Accesses an object field or array element using bracket notation,
612    /// e.g. `obj['foo']`.
613    ///
614    /// See <https://docs.snowflake.com/en/user-guide/querying-semistructured#bracket-notation>.
615    Bracket { key: Expr },
616}
617
618/// A JSON path.
619///
620/// See <https://docs.snowflake.com/en/user-guide/querying-semistructured>.
621/// See <https://docs.databricks.com/en/sql/language-manual/sql-ref-json-path-expression.html>.
622#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
623#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
624#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
625pub struct JsonPath {
626    pub path: Vec<JsonPathElem>,
627}
628
629impl fmt::Display for JsonPath {
630    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
631        for (i, elem) in self.path.iter().enumerate() {
632            match elem {
633                JsonPathElem::Dot { key, quoted } => {
634                    if i == 0 {
635                        write!(f, ":")?;
636                    } else {
637                        write!(f, ".")?;
638                    }
639
640                    if *quoted {
641                        write!(f, "\"{}\"", escape_double_quote_string(key))?;
642                    } else {
643                        write!(f, "{key}")?;
644                    }
645                }
646                JsonPathElem::Bracket { key } => {
647                    write!(f, "[{key}]")?;
648                }
649            }
650        }
651        Ok(())
652    }
653}
654
655/// The syntax used for in a cast expression.
656#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
657#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
658#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
659pub enum CastKind {
660    /// The standard SQL cast syntax, e.g. `CAST(<expr> as <datatype>)`
661    Cast,
662    /// A cast that returns `NULL` on failure, e.g. `TRY_CAST(<expr> as <datatype>)`.
663    ///
664    /// See <https://docs.snowflake.com/en/sql-reference/functions/try_cast>.
665    /// See <https://learn.microsoft.com/en-us/sql/t-sql/functions/try-cast-transact-sql>.
666    TryCast,
667    /// A cast that returns `NULL` on failure, bigQuery-specific ,  e.g. `SAFE_CAST(<expr> as <datatype>)`.
668    ///
669    /// See <https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#safe_casting>.
670    SafeCast,
671    /// `<expr> :: <datatype>`
672    DoubleColon,
673}
674
675/// `MATCH` type for constraint references
676///
677/// See: <https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-PARMS-REFERENCES>
678#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
679#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
680#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
681pub enum ConstraintReferenceMatchKind {
682    /// `MATCH FULL`
683    Full,
684    /// `MATCH PARTIAL`
685    Partial,
686    /// `MATCH SIMPLE`
687    Simple,
688}
689
690impl fmt::Display for ConstraintReferenceMatchKind {
691    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
692        match self {
693            Self::Full => write!(f, "MATCH FULL"),
694            Self::Partial => write!(f, "MATCH PARTIAL"),
695            Self::Simple => write!(f, "MATCH SIMPLE"),
696        }
697    }
698}
699
700/// `EXTRACT` syntax variants.
701///
702/// In Snowflake dialect, the `EXTRACT` expression can support either the `from` syntax
703/// or the comma syntax.
704///
705/// See <https://docs.snowflake.com/en/sql-reference/functions/extract>
706#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
707#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
708#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
709pub enum ExtractSyntax {
710    /// `EXTRACT( <date_or_time_part> FROM <date_or_time_expr> )`
711    From,
712    /// `EXTRACT( <date_or_time_part> , <date_or_timestamp_expr> )`
713    Comma,
714}
715
716/// The syntax used in a CEIL or FLOOR expression.
717///
718/// The `CEIL/FLOOR(<datetime value expression> TO <time unit>)` is an Amazon Kinesis Data Analytics extension.
719/// See <https://docs.aws.amazon.com/kinesisanalytics/latest/sqlref/sql-reference-ceil.html> for
720/// details.
721///
722/// Other dialects either support `CEIL/FLOOR( <expr> [, <scale>])` format or just
723/// `CEIL/FLOOR(<expr>)`.
724#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
725#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
726#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
727pub enum CeilFloorKind {
728    /// `CEIL( <expr> TO <DateTimeField>)`
729    DateTimeField(DateTimeField),
730    /// `CEIL( <expr> [, <scale>])`
731    Scale(Value),
732}
733
734/// A WHEN clause in a CASE expression containing both
735/// the condition and its corresponding result
736#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
737#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
738#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
739pub struct CaseWhen {
740    pub condition: Expr,
741    pub result: Expr,
742}
743
744impl fmt::Display for CaseWhen {
745    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
746        f.write_str("WHEN ")?;
747        self.condition.fmt(f)?;
748        f.write_str(" THEN")?;
749        SpaceOrNewline.fmt(f)?;
750        Indent(&self.result).fmt(f)?;
751        Ok(())
752    }
753}
754
755/// An SQL expression of any type.
756///
757/// # Semantics / Type Checking
758///
759/// The parser does not distinguish between expressions of different types
760/// (e.g. boolean vs string). The caller is responsible for detecting and
761/// validating types as necessary (for example  `WHERE 1` vs `SELECT 1=1`)
762/// See the [README.md] for more details.
763///
764/// [README.md]: https://github.com/apache/datafusion-sqlparser-rs/blob/main/README.md#syntax-vs-semantics
765///
766/// # Equality and Hashing Does not Include Source Locations
767///
768/// The `Expr` type implements `PartialEq` and `Eq` based on the semantic value
769/// of the expression (not bitwise comparison). This means that `Expr` instances
770/// that are semantically equivalent but have different spans (locations in the
771/// source tree) will compare as equal.
772#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
773#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
774#[cfg_attr(
775    feature = "visitor",
776    derive(Visit, VisitMut),
777    visit(with = "visit_expr")
778)]
779pub enum Expr {
780    /// Identifier e.g. table name or column name
781    Identifier(Ident),
782    /// Multi-part identifier, e.g. `table_alias.column` or `schema.table.col`
783    CompoundIdentifier(Vec<Ident>),
784    /// Multi-part expression access.
785    ///
786    /// This structure represents an access chain in structured / nested types
787    /// such as maps, arrays, and lists:
788    /// - Array
789    ///     - A 1-dim array `a[1]` will be represented like:
790    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript(1)]`
791    ///     - A 2-dim array `a[1][2]` will be represented like:
792    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript(1), Subscript(2)]`
793    /// - Map or Struct (Bracket-style)
794    ///     - A map `a['field1']` will be represented like:
795    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript('field')]`
796    ///     - A 2-dim map `a['field1']['field2']` will be represented like:
797    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript('field1'), Subscript('field2')]`
798    /// - Struct (Dot-style) (only effect when the chain contains both subscript and expr)
799    ///     - A struct access `a[field1].field2` will be represented like:
800    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript('field1'), Ident('field2')]`
801    /// - If a struct access likes `a.field1.field2`, it will be represented by CompoundIdentifier([a, field1, field2])
802    CompoundFieldAccess {
803        root: Box<Expr>,
804        access_chain: Vec<AccessExpr>,
805    },
806    /// Access data nested in a value containing semi-structured data, such as
807    /// the `VARIANT` type on Snowflake. for example `src:customer[0].name`.
808    ///
809    /// See <https://docs.snowflake.com/en/user-guide/querying-semistructured>.
810    /// See <https://docs.databricks.com/en/sql/language-manual/functions/colonsign.html>.
811    JsonAccess {
812        /// The value being queried.
813        value: Box<Expr>,
814        /// The path to the data to extract.
815        path: JsonPath,
816    },
817    /// `IS FALSE` operator
818    IsFalse(Box<Expr>),
819    /// `IS NOT FALSE` operator
820    IsNotFalse(Box<Expr>),
821    /// `IS TRUE` operator
822    IsTrue(Box<Expr>),
823    /// `IS NOT TRUE` operator
824    IsNotTrue(Box<Expr>),
825    /// `IS NULL` operator
826    IsNull(Box<Expr>),
827    /// `IS NOT NULL` operator
828    IsNotNull(Box<Expr>),
829    /// `IS UNKNOWN` operator
830    IsUnknown(Box<Expr>),
831    /// `IS NOT UNKNOWN` operator
832    IsNotUnknown(Box<Expr>),
833    /// `IS DISTINCT FROM` operator
834    IsDistinctFrom(Box<Expr>, Box<Expr>),
835    /// `IS NOT DISTINCT FROM` operator
836    IsNotDistinctFrom(Box<Expr>, Box<Expr>),
837    /// `<expr> IS [ NOT ] [ form ] NORMALIZED`
838    IsNormalized {
839        expr: Box<Expr>,
840        form: Option<NormalizationForm>,
841        negated: bool,
842    },
843    /// `[ NOT ] IN (val1, val2, ...)`
844    InList {
845        expr: Box<Expr>,
846        list: Vec<Expr>,
847        negated: bool,
848    },
849    /// `[ NOT ] IN (SELECT ...)`
850    InSubquery {
851        expr: Box<Expr>,
852        subquery: Box<Query>,
853        negated: bool,
854    },
855    /// `[ NOT ] IN UNNEST(array_expression)`
856    InUnnest {
857        expr: Box<Expr>,
858        array_expr: Box<Expr>,
859        negated: bool,
860    },
861    /// `<expr> [ NOT ] BETWEEN <low> AND <high>`
862    Between {
863        expr: Box<Expr>,
864        negated: bool,
865        low: Box<Expr>,
866        high: Box<Expr>,
867    },
868    /// Binary operation e.g. `1 + 1` or `foo > bar`
869    BinaryOp {
870        left: Box<Expr>,
871        op: BinaryOperator,
872        right: Box<Expr>,
873    },
874    /// `[NOT] LIKE <pattern> [ESCAPE <escape_character>]`
875    Like {
876        negated: bool,
877        // Snowflake supports the ANY keyword to match against a list of patterns
878        // https://docs.snowflake.com/en/sql-reference/functions/like_any
879        any: bool,
880        expr: Box<Expr>,
881        pattern: Box<Expr>,
882        escape_char: Option<Value>,
883    },
884    /// `ILIKE` (case-insensitive `LIKE`)
885    ILike {
886        negated: bool,
887        // Snowflake supports the ANY keyword to match against a list of patterns
888        // https://docs.snowflake.com/en/sql-reference/functions/like_any
889        any: bool,
890        expr: Box<Expr>,
891        pattern: Box<Expr>,
892        escape_char: Option<Value>,
893    },
894    /// SIMILAR TO regex
895    SimilarTo {
896        negated: bool,
897        expr: Box<Expr>,
898        pattern: Box<Expr>,
899        escape_char: Option<Value>,
900    },
901    /// MySQL: RLIKE regex or REGEXP regex
902    RLike {
903        negated: bool,
904        expr: Box<Expr>,
905        pattern: Box<Expr>,
906        // true for REGEXP, false for RLIKE (no difference in semantics)
907        regexp: bool,
908    },
909    /// `ANY` operation e.g. `foo > ANY(bar)`, comparison operator is one of `[=, >, <, =>, =<, !=]`
910    /// <https://docs.snowflake.com/en/sql-reference/operators-subquery#all-any>
911    AnyOp {
912        left: Box<Expr>,
913        compare_op: BinaryOperator,
914        right: Box<Expr>,
915        // ANY and SOME are synonymous: https://docs.cloudera.com/cdw-runtime/cloud/using-hiveql/topics/hive_comparison_predicates.html
916        is_some: bool,
917    },
918    /// `ALL` operation e.g. `foo > ALL(bar)`, comparison operator is one of `[=, >, <, =>, =<, !=]`
919    /// <https://docs.snowflake.com/en/sql-reference/operators-subquery#all-any>
920    AllOp {
921        left: Box<Expr>,
922        compare_op: BinaryOperator,
923        right: Box<Expr>,
924    },
925    /// Unary operation e.g. `NOT foo`
926    UnaryOp {
927        op: UnaryOperator,
928        expr: Box<Expr>,
929    },
930    /// CONVERT a value to a different data type or character encoding. e.g. `CONVERT(foo USING utf8mb4)`
931    Convert {
932        /// CONVERT (false) or TRY_CONVERT (true)
933        /// <https://learn.microsoft.com/en-us/sql/t-sql/functions/try-convert-transact-sql?view=sql-server-ver16>
934        is_try: bool,
935        /// The expression to convert
936        expr: Box<Expr>,
937        /// The target data type
938        data_type: Option<DataType>,
939        /// The target character encoding
940        charset: Option<ObjectName>,
941        /// whether the target comes before the expr (MSSQL syntax)
942        target_before_value: bool,
943        /// How to translate the expression.
944        ///
945        /// [MSSQL]: https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#style
946        styles: Vec<Expr>,
947    },
948    /// `CAST` an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))`
949    Cast {
950        kind: CastKind,
951        expr: Box<Expr>,
952        data_type: DataType,
953        /// Optional CAST(string_expression AS type FORMAT format_string_expression) as used by [BigQuery]
954        ///
955        /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax
956        format: Option<CastFormat>,
957    },
958    /// AT a timestamp to a different timezone e.g. `FROM_UNIXTIME(0) AT TIME ZONE 'UTC-06:00'`
959    AtTimeZone {
960        timestamp: Box<Expr>,
961        time_zone: Box<Expr>,
962    },
963    /// Extract a field from a timestamp e.g. `EXTRACT(MONTH FROM foo)`
964    /// Or `EXTRACT(MONTH, foo)`
965    ///
966    /// Syntax:
967    /// ```sql
968    /// EXTRACT(DateTimeField FROM <expr>) | EXTRACT(DateTimeField, <expr>)
969    /// ```
970    Extract {
971        field: DateTimeField,
972        syntax: ExtractSyntax,
973        expr: Box<Expr>,
974    },
975    /// ```sql
976    /// CEIL(<expr> [TO DateTimeField])
977    /// ```
978    /// ```sql
979    /// CEIL( <input_expr> [, <scale_expr> ] )
980    /// ```
981    Ceil {
982        expr: Box<Expr>,
983        field: CeilFloorKind,
984    },
985    /// ```sql
986    /// FLOOR(<expr> [TO DateTimeField])
987    /// ```
988    /// ```sql
989    /// FLOOR( <input_expr> [, <scale_expr> ] )
990    ///
991    Floor {
992        expr: Box<Expr>,
993        field: CeilFloorKind,
994    },
995    /// ```sql
996    /// POSITION(<expr> in <expr>)
997    /// ```
998    Position {
999        expr: Box<Expr>,
1000        r#in: Box<Expr>,
1001    },
1002    /// ```sql
1003    /// SUBSTRING(<expr> [FROM <expr>] [FOR <expr>])
1004    /// ```
1005    /// or
1006    /// ```sql
1007    /// SUBSTRING(<expr>, <expr>, <expr>)
1008    /// ```
1009    Substring {
1010        expr: Box<Expr>,
1011        substring_from: Option<Box<Expr>>,
1012        substring_for: Option<Box<Expr>>,
1013
1014        /// false if the expression is represented using the `SUBSTRING(expr [FROM start] [FOR len])` syntax
1015        /// true if the expression is represented using the `SUBSTRING(expr, start, len)` syntax
1016        /// This flag is used for formatting.
1017        special: bool,
1018
1019        /// true if the expression is represented using the `SUBSTR` shorthand
1020        /// This flag is used for formatting.
1021        shorthand: bool,
1022    },
1023    /// ```sql
1024    /// TRIM([BOTH | LEADING | TRAILING] [<expr> FROM] <expr>)
1025    /// TRIM(<expr>)
1026    /// TRIM(<expr>, [, characters]) -- only Snowflake or Bigquery
1027    /// ```
1028    Trim {
1029        expr: Box<Expr>,
1030        // ([BOTH | LEADING | TRAILING]
1031        trim_where: Option<TrimWhereField>,
1032        trim_what: Option<Box<Expr>>,
1033        trim_characters: Option<Vec<Expr>>,
1034    },
1035    /// ```sql
1036    /// OVERLAY(<expr> PLACING <expr> FROM <expr>[ FOR <expr> ]
1037    /// ```
1038    Overlay {
1039        expr: Box<Expr>,
1040        overlay_what: Box<Expr>,
1041        overlay_from: Box<Expr>,
1042        overlay_for: Option<Box<Expr>>,
1043    },
1044    /// `expr COLLATE collation`
1045    Collate {
1046        expr: Box<Expr>,
1047        collation: ObjectName,
1048    },
1049    /// Nested expression e.g. `(foo > bar)` or `(1)`
1050    Nested(Box<Expr>),
1051    /// A literal value, such as string, number, date or NULL
1052    Value(ValueWithSpan),
1053    /// Prefixed expression, e.g. introducer strings, projection prefix
1054    /// <https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html>
1055    /// <https://docs.snowflake.com/en/sql-reference/constructs/connect-by>
1056    Prefixed {
1057        prefix: Ident,
1058        /// The value of the constant.
1059        /// Hint: you can unwrap the string value using `value.into_string()`.
1060        value: Box<Expr>,
1061    },
1062    /// A constant of form `<data_type> 'value'`.
1063    /// This can represent ANSI SQL `DATE`, `TIME`, and `TIMESTAMP` literals (such as `DATE '2020-01-01'`),
1064    /// as well as constants of other types (a non-standard PostgreSQL extension).
1065    TypedString(TypedString),
1066    /// Scalar function call e.g. `LEFT(foo, 5)`
1067    Function(Function),
1068    /// `CASE [<operand>] WHEN <condition> THEN <result> ... [ELSE <result>] END`
1069    ///
1070    /// Note we only recognize a complete single expression as `<condition>`,
1071    /// not `< 0` nor `1, 2, 3` as allowed in a `<simple when clause>` per
1072    /// <https://jakewheat.github.io/sql-overview/sql-2011-foundation-grammar.html#simple-when-clause>
1073    Case {
1074        case_token: AttachedToken,
1075        end_token: AttachedToken,
1076        operand: Option<Box<Expr>>,
1077        conditions: Vec<CaseWhen>,
1078        else_result: Option<Box<Expr>>,
1079    },
1080    /// An exists expression `[ NOT ] EXISTS(SELECT ...)`, used in expressions like
1081    /// `WHERE [ NOT ] EXISTS (SELECT ...)`.
1082    Exists {
1083        subquery: Box<Query>,
1084        negated: bool,
1085    },
1086    /// A parenthesized subquery `(SELECT ...)`, used in expression like
1087    /// `SELECT (subquery) AS x` or `WHERE (subquery) = x`
1088    Subquery(Box<Query>),
1089    /// The `GROUPING SETS` expr.
1090    GroupingSets(Vec<Vec<Expr>>),
1091    /// The `CUBE` expr.
1092    Cube(Vec<Vec<Expr>>),
1093    /// The `ROLLUP` expr.
1094    Rollup(Vec<Vec<Expr>>),
1095    /// ROW / TUPLE a single value, such as `SELECT (1, 2)`
1096    Tuple(Vec<Expr>),
1097    /// `Struct` literal expression
1098    /// Syntax:
1099    /// ```sql
1100    /// STRUCT<[field_name] field_type, ...>( expr1 [, ... ])
1101    ///
1102    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type)
1103    /// [Databricks](https://docs.databricks.com/en/sql/language-manual/functions/struct.html)
1104    /// ```
1105    Struct {
1106        /// Struct values.
1107        values: Vec<Expr>,
1108        /// Struct field definitions.
1109        fields: Vec<StructField>,
1110    },
1111    /// `BigQuery` specific: An named expression in a typeless struct [1]
1112    ///
1113    /// Syntax
1114    /// ```sql
1115    /// 1 AS A
1116    /// ```
1117    /// [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
1118    Named {
1119        expr: Box<Expr>,
1120        name: Ident,
1121    },
1122    /// `DuckDB` specific `Struct` literal expression [1]
1123    ///
1124    /// Syntax:
1125    /// ```sql
1126    /// syntax: {'field_name': expr1[, ... ]}
1127    /// ```
1128    /// [1]: https://duckdb.org/docs/sql/data_types/struct#creating-structs
1129    Dictionary(Vec<DictionaryField>),
1130    /// `DuckDB` specific `Map` literal expression [1]
1131    ///
1132    /// Syntax:
1133    /// ```sql
1134    /// syntax: Map {key1: value1[, ... ]}
1135    /// ```
1136    /// [1]: https://duckdb.org/docs/sql/data_types/map#creating-maps
1137    Map(Map),
1138    /// An array expression e.g. `ARRAY[1, 2]`
1139    Array(Array),
1140    /// An interval expression e.g. `INTERVAL '1' YEAR`
1141    Interval(Interval),
1142    /// `MySQL` specific text search function [(1)].
1143    ///
1144    /// Syntax:
1145    /// ```sql
1146    /// MATCH (<col>, <col>, ...) AGAINST (<expr> [<search modifier>])
1147    ///
1148    /// <col> = CompoundIdentifier
1149    /// <expr> = String literal
1150    /// ```
1151    /// [(1)]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html#function_match
1152    MatchAgainst {
1153        /// `(<col>, <col>, ...)`.
1154        columns: Vec<ObjectName>,
1155        /// `<expr>`.
1156        match_value: Value,
1157        /// `<search modifier>`
1158        opt_search_modifier: Option<SearchModifier>,
1159    },
1160    Wildcard(AttachedToken),
1161    /// Qualified wildcard, e.g. `alias.*` or `schema.table.*`.
1162    /// (Same caveats apply to `QualifiedWildcard` as to `Wildcard`.)
1163    QualifiedWildcard(ObjectName, AttachedToken),
1164    /// Some dialects support an older syntax for outer joins where columns are
1165    /// marked with the `(+)` operator in the WHERE clause, for example:
1166    ///
1167    /// ```sql
1168    /// SELECT t1.c1, t2.c2 FROM t1, t2 WHERE t1.c1 = t2.c2 (+)
1169    /// ```
1170    ///
1171    /// which is equivalent to
1172    ///
1173    /// ```sql
1174    /// SELECT t1.c1, t2.c2 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c2
1175    /// ```
1176    ///
1177    /// See <https://docs.snowflake.com/en/sql-reference/constructs/where#joins-in-the-where-clause>.
1178    OuterJoin(Box<Expr>),
1179    /// A reference to the prior level in a CONNECT BY clause.
1180    Prior(Box<Expr>),
1181    /// A lambda function.
1182    ///
1183    /// Syntax:
1184    /// ```plaintext
1185    /// param -> expr | (param1, ...) -> expr
1186    /// ```
1187    ///
1188    /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/functions#higher-order-functions---operator-and-lambdaparams-expr-function)
1189    /// [Databricks](https://docs.databricks.com/en/sql/language-manual/sql-ref-lambda-functions.html)
1190    /// [DuckDB](https://duckdb.org/docs/stable/sql/functions/lambda)
1191    Lambda(LambdaFunction),
1192    /// Checks membership of a value in a JSON array
1193    MemberOf(MemberOf),
1194}
1195
1196impl Expr {
1197    /// Creates a new [`Expr::Value`]
1198    pub fn value(value: impl Into<ValueWithSpan>) -> Self {
1199        Expr::Value(value.into())
1200    }
1201}
1202
1203/// The contents inside the `[` and `]` in a subscript expression.
1204#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1205#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1206#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1207pub enum Subscript {
1208    /// Accesses the element of the array at the given index.
1209    Index { index: Expr },
1210
1211    /// Accesses a slice of an array on PostgreSQL, e.g.
1212    ///
1213    /// ```plaintext
1214    /// => select (array[1,2,3,4,5,6])[2:5];
1215    /// -----------
1216    /// {2,3,4,5}
1217    /// ```
1218    ///
1219    /// The lower and/or upper bound can be omitted to slice from the start or
1220    /// end of the array respectively.
1221    ///
1222    /// See <https://www.postgresql.org/docs/current/arrays.html#ARRAYS-ACCESSING>.
1223    ///
1224    /// Also supports an optional "stride" as the last element (this is not
1225    /// supported by postgres), e.g.
1226    ///
1227    /// ```plaintext
1228    /// => select (array[1,2,3,4,5,6])[1:6:2];
1229    /// -----------
1230    /// {1,3,5}
1231    /// ```
1232    Slice {
1233        lower_bound: Option<Expr>,
1234        upper_bound: Option<Expr>,
1235        stride: Option<Expr>,
1236    },
1237}
1238
1239impl fmt::Display for Subscript {
1240    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1241        match self {
1242            Subscript::Index { index } => write!(f, "{index}"),
1243            Subscript::Slice {
1244                lower_bound,
1245                upper_bound,
1246                stride,
1247            } => {
1248                if let Some(lower) = lower_bound {
1249                    write!(f, "{lower}")?;
1250                }
1251                write!(f, ":")?;
1252                if let Some(upper) = upper_bound {
1253                    write!(f, "{upper}")?;
1254                }
1255                if let Some(stride) = stride {
1256                    write!(f, ":")?;
1257                    write!(f, "{stride}")?;
1258                }
1259                Ok(())
1260            }
1261        }
1262    }
1263}
1264
1265/// An element of a [`Expr::CompoundFieldAccess`].
1266/// It can be an expression or a subscript.
1267#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1268#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1269#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1270pub enum AccessExpr {
1271    /// Accesses a field using dot notation, e.g. `foo.bar.baz`.
1272    Dot(Expr),
1273    /// Accesses a field or array element using bracket notation, e.g. `foo['bar']`.
1274    Subscript(Subscript),
1275}
1276
1277impl fmt::Display for AccessExpr {
1278    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1279        match self {
1280            AccessExpr::Dot(expr) => write!(f, ".{expr}"),
1281            AccessExpr::Subscript(subscript) => write!(f, "[{subscript}]"),
1282        }
1283    }
1284}
1285
1286/// A lambda function.
1287#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1288#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1289#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1290pub struct LambdaFunction {
1291    /// The parameters to the lambda function.
1292    pub params: OneOrManyWithParens<Ident>,
1293    /// The body of the lambda function.
1294    pub body: Box<Expr>,
1295}
1296
1297impl fmt::Display for LambdaFunction {
1298    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1299        write!(f, "{} -> {}", self.params, self.body)
1300    }
1301}
1302
1303/// Encapsulates the common pattern in SQL where either one unparenthesized item
1304/// such as an identifier or expression is permitted, or multiple of the same
1305/// item in a parenthesized list. For accessing items regardless of the form,
1306/// `OneOrManyWithParens` implements `Deref<Target = [T]>` and `IntoIterator`,
1307/// so you can call slice methods on it and iterate over items
1308/// # Examples
1309/// Accessing as a slice:
1310/// ```
1311/// # use sqlparser::ast::OneOrManyWithParens;
1312/// let one = OneOrManyWithParens::One("a");
1313///
1314/// assert_eq!(one[0], "a");
1315/// assert_eq!(one.len(), 1);
1316/// ```
1317/// Iterating:
1318/// ```
1319/// # use sqlparser::ast::OneOrManyWithParens;
1320/// let one = OneOrManyWithParens::One("a");
1321/// let many = OneOrManyWithParens::Many(vec!["a", "b"]);
1322///
1323/// assert_eq!(one.into_iter().chain(many).collect::<Vec<_>>(), vec!["a", "a", "b"] );
1324/// ```
1325#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1326#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1327#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1328pub enum OneOrManyWithParens<T> {
1329    /// A single `T`, unparenthesized.
1330    One(T),
1331    /// One or more `T`s, parenthesized.
1332    Many(Vec<T>),
1333}
1334
1335impl<T> Deref for OneOrManyWithParens<T> {
1336    type Target = [T];
1337
1338    fn deref(&self) -> &[T] {
1339        match self {
1340            OneOrManyWithParens::One(one) => core::slice::from_ref(one),
1341            OneOrManyWithParens::Many(many) => many,
1342        }
1343    }
1344}
1345
1346impl<T> AsRef<[T]> for OneOrManyWithParens<T> {
1347    fn as_ref(&self) -> &[T] {
1348        self
1349    }
1350}
1351
1352impl<'a, T> IntoIterator for &'a OneOrManyWithParens<T> {
1353    type Item = &'a T;
1354    type IntoIter = core::slice::Iter<'a, T>;
1355
1356    fn into_iter(self) -> Self::IntoIter {
1357        self.iter()
1358    }
1359}
1360
1361/// Owned iterator implementation of `OneOrManyWithParens`
1362#[derive(Debug, Clone)]
1363pub struct OneOrManyWithParensIntoIter<T> {
1364    inner: OneOrManyWithParensIntoIterInner<T>,
1365}
1366
1367#[derive(Debug, Clone)]
1368enum OneOrManyWithParensIntoIterInner<T> {
1369    One(core::iter::Once<T>),
1370    Many(<Vec<T> as IntoIterator>::IntoIter),
1371}
1372
1373impl<T> core::iter::FusedIterator for OneOrManyWithParensIntoIter<T>
1374where
1375    core::iter::Once<T>: core::iter::FusedIterator,
1376    <Vec<T> as IntoIterator>::IntoIter: core::iter::FusedIterator,
1377{
1378}
1379
1380impl<T> core::iter::ExactSizeIterator for OneOrManyWithParensIntoIter<T>
1381where
1382    core::iter::Once<T>: core::iter::ExactSizeIterator,
1383    <Vec<T> as IntoIterator>::IntoIter: core::iter::ExactSizeIterator,
1384{
1385}
1386
1387impl<T> core::iter::Iterator for OneOrManyWithParensIntoIter<T> {
1388    type Item = T;
1389
1390    fn next(&mut self) -> Option<Self::Item> {
1391        match &mut self.inner {
1392            OneOrManyWithParensIntoIterInner::One(one) => one.next(),
1393            OneOrManyWithParensIntoIterInner::Many(many) => many.next(),
1394        }
1395    }
1396
1397    fn size_hint(&self) -> (usize, Option<usize>) {
1398        match &self.inner {
1399            OneOrManyWithParensIntoIterInner::One(one) => one.size_hint(),
1400            OneOrManyWithParensIntoIterInner::Many(many) => many.size_hint(),
1401        }
1402    }
1403
1404    fn count(self) -> usize
1405    where
1406        Self: Sized,
1407    {
1408        match self.inner {
1409            OneOrManyWithParensIntoIterInner::One(one) => one.count(),
1410            OneOrManyWithParensIntoIterInner::Many(many) => many.count(),
1411        }
1412    }
1413
1414    fn fold<B, F>(mut self, init: B, f: F) -> B
1415    where
1416        Self: Sized,
1417        F: FnMut(B, Self::Item) -> B,
1418    {
1419        match &mut self.inner {
1420            OneOrManyWithParensIntoIterInner::One(one) => one.fold(init, f),
1421            OneOrManyWithParensIntoIterInner::Many(many) => many.fold(init, f),
1422        }
1423    }
1424}
1425
1426impl<T> core::iter::DoubleEndedIterator for OneOrManyWithParensIntoIter<T> {
1427    fn next_back(&mut self) -> Option<Self::Item> {
1428        match &mut self.inner {
1429            OneOrManyWithParensIntoIterInner::One(one) => one.next_back(),
1430            OneOrManyWithParensIntoIterInner::Many(many) => many.next_back(),
1431        }
1432    }
1433}
1434
1435impl<T> IntoIterator for OneOrManyWithParens<T> {
1436    type Item = T;
1437
1438    type IntoIter = OneOrManyWithParensIntoIter<T>;
1439
1440    fn into_iter(self) -> Self::IntoIter {
1441        let inner = match self {
1442            OneOrManyWithParens::One(one) => {
1443                OneOrManyWithParensIntoIterInner::One(core::iter::once(one))
1444            }
1445            OneOrManyWithParens::Many(many) => {
1446                OneOrManyWithParensIntoIterInner::Many(many.into_iter())
1447            }
1448        };
1449
1450        OneOrManyWithParensIntoIter { inner }
1451    }
1452}
1453
1454impl<T> fmt::Display for OneOrManyWithParens<T>
1455where
1456    T: fmt::Display,
1457{
1458    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1459        match self {
1460            OneOrManyWithParens::One(value) => write!(f, "{value}"),
1461            OneOrManyWithParens::Many(values) => {
1462                write!(f, "({})", display_comma_separated(values))
1463            }
1464        }
1465    }
1466}
1467
1468impl fmt::Display for CastFormat {
1469    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1470        match self {
1471            CastFormat::Value(v) => write!(f, "{v}"),
1472            CastFormat::ValueAtTimeZone(v, tz) => write!(f, "{v} AT TIME ZONE {tz}"),
1473        }
1474    }
1475}
1476
1477impl fmt::Display for Expr {
1478    #[cfg_attr(feature = "recursive-protection", recursive::recursive)]
1479    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1480        match self {
1481            Expr::Identifier(s) => write!(f, "{s}"),
1482            Expr::Wildcard(_) => f.write_str("*"),
1483            Expr::QualifiedWildcard(prefix, _) => write!(f, "{prefix}.*"),
1484            Expr::CompoundIdentifier(s) => write!(f, "{}", display_separated(s, ".")),
1485            Expr::CompoundFieldAccess { root, access_chain } => {
1486                write!(f, "{root}")?;
1487                for field in access_chain {
1488                    write!(f, "{field}")?;
1489                }
1490                Ok(())
1491            }
1492            Expr::IsTrue(ast) => write!(f, "{ast} IS TRUE"),
1493            Expr::IsNotTrue(ast) => write!(f, "{ast} IS NOT TRUE"),
1494            Expr::IsFalse(ast) => write!(f, "{ast} IS FALSE"),
1495            Expr::IsNotFalse(ast) => write!(f, "{ast} IS NOT FALSE"),
1496            Expr::IsNull(ast) => write!(f, "{ast} IS NULL"),
1497            Expr::IsNotNull(ast) => write!(f, "{ast} IS NOT NULL"),
1498            Expr::IsUnknown(ast) => write!(f, "{ast} IS UNKNOWN"),
1499            Expr::IsNotUnknown(ast) => write!(f, "{ast} IS NOT UNKNOWN"),
1500            Expr::InList {
1501                expr,
1502                list,
1503                negated,
1504            } => write!(
1505                f,
1506                "{} {}IN ({})",
1507                expr,
1508                if *negated { "NOT " } else { "" },
1509                display_comma_separated(list)
1510            ),
1511            Expr::InSubquery {
1512                expr,
1513                subquery,
1514                negated,
1515            } => write!(
1516                f,
1517                "{} {}IN ({})",
1518                expr,
1519                if *negated { "NOT " } else { "" },
1520                subquery
1521            ),
1522            Expr::InUnnest {
1523                expr,
1524                array_expr,
1525                negated,
1526            } => write!(
1527                f,
1528                "{} {}IN UNNEST({})",
1529                expr,
1530                if *negated { "NOT " } else { "" },
1531                array_expr
1532            ),
1533            Expr::Between {
1534                expr,
1535                negated,
1536                low,
1537                high,
1538            } => write!(
1539                f,
1540                "{} {}BETWEEN {} AND {}",
1541                expr,
1542                if *negated { "NOT " } else { "" },
1543                low,
1544                high
1545            ),
1546            Expr::BinaryOp { left, op, right } => write!(f, "{left} {op} {right}"),
1547            Expr::Like {
1548                negated,
1549                expr,
1550                pattern,
1551                escape_char,
1552                any,
1553            } => match escape_char {
1554                Some(ch) => write!(
1555                    f,
1556                    "{} {}LIKE {}{} ESCAPE {}",
1557                    expr,
1558                    if *negated { "NOT " } else { "" },
1559                    if *any { "ANY " } else { "" },
1560                    pattern,
1561                    ch
1562                ),
1563                _ => write!(
1564                    f,
1565                    "{} {}LIKE {}{}",
1566                    expr,
1567                    if *negated { "NOT " } else { "" },
1568                    if *any { "ANY " } else { "" },
1569                    pattern
1570                ),
1571            },
1572            Expr::ILike {
1573                negated,
1574                expr,
1575                pattern,
1576                escape_char,
1577                any,
1578            } => match escape_char {
1579                Some(ch) => write!(
1580                    f,
1581                    "{} {}ILIKE {}{} ESCAPE {}",
1582                    expr,
1583                    if *negated { "NOT " } else { "" },
1584                    if *any { "ANY" } else { "" },
1585                    pattern,
1586                    ch
1587                ),
1588                _ => write!(
1589                    f,
1590                    "{} {}ILIKE {}{}",
1591                    expr,
1592                    if *negated { "NOT " } else { "" },
1593                    if *any { "ANY " } else { "" },
1594                    pattern
1595                ),
1596            },
1597            Expr::RLike {
1598                negated,
1599                expr,
1600                pattern,
1601                regexp,
1602            } => write!(
1603                f,
1604                "{} {}{} {}",
1605                expr,
1606                if *negated { "NOT " } else { "" },
1607                if *regexp { "REGEXP" } else { "RLIKE" },
1608                pattern
1609            ),
1610            Expr::IsNormalized {
1611                expr,
1612                form,
1613                negated,
1614            } => {
1615                let not_ = if *negated { "NOT " } else { "" };
1616                if form.is_none() {
1617                    write!(f, "{expr} IS {not_}NORMALIZED")
1618                } else {
1619                    write!(
1620                        f,
1621                        "{} IS {}{} NORMALIZED",
1622                        expr,
1623                        not_,
1624                        form.as_ref().unwrap()
1625                    )
1626                }
1627            }
1628            Expr::SimilarTo {
1629                negated,
1630                expr,
1631                pattern,
1632                escape_char,
1633            } => match escape_char {
1634                Some(ch) => write!(
1635                    f,
1636                    "{} {}SIMILAR TO {} ESCAPE {}",
1637                    expr,
1638                    if *negated { "NOT " } else { "" },
1639                    pattern,
1640                    ch
1641                ),
1642                _ => write!(
1643                    f,
1644                    "{} {}SIMILAR TO {}",
1645                    expr,
1646                    if *negated { "NOT " } else { "" },
1647                    pattern
1648                ),
1649            },
1650            Expr::AnyOp {
1651                left,
1652                compare_op,
1653                right,
1654                is_some,
1655            } => {
1656                let add_parens = !matches!(right.as_ref(), Expr::Subquery(_));
1657                write!(
1658                    f,
1659                    "{left} {compare_op} {}{}{right}{}",
1660                    if *is_some { "SOME" } else { "ANY" },
1661                    if add_parens { "(" } else { "" },
1662                    if add_parens { ")" } else { "" },
1663                )
1664            }
1665            Expr::AllOp {
1666                left,
1667                compare_op,
1668                right,
1669            } => {
1670                let add_parens = !matches!(right.as_ref(), Expr::Subquery(_));
1671                write!(
1672                    f,
1673                    "{left} {compare_op} ALL{}{right}{}",
1674                    if add_parens { "(" } else { "" },
1675                    if add_parens { ")" } else { "" },
1676                )
1677            }
1678            Expr::UnaryOp { op, expr } => {
1679                if op == &UnaryOperator::PGPostfixFactorial {
1680                    write!(f, "{expr}{op}")
1681                } else if matches!(
1682                    op,
1683                    UnaryOperator::Not
1684                        | UnaryOperator::Hash
1685                        | UnaryOperator::AtDashAt
1686                        | UnaryOperator::DoubleAt
1687                        | UnaryOperator::QuestionDash
1688                        | UnaryOperator::QuestionPipe
1689                ) {
1690                    write!(f, "{op} {expr}")
1691                } else {
1692                    write!(f, "{op}{expr}")
1693                }
1694            }
1695            Expr::Convert {
1696                is_try,
1697                expr,
1698                target_before_value,
1699                data_type,
1700                charset,
1701                styles,
1702            } => {
1703                write!(f, "{}CONVERT(", if *is_try { "TRY_" } else { "" })?;
1704                if let Some(data_type) = data_type {
1705                    if let Some(charset) = charset {
1706                        write!(f, "{expr}, {data_type} CHARACTER SET {charset}")
1707                    } else if *target_before_value {
1708                        write!(f, "{data_type}, {expr}")
1709                    } else {
1710                        write!(f, "{expr}, {data_type}")
1711                    }
1712                } else if let Some(charset) = charset {
1713                    write!(f, "{expr} USING {charset}")
1714                } else {
1715                    write!(f, "{expr}") // This should never happen
1716                }?;
1717                if !styles.is_empty() {
1718                    write!(f, ", {}", display_comma_separated(styles))?;
1719                }
1720                write!(f, ")")
1721            }
1722            Expr::Cast {
1723                kind,
1724                expr,
1725                data_type,
1726                format,
1727            } => match kind {
1728                CastKind::Cast => {
1729                    if let Some(format) = format {
1730                        write!(f, "CAST({expr} AS {data_type} FORMAT {format})")
1731                    } else {
1732                        write!(f, "CAST({expr} AS {data_type})")
1733                    }
1734                }
1735                CastKind::TryCast => {
1736                    if let Some(format) = format {
1737                        write!(f, "TRY_CAST({expr} AS {data_type} FORMAT {format})")
1738                    } else {
1739                        write!(f, "TRY_CAST({expr} AS {data_type})")
1740                    }
1741                }
1742                CastKind::SafeCast => {
1743                    if let Some(format) = format {
1744                        write!(f, "SAFE_CAST({expr} AS {data_type} FORMAT {format})")
1745                    } else {
1746                        write!(f, "SAFE_CAST({expr} AS {data_type})")
1747                    }
1748                }
1749                CastKind::DoubleColon => {
1750                    write!(f, "{expr}::{data_type}")
1751                }
1752            },
1753            Expr::Extract {
1754                field,
1755                syntax,
1756                expr,
1757            } => match syntax {
1758                ExtractSyntax::From => write!(f, "EXTRACT({field} FROM {expr})"),
1759                ExtractSyntax::Comma => write!(f, "EXTRACT({field}, {expr})"),
1760            },
1761            Expr::Ceil { expr, field } => match field {
1762                CeilFloorKind::DateTimeField(DateTimeField::NoDateTime) => {
1763                    write!(f, "CEIL({expr})")
1764                }
1765                CeilFloorKind::DateTimeField(dt_field) => write!(f, "CEIL({expr} TO {dt_field})"),
1766                CeilFloorKind::Scale(s) => write!(f, "CEIL({expr}, {s})"),
1767            },
1768            Expr::Floor { expr, field } => match field {
1769                CeilFloorKind::DateTimeField(DateTimeField::NoDateTime) => {
1770                    write!(f, "FLOOR({expr})")
1771                }
1772                CeilFloorKind::DateTimeField(dt_field) => write!(f, "FLOOR({expr} TO {dt_field})"),
1773                CeilFloorKind::Scale(s) => write!(f, "FLOOR({expr}, {s})"),
1774            },
1775            Expr::Position { expr, r#in } => write!(f, "POSITION({expr} IN {in})"),
1776            Expr::Collate { expr, collation } => write!(f, "{expr} COLLATE {collation}"),
1777            Expr::Nested(ast) => write!(f, "({ast})"),
1778            Expr::Value(v) => write!(f, "{v}"),
1779            Expr::Prefixed { prefix, value } => write!(f, "{prefix} {value}"),
1780            Expr::TypedString(ts) => ts.fmt(f),
1781            Expr::Function(fun) => fun.fmt(f),
1782            Expr::Case {
1783                case_token: _,
1784                end_token: _,
1785                operand,
1786                conditions,
1787                else_result,
1788            } => {
1789                f.write_str("CASE")?;
1790                if let Some(operand) = operand {
1791                    f.write_str(" ")?;
1792                    operand.fmt(f)?;
1793                }
1794                for when in conditions {
1795                    SpaceOrNewline.fmt(f)?;
1796                    Indent(when).fmt(f)?;
1797                }
1798                if let Some(else_result) = else_result {
1799                    SpaceOrNewline.fmt(f)?;
1800                    Indent("ELSE").fmt(f)?;
1801                    SpaceOrNewline.fmt(f)?;
1802                    Indent(Indent(else_result)).fmt(f)?;
1803                }
1804                SpaceOrNewline.fmt(f)?;
1805                f.write_str("END")
1806            }
1807            Expr::Exists { subquery, negated } => write!(
1808                f,
1809                "{}EXISTS ({})",
1810                if *negated { "NOT " } else { "" },
1811                subquery
1812            ),
1813            Expr::Subquery(s) => write!(f, "({s})"),
1814            Expr::GroupingSets(sets) => {
1815                write!(f, "GROUPING SETS (")?;
1816                let mut sep = "";
1817                for set in sets {
1818                    write!(f, "{sep}")?;
1819                    sep = ", ";
1820                    write!(f, "({})", display_comma_separated(set))?;
1821                }
1822                write!(f, ")")
1823            }
1824            Expr::Cube(sets) => {
1825                write!(f, "CUBE (")?;
1826                let mut sep = "";
1827                for set in sets {
1828                    write!(f, "{sep}")?;
1829                    sep = ", ";
1830                    if set.len() == 1 {
1831                        write!(f, "{}", set[0])?;
1832                    } else {
1833                        write!(f, "({})", display_comma_separated(set))?;
1834                    }
1835                }
1836                write!(f, ")")
1837            }
1838            Expr::Rollup(sets) => {
1839                write!(f, "ROLLUP (")?;
1840                let mut sep = "";
1841                for set in sets {
1842                    write!(f, "{sep}")?;
1843                    sep = ", ";
1844                    if set.len() == 1 {
1845                        write!(f, "{}", set[0])?;
1846                    } else {
1847                        write!(f, "({})", display_comma_separated(set))?;
1848                    }
1849                }
1850                write!(f, ")")
1851            }
1852            Expr::Substring {
1853                expr,
1854                substring_from,
1855                substring_for,
1856                special,
1857                shorthand,
1858            } => {
1859                f.write_str("SUBSTR")?;
1860                if !*shorthand {
1861                    f.write_str("ING")?;
1862                }
1863                write!(f, "({expr}")?;
1864                if let Some(from_part) = substring_from {
1865                    if *special {
1866                        write!(f, ", {from_part}")?;
1867                    } else {
1868                        write!(f, " FROM {from_part}")?;
1869                    }
1870                }
1871                if let Some(for_part) = substring_for {
1872                    if *special {
1873                        write!(f, ", {for_part}")?;
1874                    } else {
1875                        write!(f, " FOR {for_part}")?;
1876                    }
1877                }
1878
1879                write!(f, ")")
1880            }
1881            Expr::Overlay {
1882                expr,
1883                overlay_what,
1884                overlay_from,
1885                overlay_for,
1886            } => {
1887                write!(
1888                    f,
1889                    "OVERLAY({expr} PLACING {overlay_what} FROM {overlay_from}"
1890                )?;
1891                if let Some(for_part) = overlay_for {
1892                    write!(f, " FOR {for_part}")?;
1893                }
1894
1895                write!(f, ")")
1896            }
1897            Expr::IsDistinctFrom(a, b) => write!(f, "{a} IS DISTINCT FROM {b}"),
1898            Expr::IsNotDistinctFrom(a, b) => write!(f, "{a} IS NOT DISTINCT FROM {b}"),
1899            Expr::Trim {
1900                expr,
1901                trim_where,
1902                trim_what,
1903                trim_characters,
1904            } => {
1905                write!(f, "TRIM(")?;
1906                if let Some(ident) = trim_where {
1907                    write!(f, "{ident} ")?;
1908                }
1909                if let Some(trim_char) = trim_what {
1910                    write!(f, "{trim_char} FROM {expr}")?;
1911                } else {
1912                    write!(f, "{expr}")?;
1913                }
1914                if let Some(characters) = trim_characters {
1915                    write!(f, ", {}", display_comma_separated(characters))?;
1916                }
1917
1918                write!(f, ")")
1919            }
1920            Expr::Tuple(exprs) => {
1921                write!(f, "({})", display_comma_separated(exprs))
1922            }
1923            Expr::Struct { values, fields } => {
1924                if !fields.is_empty() {
1925                    write!(
1926                        f,
1927                        "STRUCT<{}>({})",
1928                        display_comma_separated(fields),
1929                        display_comma_separated(values)
1930                    )
1931                } else {
1932                    write!(f, "STRUCT({})", display_comma_separated(values))
1933                }
1934            }
1935            Expr::Named { expr, name } => {
1936                write!(f, "{expr} AS {name}")
1937            }
1938            Expr::Dictionary(fields) => {
1939                write!(f, "{{{}}}", display_comma_separated(fields))
1940            }
1941            Expr::Map(map) => {
1942                write!(f, "{map}")
1943            }
1944            Expr::Array(set) => {
1945                write!(f, "{set}")
1946            }
1947            Expr::JsonAccess { value, path } => {
1948                write!(f, "{value}{path}")
1949            }
1950            Expr::AtTimeZone {
1951                timestamp,
1952                time_zone,
1953            } => {
1954                write!(f, "{timestamp} AT TIME ZONE {time_zone}")
1955            }
1956            Expr::Interval(interval) => {
1957                write!(f, "{interval}")
1958            }
1959            Expr::MatchAgainst {
1960                columns,
1961                match_value: match_expr,
1962                opt_search_modifier,
1963            } => {
1964                write!(f, "MATCH ({}) AGAINST ", display_comma_separated(columns),)?;
1965
1966                if let Some(search_modifier) = opt_search_modifier {
1967                    write!(f, "({match_expr} {search_modifier})")?;
1968                } else {
1969                    write!(f, "({match_expr})")?;
1970                }
1971
1972                Ok(())
1973            }
1974            Expr::OuterJoin(expr) => {
1975                write!(f, "{expr} (+)")
1976            }
1977            Expr::Prior(expr) => write!(f, "PRIOR {expr}"),
1978            Expr::Lambda(lambda) => write!(f, "{lambda}"),
1979            Expr::MemberOf(member_of) => write!(f, "{member_of}"),
1980        }
1981    }
1982}
1983
1984#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1985#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1986#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1987pub enum WindowType {
1988    WindowSpec(WindowSpec),
1989    NamedWindow(Ident),
1990}
1991
1992impl Display for WindowType {
1993    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1994        match self {
1995            WindowType::WindowSpec(spec) => {
1996                f.write_str("(")?;
1997                NewLine.fmt(f)?;
1998                Indent(spec).fmt(f)?;
1999                NewLine.fmt(f)?;
2000                f.write_str(")")
2001            }
2002            WindowType::NamedWindow(name) => name.fmt(f),
2003        }
2004    }
2005}
2006
2007/// A window specification (i.e. `OVER ([window_name] PARTITION BY .. ORDER BY .. etc.)`)
2008#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2009#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2010#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2011pub struct WindowSpec {
2012    /// Optional window name.
2013    ///
2014    /// You can find it at least in [MySQL][1], [BigQuery][2], [PostgreSQL][3]
2015    ///
2016    /// [1]: https://dev.mysql.com/doc/refman/8.0/en/window-functions-named-windows.html
2017    /// [2]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
2018    /// [3]: https://www.postgresql.org/docs/current/sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS
2019    pub window_name: Option<Ident>,
2020    /// `OVER (PARTITION BY ...)`
2021    pub partition_by: Vec<Expr>,
2022    /// `OVER (ORDER BY ...)`
2023    pub order_by: Vec<OrderByExpr>,
2024    /// `OVER (window frame)`
2025    pub window_frame: Option<WindowFrame>,
2026}
2027
2028impl fmt::Display for WindowSpec {
2029    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2030        let mut is_first = true;
2031        if let Some(window_name) = &self.window_name {
2032            if !is_first {
2033                SpaceOrNewline.fmt(f)?;
2034            }
2035            is_first = false;
2036            write!(f, "{window_name}")?;
2037        }
2038        if !self.partition_by.is_empty() {
2039            if !is_first {
2040                SpaceOrNewline.fmt(f)?;
2041            }
2042            is_first = false;
2043            write!(
2044                f,
2045                "PARTITION BY {}",
2046                display_comma_separated(&self.partition_by)
2047            )?;
2048        }
2049        if !self.order_by.is_empty() {
2050            if !is_first {
2051                SpaceOrNewline.fmt(f)?;
2052            }
2053            is_first = false;
2054            write!(f, "ORDER BY {}", display_comma_separated(&self.order_by))?;
2055        }
2056        if let Some(window_frame) = &self.window_frame {
2057            if !is_first {
2058                SpaceOrNewline.fmt(f)?;
2059            }
2060            if let Some(end_bound) = &window_frame.end_bound {
2061                write!(
2062                    f,
2063                    "{} BETWEEN {} AND {}",
2064                    window_frame.units, window_frame.start_bound, end_bound
2065                )?;
2066            } else {
2067                write!(f, "{} {}", window_frame.units, window_frame.start_bound)?;
2068            }
2069        }
2070        Ok(())
2071    }
2072}
2073
2074/// Specifies the data processed by a window function, e.g.
2075/// `RANGE UNBOUNDED PRECEDING` or `ROWS BETWEEN 5 PRECEDING AND CURRENT ROW`.
2076///
2077/// Note: The parser does not validate the specified bounds; the caller should
2078/// reject invalid bounds like `ROWS UNBOUNDED FOLLOWING` before execution.
2079#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2080#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2081#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2082pub struct WindowFrame {
2083    pub units: WindowFrameUnits,
2084    pub start_bound: WindowFrameBound,
2085    /// The right bound of the `BETWEEN .. AND` clause. The end bound of `None`
2086    /// indicates the shorthand form (e.g. `ROWS 1 PRECEDING`), which must
2087    /// behave the same as `end_bound = WindowFrameBound::CurrentRow`.
2088    pub end_bound: Option<WindowFrameBound>,
2089    // TBD: EXCLUDE
2090}
2091
2092impl Default for WindowFrame {
2093    /// Returns default value for window frame
2094    ///
2095    /// See [this page](https://www.sqlite.org/windowfunctions.html#frame_specifications) for more details.
2096    fn default() -> Self {
2097        Self {
2098            units: WindowFrameUnits::Range,
2099            start_bound: WindowFrameBound::Preceding(None),
2100            end_bound: None,
2101        }
2102    }
2103}
2104
2105#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2106#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2107#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2108pub enum WindowFrameUnits {
2109    Rows,
2110    Range,
2111    Groups,
2112}
2113
2114impl fmt::Display for WindowFrameUnits {
2115    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2116        f.write_str(match self {
2117            WindowFrameUnits::Rows => "ROWS",
2118            WindowFrameUnits::Range => "RANGE",
2119            WindowFrameUnits::Groups => "GROUPS",
2120        })
2121    }
2122}
2123
2124/// Specifies Ignore / Respect NULL within window functions.
2125/// For example
2126/// `FIRST_VALUE(column2) IGNORE NULLS OVER (PARTITION BY column1)`
2127#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2128#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2129#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2130pub enum NullTreatment {
2131    IgnoreNulls,
2132    RespectNulls,
2133}
2134
2135impl fmt::Display for NullTreatment {
2136    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2137        f.write_str(match self {
2138            NullTreatment::IgnoreNulls => "IGNORE NULLS",
2139            NullTreatment::RespectNulls => "RESPECT NULLS",
2140        })
2141    }
2142}
2143
2144/// Specifies [WindowFrame]'s `start_bound` and `end_bound`
2145#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2146#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2147#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2148pub enum WindowFrameBound {
2149    /// `CURRENT ROW`
2150    CurrentRow,
2151    /// `<N> PRECEDING` or `UNBOUNDED PRECEDING`
2152    Preceding(Option<Box<Expr>>),
2153    /// `<N> FOLLOWING` or `UNBOUNDED FOLLOWING`.
2154    Following(Option<Box<Expr>>),
2155}
2156
2157impl fmt::Display for WindowFrameBound {
2158    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2159        match self {
2160            WindowFrameBound::CurrentRow => f.write_str("CURRENT ROW"),
2161            WindowFrameBound::Preceding(None) => f.write_str("UNBOUNDED PRECEDING"),
2162            WindowFrameBound::Following(None) => f.write_str("UNBOUNDED FOLLOWING"),
2163            WindowFrameBound::Preceding(Some(n)) => write!(f, "{n} PRECEDING"),
2164            WindowFrameBound::Following(Some(n)) => write!(f, "{n} FOLLOWING"),
2165        }
2166    }
2167}
2168
2169#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2170#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2171#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2172pub enum AddDropSync {
2173    ADD,
2174    DROP,
2175    SYNC,
2176}
2177
2178impl fmt::Display for AddDropSync {
2179    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2180        match self {
2181            AddDropSync::SYNC => f.write_str("SYNC PARTITIONS"),
2182            AddDropSync::DROP => f.write_str("DROP PARTITIONS"),
2183            AddDropSync::ADD => f.write_str("ADD PARTITIONS"),
2184        }
2185    }
2186}
2187
2188#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2189#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2190#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2191pub enum ShowCreateObject {
2192    Event,
2193    Function,
2194    Procedure,
2195    Table,
2196    Trigger,
2197    View,
2198}
2199
2200impl fmt::Display for ShowCreateObject {
2201    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2202        match self {
2203            ShowCreateObject::Event => f.write_str("EVENT"),
2204            ShowCreateObject::Function => f.write_str("FUNCTION"),
2205            ShowCreateObject::Procedure => f.write_str("PROCEDURE"),
2206            ShowCreateObject::Table => f.write_str("TABLE"),
2207            ShowCreateObject::Trigger => f.write_str("TRIGGER"),
2208            ShowCreateObject::View => f.write_str("VIEW"),
2209        }
2210    }
2211}
2212
2213#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2214#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2215#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2216pub enum CommentObject {
2217    Column,
2218    Table,
2219    Extension,
2220    Schema,
2221    Database,
2222    User,
2223    Role,
2224}
2225
2226impl fmt::Display for CommentObject {
2227    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2228        match self {
2229            CommentObject::Column => f.write_str("COLUMN"),
2230            CommentObject::Table => f.write_str("TABLE"),
2231            CommentObject::Extension => f.write_str("EXTENSION"),
2232            CommentObject::Schema => f.write_str("SCHEMA"),
2233            CommentObject::Database => f.write_str("DATABASE"),
2234            CommentObject::User => f.write_str("USER"),
2235            CommentObject::Role => f.write_str("ROLE"),
2236        }
2237    }
2238}
2239
2240#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2241#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2242#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2243pub enum Password {
2244    Password(Expr),
2245    NullPassword,
2246}
2247
2248/// A `CASE` statement.
2249///
2250/// Examples:
2251/// ```sql
2252/// CASE
2253///     WHEN EXISTS(SELECT 1)
2254///         THEN SELECT 1 FROM T;
2255///     WHEN EXISTS(SELECT 2)
2256///         THEN SELECT 1 FROM U;
2257///     ELSE
2258///         SELECT 1 FROM V;
2259/// END CASE;
2260/// ```
2261///
2262/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#case_search_expression)
2263/// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/case)
2264#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2265#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2266#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2267pub struct CaseStatement {
2268    /// The `CASE` token that starts the statement.
2269    pub case_token: AttachedToken,
2270    pub match_expr: Option<Expr>,
2271    pub when_blocks: Vec<ConditionalStatementBlock>,
2272    pub else_block: Option<ConditionalStatementBlock>,
2273    /// The last token of the statement (`END` or `CASE`).
2274    pub end_case_token: AttachedToken,
2275}
2276
2277impl fmt::Display for CaseStatement {
2278    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2279        let CaseStatement {
2280            case_token: _,
2281            match_expr,
2282            when_blocks,
2283            else_block,
2284            end_case_token: AttachedToken(end),
2285        } = self;
2286
2287        write!(f, "CASE")?;
2288
2289        if let Some(expr) = match_expr {
2290            write!(f, " {expr}")?;
2291        }
2292
2293        if !when_blocks.is_empty() {
2294            write!(f, " {}", display_separated(when_blocks, " "))?;
2295        }
2296
2297        if let Some(else_block) = else_block {
2298            write!(f, " {else_block}")?;
2299        }
2300
2301        write!(f, " END")?;
2302
2303        if let Token::Word(w) = &end.token {
2304            if w.keyword == Keyword::CASE {
2305                write!(f, " CASE")?;
2306            }
2307        }
2308
2309        Ok(())
2310    }
2311}
2312
2313/// An `IF` statement.
2314///
2315/// Example (BigQuery or Snowflake):
2316/// ```sql
2317/// IF TRUE THEN
2318///     SELECT 1;
2319///     SELECT 2;
2320/// ELSEIF TRUE THEN
2321///     SELECT 3;
2322/// ELSE
2323///     SELECT 4;
2324/// END IF
2325/// ```
2326/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#if)
2327/// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/if)
2328///
2329/// Example (MSSQL):
2330/// ```sql
2331/// IF 1=1 SELECT 1 ELSE SELECT 2
2332/// ```
2333/// [MSSQL](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/if-else-transact-sql?view=sql-server-ver16)
2334#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2335#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2336#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2337pub struct IfStatement {
2338    pub if_block: ConditionalStatementBlock,
2339    pub elseif_blocks: Vec<ConditionalStatementBlock>,
2340    pub else_block: Option<ConditionalStatementBlock>,
2341    pub end_token: Option<AttachedToken>,
2342}
2343
2344impl fmt::Display for IfStatement {
2345    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2346        let IfStatement {
2347            if_block,
2348            elseif_blocks,
2349            else_block,
2350            end_token,
2351        } = self;
2352
2353        write!(f, "{if_block}")?;
2354
2355        for elseif_block in elseif_blocks {
2356            write!(f, " {elseif_block}")?;
2357        }
2358
2359        if let Some(else_block) = else_block {
2360            write!(f, " {else_block}")?;
2361        }
2362
2363        if let Some(AttachedToken(end_token)) = end_token {
2364            write!(f, " END {end_token}")?;
2365        }
2366
2367        Ok(())
2368    }
2369}
2370
2371/// A `WHILE` statement.
2372///
2373/// Example:
2374/// ```sql
2375/// WHILE @@FETCH_STATUS = 0
2376/// BEGIN
2377///    FETCH NEXT FROM c1 INTO @var1, @var2;
2378/// END
2379/// ```
2380///
2381/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/while-transact-sql)
2382#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2383#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2384#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2385pub struct WhileStatement {
2386    pub while_block: ConditionalStatementBlock,
2387}
2388
2389impl fmt::Display for WhileStatement {
2390    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2391        let WhileStatement { while_block } = self;
2392        write!(f, "{while_block}")?;
2393        Ok(())
2394    }
2395}
2396
2397/// A block within a [Statement::Case] or [Statement::If] or [Statement::While]-like statement
2398///
2399/// Example 1:
2400/// ```sql
2401/// WHEN EXISTS(SELECT 1) THEN SELECT 1;
2402/// ```
2403///
2404/// Example 2:
2405/// ```sql
2406/// IF TRUE THEN SELECT 1; SELECT 2;
2407/// ```
2408///
2409/// Example 3:
2410/// ```sql
2411/// ELSE SELECT 1; SELECT 2;
2412/// ```
2413///
2414/// Example 4:
2415/// ```sql
2416/// WHILE @@FETCH_STATUS = 0
2417/// BEGIN
2418///    FETCH NEXT FROM c1 INTO @var1, @var2;
2419/// END
2420/// ```
2421#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2422#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2423#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2424pub struct ConditionalStatementBlock {
2425    pub start_token: AttachedToken,
2426    pub condition: Option<Expr>,
2427    pub then_token: Option<AttachedToken>,
2428    pub conditional_statements: ConditionalStatements,
2429}
2430
2431impl ConditionalStatementBlock {
2432    pub fn statements(&self) -> &Vec<Statement> {
2433        self.conditional_statements.statements()
2434    }
2435}
2436
2437impl fmt::Display for ConditionalStatementBlock {
2438    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2439        let ConditionalStatementBlock {
2440            start_token: AttachedToken(start_token),
2441            condition,
2442            then_token,
2443            conditional_statements,
2444        } = self;
2445
2446        write!(f, "{start_token}")?;
2447
2448        if let Some(condition) = condition {
2449            write!(f, " {condition}")?;
2450        }
2451
2452        if then_token.is_some() {
2453            write!(f, " THEN")?;
2454        }
2455
2456        if !conditional_statements.statements().is_empty() {
2457            write!(f, " {conditional_statements}")?;
2458        }
2459
2460        Ok(())
2461    }
2462}
2463
2464/// A list of statements in a [ConditionalStatementBlock].
2465#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2466#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2467#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2468pub enum ConditionalStatements {
2469    /// SELECT 1; SELECT 2; SELECT 3; ...
2470    Sequence { statements: Vec<Statement> },
2471    /// BEGIN SELECT 1; SELECT 2; SELECT 3; ... END
2472    BeginEnd(BeginEndStatements),
2473}
2474
2475impl ConditionalStatements {
2476    pub fn statements(&self) -> &Vec<Statement> {
2477        match self {
2478            ConditionalStatements::Sequence { statements } => statements,
2479            ConditionalStatements::BeginEnd(bes) => &bes.statements,
2480        }
2481    }
2482}
2483
2484impl fmt::Display for ConditionalStatements {
2485    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2486        match self {
2487            ConditionalStatements::Sequence { statements } => {
2488                if !statements.is_empty() {
2489                    format_statement_list(f, statements)?;
2490                }
2491                Ok(())
2492            }
2493            ConditionalStatements::BeginEnd(bes) => write!(f, "{bes}"),
2494        }
2495    }
2496}
2497
2498/// Represents a list of statements enclosed within `BEGIN` and `END` keywords.
2499/// Example:
2500/// ```sql
2501/// BEGIN
2502///     SELECT 1;
2503///     SELECT 2;
2504/// END
2505/// ```
2506#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2507#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2508#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2509pub struct BeginEndStatements {
2510    pub begin_token: AttachedToken,
2511    pub statements: Vec<Statement>,
2512    pub end_token: AttachedToken,
2513}
2514
2515impl fmt::Display for BeginEndStatements {
2516    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2517        let BeginEndStatements {
2518            begin_token: AttachedToken(begin_token),
2519            statements,
2520            end_token: AttachedToken(end_token),
2521        } = self;
2522
2523        if begin_token.token != Token::EOF {
2524            write!(f, "{begin_token} ")?;
2525        }
2526        if !statements.is_empty() {
2527            format_statement_list(f, statements)?;
2528        }
2529        if end_token.token != Token::EOF {
2530            write!(f, " {end_token}")?;
2531        }
2532        Ok(())
2533    }
2534}
2535
2536/// A `RAISE` statement.
2537///
2538/// Examples:
2539/// ```sql
2540/// RAISE USING MESSAGE = 'error';
2541///
2542/// RAISE myerror;
2543/// ```
2544///
2545/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#raise)
2546/// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/raise)
2547#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2548#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2549#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2550pub struct RaiseStatement {
2551    pub value: Option<RaiseStatementValue>,
2552}
2553
2554impl fmt::Display for RaiseStatement {
2555    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2556        let RaiseStatement { value } = self;
2557
2558        write!(f, "RAISE")?;
2559        if let Some(value) = value {
2560            write!(f, " {value}")?;
2561        }
2562
2563        Ok(())
2564    }
2565}
2566
2567/// Represents the error value of a [RaiseStatement].
2568#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2569#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2570#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2571pub enum RaiseStatementValue {
2572    /// `RAISE USING MESSAGE = 'error'`
2573    UsingMessage(Expr),
2574    /// `RAISE myerror`
2575    Expr(Expr),
2576}
2577
2578impl fmt::Display for RaiseStatementValue {
2579    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2580        match self {
2581            RaiseStatementValue::Expr(expr) => write!(f, "{expr}"),
2582            RaiseStatementValue::UsingMessage(expr) => write!(f, "USING MESSAGE = {expr}"),
2583        }
2584    }
2585}
2586
2587/// Represents an expression assignment within a variable `DECLARE` statement.
2588///
2589/// Examples:
2590/// ```sql
2591/// DECLARE variable_name := 42
2592/// DECLARE variable_name DEFAULT 42
2593/// ```
2594#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2595#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2596#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2597pub enum DeclareAssignment {
2598    /// Plain expression specified.
2599    Expr(Box<Expr>),
2600
2601    /// Expression assigned via the `DEFAULT` keyword
2602    Default(Box<Expr>),
2603
2604    /// Expression assigned via the `:=` syntax
2605    ///
2606    /// Example:
2607    /// ```sql
2608    /// DECLARE variable_name := 42;
2609    /// ```
2610    DuckAssignment(Box<Expr>),
2611
2612    /// Expression via the `FOR` keyword
2613    ///
2614    /// Example:
2615    /// ```sql
2616    /// DECLARE c1 CURSOR FOR res
2617    /// ```
2618    For(Box<Expr>),
2619
2620    /// Expression via the `=` syntax.
2621    ///
2622    /// Example:
2623    /// ```sql
2624    /// DECLARE @variable AS INT = 100
2625    /// ```
2626    MsSqlAssignment(Box<Expr>),
2627}
2628
2629impl fmt::Display for DeclareAssignment {
2630    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2631        match self {
2632            DeclareAssignment::Expr(expr) => {
2633                write!(f, "{expr}")
2634            }
2635            DeclareAssignment::Default(expr) => {
2636                write!(f, "DEFAULT {expr}")
2637            }
2638            DeclareAssignment::DuckAssignment(expr) => {
2639                write!(f, ":= {expr}")
2640            }
2641            DeclareAssignment::MsSqlAssignment(expr) => {
2642                write!(f, "= {expr}")
2643            }
2644            DeclareAssignment::For(expr) => {
2645                write!(f, "FOR {expr}")
2646            }
2647        }
2648    }
2649}
2650
2651/// Represents the type of a `DECLARE` statement.
2652#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2653#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2654#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2655pub enum DeclareType {
2656    /// Cursor variable type. e.g. [Snowflake] [PostgreSQL] [MsSql]
2657    ///
2658    /// [Snowflake]: https://docs.snowflake.com/en/developer-guide/snowflake-scripting/cursors#declaring-a-cursor
2659    /// [PostgreSQL]: https://www.postgresql.org/docs/current/plpgsql-cursors.html
2660    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-cursor-transact-sql
2661    Cursor,
2662
2663    /// Result set variable type. [Snowflake]
2664    ///
2665    /// Syntax:
2666    /// ```text
2667    /// <resultset_name> RESULTSET [ { DEFAULT | := } ( <query> ) ] ;
2668    /// ```
2669    /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare#resultset-declaration-syntax
2670    ResultSet,
2671
2672    /// Exception declaration syntax. [Snowflake]
2673    ///
2674    /// Syntax:
2675    /// ```text
2676    /// <exception_name> EXCEPTION [ ( <exception_number> , '<exception_message>' ) ] ;
2677    /// ```
2678    /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare#exception-declaration-syntax
2679    Exception,
2680}
2681
2682impl fmt::Display for DeclareType {
2683    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2684        match self {
2685            DeclareType::Cursor => {
2686                write!(f, "CURSOR")
2687            }
2688            DeclareType::ResultSet => {
2689                write!(f, "RESULTSET")
2690            }
2691            DeclareType::Exception => {
2692                write!(f, "EXCEPTION")
2693            }
2694        }
2695    }
2696}
2697
2698/// A `DECLARE` statement.
2699/// [PostgreSQL] [Snowflake] [BigQuery]
2700///
2701/// Examples:
2702/// ```sql
2703/// DECLARE variable_name := 42
2704/// DECLARE liahona CURSOR FOR SELECT * FROM films;
2705/// ```
2706///
2707/// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-declare.html
2708/// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare
2709/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#declare
2710#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2711#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2712#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2713pub struct Declare {
2714    /// The name(s) being declared.
2715    /// Example: `DECLARE a, b, c DEFAULT 42;
2716    pub names: Vec<Ident>,
2717    /// Data-type assigned to the declared variable.
2718    /// Example: `DECLARE x INT64 DEFAULT 42;
2719    pub data_type: Option<DataType>,
2720    /// Expression being assigned to the declared variable.
2721    pub assignment: Option<DeclareAssignment>,
2722    /// Represents the type of the declared variable.
2723    pub declare_type: Option<DeclareType>,
2724    /// Causes the cursor to return data in binary rather than in text format.
2725    pub binary: Option<bool>,
2726    /// None = Not specified
2727    /// Some(true) = INSENSITIVE
2728    /// Some(false) = ASENSITIVE
2729    pub sensitive: Option<bool>,
2730    /// None = Not specified
2731    /// Some(true) = SCROLL
2732    /// Some(false) = NO SCROLL
2733    pub scroll: Option<bool>,
2734    /// None = Not specified
2735    /// Some(true) = WITH HOLD, specifies that the cursor can continue to be used after the transaction that created it successfully commits
2736    /// Some(false) = WITHOUT HOLD, specifies that the cursor cannot be used outside of the transaction that created it
2737    pub hold: Option<bool>,
2738    /// `FOR <query>` clause in a CURSOR declaration.
2739    pub for_query: Option<Box<Query>>,
2740}
2741
2742impl fmt::Display for Declare {
2743    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2744        let Declare {
2745            names,
2746            data_type,
2747            assignment,
2748            declare_type,
2749            binary,
2750            sensitive,
2751            scroll,
2752            hold,
2753            for_query,
2754        } = self;
2755        write!(f, "{}", display_comma_separated(names))?;
2756
2757        if let Some(true) = binary {
2758            write!(f, " BINARY")?;
2759        }
2760
2761        if let Some(sensitive) = sensitive {
2762            if *sensitive {
2763                write!(f, " INSENSITIVE")?;
2764            } else {
2765                write!(f, " ASENSITIVE")?;
2766            }
2767        }
2768
2769        if let Some(scroll) = scroll {
2770            if *scroll {
2771                write!(f, " SCROLL")?;
2772            } else {
2773                write!(f, " NO SCROLL")?;
2774            }
2775        }
2776
2777        if let Some(declare_type) = declare_type {
2778            write!(f, " {declare_type}")?;
2779        }
2780
2781        if let Some(hold) = hold {
2782            if *hold {
2783                write!(f, " WITH HOLD")?;
2784            } else {
2785                write!(f, " WITHOUT HOLD")?;
2786            }
2787        }
2788
2789        if let Some(query) = for_query {
2790            write!(f, " FOR {query}")?;
2791        }
2792
2793        if let Some(data_type) = data_type {
2794            write!(f, " {data_type}")?;
2795        }
2796
2797        if let Some(expr) = assignment {
2798            write!(f, " {expr}")?;
2799        }
2800        Ok(())
2801    }
2802}
2803
2804/// Sql options of a `CREATE TABLE` statement.
2805#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2806#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2807#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2808pub enum CreateTableOptions {
2809    #[default]
2810    None,
2811    /// Options specified using the `WITH` keyword.
2812    /// e.g. `WITH (description = "123")`
2813    ///
2814    /// <https://www.postgresql.org/docs/current/sql-createtable.html>
2815    ///
2816    /// MSSQL supports more specific options that's not only key-value pairs.
2817    ///
2818    /// WITH (
2819    ///     DISTRIBUTION = ROUND_ROBIN,
2820    ///     CLUSTERED INDEX (column_a DESC, column_b)
2821    /// )
2822    ///
2823    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#syntax>
2824    With(Vec<SqlOption>),
2825    /// Options specified using the `OPTIONS` keyword.
2826    /// e.g. `OPTIONS(description = "123")`
2827    ///
2828    /// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list>
2829    Options(Vec<SqlOption>),
2830
2831    /// Plain options, options which are not part on any declerative statement e.g. WITH/OPTIONS/...
2832    /// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
2833    Plain(Vec<SqlOption>),
2834
2835    TableProperties(Vec<SqlOption>),
2836}
2837
2838impl fmt::Display for CreateTableOptions {
2839    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2840        match self {
2841            CreateTableOptions::With(with_options) => {
2842                write!(f, "WITH ({})", display_comma_separated(with_options))
2843            }
2844            CreateTableOptions::Options(options) => {
2845                write!(f, "OPTIONS({})", display_comma_separated(options))
2846            }
2847            CreateTableOptions::TableProperties(options) => {
2848                write!(f, "TBLPROPERTIES ({})", display_comma_separated(options))
2849            }
2850            CreateTableOptions::Plain(options) => {
2851                write!(f, "{}", display_separated(options, " "))
2852            }
2853            CreateTableOptions::None => Ok(()),
2854        }
2855    }
2856}
2857
2858/// A `FROM` clause within a `DELETE` statement.
2859///
2860/// Syntax
2861/// ```sql
2862/// [FROM] table
2863/// ```
2864#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2865#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2866#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2867pub enum FromTable {
2868    /// An explicit `FROM` keyword was specified.
2869    WithFromKeyword(Vec<TableWithJoins>),
2870    /// BigQuery: `FROM` keyword was omitted.
2871    /// <https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#delete_statement>
2872    WithoutKeyword(Vec<TableWithJoins>),
2873}
2874impl Display for FromTable {
2875    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2876        match self {
2877            FromTable::WithFromKeyword(tables) => {
2878                write!(f, "FROM {}", display_comma_separated(tables))
2879            }
2880            FromTable::WithoutKeyword(tables) => {
2881                write!(f, "{}", display_comma_separated(tables))
2882            }
2883        }
2884    }
2885}
2886
2887/// Policy type for a `CREATE POLICY` statement.
2888/// ```sql
2889/// AS [ PERMISSIVE | RESTRICTIVE ]
2890/// ```
2891/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)
2892#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2893#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2894#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2895pub enum CreatePolicyType {
2896    Permissive,
2897    Restrictive,
2898}
2899
2900/// Policy command for a `CREATE POLICY` statement.
2901/// ```sql
2902/// FOR [ALL | SELECT | INSERT | UPDATE | DELETE]
2903/// ```
2904/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)
2905#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2906#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2907#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2908pub enum CreatePolicyCommand {
2909    All,
2910    Select,
2911    Insert,
2912    Update,
2913    Delete,
2914}
2915
2916#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2917#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2918#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2919pub enum Set {
2920    /// SQL Standard-style
2921    /// SET a = 1;
2922    SingleAssignment {
2923        scope: Option<ContextModifier>,
2924        hivevar: bool,
2925        variable: ObjectName,
2926        values: Vec<Expr>,
2927    },
2928    /// Snowflake-style
2929    /// SET (a, b, ..) = (1, 2, ..);
2930    ParenthesizedAssignments {
2931        variables: Vec<ObjectName>,
2932        values: Vec<Expr>,
2933    },
2934    /// MySQL-style
2935    /// SET a = 1, b = 2, ..;
2936    MultipleAssignments { assignments: Vec<SetAssignment> },
2937    /// Session authorization for Postgres/Redshift
2938    ///
2939    /// ```sql
2940    /// SET SESSION AUTHORIZATION { user_name | DEFAULT }
2941    /// ```
2942    ///
2943    /// See <https://www.postgresql.org/docs/current/sql-set-session-authorization.html>
2944    /// See <https://docs.aws.amazon.com/redshift/latest/dg/r_SET_SESSION_AUTHORIZATION.html>
2945    SetSessionAuthorization(SetSessionAuthorizationParam),
2946    /// MS-SQL session
2947    ///
2948    /// See <https://learn.microsoft.com/en-us/sql/t-sql/statements/set-statements-transact-sql>
2949    SetSessionParam(SetSessionParamKind),
2950    /// ```sql
2951    /// SET [ SESSION | LOCAL ] ROLE role_name
2952    /// ```
2953    ///
2954    /// Sets session state. Examples: [ANSI][1], [Postgresql][2], [MySQL][3], and [Oracle][4]
2955    ///
2956    /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#set-role-statement
2957    /// [2]: https://www.postgresql.org/docs/14/sql-set-role.html
2958    /// [3]: https://dev.mysql.com/doc/refman/8.0/en/set-role.html
2959    /// [4]: https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_10004.htm
2960    SetRole {
2961        /// Non-ANSI optional identifier to inform if the role is defined inside the current session (`SESSION`) or transaction (`LOCAL`).
2962        context_modifier: Option<ContextModifier>,
2963        /// Role name. If NONE is specified, then the current role name is removed.
2964        role_name: Option<Ident>,
2965    },
2966    /// ```sql
2967    /// SET TIME ZONE <value>
2968    /// ```
2969    ///
2970    /// Note: this is a PostgreSQL-specific statements
2971    /// `SET TIME ZONE <value>` is an alias for `SET timezone TO <value>` in PostgreSQL
2972    /// However, we allow it for all dialects.
2973    SetTimeZone { local: bool, value: Expr },
2974    /// ```sql
2975    /// SET NAMES 'charset_name' [COLLATE 'collation_name']
2976    /// ```
2977    SetNames {
2978        charset_name: Ident,
2979        collation_name: Option<String>,
2980    },
2981    /// ```sql
2982    /// SET NAMES DEFAULT
2983    /// ```
2984    ///
2985    /// Note: this is a MySQL-specific statement.
2986    SetNamesDefault {},
2987    /// ```sql
2988    /// SET TRANSACTION ...
2989    /// ```
2990    SetTransaction {
2991        modes: Vec<TransactionMode>,
2992        snapshot: Option<Value>,
2993        session: bool,
2994    },
2995}
2996
2997impl Display for Set {
2998    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2999        match self {
3000            Self::ParenthesizedAssignments { variables, values } => write!(
3001                f,
3002                "SET ({}) = ({})",
3003                display_comma_separated(variables),
3004                display_comma_separated(values)
3005            ),
3006            Self::MultipleAssignments { assignments } => {
3007                write!(f, "SET {}", display_comma_separated(assignments))
3008            }
3009            Self::SetRole {
3010                context_modifier,
3011                role_name,
3012            } => {
3013                let role_name = role_name.clone().unwrap_or_else(|| Ident::new("NONE"));
3014                write!(
3015                    f,
3016                    "SET {modifier}ROLE {role_name}",
3017                    modifier = context_modifier.map(|m| format!("{m}")).unwrap_or_default()
3018                )
3019            }
3020            Self::SetSessionAuthorization(kind) => write!(f, "SET SESSION AUTHORIZATION {kind}"),
3021            Self::SetSessionParam(kind) => write!(f, "SET {kind}"),
3022            Self::SetTransaction {
3023                modes,
3024                snapshot,
3025                session,
3026            } => {
3027                if *session {
3028                    write!(f, "SET SESSION CHARACTERISTICS AS TRANSACTION")?;
3029                } else {
3030                    write!(f, "SET TRANSACTION")?;
3031                }
3032                if !modes.is_empty() {
3033                    write!(f, " {}", display_comma_separated(modes))?;
3034                }
3035                if let Some(snapshot_id) = snapshot {
3036                    write!(f, " SNAPSHOT {snapshot_id}")?;
3037                }
3038                Ok(())
3039            }
3040            Self::SetTimeZone { local, value } => {
3041                f.write_str("SET ")?;
3042                if *local {
3043                    f.write_str("LOCAL ")?;
3044                }
3045                write!(f, "TIME ZONE {value}")
3046            }
3047            Self::SetNames {
3048                charset_name,
3049                collation_name,
3050            } => {
3051                write!(f, "SET NAMES {charset_name}")?;
3052
3053                if let Some(collation) = collation_name {
3054                    f.write_str(" COLLATE ")?;
3055                    f.write_str(collation)?;
3056                };
3057
3058                Ok(())
3059            }
3060            Self::SetNamesDefault {} => {
3061                f.write_str("SET NAMES DEFAULT")?;
3062
3063                Ok(())
3064            }
3065            Set::SingleAssignment {
3066                scope,
3067                hivevar,
3068                variable,
3069                values,
3070            } => {
3071                write!(
3072                    f,
3073                    "SET {}{}{} = {}",
3074                    scope.map(|s| format!("{s}")).unwrap_or_default(),
3075                    if *hivevar { "HIVEVAR:" } else { "" },
3076                    variable,
3077                    display_comma_separated(values)
3078                )
3079            }
3080        }
3081    }
3082}
3083
3084/// A representation of a `WHEN` arm with all the identifiers catched and the statements to execute
3085/// for the arm.
3086///
3087/// Snowflake: <https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
3088/// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
3089#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3090#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3091#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3092pub struct ExceptionWhen {
3093    pub idents: Vec<Ident>,
3094    pub statements: Vec<Statement>,
3095}
3096
3097impl Display for ExceptionWhen {
3098    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3099        write!(
3100            f,
3101            "WHEN {idents} THEN",
3102            idents = display_separated(&self.idents, " OR ")
3103        )?;
3104
3105        if !self.statements.is_empty() {
3106            write!(f, " ")?;
3107            format_statement_list(f, &self.statements)?;
3108        }
3109
3110        Ok(())
3111    }
3112}
3113
3114/// ANALYZE TABLE statement (Hive-specific)
3115#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3116#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3117#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3118pub struct Analyze {
3119    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3120    pub table_name: ObjectName,
3121    pub partitions: Option<Vec<Expr>>,
3122    pub for_columns: bool,
3123    pub columns: Vec<Ident>,
3124    pub cache_metadata: bool,
3125    pub noscan: bool,
3126    pub compute_statistics: bool,
3127    pub has_table_keyword: bool,
3128}
3129
3130impl fmt::Display for Analyze {
3131    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3132        write!(
3133            f,
3134            "ANALYZE{}{table_name}",
3135            if self.has_table_keyword {
3136                " TABLE "
3137            } else {
3138                " "
3139            },
3140            table_name = self.table_name
3141        )?;
3142        if let Some(ref parts) = self.partitions {
3143            if !parts.is_empty() {
3144                write!(f, " PARTITION ({})", display_comma_separated(parts))?;
3145            }
3146        }
3147
3148        if self.compute_statistics {
3149            write!(f, " COMPUTE STATISTICS")?;
3150        }
3151        if self.noscan {
3152            write!(f, " NOSCAN")?;
3153        }
3154        if self.cache_metadata {
3155            write!(f, " CACHE METADATA")?;
3156        }
3157        if self.for_columns {
3158            write!(f, " FOR COLUMNS")?;
3159            if !self.columns.is_empty() {
3160                write!(f, " {}", display_comma_separated(&self.columns))?;
3161            }
3162        }
3163        Ok(())
3164    }
3165}
3166
3167/// A top-level statement (SELECT, INSERT, CREATE, etc.)
3168#[allow(clippy::large_enum_variant)]
3169#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3170#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3171#[cfg_attr(
3172    feature = "visitor",
3173    derive(Visit, VisitMut),
3174    visit(with = "visit_statement")
3175)]
3176pub enum Statement {
3177    /// ```sql
3178    /// ANALYZE
3179    /// ```
3180    /// Analyze (Hive)
3181    Analyze(Analyze),
3182    Set(Set),
3183    /// ```sql
3184    /// TRUNCATE
3185    /// ```
3186    /// Truncate (Hive)
3187    Truncate(Truncate),
3188    /// ```sql
3189    /// MSCK
3190    /// ```
3191    /// Msck (Hive)
3192    Msck(Msck),
3193    /// ```sql
3194    /// SELECT
3195    /// ```
3196    Query(Box<Query>),
3197    /// ```sql
3198    /// INSERT
3199    /// ```
3200    Insert(Insert),
3201    /// ```sql
3202    /// INSTALL
3203    /// ```
3204    Install {
3205        /// Only for DuckDB
3206        extension_name: Ident,
3207    },
3208    /// ```sql
3209    /// LOAD
3210    /// ```
3211    Load {
3212        /// Only for DuckDB
3213        extension_name: Ident,
3214    },
3215    // TODO: Support ROW FORMAT
3216    Directory {
3217        overwrite: bool,
3218        local: bool,
3219        path: String,
3220        file_format: Option<FileFormat>,
3221        source: Box<Query>,
3222    },
3223    /// A `CASE` statement.
3224    Case(CaseStatement),
3225    /// An `IF` statement.
3226    If(IfStatement),
3227    /// A `WHILE` statement.
3228    While(WhileStatement),
3229    /// A `RAISE` statement.
3230    Raise(RaiseStatement),
3231    /// ```sql
3232    /// CALL <function>
3233    /// ```
3234    Call(Function),
3235    /// ```sql
3236    /// COPY [TO | FROM] ...
3237    /// ```
3238    Copy {
3239        /// The source of 'COPY TO', or the target of 'COPY FROM'
3240        source: CopySource,
3241        /// If true, is a 'COPY TO' statement. If false is a 'COPY FROM'
3242        to: bool,
3243        /// The target of 'COPY TO', or the source of 'COPY FROM'
3244        target: CopyTarget,
3245        /// WITH options (from PostgreSQL version 9.0)
3246        options: Vec<CopyOption>,
3247        /// WITH options (before PostgreSQL version 9.0)
3248        legacy_options: Vec<CopyLegacyOption>,
3249        /// VALUES a vector of values to be copied
3250        values: Vec<Option<String>>,
3251    },
3252    /// ```sql
3253    /// COPY INTO <table> | <location>
3254    /// ```
3255    /// See:
3256    /// <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table>
3257    /// <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location>
3258    ///
3259    /// Copy Into syntax available for Snowflake is different than the one implemented in
3260    /// Postgres. Although they share common prefix, it is reasonable to implement them
3261    /// in different enums. This can be refactored later once custom dialects
3262    /// are allowed to have custom Statements.
3263    CopyIntoSnowflake {
3264        kind: CopyIntoSnowflakeKind,
3265        into: ObjectName,
3266        into_columns: Option<Vec<Ident>>,
3267        from_obj: Option<ObjectName>,
3268        from_obj_alias: Option<Ident>,
3269        stage_params: StageParamsObject,
3270        from_transformations: Option<Vec<StageLoadSelectItemKind>>,
3271        from_query: Option<Box<Query>>,
3272        files: Option<Vec<String>>,
3273        pattern: Option<String>,
3274        file_format: KeyValueOptions,
3275        copy_options: KeyValueOptions,
3276        validation_mode: Option<String>,
3277        partition: Option<Box<Expr>>,
3278    },
3279    /// ```sql
3280    /// OPEN cursor_name
3281    /// ```
3282    /// Opens a cursor.
3283    Open(OpenStatement),
3284    /// ```sql
3285    /// CLOSE
3286    /// ```
3287    /// Closes the portal underlying an open cursor.
3288    Close {
3289        /// Cursor name
3290        cursor: CloseCursor,
3291    },
3292    /// ```sql
3293    /// UPDATE
3294    /// ```
3295    Update(Update),
3296    /// ```sql
3297    /// DELETE
3298    /// ```
3299    Delete(Delete),
3300    /// ```sql
3301    /// CREATE VIEW
3302    /// ```
3303    CreateView(CreateView),
3304    /// ```sql
3305    /// CREATE TABLE
3306    /// ```
3307    CreateTable(CreateTable),
3308    /// ```sql
3309    /// CREATE VIRTUAL TABLE .. USING <module_name> (<module_args>)`
3310    /// ```
3311    /// Sqlite specific statement
3312    CreateVirtualTable {
3313        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3314        name: ObjectName,
3315        if_not_exists: bool,
3316        module_name: Ident,
3317        module_args: Vec<Ident>,
3318    },
3319    /// ```sql
3320    /// `CREATE INDEX`
3321    /// ```
3322    CreateIndex(CreateIndex),
3323    /// ```sql
3324    /// CREATE ROLE
3325    /// ```
3326    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createrole.html)
3327    CreateRole(CreateRole),
3328    /// ```sql
3329    /// CREATE SECRET
3330    /// ```
3331    /// See [DuckDB](https://duckdb.org/docs/sql/statements/create_secret.html)
3332    CreateSecret {
3333        or_replace: bool,
3334        temporary: Option<bool>,
3335        if_not_exists: bool,
3336        name: Option<Ident>,
3337        storage_specifier: Option<Ident>,
3338        secret_type: Ident,
3339        options: Vec<SecretOption>,
3340    },
3341    /// A `CREATE SERVER` statement.
3342    CreateServer(CreateServerStatement),
3343    /// ```sql
3344    /// CREATE POLICY
3345    /// ```
3346    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)
3347    CreatePolicy {
3348        name: Ident,
3349        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3350        table_name: ObjectName,
3351        policy_type: Option<CreatePolicyType>,
3352        command: Option<CreatePolicyCommand>,
3353        to: Option<Vec<Owner>>,
3354        using: Option<Expr>,
3355        with_check: Option<Expr>,
3356    },
3357    /// ```sql
3358    /// CREATE CONNECTOR
3359    /// ```
3360    /// See [Hive](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-CreateDataConnectorCreateConnector)
3361    CreateConnector(CreateConnector),
3362    /// ```sql
3363    /// CREATE OPERATOR
3364    /// ```
3365    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createoperator.html)
3366    CreateOperator(CreateOperator),
3367    /// ```sql
3368    /// CREATE OPERATOR FAMILY
3369    /// ```
3370    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopfamily.html)
3371    CreateOperatorFamily(CreateOperatorFamily),
3372    /// ```sql
3373    /// CREATE OPERATOR CLASS
3374    /// ```
3375    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopclass.html)
3376    CreateOperatorClass(CreateOperatorClass),
3377    /// ```sql
3378    /// ALTER TABLE
3379    /// ```
3380    AlterTable(AlterTable),
3381    /// ```sql
3382    /// ALTER SCHEMA
3383    /// ```
3384    /// See [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#alter_schema_collate_statement)
3385    AlterSchema(AlterSchema),
3386    /// ```sql
3387    /// ALTER INDEX
3388    /// ```
3389    AlterIndex {
3390        name: ObjectName,
3391        operation: AlterIndexOperation,
3392    },
3393    /// ```sql
3394    /// ALTER VIEW
3395    /// ```
3396    AlterView {
3397        /// View name
3398        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3399        name: ObjectName,
3400        columns: Vec<Ident>,
3401        query: Box<Query>,
3402        with_options: Vec<SqlOption>,
3403    },
3404    /// ```sql
3405    /// ALTER TYPE
3406    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-altertype.html)
3407    /// ```
3408    AlterType(AlterType),
3409    /// ```sql
3410    /// ALTER OPERATOR
3411    /// ```
3412    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteroperator.html)
3413    AlterOperator(AlterOperator),
3414    /// ```sql
3415    /// ALTER ROLE
3416    /// ```
3417    AlterRole {
3418        name: Ident,
3419        operation: AlterRoleOperation,
3420    },
3421    /// ```sql
3422    /// ALTER POLICY <NAME> ON <TABLE NAME> [<OPERATION>]
3423    /// ```
3424    /// (Postgresql-specific)
3425    AlterPolicy {
3426        name: Ident,
3427        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3428        table_name: ObjectName,
3429        operation: AlterPolicyOperation,
3430    },
3431    /// ```sql
3432    /// ALTER CONNECTOR connector_name SET DCPROPERTIES(property_name=property_value, ...);
3433    /// or
3434    /// ALTER CONNECTOR connector_name SET URL new_url;
3435    /// or
3436    /// ALTER CONNECTOR connector_name SET OWNER [USER|ROLE] user_or_role;
3437    /// ```
3438    /// (Hive-specific)
3439    AlterConnector {
3440        name: Ident,
3441        properties: Option<Vec<SqlOption>>,
3442        url: Option<String>,
3443        owner: Option<ddl::AlterConnectorOwner>,
3444    },
3445    /// ```sql
3446    /// ALTER SESSION SET sessionParam
3447    /// ALTER SESSION UNSET <param_name> [ , <param_name> , ... ]
3448    /// ```
3449    /// See <https://docs.snowflake.com/en/sql-reference/sql/alter-session>
3450    AlterSession {
3451        /// true is to set for the session parameters, false is to unset
3452        set: bool,
3453        /// The session parameters to set or unset
3454        session_params: KeyValueOptions,
3455    },
3456    /// ```sql
3457    /// ATTACH DATABASE 'path/to/file' AS alias
3458    /// ```
3459    /// (SQLite-specific)
3460    AttachDatabase {
3461        /// The name to bind to the newly attached database
3462        schema_name: Ident,
3463        /// An expression that indicates the path to the database file
3464        database_file_name: Expr,
3465        /// true if the syntax is 'ATTACH DATABASE', false if it's just 'ATTACH'
3466        database: bool,
3467    },
3468    /// (DuckDB-specific)
3469    /// ```sql
3470    /// ATTACH 'sqlite_file.db' AS sqlite_db (READ_ONLY, TYPE SQLITE);
3471    /// ```
3472    /// See <https://duckdb.org/docs/sql/statements/attach.html>
3473    AttachDuckDBDatabase {
3474        if_not_exists: bool,
3475        /// true if the syntax is 'ATTACH DATABASE', false if it's just 'ATTACH'
3476        database: bool,
3477        /// An expression that indicates the path to the database file
3478        database_path: Ident,
3479        database_alias: Option<Ident>,
3480        attach_options: Vec<AttachDuckDBDatabaseOption>,
3481    },
3482    /// (DuckDB-specific)
3483    /// ```sql
3484    /// DETACH db_alias;
3485    /// ```
3486    /// See <https://duckdb.org/docs/sql/statements/attach.html>
3487    DetachDuckDBDatabase {
3488        if_exists: bool,
3489        /// true if the syntax is 'DETACH DATABASE', false if it's just 'DETACH'
3490        database: bool,
3491        database_alias: Ident,
3492    },
3493    /// ```sql
3494    /// DROP [TABLE, VIEW, ...]
3495    /// ```
3496    Drop {
3497        /// The type of the object to drop: TABLE, VIEW, etc.
3498        object_type: ObjectType,
3499        /// An optional `IF EXISTS` clause. (Non-standard.)
3500        if_exists: bool,
3501        /// One or more objects to drop. (ANSI SQL requires exactly one.)
3502        names: Vec<ObjectName>,
3503        /// Whether `CASCADE` was specified. This will be `false` when
3504        /// `RESTRICT` or no drop behavior at all was specified.
3505        cascade: bool,
3506        /// Whether `RESTRICT` was specified. This will be `false` when
3507        /// `CASCADE` or no drop behavior at all was specified.
3508        restrict: bool,
3509        /// Hive allows you specify whether the table's stored data will be
3510        /// deleted along with the dropped table
3511        purge: bool,
3512        /// MySQL-specific "TEMPORARY" keyword
3513        temporary: bool,
3514        /// MySQL-specific drop index syntax, which requires table specification
3515        /// See <https://dev.mysql.com/doc/refman/8.4/en/drop-index.html>
3516        table: Option<ObjectName>,
3517    },
3518    /// ```sql
3519    /// DROP FUNCTION
3520    /// ```
3521    DropFunction(DropFunction),
3522    /// ```sql
3523    /// DROP DOMAIN
3524    /// ```
3525    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-dropdomain.html)
3526    ///
3527    /// DROP DOMAIN [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
3528    ///
3529    DropDomain(DropDomain),
3530    /// ```sql
3531    /// DROP PROCEDURE
3532    /// ```
3533    DropProcedure {
3534        if_exists: bool,
3535        /// One or more function to drop
3536        proc_desc: Vec<FunctionDesc>,
3537        /// `CASCADE` or `RESTRICT`
3538        drop_behavior: Option<DropBehavior>,
3539    },
3540    /// ```sql
3541    /// DROP SECRET
3542    /// ```
3543    DropSecret {
3544        if_exists: bool,
3545        temporary: Option<bool>,
3546        name: Ident,
3547        storage_specifier: Option<Ident>,
3548    },
3549    ///```sql
3550    /// DROP POLICY
3551    /// ```
3552    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-droppolicy.html)
3553    DropPolicy {
3554        if_exists: bool,
3555        name: Ident,
3556        table_name: ObjectName,
3557        drop_behavior: Option<DropBehavior>,
3558    },
3559    /// ```sql
3560    /// DROP CONNECTOR
3561    /// ```
3562    /// See [Hive](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-DropConnector)
3563    DropConnector {
3564        if_exists: bool,
3565        name: Ident,
3566    },
3567    /// ```sql
3568    /// DECLARE
3569    /// ```
3570    /// Declare Cursor Variables
3571    ///
3572    /// Note: this is a PostgreSQL-specific statement,
3573    /// but may also compatible with other SQL.
3574    Declare {
3575        stmts: Vec<Declare>,
3576    },
3577    /// ```sql
3578    /// CREATE EXTENSION [ IF NOT EXISTS ] extension_name
3579    ///     [ WITH ] [ SCHEMA schema_name ]
3580    ///              [ VERSION version ]
3581    ///              [ CASCADE ]
3582    /// ```
3583    ///
3584    /// Note: this is a PostgreSQL-specific statement,
3585    CreateExtension(CreateExtension),
3586    /// ```sql
3587    /// DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
3588    /// ```
3589    /// Note: this is a PostgreSQL-specific statement.
3590    /// <https://www.postgresql.org/docs/current/sql-dropextension.html>
3591    DropExtension(DropExtension),
3592    /// ```sql
3593    /// DROP OPERATOR [ IF EXISTS ] name ( { left_type | NONE } , right_type ) [, ...] [ CASCADE | RESTRICT ]
3594    /// ```
3595    /// Note: this is a PostgreSQL-specific statement.
3596    /// <https://www.postgresql.org/docs/current/sql-dropoperator.html>
3597    DropOperator(DropOperator),
3598    /// ```sql
3599    /// DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]
3600    /// ```
3601    /// Note: this is a PostgreSQL-specific statement.
3602    /// <https://www.postgresql.org/docs/current/sql-dropopfamily.html>
3603    DropOperatorFamily(DropOperatorFamily),
3604    /// ```sql
3605    /// DROP OPERATOR CLASS [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]
3606    /// ```
3607    /// Note: this is a PostgreSQL-specific statement.
3608    /// <https://www.postgresql.org/docs/current/sql-dropopclass.html>
3609    DropOperatorClass(DropOperatorClass),
3610    /// ```sql
3611    /// FETCH
3612    /// ```
3613    /// Retrieve rows from a query using a cursor
3614    ///
3615    /// Note: this is a PostgreSQL-specific statement,
3616    /// but may also compatible with other SQL.
3617    Fetch {
3618        /// Cursor name
3619        name: Ident,
3620        direction: FetchDirection,
3621        position: FetchPosition,
3622        /// Optional, It's possible to fetch rows form cursor to the table
3623        into: Option<ObjectName>,
3624    },
3625    /// ```sql
3626    /// FLUSH [NO_WRITE_TO_BINLOG | LOCAL] flush_option [, flush_option] ... | tables_option
3627    /// ```
3628    ///
3629    /// Note: this is a Mysql-specific statement,
3630    /// but may also compatible with other SQL.
3631    Flush {
3632        object_type: FlushType,
3633        location: Option<FlushLocation>,
3634        channel: Option<String>,
3635        read_lock: bool,
3636        export: bool,
3637        tables: Vec<ObjectName>,
3638    },
3639    /// ```sql
3640    /// DISCARD [ ALL | PLANS | SEQUENCES | TEMPORARY | TEMP ]
3641    /// ```
3642    ///
3643    /// Note: this is a PostgreSQL-specific statement,
3644    /// but may also compatible with other SQL.
3645    Discard {
3646        object_type: DiscardObject,
3647    },
3648    /// `SHOW FUNCTIONS`
3649    ///
3650    /// Note: this is a Presto-specific statement.
3651    ShowFunctions {
3652        filter: Option<ShowStatementFilter>,
3653    },
3654    /// ```sql
3655    /// SHOW <variable>
3656    /// ```
3657    ///
3658    /// Note: this is a PostgreSQL-specific statement.
3659    ShowVariable {
3660        variable: Vec<Ident>,
3661    },
3662    /// ```sql
3663    /// SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern' | WHERE expr]
3664    /// ```
3665    ///
3666    /// Note: this is a MySQL-specific statement.
3667    ShowStatus {
3668        filter: Option<ShowStatementFilter>,
3669        global: bool,
3670        session: bool,
3671    },
3672    /// ```sql
3673    /// SHOW VARIABLES
3674    /// ```
3675    ///
3676    /// Note: this is a MySQL-specific statement.
3677    ShowVariables {
3678        filter: Option<ShowStatementFilter>,
3679        global: bool,
3680        session: bool,
3681    },
3682    /// ```sql
3683    /// SHOW CREATE TABLE
3684    /// ```
3685    ///
3686    /// Note: this is a MySQL-specific statement.
3687    ShowCreate {
3688        obj_type: ShowCreateObject,
3689        obj_name: ObjectName,
3690    },
3691    /// ```sql
3692    /// SHOW COLUMNS
3693    /// ```
3694    ShowColumns {
3695        extended: bool,
3696        full: bool,
3697        show_options: ShowStatementOptions,
3698    },
3699    /// ```sql
3700    /// SHOW DATABASES
3701    /// ```
3702    ShowDatabases {
3703        terse: bool,
3704        history: bool,
3705        show_options: ShowStatementOptions,
3706    },
3707    /// ```sql
3708    /// SHOW SCHEMAS
3709    /// ```
3710    ShowSchemas {
3711        terse: bool,
3712        history: bool,
3713        show_options: ShowStatementOptions,
3714    },
3715    // ```sql
3716    // SHOW {CHARACTER SET | CHARSET}
3717    // ```
3718    // [MySQL]:
3719    // <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>
3720    ShowCharset(ShowCharset),
3721    /// ```sql
3722    /// SHOW OBJECTS LIKE 'line%' IN mydb.public
3723    /// ```
3724    /// Snowflake-specific statement
3725    /// <https://docs.snowflake.com/en/sql-reference/sql/show-objects>
3726    ShowObjects(ShowObjects),
3727    /// ```sql
3728    /// SHOW TABLES
3729    /// ```
3730    ShowTables {
3731        terse: bool,
3732        history: bool,
3733        extended: bool,
3734        full: bool,
3735        external: bool,
3736        show_options: ShowStatementOptions,
3737    },
3738    /// ```sql
3739    /// SHOW VIEWS
3740    /// ```
3741    ShowViews {
3742        terse: bool,
3743        materialized: bool,
3744        show_options: ShowStatementOptions,
3745    },
3746    /// ```sql
3747    /// SHOW COLLATION
3748    /// ```
3749    ///
3750    /// Note: this is a MySQL-specific statement.
3751    ShowCollation {
3752        filter: Option<ShowStatementFilter>,
3753    },
3754    /// ```sql
3755    /// `USE ...`
3756    /// ```
3757    Use(Use),
3758    /// ```sql
3759    /// START  [ TRANSACTION | WORK ] | START TRANSACTION } ...
3760    /// ```
3761    /// If `begin` is false.
3762    ///
3763    /// ```sql
3764    /// `BEGIN  [ TRANSACTION | WORK ] | START TRANSACTION } ...`
3765    /// ```
3766    /// If `begin` is true
3767    StartTransaction {
3768        modes: Vec<TransactionMode>,
3769        begin: bool,
3770        transaction: Option<BeginTransactionKind>,
3771        modifier: Option<TransactionModifier>,
3772        /// List of statements belonging to the `BEGIN` block.
3773        /// Example:
3774        /// ```sql
3775        /// BEGIN
3776        ///     SELECT 1;
3777        ///     SELECT 2;
3778        /// END;
3779        /// ```
3780        statements: Vec<Statement>,
3781        /// Exception handling with exception clauses.
3782        /// Example:
3783        /// ```sql
3784        /// EXCEPTION
3785        ///     WHEN EXCEPTION_1 THEN
3786        ///         SELECT 2;
3787        ///     WHEN EXCEPTION_2 OR EXCEPTION_3 THEN
3788        ///         SELECT 3;
3789        ///     WHEN OTHER THEN
3790        ///         SELECT 4;
3791        /// ```
3792        /// <https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
3793        /// <https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
3794        exception: Option<Vec<ExceptionWhen>>,
3795        /// TRUE if the statement has an `END` keyword.
3796        has_end_keyword: bool,
3797    },
3798    /// ```sql
3799    /// COMMENT ON ...
3800    /// ```
3801    ///
3802    /// Note: this is a PostgreSQL-specific statement.
3803    Comment {
3804        object_type: CommentObject,
3805        object_name: ObjectName,
3806        comment: Option<String>,
3807        /// An optional `IF EXISTS` clause. (Non-standard.)
3808        /// See <https://docs.snowflake.com/en/sql-reference/sql/comment>
3809        if_exists: bool,
3810    },
3811    /// ```sql
3812    /// COMMIT [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]
3813    /// ```
3814    /// If `end` is false
3815    ///
3816    /// ```sql
3817    /// END [ TRY | CATCH ]
3818    /// ```
3819    /// If `end` is true
3820    Commit {
3821        chain: bool,
3822        end: bool,
3823        modifier: Option<TransactionModifier>,
3824    },
3825    /// ```sql
3826    /// ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ] [ TO [ SAVEPOINT ] savepoint_name ]
3827    /// ```
3828    Rollback {
3829        chain: bool,
3830        savepoint: Option<Ident>,
3831    },
3832    /// ```sql
3833    /// CREATE SCHEMA
3834    /// ```
3835    CreateSchema {
3836        /// `<schema name> | AUTHORIZATION <schema authorization identifier>  | <schema name>  AUTHORIZATION <schema authorization identifier>`
3837        schema_name: SchemaName,
3838        if_not_exists: bool,
3839        /// Schema properties.
3840        ///
3841        /// ```sql
3842        /// CREATE SCHEMA myschema WITH (key1='value1');
3843        /// ```
3844        ///
3845        /// [Trino](https://trino.io/docs/current/sql/create-schema.html)
3846        with: Option<Vec<SqlOption>>,
3847        /// Schema options.
3848        ///
3849        /// ```sql
3850        /// CREATE SCHEMA myschema OPTIONS(key1='value1');
3851        /// ```
3852        ///
3853        /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_schema_statement)
3854        options: Option<Vec<SqlOption>>,
3855        /// Default collation specification for the schema.
3856        ///
3857        /// ```sql
3858        /// CREATE SCHEMA myschema DEFAULT COLLATE 'und:ci';
3859        /// ```
3860        ///
3861        /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_schema_statement)
3862        default_collate_spec: Option<Expr>,
3863        /// Clones a schema
3864        ///
3865        /// ```sql
3866        /// CREATE SCHEMA myschema CLONE otherschema
3867        /// ```
3868        ///
3869        /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-clone#databases-schemas)
3870        clone: Option<ObjectName>,
3871    },
3872    /// ```sql
3873    /// CREATE DATABASE
3874    /// ```
3875    /// See:
3876    /// <https://docs.snowflake.com/en/sql-reference/sql/create-database>
3877    CreateDatabase {
3878        db_name: ObjectName,
3879        if_not_exists: bool,
3880        location: Option<String>,
3881        managed_location: Option<String>,
3882        or_replace: bool,
3883        transient: bool,
3884        clone: Option<ObjectName>,
3885        data_retention_time_in_days: Option<u64>,
3886        max_data_extension_time_in_days: Option<u64>,
3887        external_volume: Option<String>,
3888        catalog: Option<String>,
3889        replace_invalid_characters: Option<bool>,
3890        default_ddl_collation: Option<String>,
3891        storage_serialization_policy: Option<StorageSerializationPolicy>,
3892        comment: Option<String>,
3893        catalog_sync: Option<String>,
3894        catalog_sync_namespace_mode: Option<CatalogSyncNamespaceMode>,
3895        catalog_sync_namespace_flatten_delimiter: Option<String>,
3896        with_tags: Option<Vec<Tag>>,
3897        with_contacts: Option<Vec<ContactEntry>>,
3898    },
3899    /// ```sql
3900    /// CREATE FUNCTION
3901    /// ```
3902    ///
3903    /// Supported variants:
3904    /// 1. [Hive](https://cwiki.apache.org/confluence/display/hive/languagemanual+ddl#LanguageManualDDL-Create/Drop/ReloadFunction)
3905    /// 2. [PostgreSQL](https://www.postgresql.org/docs/15/sql-createfunction.html)
3906    /// 3. [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_function_statement)
3907    /// 4. [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql)
3908    CreateFunction(CreateFunction),
3909    /// CREATE TRIGGER statement. See struct [CreateTrigger] for details.
3910    CreateTrigger(CreateTrigger),
3911    /// DROP TRIGGER statement. See struct [DropTrigger] for details.
3912    DropTrigger(DropTrigger),
3913    /// ```sql
3914    /// CREATE PROCEDURE
3915    /// ```
3916    CreateProcedure {
3917        or_alter: bool,
3918        name: ObjectName,
3919        params: Option<Vec<ProcedureParam>>,
3920        language: Option<Ident>,
3921        body: ConditionalStatements,
3922    },
3923    /// ```sql
3924    /// CREATE MACRO
3925    /// ```
3926    ///
3927    /// Supported variants:
3928    /// 1. [DuckDB](https://duckdb.org/docs/sql/statements/create_macro)
3929    CreateMacro {
3930        or_replace: bool,
3931        temporary: bool,
3932        name: ObjectName,
3933        args: Option<Vec<MacroArg>>,
3934        definition: MacroDefinition,
3935    },
3936    /// ```sql
3937    /// CREATE STAGE
3938    /// ```
3939    /// See <https://docs.snowflake.com/en/sql-reference/sql/create-stage>
3940    CreateStage {
3941        or_replace: bool,
3942        temporary: bool,
3943        if_not_exists: bool,
3944        name: ObjectName,
3945        stage_params: StageParamsObject,
3946        directory_table_params: KeyValueOptions,
3947        file_format: KeyValueOptions,
3948        copy_options: KeyValueOptions,
3949        comment: Option<String>,
3950    },
3951    /// ```sql
3952    /// ASSERT <condition> [AS <message>]
3953    /// ```
3954    Assert {
3955        condition: Expr,
3956        message: Option<Expr>,
3957    },
3958    /// ```sql
3959    /// GRANT privileges ON objects TO grantees
3960    /// ```
3961    Grant {
3962        privileges: Privileges,
3963        objects: Option<GrantObjects>,
3964        grantees: Vec<Grantee>,
3965        with_grant_option: bool,
3966        as_grantor: Option<Ident>,
3967        granted_by: Option<Ident>,
3968        current_grants: Option<CurrentGrantsKind>,
3969    },
3970    /// ```sql
3971    /// DENY privileges ON object TO grantees
3972    /// ```
3973    Deny(DenyStatement),
3974    /// ```sql
3975    /// REVOKE privileges ON objects FROM grantees
3976    /// ```
3977    Revoke {
3978        privileges: Privileges,
3979        objects: Option<GrantObjects>,
3980        grantees: Vec<Grantee>,
3981        granted_by: Option<Ident>,
3982        cascade: Option<CascadeOption>,
3983    },
3984    /// ```sql
3985    /// DEALLOCATE [ PREPARE ] { name | ALL }
3986    /// ```
3987    ///
3988    /// Note: this is a PostgreSQL-specific statement.
3989    Deallocate {
3990        name: Ident,
3991        prepare: bool,
3992    },
3993    /// ```sql
3994    /// An `EXECUTE` statement
3995    /// ```
3996    ///
3997    /// Postgres: <https://www.postgresql.org/docs/current/sql-execute.html>
3998    /// MSSQL: <https://learn.microsoft.com/en-us/sql/relational-databases/stored-procedures/execute-a-stored-procedure>
3999    /// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#execute_immediate>
4000    /// Snowflake: <https://docs.snowflake.com/en/sql-reference/sql/execute-immediate>
4001    Execute {
4002        name: Option<ObjectName>,
4003        parameters: Vec<Expr>,
4004        has_parentheses: bool,
4005        /// Is this an `EXECUTE IMMEDIATE`
4006        immediate: bool,
4007        into: Vec<Ident>,
4008        using: Vec<ExprWithAlias>,
4009        /// Whether the last parameter is the return value of the procedure
4010        /// MSSQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver17#output>
4011        output: bool,
4012        /// Whether to invoke the procedure with the default parameter values
4013        /// MSSQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver17#default>
4014        default: bool,
4015    },
4016    /// ```sql
4017    /// PREPARE name [ ( data_type [, ...] ) ] AS statement
4018    /// ```
4019    ///
4020    /// Note: this is a PostgreSQL-specific statement.
4021    Prepare {
4022        name: Ident,
4023        data_types: Vec<DataType>,
4024        statement: Box<Statement>,
4025    },
4026    /// ```sql
4027    /// KILL [CONNECTION | QUERY | MUTATION]
4028    /// ```
4029    ///
4030    /// See <https://clickhouse.com/docs/en/sql-reference/statements/kill/>
4031    /// See <https://dev.mysql.com/doc/refman/8.0/en/kill.html>
4032    Kill {
4033        modifier: Option<KillType>,
4034        // processlist_id
4035        id: u64,
4036    },
4037    /// ```sql
4038    /// [EXPLAIN | DESC | DESCRIBE] TABLE
4039    /// ```
4040    /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/explain.html>
4041    ExplainTable {
4042        /// `EXPLAIN | DESC | DESCRIBE`
4043        describe_alias: DescribeAlias,
4044        /// Hive style `FORMATTED | EXTENDED`
4045        hive_format: Option<HiveDescribeFormat>,
4046        /// Snowflake and ClickHouse support `DESC|DESCRIBE TABLE <table_name>` syntax
4047        ///
4048        /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/desc-table.html)
4049        /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/describe-table)
4050        has_table_keyword: bool,
4051        /// Table name
4052        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
4053        table_name: ObjectName,
4054    },
4055    /// ```sql
4056    /// [EXPLAIN | DESC | DESCRIBE]  <statement>
4057    /// ```
4058    Explain {
4059        /// `EXPLAIN | DESC | DESCRIBE`
4060        describe_alias: DescribeAlias,
4061        /// Carry out the command and show actual run times and other statistics.
4062        analyze: bool,
4063        // Display additional information regarding the plan.
4064        verbose: bool,
4065        /// `EXPLAIN QUERY PLAN`
4066        /// Display the query plan without running the query.
4067        ///
4068        /// [SQLite](https://sqlite.org/lang_explain.html)
4069        query_plan: bool,
4070        /// `EXPLAIN ESTIMATE`
4071        /// [Clickhouse](https://clickhouse.com/docs/en/sql-reference/statements/explain#explain-estimate)
4072        estimate: bool,
4073        /// A SQL query that specifies what to explain
4074        statement: Box<Statement>,
4075        /// Optional output format of explain
4076        format: Option<AnalyzeFormatKind>,
4077        /// Postgres style utility options, `(analyze, verbose true)`
4078        options: Option<Vec<UtilityOption>>,
4079    },
4080    /// ```sql
4081    /// SAVEPOINT
4082    /// ```
4083    /// Define a new savepoint within the current transaction
4084    Savepoint {
4085        name: Ident,
4086    },
4087    /// ```sql
4088    /// RELEASE [ SAVEPOINT ] savepoint_name
4089    /// ```
4090    ReleaseSavepoint {
4091        name: Ident,
4092    },
4093    /// A `MERGE` statement.
4094    ///
4095    /// ```sql
4096    /// MERGE INTO <target_table> USING <source> ON <join_expr> { matchedClause | notMatchedClause } [ ... ]
4097    /// ```
4098    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/merge)
4099    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
4100    /// [MSSQL](https://learn.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver16)
4101    Merge(Merge),
4102    /// ```sql
4103    /// CACHE [ FLAG ] TABLE <table_name> [ OPTIONS('K1' = 'V1', 'K2' = V2) ] [ AS ] [ <query> ]
4104    /// ```
4105    ///
4106    /// See [Spark SQL docs] for more details.
4107    ///
4108    /// [Spark SQL docs]: https://docs.databricks.com/spark/latest/spark-sql/language-manual/sql-ref-syntax-aux-cache-cache-table.html
4109    Cache {
4110        /// Table flag
4111        table_flag: Option<ObjectName>,
4112        /// Table name
4113        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
4114        table_name: ObjectName,
4115        has_as: bool,
4116        /// Table confs
4117        options: Vec<SqlOption>,
4118        /// Cache table as a Query
4119        query: Option<Box<Query>>,
4120    },
4121    /// ```sql
4122    /// UNCACHE TABLE [ IF EXISTS ]  <table_name>
4123    /// ```
4124    UNCache {
4125        /// Table name
4126        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
4127        table_name: ObjectName,
4128        if_exists: bool,
4129    },
4130    /// ```sql
4131    /// CREATE [ { TEMPORARY | TEMP } ] SEQUENCE [ IF NOT EXISTS ] <sequence_name>
4132    /// ```
4133    /// Define a new sequence:
4134    CreateSequence {
4135        temporary: bool,
4136        if_not_exists: bool,
4137        name: ObjectName,
4138        data_type: Option<DataType>,
4139        sequence_options: Vec<SequenceOptions>,
4140        owned_by: Option<ObjectName>,
4141    },
4142    /// A `CREATE DOMAIN` statement.
4143    CreateDomain(CreateDomain),
4144    /// ```sql
4145    /// CREATE TYPE <name>
4146    /// ```
4147    CreateType {
4148        name: ObjectName,
4149        representation: Option<UserDefinedTypeRepresentation>,
4150    },
4151    /// ```sql
4152    /// PRAGMA <schema-name>.<pragma-name> = <pragma-value>
4153    /// ```
4154    Pragma {
4155        name: ObjectName,
4156        value: Option<Value>,
4157        is_eq: bool,
4158    },
4159    /// ```sql
4160    /// LOCK TABLES <table_name> [READ [LOCAL] | [LOW_PRIORITY] WRITE]
4161    /// ```
4162    /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html>
4163    LockTables {
4164        tables: Vec<LockTable>,
4165    },
4166    /// ```sql
4167    /// UNLOCK TABLES
4168    /// ```
4169    /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html>
4170    UnlockTables,
4171    /// Unloads the result of a query to file
4172    ///
4173    /// [Athena](https://docs.aws.amazon.com/athena/latest/ug/unload.html):
4174    /// ```sql
4175    /// UNLOAD(statement) TO <destination> [ WITH options ]
4176    /// ```
4177    ///
4178    /// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD.html):
4179    /// ```sql
4180    /// UNLOAD('statement') TO <destination> [ OPTIONS ]
4181    /// ```
4182    Unload {
4183        query: Option<Box<Query>>,
4184        query_text: Option<String>,
4185        to: Ident,
4186        auth: Option<IamRoleKind>,
4187        with: Vec<SqlOption>,
4188        options: Vec<CopyLegacyOption>,
4189    },
4190    /// ```sql
4191    /// OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition | PARTITION ID 'partition_id'] [FINAL] [DEDUPLICATE [BY expression]]
4192    /// ```
4193    ///
4194    /// See ClickHouse <https://clickhouse.com/docs/en/sql-reference/statements/optimize>
4195    OptimizeTable {
4196        name: ObjectName,
4197        on_cluster: Option<Ident>,
4198        partition: Option<Partition>,
4199        include_final: bool,
4200        deduplicate: Option<Deduplicate>,
4201    },
4202    /// ```sql
4203    /// LISTEN
4204    /// ```
4205    /// listen for a notification channel
4206    ///
4207    /// See Postgres <https://www.postgresql.org/docs/current/sql-listen.html>
4208    LISTEN {
4209        channel: Ident,
4210    },
4211    /// ```sql
4212    /// UNLISTEN
4213    /// ```
4214    /// stop listening for a notification
4215    ///
4216    /// See Postgres <https://www.postgresql.org/docs/current/sql-unlisten.html>
4217    UNLISTEN {
4218        channel: Ident,
4219    },
4220    /// ```sql
4221    /// NOTIFY channel [ , payload ]
4222    /// ```
4223    /// send a notification event together with an optional "payload" string to channel
4224    ///
4225    /// See Postgres <https://www.postgresql.org/docs/current/sql-notify.html>
4226    NOTIFY {
4227        channel: Ident,
4228        payload: Option<String>,
4229    },
4230    /// ```sql
4231    /// LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename
4232    /// [PARTITION (partcol1=val1, partcol2=val2 ...)]
4233    /// [INPUTFORMAT 'inputformat' SERDE 'serde']
4234    /// ```
4235    /// Loading files into tables
4236    ///
4237    /// See Hive <https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362036#LanguageManualDML-Loadingfilesintotables>
4238    LoadData {
4239        local: bool,
4240        inpath: String,
4241        overwrite: bool,
4242        table_name: ObjectName,
4243        partitioned: Option<Vec<Expr>>,
4244        table_format: Option<HiveLoadDataFormat>,
4245    },
4246    /// ```sql
4247    /// Rename TABLE tbl_name TO new_tbl_name[, tbl_name2 TO new_tbl_name2] ...
4248    /// ```
4249    /// Renames one or more tables
4250    ///
4251    /// See Mysql <https://dev.mysql.com/doc/refman/9.1/en/rename-table.html>
4252    RenameTable(Vec<RenameTable>),
4253    /// Snowflake `LIST`
4254    /// See: <https://docs.snowflake.com/en/sql-reference/sql/list>
4255    List(FileStagingCommand),
4256    /// Snowflake `REMOVE`
4257    /// See: <https://docs.snowflake.com/en/sql-reference/sql/remove>
4258    Remove(FileStagingCommand),
4259    /// RaiseError (MSSQL)
4260    /// RAISERROR ( { msg_id | msg_str | @local_variable }
4261    /// { , severity , state }
4262    /// [ , argument [ , ...n ] ] )
4263    /// [ WITH option [ , ...n ] ]
4264    /// See <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/raiserror-transact-sql?view=sql-server-ver16>
4265    RaisError {
4266        message: Box<Expr>,
4267        severity: Box<Expr>,
4268        state: Box<Expr>,
4269        arguments: Vec<Expr>,
4270        options: Vec<RaisErrorOption>,
4271    },
4272    /// ```sql
4273    /// PRINT msg_str | @local_variable | string_expr
4274    /// ```
4275    ///
4276    /// See: <https://learn.microsoft.com/en-us/sql/t-sql/statements/print-transact-sql>
4277    Print(PrintStatement),
4278    /// ```sql
4279    /// RETURN [ expression ]
4280    /// ```
4281    ///
4282    /// See [ReturnStatement]
4283    Return(ReturnStatement),
4284    /// Export data statement
4285    ///
4286    /// Example:
4287    /// ```sql
4288    /// EXPORT DATA OPTIONS(uri='gs://bucket/folder/*', format='PARQUET', overwrite=true) AS
4289    /// SELECT field1, field2 FROM mydataset.table1 ORDER BY field1 LIMIT 10
4290    /// ```
4291    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/export-statements)
4292    ExportData(ExportData),
4293    /// ```sql
4294    /// CREATE [OR REPLACE] USER <user> [IF NOT EXISTS]
4295    /// ```
4296    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-user)
4297    CreateUser(CreateUser),
4298    /// ```sql
4299    /// ALTER USER \[ IF EXISTS \] \[ <name> \]
4300    /// ```
4301    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/alter-user)
4302    AlterUser(AlterUser),
4303    /// Re-sorts rows and reclaims space in either a specified table or all tables in the current database
4304    ///
4305    /// ```sql
4306    /// VACUUM tbl
4307    /// ```
4308    /// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)
4309    Vacuum(VacuumStatement),
4310    /// Restore the value of a run-time parameter to the default value.
4311    ///
4312    /// ```sql
4313    /// RESET configuration_parameter;
4314    /// RESET ALL;
4315    /// ```
4316    /// [PostgreSQL](https://www.postgresql.org/docs/current/sql-reset.html)
4317    Reset(ResetStatement),
4318}
4319
4320impl From<Analyze> for Statement {
4321    fn from(analyze: Analyze) -> Self {
4322        Statement::Analyze(analyze)
4323    }
4324}
4325
4326impl From<ddl::Truncate> for Statement {
4327    fn from(truncate: ddl::Truncate) -> Self {
4328        Statement::Truncate(truncate)
4329    }
4330}
4331
4332impl From<ddl::Msck> for Statement {
4333    fn from(msck: ddl::Msck) -> Self {
4334        Statement::Msck(msck)
4335    }
4336}
4337
4338/// ```sql
4339/// {COPY | REVOKE} CURRENT GRANTS
4340/// ```
4341///
4342/// - [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/grant-ownership#optional-parameters)
4343#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4344#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4345#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4346pub enum CurrentGrantsKind {
4347    CopyCurrentGrants,
4348    RevokeCurrentGrants,
4349}
4350
4351impl fmt::Display for CurrentGrantsKind {
4352    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4353        match self {
4354            CurrentGrantsKind::CopyCurrentGrants => write!(f, "COPY CURRENT GRANTS"),
4355            CurrentGrantsKind::RevokeCurrentGrants => write!(f, "REVOKE CURRENT GRANTS"),
4356        }
4357    }
4358}
4359
4360#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4361#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4362#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4363pub enum RaisErrorOption {
4364    Log,
4365    NoWait,
4366    SetError,
4367}
4368
4369impl fmt::Display for RaisErrorOption {
4370    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4371        match self {
4372            RaisErrorOption::Log => write!(f, "LOG"),
4373            RaisErrorOption::NoWait => write!(f, "NOWAIT"),
4374            RaisErrorOption::SetError => write!(f, "SETERROR"),
4375        }
4376    }
4377}
4378
4379impl fmt::Display for Statement {
4380    /// Formats a SQL statement with support for pretty printing.
4381    ///
4382    /// When using the alternate flag (`{:#}`), the statement will be formatted with proper
4383    /// indentation and line breaks. For example:
4384    ///
4385    /// ```
4386    /// # use sqlparser::dialect::GenericDialect;
4387    /// # use sqlparser::parser::Parser;
4388    /// let sql = "SELECT a, b FROM table_1";
4389    /// let ast = Parser::parse_sql(&GenericDialect, sql).unwrap();
4390    ///
4391    /// // Regular formatting
4392    /// assert_eq!(format!("{}", ast[0]), "SELECT a, b FROM table_1");
4393    ///
4394    /// // Pretty printing
4395    /// assert_eq!(format!("{:#}", ast[0]),
4396    /// r#"SELECT
4397    ///   a,
4398    ///   b
4399    /// FROM
4400    ///   table_1"#);
4401    /// ```
4402    // Clippy thinks this function is too complicated, but it is painful to
4403    // split up without extracting structs for each `Statement` variant.
4404    #[allow(clippy::cognitive_complexity)]
4405    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4406        match self {
4407            Statement::Flush {
4408                object_type,
4409                location,
4410                channel,
4411                read_lock,
4412                export,
4413                tables,
4414            } => {
4415                write!(f, "FLUSH")?;
4416                if let Some(location) = location {
4417                    f.write_str(" ")?;
4418                    location.fmt(f)?;
4419                }
4420                write!(f, " {object_type}")?;
4421
4422                if let Some(channel) = channel {
4423                    write!(f, " FOR CHANNEL {channel}")?;
4424                }
4425
4426                write!(
4427                    f,
4428                    "{tables}{read}{export}",
4429                    tables = if !tables.is_empty() {
4430                        " ".to_string() + &display_comma_separated(tables).to_string()
4431                    } else {
4432                        "".to_string()
4433                    },
4434                    export = if *export { " FOR EXPORT" } else { "" },
4435                    read = if *read_lock { " WITH READ LOCK" } else { "" }
4436                )
4437            }
4438            Statement::Kill { modifier, id } => {
4439                write!(f, "KILL ")?;
4440
4441                if let Some(m) = modifier {
4442                    write!(f, "{m} ")?;
4443                }
4444
4445                write!(f, "{id}")
4446            }
4447            Statement::ExplainTable {
4448                describe_alias,
4449                hive_format,
4450                has_table_keyword,
4451                table_name,
4452            } => {
4453                write!(f, "{describe_alias} ")?;
4454
4455                if let Some(format) = hive_format {
4456                    write!(f, "{format} ")?;
4457                }
4458                if *has_table_keyword {
4459                    write!(f, "TABLE ")?;
4460                }
4461
4462                write!(f, "{table_name}")
4463            }
4464            Statement::Explain {
4465                describe_alias,
4466                verbose,
4467                analyze,
4468                query_plan,
4469                estimate,
4470                statement,
4471                format,
4472                options,
4473            } => {
4474                write!(f, "{describe_alias} ")?;
4475
4476                if *query_plan {
4477                    write!(f, "QUERY PLAN ")?;
4478                }
4479                if *analyze {
4480                    write!(f, "ANALYZE ")?;
4481                }
4482                if *estimate {
4483                    write!(f, "ESTIMATE ")?;
4484                }
4485
4486                if *verbose {
4487                    write!(f, "VERBOSE ")?;
4488                }
4489
4490                if let Some(format) = format {
4491                    write!(f, "{format} ")?;
4492                }
4493
4494                if let Some(options) = options {
4495                    write!(f, "({}) ", display_comma_separated(options))?;
4496                }
4497
4498                write!(f, "{statement}")
4499            }
4500            Statement::Query(s) => s.fmt(f),
4501            Statement::Declare { stmts } => {
4502                write!(f, "DECLARE ")?;
4503                write!(f, "{}", display_separated(stmts, "; "))
4504            }
4505            Statement::Fetch {
4506                name,
4507                direction,
4508                position,
4509                into,
4510            } => {
4511                write!(f, "FETCH {direction} {position} {name}")?;
4512
4513                if let Some(into) = into {
4514                    write!(f, " INTO {into}")?;
4515                }
4516
4517                Ok(())
4518            }
4519            Statement::Directory {
4520                overwrite,
4521                local,
4522                path,
4523                file_format,
4524                source,
4525            } => {
4526                write!(
4527                    f,
4528                    "INSERT{overwrite}{local} DIRECTORY '{path}'",
4529                    overwrite = if *overwrite { " OVERWRITE" } else { "" },
4530                    local = if *local { " LOCAL" } else { "" },
4531                    path = path
4532                )?;
4533                if let Some(ref ff) = file_format {
4534                    write!(f, " STORED AS {ff}")?
4535                }
4536                write!(f, " {source}")
4537            }
4538            Statement::Msck(msck) => msck.fmt(f),
4539            Statement::Truncate(truncate) => truncate.fmt(f),
4540            Statement::Case(stmt) => {
4541                write!(f, "{stmt}")
4542            }
4543            Statement::If(stmt) => {
4544                write!(f, "{stmt}")
4545            }
4546            Statement::While(stmt) => {
4547                write!(f, "{stmt}")
4548            }
4549            Statement::Raise(stmt) => {
4550                write!(f, "{stmt}")
4551            }
4552            Statement::AttachDatabase {
4553                schema_name,
4554                database_file_name,
4555                database,
4556            } => {
4557                let keyword = if *database { "DATABASE " } else { "" };
4558                write!(f, "ATTACH {keyword}{database_file_name} AS {schema_name}")
4559            }
4560            Statement::AttachDuckDBDatabase {
4561                if_not_exists,
4562                database,
4563                database_path,
4564                database_alias,
4565                attach_options,
4566            } => {
4567                write!(
4568                    f,
4569                    "ATTACH{database}{if_not_exists} {database_path}",
4570                    database = if *database { " DATABASE" } else { "" },
4571                    if_not_exists = if *if_not_exists { " IF NOT EXISTS" } else { "" },
4572                )?;
4573                if let Some(alias) = database_alias {
4574                    write!(f, " AS {alias}")?;
4575                }
4576                if !attach_options.is_empty() {
4577                    write!(f, " ({})", display_comma_separated(attach_options))?;
4578                }
4579                Ok(())
4580            }
4581            Statement::DetachDuckDBDatabase {
4582                if_exists,
4583                database,
4584                database_alias,
4585            } => {
4586                write!(
4587                    f,
4588                    "DETACH{database}{if_exists} {database_alias}",
4589                    database = if *database { " DATABASE" } else { "" },
4590                    if_exists = if *if_exists { " IF EXISTS" } else { "" },
4591                )?;
4592                Ok(())
4593            }
4594            Statement::Analyze(analyze) => analyze.fmt(f),
4595            Statement::Insert(insert) => insert.fmt(f),
4596            Statement::Install {
4597                extension_name: name,
4598            } => write!(f, "INSTALL {name}"),
4599
4600            Statement::Load {
4601                extension_name: name,
4602            } => write!(f, "LOAD {name}"),
4603
4604            Statement::Call(function) => write!(f, "CALL {function}"),
4605
4606            Statement::Copy {
4607                source,
4608                to,
4609                target,
4610                options,
4611                legacy_options,
4612                values,
4613            } => {
4614                write!(f, "COPY")?;
4615                match source {
4616                    CopySource::Query(query) => write!(f, " ({query})")?,
4617                    CopySource::Table {
4618                        table_name,
4619                        columns,
4620                    } => {
4621                        write!(f, " {table_name}")?;
4622                        if !columns.is_empty() {
4623                            write!(f, " ({})", display_comma_separated(columns))?;
4624                        }
4625                    }
4626                }
4627                write!(f, " {} {}", if *to { "TO" } else { "FROM" }, target)?;
4628                if !options.is_empty() {
4629                    write!(f, " ({})", display_comma_separated(options))?;
4630                }
4631                if !legacy_options.is_empty() {
4632                    write!(f, " {}", display_separated(legacy_options, " "))?;
4633                }
4634                if !values.is_empty() {
4635                    writeln!(f, ";")?;
4636                    let mut delim = "";
4637                    for v in values {
4638                        write!(f, "{delim}")?;
4639                        delim = "\t";
4640                        if let Some(v) = v {
4641                            write!(f, "{v}")?;
4642                        } else {
4643                            write!(f, "\\N")?;
4644                        }
4645                    }
4646                    write!(f, "\n\\.")?;
4647                }
4648                Ok(())
4649            }
4650            Statement::Update(update) => update.fmt(f),
4651            Statement::Delete(delete) => delete.fmt(f),
4652            Statement::Open(open) => open.fmt(f),
4653            Statement::Close { cursor } => {
4654                write!(f, "CLOSE {cursor}")?;
4655
4656                Ok(())
4657            }
4658            Statement::CreateDatabase {
4659                db_name,
4660                if_not_exists,
4661                location,
4662                managed_location,
4663                or_replace,
4664                transient,
4665                clone,
4666                data_retention_time_in_days,
4667                max_data_extension_time_in_days,
4668                external_volume,
4669                catalog,
4670                replace_invalid_characters,
4671                default_ddl_collation,
4672                storage_serialization_policy,
4673                comment,
4674                catalog_sync,
4675                catalog_sync_namespace_mode,
4676                catalog_sync_namespace_flatten_delimiter,
4677                with_tags,
4678                with_contacts,
4679            } => {
4680                write!(
4681                    f,
4682                    "CREATE {or_replace}{transient}DATABASE {if_not_exists}{name}",
4683                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
4684                    transient = if *transient { "TRANSIENT " } else { "" },
4685                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
4686                    name = db_name,
4687                )?;
4688
4689                if let Some(l) = location {
4690                    write!(f, " LOCATION '{l}'")?;
4691                }
4692                if let Some(ml) = managed_location {
4693                    write!(f, " MANAGEDLOCATION '{ml}'")?;
4694                }
4695                if let Some(clone) = clone {
4696                    write!(f, " CLONE {clone}")?;
4697                }
4698
4699                if let Some(value) = data_retention_time_in_days {
4700                    write!(f, " DATA_RETENTION_TIME_IN_DAYS = {value}")?;
4701                }
4702
4703                if let Some(value) = max_data_extension_time_in_days {
4704                    write!(f, " MAX_DATA_EXTENSION_TIME_IN_DAYS = {value}")?;
4705                }
4706
4707                if let Some(vol) = external_volume {
4708                    write!(f, " EXTERNAL_VOLUME = '{vol}'")?;
4709                }
4710
4711                if let Some(cat) = catalog {
4712                    write!(f, " CATALOG = '{cat}'")?;
4713                }
4714
4715                if let Some(true) = replace_invalid_characters {
4716                    write!(f, " REPLACE_INVALID_CHARACTERS = TRUE")?;
4717                } else if let Some(false) = replace_invalid_characters {
4718                    write!(f, " REPLACE_INVALID_CHARACTERS = FALSE")?;
4719                }
4720
4721                if let Some(collation) = default_ddl_collation {
4722                    write!(f, " DEFAULT_DDL_COLLATION = '{collation}'")?;
4723                }
4724
4725                if let Some(policy) = storage_serialization_policy {
4726                    write!(f, " STORAGE_SERIALIZATION_POLICY = {policy}")?;
4727                }
4728
4729                if let Some(comment) = comment {
4730                    write!(f, " COMMENT = '{comment}'")?;
4731                }
4732
4733                if let Some(sync) = catalog_sync {
4734                    write!(f, " CATALOG_SYNC = '{sync}'")?;
4735                }
4736
4737                if let Some(mode) = catalog_sync_namespace_mode {
4738                    write!(f, " CATALOG_SYNC_NAMESPACE_MODE = {mode}")?;
4739                }
4740
4741                if let Some(delim) = catalog_sync_namespace_flatten_delimiter {
4742                    write!(f, " CATALOG_SYNC_NAMESPACE_FLATTEN_DELIMITER = '{delim}'")?;
4743                }
4744
4745                if let Some(tags) = with_tags {
4746                    write!(f, " WITH TAG ({})", display_comma_separated(tags))?;
4747                }
4748
4749                if let Some(contacts) = with_contacts {
4750                    write!(f, " WITH CONTACT ({})", display_comma_separated(contacts))?;
4751                }
4752                Ok(())
4753            }
4754            Statement::CreateFunction(create_function) => create_function.fmt(f),
4755            Statement::CreateDomain(create_domain) => create_domain.fmt(f),
4756            Statement::CreateTrigger(create_trigger) => create_trigger.fmt(f),
4757            Statement::DropTrigger(drop_trigger) => drop_trigger.fmt(f),
4758            Statement::CreateProcedure {
4759                name,
4760                or_alter,
4761                params,
4762                language,
4763                body,
4764            } => {
4765                write!(
4766                    f,
4767                    "CREATE {or_alter}PROCEDURE {name}",
4768                    or_alter = if *or_alter { "OR ALTER " } else { "" },
4769                    name = name
4770                )?;
4771
4772                if let Some(p) = params {
4773                    if !p.is_empty() {
4774                        write!(f, " ({})", display_comma_separated(p))?;
4775                    }
4776                }
4777
4778                if let Some(language) = language {
4779                    write!(f, " LANGUAGE {language}")?;
4780                }
4781
4782                write!(f, " AS {body}")
4783            }
4784            Statement::CreateMacro {
4785                or_replace,
4786                temporary,
4787                name,
4788                args,
4789                definition,
4790            } => {
4791                write!(
4792                    f,
4793                    "CREATE {or_replace}{temp}MACRO {name}",
4794                    temp = if *temporary { "TEMPORARY " } else { "" },
4795                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
4796                )?;
4797                if let Some(args) = args {
4798                    write!(f, "({})", display_comma_separated(args))?;
4799                }
4800                match definition {
4801                    MacroDefinition::Expr(expr) => write!(f, " AS {expr}")?,
4802                    MacroDefinition::Table(query) => write!(f, " AS TABLE {query}")?,
4803                }
4804                Ok(())
4805            }
4806            Statement::CreateView(create_view) => create_view.fmt(f),
4807            Statement::CreateTable(create_table) => create_table.fmt(f),
4808            Statement::LoadData {
4809                local,
4810                inpath,
4811                overwrite,
4812                table_name,
4813                partitioned,
4814                table_format,
4815            } => {
4816                write!(
4817                    f,
4818                    "LOAD DATA {local}INPATH '{inpath}' {overwrite}INTO TABLE {table_name}",
4819                    local = if *local { "LOCAL " } else { "" },
4820                    inpath = inpath,
4821                    overwrite = if *overwrite { "OVERWRITE " } else { "" },
4822                    table_name = table_name,
4823                )?;
4824                if let Some(ref parts) = &partitioned {
4825                    if !parts.is_empty() {
4826                        write!(f, " PARTITION ({})", display_comma_separated(parts))?;
4827                    }
4828                }
4829                if let Some(HiveLoadDataFormat {
4830                    serde,
4831                    input_format,
4832                }) = &table_format
4833                {
4834                    write!(f, " INPUTFORMAT {input_format} SERDE {serde}")?;
4835                }
4836                Ok(())
4837            }
4838            Statement::CreateVirtualTable {
4839                name,
4840                if_not_exists,
4841                module_name,
4842                module_args,
4843            } => {
4844                write!(
4845                    f,
4846                    "CREATE VIRTUAL TABLE {if_not_exists}{name} USING {module_name}",
4847                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
4848                    name = name,
4849                    module_name = module_name
4850                )?;
4851                if !module_args.is_empty() {
4852                    write!(f, " ({})", display_comma_separated(module_args))?;
4853                }
4854                Ok(())
4855            }
4856            Statement::CreateIndex(create_index) => create_index.fmt(f),
4857            Statement::CreateExtension(create_extension) => write!(f, "{create_extension}"),
4858            Statement::DropExtension(drop_extension) => write!(f, "{drop_extension}"),
4859            Statement::DropOperator(drop_operator) => write!(f, "{drop_operator}"),
4860            Statement::DropOperatorFamily(drop_operator_family) => {
4861                write!(f, "{drop_operator_family}")
4862            }
4863            Statement::DropOperatorClass(drop_operator_class) => {
4864                write!(f, "{drop_operator_class}")
4865            }
4866            Statement::CreateRole(create_role) => write!(f, "{create_role}"),
4867            Statement::CreateSecret {
4868                or_replace,
4869                temporary,
4870                if_not_exists,
4871                name,
4872                storage_specifier,
4873                secret_type,
4874                options,
4875            } => {
4876                write!(
4877                    f,
4878                    "CREATE {or_replace}",
4879                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
4880                )?;
4881                if let Some(t) = temporary {
4882                    write!(f, "{}", if *t { "TEMPORARY " } else { "PERSISTENT " })?;
4883                }
4884                write!(
4885                    f,
4886                    "SECRET {if_not_exists}",
4887                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
4888                )?;
4889                if let Some(n) = name {
4890                    write!(f, "{n} ")?;
4891                };
4892                if let Some(s) = storage_specifier {
4893                    write!(f, "IN {s} ")?;
4894                }
4895                write!(f, "( TYPE {secret_type}",)?;
4896                if !options.is_empty() {
4897                    write!(f, ", {o}", o = display_comma_separated(options))?;
4898                }
4899                write!(f, " )")?;
4900                Ok(())
4901            }
4902            Statement::CreateServer(stmt) => {
4903                write!(f, "{stmt}")
4904            }
4905            Statement::CreatePolicy {
4906                name,
4907                table_name,
4908                policy_type,
4909                command,
4910                to,
4911                using,
4912                with_check,
4913            } => {
4914                write!(f, "CREATE POLICY {name} ON {table_name}")?;
4915
4916                if let Some(policy_type) = policy_type {
4917                    match policy_type {
4918                        CreatePolicyType::Permissive => write!(f, " AS PERMISSIVE")?,
4919                        CreatePolicyType::Restrictive => write!(f, " AS RESTRICTIVE")?,
4920                    }
4921                }
4922
4923                if let Some(command) = command {
4924                    match command {
4925                        CreatePolicyCommand::All => write!(f, " FOR ALL")?,
4926                        CreatePolicyCommand::Select => write!(f, " FOR SELECT")?,
4927                        CreatePolicyCommand::Insert => write!(f, " FOR INSERT")?,
4928                        CreatePolicyCommand::Update => write!(f, " FOR UPDATE")?,
4929                        CreatePolicyCommand::Delete => write!(f, " FOR DELETE")?,
4930                    }
4931                }
4932
4933                if let Some(to) = to {
4934                    write!(f, " TO {}", display_comma_separated(to))?;
4935                }
4936
4937                if let Some(using) = using {
4938                    write!(f, " USING ({using})")?;
4939                }
4940
4941                if let Some(with_check) = with_check {
4942                    write!(f, " WITH CHECK ({with_check})")?;
4943                }
4944
4945                Ok(())
4946            }
4947            Statement::CreateConnector(create_connector) => create_connector.fmt(f),
4948            Statement::CreateOperator(create_operator) => create_operator.fmt(f),
4949            Statement::CreateOperatorFamily(create_operator_family) => {
4950                create_operator_family.fmt(f)
4951            }
4952            Statement::CreateOperatorClass(create_operator_class) => create_operator_class.fmt(f),
4953            Statement::AlterTable(alter_table) => write!(f, "{alter_table}"),
4954            Statement::AlterIndex { name, operation } => {
4955                write!(f, "ALTER INDEX {name} {operation}")
4956            }
4957            Statement::AlterView {
4958                name,
4959                columns,
4960                query,
4961                with_options,
4962            } => {
4963                write!(f, "ALTER VIEW {name}")?;
4964                if !with_options.is_empty() {
4965                    write!(f, " WITH ({})", display_comma_separated(with_options))?;
4966                }
4967                if !columns.is_empty() {
4968                    write!(f, " ({})", display_comma_separated(columns))?;
4969                }
4970                write!(f, " AS {query}")
4971            }
4972            Statement::AlterType(AlterType { name, operation }) => {
4973                write!(f, "ALTER TYPE {name} {operation}")
4974            }
4975            Statement::AlterOperator(alter_operator) => write!(f, "{alter_operator}"),
4976            Statement::AlterRole { name, operation } => {
4977                write!(f, "ALTER ROLE {name} {operation}")
4978            }
4979            Statement::AlterPolicy {
4980                name,
4981                table_name,
4982                operation,
4983            } => {
4984                write!(f, "ALTER POLICY {name} ON {table_name}{operation}")
4985            }
4986            Statement::AlterConnector {
4987                name,
4988                properties,
4989                url,
4990                owner,
4991            } => {
4992                write!(f, "ALTER CONNECTOR {name}")?;
4993                if let Some(properties) = properties {
4994                    write!(
4995                        f,
4996                        " SET DCPROPERTIES({})",
4997                        display_comma_separated(properties)
4998                    )?;
4999                }
5000                if let Some(url) = url {
5001                    write!(f, " SET URL '{url}'")?;
5002                }
5003                if let Some(owner) = owner {
5004                    write!(f, " SET OWNER {owner}")?;
5005                }
5006                Ok(())
5007            }
5008            Statement::AlterSession {
5009                set,
5010                session_params,
5011            } => {
5012                write!(
5013                    f,
5014                    "ALTER SESSION {set}",
5015                    set = if *set { "SET" } else { "UNSET" }
5016                )?;
5017                if !session_params.options.is_empty() {
5018                    if *set {
5019                        write!(f, " {session_params}")?;
5020                    } else {
5021                        let options = session_params
5022                            .options
5023                            .iter()
5024                            .map(|p| p.option_name.clone())
5025                            .collect::<Vec<_>>();
5026                        write!(f, " {}", display_separated(&options, ", "))?;
5027                    }
5028                }
5029                Ok(())
5030            }
5031            Statement::Drop {
5032                object_type,
5033                if_exists,
5034                names,
5035                cascade,
5036                restrict,
5037                purge,
5038                temporary,
5039                table,
5040            } => {
5041                write!(
5042                    f,
5043                    "DROP {}{}{} {}{}{}{}",
5044                    if *temporary { "TEMPORARY " } else { "" },
5045                    object_type,
5046                    if *if_exists { " IF EXISTS" } else { "" },
5047                    display_comma_separated(names),
5048                    if *cascade { " CASCADE" } else { "" },
5049                    if *restrict { " RESTRICT" } else { "" },
5050                    if *purge { " PURGE" } else { "" },
5051                )?;
5052                if let Some(table_name) = table.as_ref() {
5053                    write!(f, " ON {table_name}")?;
5054                };
5055                Ok(())
5056            }
5057            Statement::DropFunction(drop_function) => write!(f, "{drop_function}"),
5058            Statement::DropDomain(DropDomain {
5059                if_exists,
5060                name,
5061                drop_behavior,
5062            }) => {
5063                write!(
5064                    f,
5065                    "DROP DOMAIN{} {name}",
5066                    if *if_exists { " IF EXISTS" } else { "" },
5067                )?;
5068                if let Some(op) = drop_behavior {
5069                    write!(f, " {op}")?;
5070                }
5071                Ok(())
5072            }
5073            Statement::DropProcedure {
5074                if_exists,
5075                proc_desc,
5076                drop_behavior,
5077            } => {
5078                write!(
5079                    f,
5080                    "DROP PROCEDURE{} {}",
5081                    if *if_exists { " IF EXISTS" } else { "" },
5082                    display_comma_separated(proc_desc),
5083                )?;
5084                if let Some(op) = drop_behavior {
5085                    write!(f, " {op}")?;
5086                }
5087                Ok(())
5088            }
5089            Statement::DropSecret {
5090                if_exists,
5091                temporary,
5092                name,
5093                storage_specifier,
5094            } => {
5095                write!(f, "DROP ")?;
5096                if let Some(t) = temporary {
5097                    write!(f, "{}", if *t { "TEMPORARY " } else { "PERSISTENT " })?;
5098                }
5099                write!(
5100                    f,
5101                    "SECRET {if_exists}{name}",
5102                    if_exists = if *if_exists { "IF EXISTS " } else { "" },
5103                )?;
5104                if let Some(s) = storage_specifier {
5105                    write!(f, " FROM {s}")?;
5106                }
5107                Ok(())
5108            }
5109            Statement::DropPolicy {
5110                if_exists,
5111                name,
5112                table_name,
5113                drop_behavior,
5114            } => {
5115                write!(f, "DROP POLICY")?;
5116                if *if_exists {
5117                    write!(f, " IF EXISTS")?;
5118                }
5119                write!(f, " {name} ON {table_name}")?;
5120                if let Some(drop_behavior) = drop_behavior {
5121                    write!(f, " {drop_behavior}")?;
5122                }
5123                Ok(())
5124            }
5125            Statement::DropConnector { if_exists, name } => {
5126                write!(
5127                    f,
5128                    "DROP CONNECTOR {if_exists}{name}",
5129                    if_exists = if *if_exists { "IF EXISTS " } else { "" }
5130                )?;
5131                Ok(())
5132            }
5133            Statement::Discard { object_type } => {
5134                write!(f, "DISCARD {object_type}")?;
5135                Ok(())
5136            }
5137            Self::Set(set) => write!(f, "{set}"),
5138            Statement::ShowVariable { variable } => {
5139                write!(f, "SHOW")?;
5140                if !variable.is_empty() {
5141                    write!(f, " {}", display_separated(variable, " "))?;
5142                }
5143                Ok(())
5144            }
5145            Statement::ShowStatus {
5146                filter,
5147                global,
5148                session,
5149            } => {
5150                write!(f, "SHOW")?;
5151                if *global {
5152                    write!(f, " GLOBAL")?;
5153                }
5154                if *session {
5155                    write!(f, " SESSION")?;
5156                }
5157                write!(f, " STATUS")?;
5158                if filter.is_some() {
5159                    write!(f, " {}", filter.as_ref().unwrap())?;
5160                }
5161                Ok(())
5162            }
5163            Statement::ShowVariables {
5164                filter,
5165                global,
5166                session,
5167            } => {
5168                write!(f, "SHOW")?;
5169                if *global {
5170                    write!(f, " GLOBAL")?;
5171                }
5172                if *session {
5173                    write!(f, " SESSION")?;
5174                }
5175                write!(f, " VARIABLES")?;
5176                if filter.is_some() {
5177                    write!(f, " {}", filter.as_ref().unwrap())?;
5178                }
5179                Ok(())
5180            }
5181            Statement::ShowCreate { obj_type, obj_name } => {
5182                write!(f, "SHOW CREATE {obj_type} {obj_name}",)?;
5183                Ok(())
5184            }
5185            Statement::ShowColumns {
5186                extended,
5187                full,
5188                show_options,
5189            } => {
5190                write!(
5191                    f,
5192                    "SHOW {extended}{full}COLUMNS{show_options}",
5193                    extended = if *extended { "EXTENDED " } else { "" },
5194                    full = if *full { "FULL " } else { "" },
5195                )?;
5196                Ok(())
5197            }
5198            Statement::ShowDatabases {
5199                terse,
5200                history,
5201                show_options,
5202            } => {
5203                write!(
5204                    f,
5205                    "SHOW {terse}DATABASES{history}{show_options}",
5206                    terse = if *terse { "TERSE " } else { "" },
5207                    history = if *history { " HISTORY" } else { "" },
5208                )?;
5209                Ok(())
5210            }
5211            Statement::ShowSchemas {
5212                terse,
5213                history,
5214                show_options,
5215            } => {
5216                write!(
5217                    f,
5218                    "SHOW {terse}SCHEMAS{history}{show_options}",
5219                    terse = if *terse { "TERSE " } else { "" },
5220                    history = if *history { " HISTORY" } else { "" },
5221                )?;
5222                Ok(())
5223            }
5224            Statement::ShowObjects(ShowObjects {
5225                terse,
5226                show_options,
5227            }) => {
5228                write!(
5229                    f,
5230                    "SHOW {terse}OBJECTS{show_options}",
5231                    terse = if *terse { "TERSE " } else { "" },
5232                )?;
5233                Ok(())
5234            }
5235            Statement::ShowTables {
5236                terse,
5237                history,
5238                extended,
5239                full,
5240                external,
5241                show_options,
5242            } => {
5243                write!(
5244                    f,
5245                    "SHOW {terse}{extended}{full}{external}TABLES{history}{show_options}",
5246                    terse = if *terse { "TERSE " } else { "" },
5247                    extended = if *extended { "EXTENDED " } else { "" },
5248                    full = if *full { "FULL " } else { "" },
5249                    external = if *external { "EXTERNAL " } else { "" },
5250                    history = if *history { " HISTORY" } else { "" },
5251                )?;
5252                Ok(())
5253            }
5254            Statement::ShowViews {
5255                terse,
5256                materialized,
5257                show_options,
5258            } => {
5259                write!(
5260                    f,
5261                    "SHOW {terse}{materialized}VIEWS{show_options}",
5262                    terse = if *terse { "TERSE " } else { "" },
5263                    materialized = if *materialized { "MATERIALIZED " } else { "" }
5264                )?;
5265                Ok(())
5266            }
5267            Statement::ShowFunctions { filter } => {
5268                write!(f, "SHOW FUNCTIONS")?;
5269                if let Some(filter) = filter {
5270                    write!(f, " {filter}")?;
5271                }
5272                Ok(())
5273            }
5274            Statement::Use(use_expr) => use_expr.fmt(f),
5275            Statement::ShowCollation { filter } => {
5276                write!(f, "SHOW COLLATION")?;
5277                if let Some(filter) = filter {
5278                    write!(f, " {filter}")?;
5279                }
5280                Ok(())
5281            }
5282            Statement::ShowCharset(show_stm) => show_stm.fmt(f),
5283            Statement::StartTransaction {
5284                modes,
5285                begin: syntax_begin,
5286                transaction,
5287                modifier,
5288                statements,
5289                exception,
5290                has_end_keyword,
5291            } => {
5292                if *syntax_begin {
5293                    if let Some(modifier) = *modifier {
5294                        write!(f, "BEGIN {modifier}")?;
5295                    } else {
5296                        write!(f, "BEGIN")?;
5297                    }
5298                } else {
5299                    write!(f, "START")?;
5300                }
5301                if let Some(transaction) = transaction {
5302                    write!(f, " {transaction}")?;
5303                }
5304                if !modes.is_empty() {
5305                    write!(f, " {}", display_comma_separated(modes))?;
5306                }
5307                if !statements.is_empty() {
5308                    write!(f, " ")?;
5309                    format_statement_list(f, statements)?;
5310                }
5311                if let Some(exception_when) = exception {
5312                    write!(f, " EXCEPTION")?;
5313                    for when in exception_when {
5314                        write!(f, " {when}")?;
5315                    }
5316                }
5317                if *has_end_keyword {
5318                    write!(f, " END")?;
5319                }
5320                Ok(())
5321            }
5322            Statement::Commit {
5323                chain,
5324                end: end_syntax,
5325                modifier,
5326            } => {
5327                if *end_syntax {
5328                    write!(f, "END")?;
5329                    if let Some(modifier) = *modifier {
5330                        write!(f, " {modifier}")?;
5331                    }
5332                    if *chain {
5333                        write!(f, " AND CHAIN")?;
5334                    }
5335                } else {
5336                    write!(f, "COMMIT{}", if *chain { " AND CHAIN" } else { "" })?;
5337                }
5338                Ok(())
5339            }
5340            Statement::Rollback { chain, savepoint } => {
5341                write!(f, "ROLLBACK")?;
5342
5343                if *chain {
5344                    write!(f, " AND CHAIN")?;
5345                }
5346
5347                if let Some(savepoint) = savepoint {
5348                    write!(f, " TO SAVEPOINT {savepoint}")?;
5349                }
5350
5351                Ok(())
5352            }
5353            Statement::CreateSchema {
5354                schema_name,
5355                if_not_exists,
5356                with,
5357                options,
5358                default_collate_spec,
5359                clone,
5360            } => {
5361                write!(
5362                    f,
5363                    "CREATE SCHEMA {if_not_exists}{name}",
5364                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5365                    name = schema_name
5366                )?;
5367
5368                if let Some(collate) = default_collate_spec {
5369                    write!(f, " DEFAULT COLLATE {collate}")?;
5370                }
5371
5372                if let Some(with) = with {
5373                    write!(f, " WITH ({})", display_comma_separated(with))?;
5374                }
5375
5376                if let Some(options) = options {
5377                    write!(f, " OPTIONS({})", display_comma_separated(options))?;
5378                }
5379
5380                if let Some(clone) = clone {
5381                    write!(f, " CLONE {clone}")?;
5382                }
5383                Ok(())
5384            }
5385            Statement::Assert { condition, message } => {
5386                write!(f, "ASSERT {condition}")?;
5387                if let Some(m) = message {
5388                    write!(f, " AS {m}")?;
5389                }
5390                Ok(())
5391            }
5392            Statement::Grant {
5393                privileges,
5394                objects,
5395                grantees,
5396                with_grant_option,
5397                as_grantor,
5398                granted_by,
5399                current_grants,
5400            } => {
5401                write!(f, "GRANT {privileges} ")?;
5402                if let Some(objects) = objects {
5403                    write!(f, "ON {objects} ")?;
5404                }
5405                write!(f, "TO {}", display_comma_separated(grantees))?;
5406                if *with_grant_option {
5407                    write!(f, " WITH GRANT OPTION")?;
5408                }
5409                if let Some(current_grants) = current_grants {
5410                    write!(f, " {current_grants}")?;
5411                }
5412                if let Some(grantor) = as_grantor {
5413                    write!(f, " AS {grantor}")?;
5414                }
5415                if let Some(grantor) = granted_by {
5416                    write!(f, " GRANTED BY {grantor}")?;
5417                }
5418                Ok(())
5419            }
5420            Statement::Deny(s) => write!(f, "{s}"),
5421            Statement::Revoke {
5422                privileges,
5423                objects,
5424                grantees,
5425                granted_by,
5426                cascade,
5427            } => {
5428                write!(f, "REVOKE {privileges} ")?;
5429                if let Some(objects) = objects {
5430                    write!(f, "ON {objects} ")?;
5431                }
5432                write!(f, "FROM {}", display_comma_separated(grantees))?;
5433                if let Some(grantor) = granted_by {
5434                    write!(f, " GRANTED BY {grantor}")?;
5435                }
5436                if let Some(cascade) = cascade {
5437                    write!(f, " {cascade}")?;
5438                }
5439                Ok(())
5440            }
5441            Statement::Deallocate { name, prepare } => write!(
5442                f,
5443                "DEALLOCATE {prepare}{name}",
5444                prepare = if *prepare { "PREPARE " } else { "" },
5445                name = name,
5446            ),
5447            Statement::Execute {
5448                name,
5449                parameters,
5450                has_parentheses,
5451                immediate,
5452                into,
5453                using,
5454                output,
5455                default,
5456            } => {
5457                let (open, close) = if *has_parentheses {
5458                    ("(", ")")
5459                } else {
5460                    (if parameters.is_empty() { "" } else { " " }, "")
5461                };
5462                write!(f, "EXECUTE")?;
5463                if *immediate {
5464                    write!(f, " IMMEDIATE")?;
5465                }
5466                if let Some(name) = name {
5467                    write!(f, " {name}")?;
5468                }
5469                write!(f, "{open}{}{close}", display_comma_separated(parameters),)?;
5470                if !into.is_empty() {
5471                    write!(f, " INTO {}", display_comma_separated(into))?;
5472                }
5473                if !using.is_empty() {
5474                    write!(f, " USING {}", display_comma_separated(using))?;
5475                };
5476                if *output {
5477                    write!(f, " OUTPUT")?;
5478                }
5479                if *default {
5480                    write!(f, " DEFAULT")?;
5481                }
5482                Ok(())
5483            }
5484            Statement::Prepare {
5485                name,
5486                data_types,
5487                statement,
5488            } => {
5489                write!(f, "PREPARE {name} ")?;
5490                if !data_types.is_empty() {
5491                    write!(f, "({}) ", display_comma_separated(data_types))?;
5492                }
5493                write!(f, "AS {statement}")
5494            }
5495            Statement::Comment {
5496                object_type,
5497                object_name,
5498                comment,
5499                if_exists,
5500            } => {
5501                write!(f, "COMMENT ")?;
5502                if *if_exists {
5503                    write!(f, "IF EXISTS ")?
5504                };
5505                write!(f, "ON {object_type} {object_name} IS ")?;
5506                if let Some(c) = comment {
5507                    write!(f, "'{c}'")
5508                } else {
5509                    write!(f, "NULL")
5510                }
5511            }
5512            Statement::Savepoint { name } => {
5513                write!(f, "SAVEPOINT ")?;
5514                write!(f, "{name}")
5515            }
5516            Statement::ReleaseSavepoint { name } => {
5517                write!(f, "RELEASE SAVEPOINT {name}")
5518            }
5519            Statement::Merge(merge) => merge.fmt(f),
5520            Statement::Cache {
5521                table_name,
5522                table_flag,
5523                has_as,
5524                options,
5525                query,
5526            } => {
5527                if let Some(table_flag) = table_flag {
5528                    write!(f, "CACHE {table_flag} TABLE {table_name}")?;
5529                } else {
5530                    write!(f, "CACHE TABLE {table_name}")?;
5531                }
5532
5533                if !options.is_empty() {
5534                    write!(f, " OPTIONS({})", display_comma_separated(options))?;
5535                }
5536
5537                match (*has_as, query) {
5538                    (true, Some(query)) => write!(f, " AS {query}"),
5539                    (true, None) => f.write_str(" AS"),
5540                    (false, Some(query)) => write!(f, " {query}"),
5541                    (false, None) => Ok(()),
5542                }
5543            }
5544            Statement::UNCache {
5545                table_name,
5546                if_exists,
5547            } => {
5548                if *if_exists {
5549                    write!(f, "UNCACHE TABLE IF EXISTS {table_name}")
5550                } else {
5551                    write!(f, "UNCACHE TABLE {table_name}")
5552                }
5553            }
5554            Statement::CreateSequence {
5555                temporary,
5556                if_not_exists,
5557                name,
5558                data_type,
5559                sequence_options,
5560                owned_by,
5561            } => {
5562                let as_type: String = if let Some(dt) = data_type.as_ref() {
5563                    //Cannot use format!(" AS {}", dt), due to format! is not available in --target thumbv6m-none-eabi
5564                    // " AS ".to_owned() + &dt.to_string()
5565                    [" AS ", &dt.to_string()].concat()
5566                } else {
5567                    "".to_string()
5568                };
5569                write!(
5570                    f,
5571                    "CREATE {temporary}SEQUENCE {if_not_exists}{name}{as_type}",
5572                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5573                    temporary = if *temporary { "TEMPORARY " } else { "" },
5574                    name = name,
5575                    as_type = as_type
5576                )?;
5577                for sequence_option in sequence_options {
5578                    write!(f, "{sequence_option}")?;
5579                }
5580                if let Some(ob) = owned_by.as_ref() {
5581                    write!(f, " OWNED BY {ob}")?;
5582                }
5583                write!(f, "")
5584            }
5585            Statement::CreateStage {
5586                or_replace,
5587                temporary,
5588                if_not_exists,
5589                name,
5590                stage_params,
5591                directory_table_params,
5592                file_format,
5593                copy_options,
5594                comment,
5595                ..
5596            } => {
5597                write!(
5598                    f,
5599                    "CREATE {or_replace}{temp}STAGE {if_not_exists}{name}{stage_params}",
5600                    temp = if *temporary { "TEMPORARY " } else { "" },
5601                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
5602                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5603                )?;
5604                if !directory_table_params.options.is_empty() {
5605                    write!(f, " DIRECTORY=({directory_table_params})")?;
5606                }
5607                if !file_format.options.is_empty() {
5608                    write!(f, " FILE_FORMAT=({file_format})")?;
5609                }
5610                if !copy_options.options.is_empty() {
5611                    write!(f, " COPY_OPTIONS=({copy_options})")?;
5612                }
5613                if comment.is_some() {
5614                    write!(f, " COMMENT='{}'", comment.as_ref().unwrap())?;
5615                }
5616                Ok(())
5617            }
5618            Statement::CopyIntoSnowflake {
5619                kind,
5620                into,
5621                into_columns,
5622                from_obj,
5623                from_obj_alias,
5624                stage_params,
5625                from_transformations,
5626                from_query,
5627                files,
5628                pattern,
5629                file_format,
5630                copy_options,
5631                validation_mode,
5632                partition,
5633            } => {
5634                write!(f, "COPY INTO {into}")?;
5635                if let Some(into_columns) = into_columns {
5636                    write!(f, " ({})", display_comma_separated(into_columns))?;
5637                }
5638                if let Some(from_transformations) = from_transformations {
5639                    // Data load with transformation
5640                    if let Some(from_stage) = from_obj {
5641                        write!(
5642                            f,
5643                            " FROM (SELECT {} FROM {}{}",
5644                            display_separated(from_transformations, ", "),
5645                            from_stage,
5646                            stage_params
5647                        )?;
5648                    }
5649                    if let Some(from_obj_alias) = from_obj_alias {
5650                        write!(f, " AS {from_obj_alias}")?;
5651                    }
5652                    write!(f, ")")?;
5653                } else if let Some(from_obj) = from_obj {
5654                    // Standard data load
5655                    write!(f, " FROM {from_obj}{stage_params}")?;
5656                    if let Some(from_obj_alias) = from_obj_alias {
5657                        write!(f, " AS {from_obj_alias}")?;
5658                    }
5659                } else if let Some(from_query) = from_query {
5660                    // Data unload from query
5661                    write!(f, " FROM ({from_query})")?;
5662                }
5663
5664                if let Some(files) = files {
5665                    write!(f, " FILES = ('{}')", display_separated(files, "', '"))?;
5666                }
5667                if let Some(pattern) = pattern {
5668                    write!(f, " PATTERN = '{pattern}'")?;
5669                }
5670                if let Some(partition) = partition {
5671                    write!(f, " PARTITION BY {partition}")?;
5672                }
5673                if !file_format.options.is_empty() {
5674                    write!(f, " FILE_FORMAT=({file_format})")?;
5675                }
5676                if !copy_options.options.is_empty() {
5677                    match kind {
5678                        CopyIntoSnowflakeKind::Table => {
5679                            write!(f, " COPY_OPTIONS=({copy_options})")?
5680                        }
5681                        CopyIntoSnowflakeKind::Location => write!(f, " {copy_options}")?,
5682                    }
5683                }
5684                if let Some(validation_mode) = validation_mode {
5685                    write!(f, " VALIDATION_MODE = {validation_mode}")?;
5686                }
5687                Ok(())
5688            }
5689            Statement::CreateType {
5690                name,
5691                representation,
5692            } => {
5693                write!(f, "CREATE TYPE {name}")?;
5694                if let Some(repr) = representation {
5695                    write!(f, " {repr}")?;
5696                }
5697                Ok(())
5698            }
5699            Statement::Pragma { name, value, is_eq } => {
5700                write!(f, "PRAGMA {name}")?;
5701                if value.is_some() {
5702                    let val = value.as_ref().unwrap();
5703                    if *is_eq {
5704                        write!(f, " = {val}")?;
5705                    } else {
5706                        write!(f, "({val})")?;
5707                    }
5708                }
5709                Ok(())
5710            }
5711            Statement::LockTables { tables } => {
5712                write!(f, "LOCK TABLES {}", display_comma_separated(tables))
5713            }
5714            Statement::UnlockTables => {
5715                write!(f, "UNLOCK TABLES")
5716            }
5717            Statement::Unload {
5718                query,
5719                query_text,
5720                to,
5721                auth,
5722                with,
5723                options,
5724            } => {
5725                write!(f, "UNLOAD(")?;
5726                if let Some(query) = query {
5727                    write!(f, "{query}")?;
5728                }
5729                if let Some(query_text) = query_text {
5730                    write!(f, "'{query_text}'")?;
5731                }
5732                write!(f, ") TO {to}")?;
5733                if let Some(auth) = auth {
5734                    write!(f, " IAM_ROLE {auth}")?;
5735                }
5736                if !with.is_empty() {
5737                    write!(f, " WITH ({})", display_comma_separated(with))?;
5738                }
5739                if !options.is_empty() {
5740                    write!(f, " {}", display_separated(options, " "))?;
5741                }
5742                Ok(())
5743            }
5744            Statement::OptimizeTable {
5745                name,
5746                on_cluster,
5747                partition,
5748                include_final,
5749                deduplicate,
5750            } => {
5751                write!(f, "OPTIMIZE TABLE {name}")?;
5752                if let Some(on_cluster) = on_cluster {
5753                    write!(f, " ON CLUSTER {on_cluster}")?;
5754                }
5755                if let Some(partition) = partition {
5756                    write!(f, " {partition}")?;
5757                }
5758                if *include_final {
5759                    write!(f, " FINAL")?;
5760                }
5761                if let Some(deduplicate) = deduplicate {
5762                    write!(f, " {deduplicate}")?;
5763                }
5764                Ok(())
5765            }
5766            Statement::LISTEN { channel } => {
5767                write!(f, "LISTEN {channel}")?;
5768                Ok(())
5769            }
5770            Statement::UNLISTEN { channel } => {
5771                write!(f, "UNLISTEN {channel}")?;
5772                Ok(())
5773            }
5774            Statement::NOTIFY { channel, payload } => {
5775                write!(f, "NOTIFY {channel}")?;
5776                if let Some(payload) = payload {
5777                    write!(f, ", '{payload}'")?;
5778                }
5779                Ok(())
5780            }
5781            Statement::RenameTable(rename_tables) => {
5782                write!(f, "RENAME TABLE {}", display_comma_separated(rename_tables))
5783            }
5784            Statement::RaisError {
5785                message,
5786                severity,
5787                state,
5788                arguments,
5789                options,
5790            } => {
5791                write!(f, "RAISERROR({message}, {severity}, {state}")?;
5792                if !arguments.is_empty() {
5793                    write!(f, ", {}", display_comma_separated(arguments))?;
5794                }
5795                write!(f, ")")?;
5796                if !options.is_empty() {
5797                    write!(f, " WITH {}", display_comma_separated(options))?;
5798                }
5799                Ok(())
5800            }
5801            Statement::Print(s) => write!(f, "{s}"),
5802            Statement::Return(r) => write!(f, "{r}"),
5803            Statement::List(command) => write!(f, "LIST {command}"),
5804            Statement::Remove(command) => write!(f, "REMOVE {command}"),
5805            Statement::ExportData(e) => write!(f, "{e}"),
5806            Statement::CreateUser(s) => write!(f, "{s}"),
5807            Statement::AlterSchema(s) => write!(f, "{s}"),
5808            Statement::Vacuum(s) => write!(f, "{s}"),
5809            Statement::AlterUser(s) => write!(f, "{s}"),
5810            Statement::Reset(s) => write!(f, "{s}"),
5811        }
5812    }
5813}
5814
5815/// Can use to describe options in create sequence or table column type identity
5816/// ```sql
5817/// [ INCREMENT [ BY ] increment ]
5818///     [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
5819///     [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
5820/// ```
5821#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5822#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5823#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5824pub enum SequenceOptions {
5825    IncrementBy(Expr, bool),
5826    MinValue(Option<Expr>),
5827    MaxValue(Option<Expr>),
5828    StartWith(Expr, bool),
5829    Cache(Expr),
5830    Cycle(bool),
5831}
5832
5833impl fmt::Display for SequenceOptions {
5834    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5835        match self {
5836            SequenceOptions::IncrementBy(increment, by) => {
5837                write!(
5838                    f,
5839                    " INCREMENT{by} {increment}",
5840                    by = if *by { " BY" } else { "" },
5841                    increment = increment
5842                )
5843            }
5844            SequenceOptions::MinValue(Some(expr)) => {
5845                write!(f, " MINVALUE {expr}")
5846            }
5847            SequenceOptions::MinValue(None) => {
5848                write!(f, " NO MINVALUE")
5849            }
5850            SequenceOptions::MaxValue(Some(expr)) => {
5851                write!(f, " MAXVALUE {expr}")
5852            }
5853            SequenceOptions::MaxValue(None) => {
5854                write!(f, " NO MAXVALUE")
5855            }
5856            SequenceOptions::StartWith(start, with) => {
5857                write!(
5858                    f,
5859                    " START{with} {start}",
5860                    with = if *with { " WITH" } else { "" },
5861                    start = start
5862                )
5863            }
5864            SequenceOptions::Cache(cache) => {
5865                write!(f, " CACHE {}", *cache)
5866            }
5867            SequenceOptions::Cycle(no) => {
5868                write!(f, " {}CYCLE", if *no { "NO " } else { "" })
5869            }
5870        }
5871    }
5872}
5873
5874/// Assignment for a `SET` statement (name [=|TO] value)
5875#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5876#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5877#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5878pub struct SetAssignment {
5879    pub scope: Option<ContextModifier>,
5880    pub name: ObjectName,
5881    pub value: Expr,
5882}
5883
5884impl fmt::Display for SetAssignment {
5885    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5886        write!(
5887            f,
5888            "{}{} = {}",
5889            self.scope.map(|s| format!("{s}")).unwrap_or_default(),
5890            self.name,
5891            self.value
5892        )
5893    }
5894}
5895
5896/// Target of a `TRUNCATE TABLE` command
5897///
5898/// Note this is its own struct because `visit_relation` requires an `ObjectName` (not a `Vec<ObjectName>`)
5899#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5900#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5901#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5902pub struct TruncateTableTarget {
5903    /// name of the table being truncated
5904    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
5905    pub name: ObjectName,
5906    /// Postgres-specific option
5907    /// [ TRUNCATE TABLE ONLY ]
5908    /// <https://www.postgresql.org/docs/current/sql-truncate.html>
5909    pub only: bool,
5910}
5911
5912impl fmt::Display for TruncateTableTarget {
5913    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5914        if self.only {
5915            write!(f, "ONLY ")?;
5916        };
5917        write!(f, "{}", self.name)
5918    }
5919}
5920
5921/// PostgreSQL identity option for TRUNCATE table
5922/// [ RESTART IDENTITY | CONTINUE IDENTITY ]
5923#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5924#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5925#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5926pub enum TruncateIdentityOption {
5927    Restart,
5928    Continue,
5929}
5930
5931/// Cascade/restrict option for Postgres TRUNCATE table, MySQL GRANT/REVOKE, etc.
5932/// [ CASCADE | RESTRICT ]
5933#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5934#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5935#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5936pub enum CascadeOption {
5937    Cascade,
5938    Restrict,
5939}
5940
5941impl Display for CascadeOption {
5942    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5943        match self {
5944            CascadeOption::Cascade => write!(f, "CASCADE"),
5945            CascadeOption::Restrict => write!(f, "RESTRICT"),
5946        }
5947    }
5948}
5949
5950/// Transaction started with [ TRANSACTION | WORK ]
5951#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5952#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5953#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5954pub enum BeginTransactionKind {
5955    Transaction,
5956    Work,
5957}
5958
5959impl Display for BeginTransactionKind {
5960    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5961        match self {
5962            BeginTransactionKind::Transaction => write!(f, "TRANSACTION"),
5963            BeginTransactionKind::Work => write!(f, "WORK"),
5964        }
5965    }
5966}
5967
5968/// Can use to describe options in  create sequence or table column type identity
5969/// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
5970#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5971#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5972#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5973pub enum MinMaxValue {
5974    // clause is not specified
5975    Empty,
5976    // NO MINVALUE/NO MAXVALUE
5977    None,
5978    // MINVALUE <expr> / MAXVALUE <expr>
5979    Some(Expr),
5980}
5981
5982#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5983#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5984#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5985#[non_exhaustive]
5986pub enum OnInsert {
5987    /// ON DUPLICATE KEY UPDATE (MySQL when the key already exists, then execute an update instead)
5988    DuplicateKeyUpdate(Vec<Assignment>),
5989    /// ON CONFLICT is a PostgreSQL and Sqlite extension
5990    OnConflict(OnConflict),
5991}
5992
5993#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5994#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5995#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5996pub struct InsertAliases {
5997    pub row_alias: ObjectName,
5998    pub col_aliases: Option<Vec<Ident>>,
5999}
6000
6001#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6002#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6003#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6004pub struct OnConflict {
6005    pub conflict_target: Option<ConflictTarget>,
6006    pub action: OnConflictAction,
6007}
6008#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6009#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6010#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6011pub enum ConflictTarget {
6012    Columns(Vec<Ident>),
6013    OnConstraint(ObjectName),
6014}
6015#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6016#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6017#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6018pub enum OnConflictAction {
6019    DoNothing,
6020    DoUpdate(DoUpdate),
6021}
6022
6023#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6024#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6025#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6026pub struct DoUpdate {
6027    /// Column assignments
6028    pub assignments: Vec<Assignment>,
6029    /// WHERE
6030    pub selection: Option<Expr>,
6031}
6032
6033impl fmt::Display for OnInsert {
6034    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6035        match self {
6036            Self::DuplicateKeyUpdate(expr) => write!(
6037                f,
6038                " ON DUPLICATE KEY UPDATE {}",
6039                display_comma_separated(expr)
6040            ),
6041            Self::OnConflict(o) => write!(f, "{o}"),
6042        }
6043    }
6044}
6045impl fmt::Display for OnConflict {
6046    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6047        write!(f, " ON CONFLICT")?;
6048        if let Some(target) = &self.conflict_target {
6049            write!(f, "{target}")?;
6050        }
6051        write!(f, " {}", self.action)
6052    }
6053}
6054impl fmt::Display for ConflictTarget {
6055    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6056        match self {
6057            ConflictTarget::Columns(cols) => write!(f, "({})", display_comma_separated(cols)),
6058            ConflictTarget::OnConstraint(name) => write!(f, " ON CONSTRAINT {name}"),
6059        }
6060    }
6061}
6062impl fmt::Display for OnConflictAction {
6063    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6064        match self {
6065            Self::DoNothing => write!(f, "DO NOTHING"),
6066            Self::DoUpdate(do_update) => {
6067                write!(f, "DO UPDATE")?;
6068                if !do_update.assignments.is_empty() {
6069                    write!(
6070                        f,
6071                        " SET {}",
6072                        display_comma_separated(&do_update.assignments)
6073                    )?;
6074                }
6075                if let Some(selection) = &do_update.selection {
6076                    write!(f, " WHERE {selection}")?;
6077                }
6078                Ok(())
6079            }
6080        }
6081    }
6082}
6083
6084/// Privileges granted in a GRANT statement or revoked in a REVOKE statement.
6085#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6086#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6087#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6088pub enum Privileges {
6089    /// All privileges applicable to the object type
6090    All {
6091        /// Optional keyword from the spec, ignored in practice
6092        with_privileges_keyword: bool,
6093    },
6094    /// Specific privileges (e.g. `SELECT`, `INSERT`)
6095    Actions(Vec<Action>),
6096}
6097
6098impl fmt::Display for Privileges {
6099    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6100        match self {
6101            Privileges::All {
6102                with_privileges_keyword,
6103            } => {
6104                write!(
6105                    f,
6106                    "ALL{}",
6107                    if *with_privileges_keyword {
6108                        " PRIVILEGES"
6109                    } else {
6110                        ""
6111                    }
6112                )
6113            }
6114            Privileges::Actions(actions) => {
6115                write!(f, "{}", display_comma_separated(actions))
6116            }
6117        }
6118    }
6119}
6120
6121/// Specific direction for FETCH statement
6122#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6123#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6124#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6125pub enum FetchDirection {
6126    Count { limit: Value },
6127    Next,
6128    Prior,
6129    First,
6130    Last,
6131    Absolute { limit: Value },
6132    Relative { limit: Value },
6133    All,
6134    // FORWARD
6135    // FORWARD count
6136    Forward { limit: Option<Value> },
6137    ForwardAll,
6138    // BACKWARD
6139    // BACKWARD count
6140    Backward { limit: Option<Value> },
6141    BackwardAll,
6142}
6143
6144impl fmt::Display for FetchDirection {
6145    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6146        match self {
6147            FetchDirection::Count { limit } => f.write_str(&limit.to_string())?,
6148            FetchDirection::Next => f.write_str("NEXT")?,
6149            FetchDirection::Prior => f.write_str("PRIOR")?,
6150            FetchDirection::First => f.write_str("FIRST")?,
6151            FetchDirection::Last => f.write_str("LAST")?,
6152            FetchDirection::Absolute { limit } => {
6153                f.write_str("ABSOLUTE ")?;
6154                f.write_str(&limit.to_string())?;
6155            }
6156            FetchDirection::Relative { limit } => {
6157                f.write_str("RELATIVE ")?;
6158                f.write_str(&limit.to_string())?;
6159            }
6160            FetchDirection::All => f.write_str("ALL")?,
6161            FetchDirection::Forward { limit } => {
6162                f.write_str("FORWARD")?;
6163
6164                if let Some(l) = limit {
6165                    f.write_str(" ")?;
6166                    f.write_str(&l.to_string())?;
6167                }
6168            }
6169            FetchDirection::ForwardAll => f.write_str("FORWARD ALL")?,
6170            FetchDirection::Backward { limit } => {
6171                f.write_str("BACKWARD")?;
6172
6173                if let Some(l) = limit {
6174                    f.write_str(" ")?;
6175                    f.write_str(&l.to_string())?;
6176                }
6177            }
6178            FetchDirection::BackwardAll => f.write_str("BACKWARD ALL")?,
6179        };
6180
6181        Ok(())
6182    }
6183}
6184
6185/// The "position" for a FETCH statement.
6186///
6187/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/fetch-transact-sql)
6188#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6189#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6190#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6191pub enum FetchPosition {
6192    From,
6193    In,
6194}
6195
6196impl fmt::Display for FetchPosition {
6197    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6198        match self {
6199            FetchPosition::From => f.write_str("FROM")?,
6200            FetchPosition::In => f.write_str("IN")?,
6201        };
6202
6203        Ok(())
6204    }
6205}
6206
6207/// A privilege on a database object (table, sequence, etc.).
6208#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6209#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6210#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6211pub enum Action {
6212    AddSearchOptimization,
6213    Apply {
6214        apply_type: ActionApplyType,
6215    },
6216    ApplyBudget,
6217    AttachListing,
6218    AttachPolicy,
6219    Audit,
6220    BindServiceEndpoint,
6221    Connect,
6222    Create {
6223        obj_type: Option<ActionCreateObjectType>,
6224    },
6225    DatabaseRole {
6226        role: ObjectName,
6227    },
6228    Delete,
6229    Drop,
6230    EvolveSchema,
6231    Exec {
6232        obj_type: Option<ActionExecuteObjectType>,
6233    },
6234    Execute {
6235        obj_type: Option<ActionExecuteObjectType>,
6236    },
6237    Failover,
6238    ImportedPrivileges,
6239    ImportShare,
6240    Insert {
6241        columns: Option<Vec<Ident>>,
6242    },
6243    Manage {
6244        manage_type: ActionManageType,
6245    },
6246    ManageReleases,
6247    ManageVersions,
6248    Modify {
6249        modify_type: Option<ActionModifyType>,
6250    },
6251    Monitor {
6252        monitor_type: Option<ActionMonitorType>,
6253    },
6254    Operate,
6255    OverrideShareRestrictions,
6256    Ownership,
6257    PurchaseDataExchangeListing,
6258    Read,
6259    ReadSession,
6260    References {
6261        columns: Option<Vec<Ident>>,
6262    },
6263    Replicate,
6264    ResolveAll,
6265    Role {
6266        role: ObjectName,
6267    },
6268    Select {
6269        columns: Option<Vec<Ident>>,
6270    },
6271    Temporary,
6272    Trigger,
6273    Truncate,
6274    Update {
6275        columns: Option<Vec<Ident>>,
6276    },
6277    Usage,
6278}
6279
6280impl fmt::Display for Action {
6281    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6282        match self {
6283            Action::AddSearchOptimization => f.write_str("ADD SEARCH OPTIMIZATION")?,
6284            Action::Apply { apply_type } => write!(f, "APPLY {apply_type}")?,
6285            Action::ApplyBudget => f.write_str("APPLYBUDGET")?,
6286            Action::AttachListing => f.write_str("ATTACH LISTING")?,
6287            Action::AttachPolicy => f.write_str("ATTACH POLICY")?,
6288            Action::Audit => f.write_str("AUDIT")?,
6289            Action::BindServiceEndpoint => f.write_str("BIND SERVICE ENDPOINT")?,
6290            Action::Connect => f.write_str("CONNECT")?,
6291            Action::Create { obj_type } => {
6292                f.write_str("CREATE")?;
6293                if let Some(obj_type) = obj_type {
6294                    write!(f, " {obj_type}")?
6295                }
6296            }
6297            Action::DatabaseRole { role } => write!(f, "DATABASE ROLE {role}")?,
6298            Action::Delete => f.write_str("DELETE")?,
6299            Action::Drop => f.write_str("DROP")?,
6300            Action::EvolveSchema => f.write_str("EVOLVE SCHEMA")?,
6301            Action::Exec { obj_type } => {
6302                f.write_str("EXEC")?;
6303                if let Some(obj_type) = obj_type {
6304                    write!(f, " {obj_type}")?
6305                }
6306            }
6307            Action::Execute { obj_type } => {
6308                f.write_str("EXECUTE")?;
6309                if let Some(obj_type) = obj_type {
6310                    write!(f, " {obj_type}")?
6311                }
6312            }
6313            Action::Failover => f.write_str("FAILOVER")?,
6314            Action::ImportedPrivileges => f.write_str("IMPORTED PRIVILEGES")?,
6315            Action::ImportShare => f.write_str("IMPORT SHARE")?,
6316            Action::Insert { .. } => f.write_str("INSERT")?,
6317            Action::Manage { manage_type } => write!(f, "MANAGE {manage_type}")?,
6318            Action::ManageReleases => f.write_str("MANAGE RELEASES")?,
6319            Action::ManageVersions => f.write_str("MANAGE VERSIONS")?,
6320            Action::Modify { modify_type } => {
6321                write!(f, "MODIFY")?;
6322                if let Some(modify_type) = modify_type {
6323                    write!(f, " {modify_type}")?;
6324                }
6325            }
6326            Action::Monitor { monitor_type } => {
6327                write!(f, "MONITOR")?;
6328                if let Some(monitor_type) = monitor_type {
6329                    write!(f, " {monitor_type}")?
6330                }
6331            }
6332            Action::Operate => f.write_str("OPERATE")?,
6333            Action::OverrideShareRestrictions => f.write_str("OVERRIDE SHARE RESTRICTIONS")?,
6334            Action::Ownership => f.write_str("OWNERSHIP")?,
6335            Action::PurchaseDataExchangeListing => f.write_str("PURCHASE DATA EXCHANGE LISTING")?,
6336            Action::Read => f.write_str("READ")?,
6337            Action::ReadSession => f.write_str("READ SESSION")?,
6338            Action::References { .. } => f.write_str("REFERENCES")?,
6339            Action::Replicate => f.write_str("REPLICATE")?,
6340            Action::ResolveAll => f.write_str("RESOLVE ALL")?,
6341            Action::Role { role } => write!(f, "ROLE {role}")?,
6342            Action::Select { .. } => f.write_str("SELECT")?,
6343            Action::Temporary => f.write_str("TEMPORARY")?,
6344            Action::Trigger => f.write_str("TRIGGER")?,
6345            Action::Truncate => f.write_str("TRUNCATE")?,
6346            Action::Update { .. } => f.write_str("UPDATE")?,
6347            Action::Usage => f.write_str("USAGE")?,
6348        };
6349        match self {
6350            Action::Insert { columns }
6351            | Action::References { columns }
6352            | Action::Select { columns }
6353            | Action::Update { columns } => {
6354                if let Some(columns) = columns {
6355                    write!(f, " ({})", display_comma_separated(columns))?;
6356                }
6357            }
6358            _ => (),
6359        };
6360        Ok(())
6361    }
6362}
6363
6364#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6365#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6366#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6367/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6368/// under `globalPrivileges` in the `CREATE` privilege.
6369pub enum ActionCreateObjectType {
6370    Account,
6371    Application,
6372    ApplicationPackage,
6373    ComputePool,
6374    DataExchangeListing,
6375    Database,
6376    ExternalVolume,
6377    FailoverGroup,
6378    Integration,
6379    NetworkPolicy,
6380    OrganiationListing,
6381    ReplicationGroup,
6382    Role,
6383    Schema,
6384    Share,
6385    User,
6386    Warehouse,
6387}
6388
6389impl fmt::Display for ActionCreateObjectType {
6390    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6391        match self {
6392            ActionCreateObjectType::Account => write!(f, "ACCOUNT"),
6393            ActionCreateObjectType::Application => write!(f, "APPLICATION"),
6394            ActionCreateObjectType::ApplicationPackage => write!(f, "APPLICATION PACKAGE"),
6395            ActionCreateObjectType::ComputePool => write!(f, "COMPUTE POOL"),
6396            ActionCreateObjectType::DataExchangeListing => write!(f, "DATA EXCHANGE LISTING"),
6397            ActionCreateObjectType::Database => write!(f, "DATABASE"),
6398            ActionCreateObjectType::ExternalVolume => write!(f, "EXTERNAL VOLUME"),
6399            ActionCreateObjectType::FailoverGroup => write!(f, "FAILOVER GROUP"),
6400            ActionCreateObjectType::Integration => write!(f, "INTEGRATION"),
6401            ActionCreateObjectType::NetworkPolicy => write!(f, "NETWORK POLICY"),
6402            ActionCreateObjectType::OrganiationListing => write!(f, "ORGANIZATION LISTING"),
6403            ActionCreateObjectType::ReplicationGroup => write!(f, "REPLICATION GROUP"),
6404            ActionCreateObjectType::Role => write!(f, "ROLE"),
6405            ActionCreateObjectType::Schema => write!(f, "SCHEMA"),
6406            ActionCreateObjectType::Share => write!(f, "SHARE"),
6407            ActionCreateObjectType::User => write!(f, "USER"),
6408            ActionCreateObjectType::Warehouse => write!(f, "WAREHOUSE"),
6409        }
6410    }
6411}
6412
6413#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6414#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6415#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6416/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6417/// under `globalPrivileges` in the `APPLY` privilege.
6418pub enum ActionApplyType {
6419    AggregationPolicy,
6420    AuthenticationPolicy,
6421    JoinPolicy,
6422    MaskingPolicy,
6423    PackagesPolicy,
6424    PasswordPolicy,
6425    ProjectionPolicy,
6426    RowAccessPolicy,
6427    SessionPolicy,
6428    Tag,
6429}
6430
6431impl fmt::Display for ActionApplyType {
6432    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6433        match self {
6434            ActionApplyType::AggregationPolicy => write!(f, "AGGREGATION POLICY"),
6435            ActionApplyType::AuthenticationPolicy => write!(f, "AUTHENTICATION POLICY"),
6436            ActionApplyType::JoinPolicy => write!(f, "JOIN POLICY"),
6437            ActionApplyType::MaskingPolicy => write!(f, "MASKING POLICY"),
6438            ActionApplyType::PackagesPolicy => write!(f, "PACKAGES POLICY"),
6439            ActionApplyType::PasswordPolicy => write!(f, "PASSWORD POLICY"),
6440            ActionApplyType::ProjectionPolicy => write!(f, "PROJECTION POLICY"),
6441            ActionApplyType::RowAccessPolicy => write!(f, "ROW ACCESS POLICY"),
6442            ActionApplyType::SessionPolicy => write!(f, "SESSION POLICY"),
6443            ActionApplyType::Tag => write!(f, "TAG"),
6444        }
6445    }
6446}
6447
6448#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6449#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6450#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6451/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6452/// under `globalPrivileges` in the `EXECUTE` privilege.
6453pub enum ActionExecuteObjectType {
6454    Alert,
6455    DataMetricFunction,
6456    ManagedAlert,
6457    ManagedTask,
6458    Task,
6459}
6460
6461impl fmt::Display for ActionExecuteObjectType {
6462    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6463        match self {
6464            ActionExecuteObjectType::Alert => write!(f, "ALERT"),
6465            ActionExecuteObjectType::DataMetricFunction => write!(f, "DATA METRIC FUNCTION"),
6466            ActionExecuteObjectType::ManagedAlert => write!(f, "MANAGED ALERT"),
6467            ActionExecuteObjectType::ManagedTask => write!(f, "MANAGED TASK"),
6468            ActionExecuteObjectType::Task => write!(f, "TASK"),
6469        }
6470    }
6471}
6472
6473#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6474#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6475#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6476/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6477/// under `globalPrivileges` in the `MANAGE` privilege.
6478pub enum ActionManageType {
6479    AccountSupportCases,
6480    EventSharing,
6481    Grants,
6482    ListingAutoFulfillment,
6483    OrganizationSupportCases,
6484    UserSupportCases,
6485    Warehouses,
6486}
6487
6488impl fmt::Display for ActionManageType {
6489    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6490        match self {
6491            ActionManageType::AccountSupportCases => write!(f, "ACCOUNT SUPPORT CASES"),
6492            ActionManageType::EventSharing => write!(f, "EVENT SHARING"),
6493            ActionManageType::Grants => write!(f, "GRANTS"),
6494            ActionManageType::ListingAutoFulfillment => write!(f, "LISTING AUTO FULFILLMENT"),
6495            ActionManageType::OrganizationSupportCases => write!(f, "ORGANIZATION SUPPORT CASES"),
6496            ActionManageType::UserSupportCases => write!(f, "USER SUPPORT CASES"),
6497            ActionManageType::Warehouses => write!(f, "WAREHOUSES"),
6498        }
6499    }
6500}
6501
6502#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6503#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6504#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6505/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6506/// under `globalPrivileges` in the `MODIFY` privilege.
6507pub enum ActionModifyType {
6508    LogLevel,
6509    TraceLevel,
6510    SessionLogLevel,
6511    SessionTraceLevel,
6512}
6513
6514impl fmt::Display for ActionModifyType {
6515    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6516        match self {
6517            ActionModifyType::LogLevel => write!(f, "LOG LEVEL"),
6518            ActionModifyType::TraceLevel => write!(f, "TRACE LEVEL"),
6519            ActionModifyType::SessionLogLevel => write!(f, "SESSION LOG LEVEL"),
6520            ActionModifyType::SessionTraceLevel => write!(f, "SESSION TRACE LEVEL"),
6521        }
6522    }
6523}
6524
6525#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6526#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6527#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6528/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6529/// under `globalPrivileges` in the `MONITOR` privilege.
6530pub enum ActionMonitorType {
6531    Execution,
6532    Security,
6533    Usage,
6534}
6535
6536impl fmt::Display for ActionMonitorType {
6537    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6538        match self {
6539            ActionMonitorType::Execution => write!(f, "EXECUTION"),
6540            ActionMonitorType::Security => write!(f, "SECURITY"),
6541            ActionMonitorType::Usage => write!(f, "USAGE"),
6542        }
6543    }
6544}
6545
6546/// The principal that receives the privileges
6547#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6548#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6549#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6550pub struct Grantee {
6551    pub grantee_type: GranteesType,
6552    pub name: Option<GranteeName>,
6553}
6554
6555impl fmt::Display for Grantee {
6556    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6557        match self.grantee_type {
6558            GranteesType::Role => {
6559                write!(f, "ROLE ")?;
6560            }
6561            GranteesType::Share => {
6562                write!(f, "SHARE ")?;
6563            }
6564            GranteesType::User => {
6565                write!(f, "USER ")?;
6566            }
6567            GranteesType::Group => {
6568                write!(f, "GROUP ")?;
6569            }
6570            GranteesType::Public => {
6571                write!(f, "PUBLIC ")?;
6572            }
6573            GranteesType::DatabaseRole => {
6574                write!(f, "DATABASE ROLE ")?;
6575            }
6576            GranteesType::Application => {
6577                write!(f, "APPLICATION ")?;
6578            }
6579            GranteesType::ApplicationRole => {
6580                write!(f, "APPLICATION ROLE ")?;
6581            }
6582            GranteesType::None => (),
6583        }
6584        if let Some(ref name) = self.name {
6585            name.fmt(f)?;
6586        }
6587        Ok(())
6588    }
6589}
6590
6591#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6592#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6593#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6594pub enum GranteesType {
6595    Role,
6596    Share,
6597    User,
6598    Group,
6599    Public,
6600    DatabaseRole,
6601    Application,
6602    ApplicationRole,
6603    None,
6604}
6605
6606/// Users/roles designated in a GRANT/REVOKE
6607#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6608#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6609#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6610pub enum GranteeName {
6611    /// A bare identifier
6612    ObjectName(ObjectName),
6613    /// A MySQL user/host pair such as 'root'@'%'
6614    UserHost { user: Ident, host: Ident },
6615}
6616
6617impl fmt::Display for GranteeName {
6618    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6619        match self {
6620            GranteeName::ObjectName(name) => name.fmt(f),
6621            GranteeName::UserHost { user, host } => {
6622                write!(f, "{user}@{host}")
6623            }
6624        }
6625    }
6626}
6627
6628/// Objects on which privileges are granted in a GRANT statement.
6629#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6630#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6631#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6632pub enum GrantObjects {
6633    /// Grant privileges on `ALL SEQUENCES IN SCHEMA <schema_name> [, ...]`
6634    AllSequencesInSchema { schemas: Vec<ObjectName> },
6635    /// Grant privileges on `ALL TABLES IN SCHEMA <schema_name> [, ...]`
6636    AllTablesInSchema { schemas: Vec<ObjectName> },
6637    /// Grant privileges on `ALL VIEWS IN SCHEMA <schema_name> [, ...]`
6638    AllViewsInSchema { schemas: Vec<ObjectName> },
6639    /// Grant privileges on `ALL MATERIALIZED VIEWS IN SCHEMA <schema_name> [, ...]`
6640    AllMaterializedViewsInSchema { schemas: Vec<ObjectName> },
6641    /// Grant privileges on `ALL EXTERNAL TABLES IN SCHEMA <schema_name> [, ...]`
6642    AllExternalTablesInSchema { schemas: Vec<ObjectName> },
6643    /// Grant privileges on `ALL FUNCTIONS IN SCHEMA <schema_name> [, ...]`
6644    AllFunctionsInSchema { schemas: Vec<ObjectName> },
6645    /// Grant privileges on `FUTURE SCHEMAS IN DATABASE <database_name> [, ...]`
6646    FutureSchemasInDatabase { databases: Vec<ObjectName> },
6647    /// Grant privileges on `FUTURE TABLES IN SCHEMA <schema_name> [, ...]`
6648    FutureTablesInSchema { schemas: Vec<ObjectName> },
6649    /// Grant privileges on `FUTURE VIEWS IN SCHEMA <schema_name> [, ...]`
6650    FutureViewsInSchema { schemas: Vec<ObjectName> },
6651    /// Grant privileges on `FUTURE EXTERNAL TABLES IN SCHEMA <schema_name> [, ...]`
6652    FutureExternalTablesInSchema { schemas: Vec<ObjectName> },
6653    /// Grant privileges on `FUTURE MATERIALIZED VIEWS IN SCHEMA <schema_name> [, ...]`
6654    FutureMaterializedViewsInSchema { schemas: Vec<ObjectName> },
6655    /// Grant privileges on `FUTURE SEQUENCES IN SCHEMA <schema_name> [, ...]`
6656    FutureSequencesInSchema { schemas: Vec<ObjectName> },
6657    /// Grant privileges on specific databases
6658    Databases(Vec<ObjectName>),
6659    /// Grant privileges on specific schemas
6660    Schemas(Vec<ObjectName>),
6661    /// Grant privileges on specific sequences
6662    Sequences(Vec<ObjectName>),
6663    /// Grant privileges on specific tables
6664    Tables(Vec<ObjectName>),
6665    /// Grant privileges on specific views
6666    Views(Vec<ObjectName>),
6667    /// Grant privileges on specific warehouses
6668    Warehouses(Vec<ObjectName>),
6669    /// Grant privileges on specific integrations
6670    Integrations(Vec<ObjectName>),
6671    /// Grant privileges on resource monitors
6672    ResourceMonitors(Vec<ObjectName>),
6673    /// Grant privileges on users
6674    Users(Vec<ObjectName>),
6675    /// Grant privileges on compute pools
6676    ComputePools(Vec<ObjectName>),
6677    /// Grant privileges on connections
6678    Connections(Vec<ObjectName>),
6679    /// Grant privileges on failover groups
6680    FailoverGroup(Vec<ObjectName>),
6681    /// Grant privileges on replication group
6682    ReplicationGroup(Vec<ObjectName>),
6683    /// Grant privileges on external volumes
6684    ExternalVolumes(Vec<ObjectName>),
6685    /// Grant privileges on a procedure. In dialects that
6686    /// support overloading, the argument types must be specified.
6687    ///
6688    /// For example:
6689    /// `GRANT USAGE ON PROCEDURE foo(varchar) TO ROLE role1`
6690    Procedure {
6691        name: ObjectName,
6692        arg_types: Vec<DataType>,
6693    },
6694
6695    /// Grant privileges on a function. In dialects that
6696    /// support overloading, the argument types must be specified.
6697    ///
6698    /// For example:
6699    /// `GRANT USAGE ON FUNCTION foo(varchar) TO ROLE role1`
6700    Function {
6701        name: ObjectName,
6702        arg_types: Vec<DataType>,
6703    },
6704}
6705
6706impl fmt::Display for GrantObjects {
6707    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6708        match self {
6709            GrantObjects::Sequences(sequences) => {
6710                write!(f, "SEQUENCE {}", display_comma_separated(sequences))
6711            }
6712            GrantObjects::Databases(databases) => {
6713                write!(f, "DATABASE {}", display_comma_separated(databases))
6714            }
6715            GrantObjects::Schemas(schemas) => {
6716                write!(f, "SCHEMA {}", display_comma_separated(schemas))
6717            }
6718            GrantObjects::Tables(tables) => {
6719                write!(f, "{}", display_comma_separated(tables))
6720            }
6721            GrantObjects::Views(views) => {
6722                write!(f, "VIEW {}", display_comma_separated(views))
6723            }
6724            GrantObjects::Warehouses(warehouses) => {
6725                write!(f, "WAREHOUSE {}", display_comma_separated(warehouses))
6726            }
6727            GrantObjects::Integrations(integrations) => {
6728                write!(f, "INTEGRATION {}", display_comma_separated(integrations))
6729            }
6730            GrantObjects::AllSequencesInSchema { schemas } => {
6731                write!(
6732                    f,
6733                    "ALL SEQUENCES IN SCHEMA {}",
6734                    display_comma_separated(schemas)
6735                )
6736            }
6737            GrantObjects::AllTablesInSchema { schemas } => {
6738                write!(
6739                    f,
6740                    "ALL TABLES IN SCHEMA {}",
6741                    display_comma_separated(schemas)
6742                )
6743            }
6744            GrantObjects::AllExternalTablesInSchema { schemas } => {
6745                write!(
6746                    f,
6747                    "ALL EXTERNAL TABLES IN SCHEMA {}",
6748                    display_comma_separated(schemas)
6749                )
6750            }
6751            GrantObjects::AllViewsInSchema { schemas } => {
6752                write!(
6753                    f,
6754                    "ALL VIEWS IN SCHEMA {}",
6755                    display_comma_separated(schemas)
6756                )
6757            }
6758            GrantObjects::AllMaterializedViewsInSchema { schemas } => {
6759                write!(
6760                    f,
6761                    "ALL MATERIALIZED VIEWS IN SCHEMA {}",
6762                    display_comma_separated(schemas)
6763                )
6764            }
6765            GrantObjects::AllFunctionsInSchema { schemas } => {
6766                write!(
6767                    f,
6768                    "ALL FUNCTIONS IN SCHEMA {}",
6769                    display_comma_separated(schemas)
6770                )
6771            }
6772            GrantObjects::FutureSchemasInDatabase { databases } => {
6773                write!(
6774                    f,
6775                    "FUTURE SCHEMAS IN DATABASE {}",
6776                    display_comma_separated(databases)
6777                )
6778            }
6779            GrantObjects::FutureTablesInSchema { schemas } => {
6780                write!(
6781                    f,
6782                    "FUTURE TABLES IN SCHEMA {}",
6783                    display_comma_separated(schemas)
6784                )
6785            }
6786            GrantObjects::FutureExternalTablesInSchema { schemas } => {
6787                write!(
6788                    f,
6789                    "FUTURE EXTERNAL TABLES IN SCHEMA {}",
6790                    display_comma_separated(schemas)
6791                )
6792            }
6793            GrantObjects::FutureViewsInSchema { schemas } => {
6794                write!(
6795                    f,
6796                    "FUTURE VIEWS IN SCHEMA {}",
6797                    display_comma_separated(schemas)
6798                )
6799            }
6800            GrantObjects::FutureMaterializedViewsInSchema { schemas } => {
6801                write!(
6802                    f,
6803                    "FUTURE MATERIALIZED VIEWS IN SCHEMA {}",
6804                    display_comma_separated(schemas)
6805                )
6806            }
6807            GrantObjects::FutureSequencesInSchema { schemas } => {
6808                write!(
6809                    f,
6810                    "FUTURE SEQUENCES IN SCHEMA {}",
6811                    display_comma_separated(schemas)
6812                )
6813            }
6814            GrantObjects::ResourceMonitors(objects) => {
6815                write!(f, "RESOURCE MONITOR {}", display_comma_separated(objects))
6816            }
6817            GrantObjects::Users(objects) => {
6818                write!(f, "USER {}", display_comma_separated(objects))
6819            }
6820            GrantObjects::ComputePools(objects) => {
6821                write!(f, "COMPUTE POOL {}", display_comma_separated(objects))
6822            }
6823            GrantObjects::Connections(objects) => {
6824                write!(f, "CONNECTION {}", display_comma_separated(objects))
6825            }
6826            GrantObjects::FailoverGroup(objects) => {
6827                write!(f, "FAILOVER GROUP {}", display_comma_separated(objects))
6828            }
6829            GrantObjects::ReplicationGroup(objects) => {
6830                write!(f, "REPLICATION GROUP {}", display_comma_separated(objects))
6831            }
6832            GrantObjects::ExternalVolumes(objects) => {
6833                write!(f, "EXTERNAL VOLUME {}", display_comma_separated(objects))
6834            }
6835            GrantObjects::Procedure { name, arg_types } => {
6836                write!(f, "PROCEDURE {name}")?;
6837                if !arg_types.is_empty() {
6838                    write!(f, "({})", display_comma_separated(arg_types))?;
6839                }
6840                Ok(())
6841            }
6842            GrantObjects::Function { name, arg_types } => {
6843                write!(f, "FUNCTION {name}")?;
6844                if !arg_types.is_empty() {
6845                    write!(f, "({})", display_comma_separated(arg_types))?;
6846                }
6847                Ok(())
6848            }
6849        }
6850    }
6851}
6852
6853/// A `DENY` statement
6854///
6855/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/deny-transact-sql)
6856#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6857#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6858#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6859pub struct DenyStatement {
6860    pub privileges: Privileges,
6861    pub objects: GrantObjects,
6862    pub grantees: Vec<Grantee>,
6863    pub granted_by: Option<Ident>,
6864    pub cascade: Option<CascadeOption>,
6865}
6866
6867impl fmt::Display for DenyStatement {
6868    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6869        write!(f, "DENY {}", self.privileges)?;
6870        write!(f, " ON {}", self.objects)?;
6871        if !self.grantees.is_empty() {
6872            write!(f, " TO {}", display_comma_separated(&self.grantees))?;
6873        }
6874        if let Some(cascade) = &self.cascade {
6875            write!(f, " {cascade}")?;
6876        }
6877        if let Some(granted_by) = &self.granted_by {
6878            write!(f, " AS {granted_by}")?;
6879        }
6880        Ok(())
6881    }
6882}
6883
6884/// SQL assignment `foo = expr` as used in SQLUpdate
6885#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6886#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6887#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6888pub struct Assignment {
6889    pub target: AssignmentTarget,
6890    pub value: Expr,
6891}
6892
6893impl fmt::Display for Assignment {
6894    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6895        write!(f, "{} = {}", self.target, self.value)
6896    }
6897}
6898
6899/// Left-hand side of an assignment in an UPDATE statement,
6900/// e.g. `foo` in `foo = 5` (ColumnName assignment) or
6901/// `(a, b)` in `(a, b) = (1, 2)` (Tuple assignment).
6902#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6903#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6904#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6905pub enum AssignmentTarget {
6906    /// A single column
6907    ColumnName(ObjectName),
6908    /// A tuple of columns
6909    Tuple(Vec<ObjectName>),
6910}
6911
6912impl fmt::Display for AssignmentTarget {
6913    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6914        match self {
6915            AssignmentTarget::ColumnName(column) => write!(f, "{column}"),
6916            AssignmentTarget::Tuple(columns) => write!(f, "({})", display_comma_separated(columns)),
6917        }
6918    }
6919}
6920
6921#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6922#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6923#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6924pub enum FunctionArgExpr {
6925    Expr(Expr),
6926    /// Qualified wildcard, e.g. `alias.*` or `schema.table.*`.
6927    QualifiedWildcard(ObjectName),
6928    /// An unqualified `*`
6929    Wildcard,
6930}
6931
6932impl From<Expr> for FunctionArgExpr {
6933    fn from(wildcard_expr: Expr) -> Self {
6934        match wildcard_expr {
6935            Expr::QualifiedWildcard(prefix, _) => Self::QualifiedWildcard(prefix),
6936            Expr::Wildcard(_) => Self::Wildcard,
6937            expr => Self::Expr(expr),
6938        }
6939    }
6940}
6941
6942impl fmt::Display for FunctionArgExpr {
6943    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6944        match self {
6945            FunctionArgExpr::Expr(expr) => write!(f, "{expr}"),
6946            FunctionArgExpr::QualifiedWildcard(prefix) => write!(f, "{prefix}.*"),
6947            FunctionArgExpr::Wildcard => f.write_str("*"),
6948        }
6949    }
6950}
6951
6952#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6953#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6954#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6955/// Operator used to separate function arguments
6956pub enum FunctionArgOperator {
6957    /// function(arg1 = value1)
6958    Equals,
6959    /// function(arg1 => value1)
6960    RightArrow,
6961    /// function(arg1 := value1)
6962    Assignment,
6963    /// function(arg1 : value1)
6964    Colon,
6965    /// function(arg1 VALUE value1)
6966    Value,
6967}
6968
6969impl fmt::Display for FunctionArgOperator {
6970    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6971        match self {
6972            FunctionArgOperator::Equals => f.write_str("="),
6973            FunctionArgOperator::RightArrow => f.write_str("=>"),
6974            FunctionArgOperator::Assignment => f.write_str(":="),
6975            FunctionArgOperator::Colon => f.write_str(":"),
6976            FunctionArgOperator::Value => f.write_str("VALUE"),
6977        }
6978    }
6979}
6980
6981#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6982#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6983#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6984pub enum FunctionArg {
6985    /// `name` is identifier
6986    ///
6987    /// Enabled when `Dialect::supports_named_fn_args_with_expr_name` returns 'false'
6988    Named {
6989        name: Ident,
6990        arg: FunctionArgExpr,
6991        operator: FunctionArgOperator,
6992    },
6993    /// `name` is arbitrary expression
6994    ///
6995    /// Enabled when `Dialect::supports_named_fn_args_with_expr_name` returns 'true'
6996    ExprNamed {
6997        name: Expr,
6998        arg: FunctionArgExpr,
6999        operator: FunctionArgOperator,
7000    },
7001    Unnamed(FunctionArgExpr),
7002}
7003
7004impl fmt::Display for FunctionArg {
7005    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7006        match self {
7007            FunctionArg::Named {
7008                name,
7009                arg,
7010                operator,
7011            } => write!(f, "{name} {operator} {arg}"),
7012            FunctionArg::ExprNamed {
7013                name,
7014                arg,
7015                operator,
7016            } => write!(f, "{name} {operator} {arg}"),
7017            FunctionArg::Unnamed(unnamed_arg) => write!(f, "{unnamed_arg}"),
7018        }
7019    }
7020}
7021
7022#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7023#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7024#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7025pub enum CloseCursor {
7026    All,
7027    Specific { name: Ident },
7028}
7029
7030impl fmt::Display for CloseCursor {
7031    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7032        match self {
7033            CloseCursor::All => write!(f, "ALL"),
7034            CloseCursor::Specific { name } => write!(f, "{name}"),
7035        }
7036    }
7037}
7038
7039/// A Drop Domain statement
7040#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7041#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7042#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7043pub struct DropDomain {
7044    /// Whether to drop the domain if it exists
7045    pub if_exists: bool,
7046    /// The name of the domain to drop
7047    pub name: ObjectName,
7048    /// The behavior to apply when dropping the domain
7049    pub drop_behavior: Option<DropBehavior>,
7050}
7051
7052/// A constant of form `<data_type> 'value'`.
7053/// This can represent ANSI SQL `DATE`, `TIME`, and `TIMESTAMP` literals (such as `DATE '2020-01-01'`),
7054/// as well as constants of other types (a non-standard PostgreSQL extension).
7055#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7056#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7057#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7058pub struct TypedString {
7059    pub data_type: DataType,
7060    /// The value of the constant.
7061    /// Hint: you can unwrap the string value using `value.into_string()`.
7062    pub value: ValueWithSpan,
7063    /// Flags whether this TypedString uses the [ODBC syntax].
7064    ///
7065    /// Example:
7066    /// ```sql
7067    /// -- An ODBC date literal:
7068    /// SELECT {d '2025-07-16'}
7069    /// -- This is equivalent to the standard ANSI SQL literal:
7070    /// SELECT DATE '2025-07-16'
7071    ///
7072    /// [ODBC syntax]: https://learn.microsoft.com/en-us/sql/odbc/reference/develop-app/date-time-and-timestamp-literals?view=sql-server-2017
7073    pub uses_odbc_syntax: bool,
7074}
7075
7076impl fmt::Display for TypedString {
7077    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7078        let data_type = &self.data_type;
7079        let value = &self.value;
7080        match self.uses_odbc_syntax {
7081            false => {
7082                write!(f, "{data_type}")?;
7083                write!(f, " {value}")
7084            }
7085            true => {
7086                let prefix = match data_type {
7087                    DataType::Date => "d",
7088                    DataType::Time(..) => "t",
7089                    DataType::Timestamp(..) => "ts",
7090                    _ => "?",
7091                };
7092                write!(f, "{{{prefix} {value}}}")
7093            }
7094        }
7095    }
7096}
7097
7098/// A function call
7099#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7100#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7101#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7102pub struct Function {
7103    pub name: ObjectName,
7104    /// Flags whether this function call uses the [ODBC syntax].
7105    ///
7106    /// Example:
7107    /// ```sql
7108    /// SELECT {fn CONCAT('foo', 'bar')}
7109    /// ```
7110    ///
7111    /// [ODBC syntax]: https://learn.microsoft.com/en-us/sql/odbc/reference/develop-app/scalar-function-calls?view=sql-server-2017
7112    pub uses_odbc_syntax: bool,
7113    /// The parameters to the function, including any options specified within the
7114    /// delimiting parentheses.
7115    ///
7116    /// Example:
7117    /// ```plaintext
7118    /// HISTOGRAM(0.5, 0.6)(x, y)
7119    /// ```
7120    ///
7121    /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/aggregate-functions/parametric-functions)
7122    pub parameters: FunctionArguments,
7123    /// The arguments to the function, including any options specified within the
7124    /// delimiting parentheses.
7125    pub args: FunctionArguments,
7126    /// e.g. `x > 5` in `COUNT(x) FILTER (WHERE x > 5)`
7127    pub filter: Option<Box<Expr>>,
7128    /// Indicates how `NULL`s should be handled in the calculation.
7129    ///
7130    /// Example:
7131    /// ```plaintext
7132    /// FIRST_VALUE( <expr> ) [ { IGNORE | RESPECT } NULLS ] OVER ...
7133    /// ```
7134    ///
7135    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/functions/first_value)
7136    pub null_treatment: Option<NullTreatment>,
7137    /// The `OVER` clause, indicating a window function call.
7138    pub over: Option<WindowType>,
7139    /// A clause used with certain aggregate functions to control the ordering
7140    /// within grouped sets before the function is applied.
7141    ///
7142    /// Syntax:
7143    /// ```plaintext
7144    /// <aggregate_function>(expression) WITHIN GROUP (ORDER BY key [ASC | DESC], ...)
7145    /// ```
7146    pub within_group: Vec<OrderByExpr>,
7147}
7148
7149impl fmt::Display for Function {
7150    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7151        if self.uses_odbc_syntax {
7152            write!(f, "{{fn ")?;
7153        }
7154
7155        write!(f, "{}{}{}", self.name, self.parameters, self.args)?;
7156
7157        if !self.within_group.is_empty() {
7158            write!(
7159                f,
7160                " WITHIN GROUP (ORDER BY {})",
7161                display_comma_separated(&self.within_group)
7162            )?;
7163        }
7164
7165        if let Some(filter_cond) = &self.filter {
7166            write!(f, " FILTER (WHERE {filter_cond})")?;
7167        }
7168
7169        if let Some(null_treatment) = &self.null_treatment {
7170            write!(f, " {null_treatment}")?;
7171        }
7172
7173        if let Some(o) = &self.over {
7174            f.write_str(" OVER ")?;
7175            o.fmt(f)?;
7176        }
7177
7178        if self.uses_odbc_syntax {
7179            write!(f, "}}")?;
7180        }
7181
7182        Ok(())
7183    }
7184}
7185
7186/// The arguments passed to a function call.
7187#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7188#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7189#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7190pub enum FunctionArguments {
7191    /// Used for special functions like `CURRENT_TIMESTAMP` that are invoked
7192    /// without parentheses.
7193    None,
7194    /// On some dialects, a subquery can be passed without surrounding
7195    /// parentheses if it's the sole argument to the function.
7196    Subquery(Box<Query>),
7197    /// A normal function argument list, including any clauses within it such as
7198    /// `DISTINCT` or `ORDER BY`.
7199    List(FunctionArgumentList),
7200}
7201
7202impl fmt::Display for FunctionArguments {
7203    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7204        match self {
7205            FunctionArguments::None => Ok(()),
7206            FunctionArguments::Subquery(query) => write!(f, "({query})"),
7207            FunctionArguments::List(args) => write!(f, "({args})"),
7208        }
7209    }
7210}
7211
7212/// This represents everything inside the parentheses when calling a function.
7213#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7214#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7215#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7216pub struct FunctionArgumentList {
7217    /// `[ ALL | DISTINCT ]`
7218    pub duplicate_treatment: Option<DuplicateTreatment>,
7219    /// The function arguments.
7220    pub args: Vec<FunctionArg>,
7221    /// Additional clauses specified within the argument list.
7222    pub clauses: Vec<FunctionArgumentClause>,
7223}
7224
7225impl fmt::Display for FunctionArgumentList {
7226    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7227        if let Some(duplicate_treatment) = self.duplicate_treatment {
7228            write!(f, "{duplicate_treatment} ")?;
7229        }
7230        write!(f, "{}", display_comma_separated(&self.args))?;
7231        if !self.clauses.is_empty() {
7232            if !self.args.is_empty() {
7233                write!(f, " ")?;
7234            }
7235            write!(f, "{}", display_separated(&self.clauses, " "))?;
7236        }
7237        Ok(())
7238    }
7239}
7240
7241#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7242#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7243#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7244pub enum FunctionArgumentClause {
7245    /// Indicates how `NULL`s should be handled in the calculation, e.g. in `FIRST_VALUE` on [BigQuery].
7246    ///
7247    /// Syntax:
7248    /// ```plaintext
7249    /// { IGNORE | RESPECT } NULLS ]
7250    /// ```
7251    ///
7252    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#first_value
7253    IgnoreOrRespectNulls(NullTreatment),
7254    /// Specifies the the ordering for some ordered set aggregates, e.g. `ARRAY_AGG` on [BigQuery].
7255    ///
7256    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#array_agg
7257    OrderBy(Vec<OrderByExpr>),
7258    /// Specifies a limit for the `ARRAY_AGG` and `ARRAY_CONCAT_AGG` functions on BigQuery.
7259    Limit(Expr),
7260    /// Specifies the behavior on overflow of the `LISTAGG` function.
7261    ///
7262    /// See <https://trino.io/docs/current/functions/aggregate.html>.
7263    OnOverflow(ListAggOnOverflow),
7264    /// Specifies a minimum or maximum bound on the input to [`ANY_VALUE`] on BigQuery.
7265    ///
7266    /// Syntax:
7267    /// ```plaintext
7268    /// HAVING { MAX | MIN } expression
7269    /// ```
7270    ///
7271    /// [`ANY_VALUE`]: https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#any_value
7272    Having(HavingBound),
7273    /// The `SEPARATOR` clause to the [`GROUP_CONCAT`] function in MySQL.
7274    ///
7275    /// [`GROUP_CONCAT`]: https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat
7276    Separator(Value),
7277    /// The `ON NULL` clause for some JSON functions.
7278    ///
7279    /// [MSSQL `JSON_ARRAY`](https://learn.microsoft.com/en-us/sql/t-sql/functions/json-array-transact-sql?view=sql-server-ver16)
7280    /// [MSSQL `JSON_OBJECT`](https://learn.microsoft.com/en-us/sql/t-sql/functions/json-object-transact-sql?view=sql-server-ver16>)
7281    /// [PostgreSQL JSON functions](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSON-PROCESSING)
7282    JsonNullClause(JsonNullClause),
7283    /// The `RETURNING` clause for some JSON functions in PostgreSQL
7284    ///
7285    /// [`JSON_OBJECT`](https://www.postgresql.org/docs/current/functions-json.html#:~:text=json_object)
7286    JsonReturningClause(JsonReturningClause),
7287}
7288
7289impl fmt::Display for FunctionArgumentClause {
7290    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7291        match self {
7292            FunctionArgumentClause::IgnoreOrRespectNulls(null_treatment) => {
7293                write!(f, "{null_treatment}")
7294            }
7295            FunctionArgumentClause::OrderBy(order_by) => {
7296                write!(f, "ORDER BY {}", display_comma_separated(order_by))
7297            }
7298            FunctionArgumentClause::Limit(limit) => write!(f, "LIMIT {limit}"),
7299            FunctionArgumentClause::OnOverflow(on_overflow) => write!(f, "{on_overflow}"),
7300            FunctionArgumentClause::Having(bound) => write!(f, "{bound}"),
7301            FunctionArgumentClause::Separator(sep) => write!(f, "SEPARATOR {sep}"),
7302            FunctionArgumentClause::JsonNullClause(null_clause) => write!(f, "{null_clause}"),
7303            FunctionArgumentClause::JsonReturningClause(returning_clause) => {
7304                write!(f, "{returning_clause}")
7305            }
7306        }
7307    }
7308}
7309
7310/// A method call
7311#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7312#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7313#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7314pub struct Method {
7315    pub expr: Box<Expr>,
7316    // always non-empty
7317    pub method_chain: Vec<Function>,
7318}
7319
7320impl fmt::Display for Method {
7321    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7322        write!(
7323            f,
7324            "{}.{}",
7325            self.expr,
7326            display_separated(&self.method_chain, ".")
7327        )
7328    }
7329}
7330
7331#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7332#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7333#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7334pub enum DuplicateTreatment {
7335    /// Perform the calculation only unique values.
7336    Distinct,
7337    /// Retain all duplicate values (the default).
7338    All,
7339}
7340
7341impl fmt::Display for DuplicateTreatment {
7342    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7343        match self {
7344            DuplicateTreatment::Distinct => write!(f, "DISTINCT"),
7345            DuplicateTreatment::All => write!(f, "ALL"),
7346        }
7347    }
7348}
7349
7350#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7351#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7352#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7353pub enum AnalyzeFormatKind {
7354    /// e.g. `EXPLAIN ANALYZE FORMAT JSON SELECT * FROM tbl`
7355    Keyword(AnalyzeFormat),
7356    /// e.g. `EXPLAIN ANALYZE FORMAT=JSON SELECT * FROM tbl`
7357    Assignment(AnalyzeFormat),
7358}
7359
7360impl fmt::Display for AnalyzeFormatKind {
7361    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7362        match self {
7363            AnalyzeFormatKind::Keyword(format) => write!(f, "FORMAT {format}"),
7364            AnalyzeFormatKind::Assignment(format) => write!(f, "FORMAT={format}"),
7365        }
7366    }
7367}
7368
7369#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7370#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7371#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7372pub enum AnalyzeFormat {
7373    TEXT,
7374    GRAPHVIZ,
7375    JSON,
7376    TRADITIONAL,
7377    TREE,
7378}
7379
7380impl fmt::Display for AnalyzeFormat {
7381    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7382        f.write_str(match self {
7383            AnalyzeFormat::TEXT => "TEXT",
7384            AnalyzeFormat::GRAPHVIZ => "GRAPHVIZ",
7385            AnalyzeFormat::JSON => "JSON",
7386            AnalyzeFormat::TRADITIONAL => "TRADITIONAL",
7387            AnalyzeFormat::TREE => "TREE",
7388        })
7389    }
7390}
7391
7392/// External table's available file format
7393#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7394#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7395#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7396pub enum FileFormat {
7397    TEXTFILE,
7398    SEQUENCEFILE,
7399    ORC,
7400    PARQUET,
7401    AVRO,
7402    RCFILE,
7403    JSONFILE,
7404}
7405
7406impl fmt::Display for FileFormat {
7407    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7408        use self::FileFormat::*;
7409        f.write_str(match self {
7410            TEXTFILE => "TEXTFILE",
7411            SEQUENCEFILE => "SEQUENCEFILE",
7412            ORC => "ORC",
7413            PARQUET => "PARQUET",
7414            AVRO => "AVRO",
7415            RCFILE => "RCFILE",
7416            JSONFILE => "JSONFILE",
7417        })
7418    }
7419}
7420
7421/// The `ON OVERFLOW` clause of a LISTAGG invocation
7422#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7423#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7424#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7425pub enum ListAggOnOverflow {
7426    /// `ON OVERFLOW ERROR`
7427    Error,
7428
7429    /// `ON OVERFLOW TRUNCATE [ <filler> ] WITH[OUT] COUNT`
7430    Truncate {
7431        filler: Option<Box<Expr>>,
7432        with_count: bool,
7433    },
7434}
7435
7436impl fmt::Display for ListAggOnOverflow {
7437    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7438        write!(f, "ON OVERFLOW")?;
7439        match self {
7440            ListAggOnOverflow::Error => write!(f, " ERROR"),
7441            ListAggOnOverflow::Truncate { filler, with_count } => {
7442                write!(f, " TRUNCATE")?;
7443                if let Some(filler) = filler {
7444                    write!(f, " {filler}")?;
7445                }
7446                if *with_count {
7447                    write!(f, " WITH")?;
7448                } else {
7449                    write!(f, " WITHOUT")?;
7450                }
7451                write!(f, " COUNT")
7452            }
7453        }
7454    }
7455}
7456
7457/// The `HAVING` clause in a call to `ANY_VALUE` on BigQuery.
7458#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7459#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7460#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7461pub struct HavingBound(pub HavingBoundKind, pub Expr);
7462
7463impl fmt::Display for HavingBound {
7464    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7465        write!(f, "HAVING {} {}", self.0, self.1)
7466    }
7467}
7468
7469#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7470#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7471#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7472pub enum HavingBoundKind {
7473    Min,
7474    Max,
7475}
7476
7477impl fmt::Display for HavingBoundKind {
7478    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7479        match self {
7480            HavingBoundKind::Min => write!(f, "MIN"),
7481            HavingBoundKind::Max => write!(f, "MAX"),
7482        }
7483    }
7484}
7485
7486#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7487#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7488#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7489pub enum ObjectType {
7490    Table,
7491    View,
7492    MaterializedView,
7493    Index,
7494    Schema,
7495    Database,
7496    Role,
7497    Sequence,
7498    Stage,
7499    Type,
7500    User,
7501    Stream,
7502}
7503
7504impl fmt::Display for ObjectType {
7505    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7506        f.write_str(match self {
7507            ObjectType::Table => "TABLE",
7508            ObjectType::View => "VIEW",
7509            ObjectType::MaterializedView => "MATERIALIZED VIEW",
7510            ObjectType::Index => "INDEX",
7511            ObjectType::Schema => "SCHEMA",
7512            ObjectType::Database => "DATABASE",
7513            ObjectType::Role => "ROLE",
7514            ObjectType::Sequence => "SEQUENCE",
7515            ObjectType::Stage => "STAGE",
7516            ObjectType::Type => "TYPE",
7517            ObjectType::User => "USER",
7518            ObjectType::Stream => "STREAM",
7519        })
7520    }
7521}
7522
7523#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7524#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7525#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7526pub enum KillType {
7527    Connection,
7528    Query,
7529    Mutation,
7530}
7531
7532impl fmt::Display for KillType {
7533    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7534        f.write_str(match self {
7535            // MySQL
7536            KillType::Connection => "CONNECTION",
7537            KillType::Query => "QUERY",
7538            // Clickhouse supports Mutation
7539            KillType::Mutation => "MUTATION",
7540        })
7541    }
7542}
7543
7544#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7545#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7546#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7547pub enum HiveDistributionStyle {
7548    PARTITIONED {
7549        columns: Vec<ColumnDef>,
7550    },
7551    SKEWED {
7552        columns: Vec<ColumnDef>,
7553        on: Vec<ColumnDef>,
7554        stored_as_directories: bool,
7555    },
7556    NONE,
7557}
7558
7559#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7560#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7561#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7562pub enum HiveRowFormat {
7563    SERDE { class: String },
7564    DELIMITED { delimiters: Vec<HiveRowDelimiter> },
7565}
7566
7567#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7568#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7569#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7570pub struct HiveLoadDataFormat {
7571    pub serde: Expr,
7572    pub input_format: Expr,
7573}
7574
7575#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7576#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7577#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7578pub struct HiveRowDelimiter {
7579    pub delimiter: HiveDelimiter,
7580    pub char: Ident,
7581}
7582
7583impl fmt::Display for HiveRowDelimiter {
7584    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7585        write!(f, "{} ", self.delimiter)?;
7586        write!(f, "{}", self.char)
7587    }
7588}
7589
7590#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7591#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7592#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7593pub enum HiveDelimiter {
7594    FieldsTerminatedBy,
7595    FieldsEscapedBy,
7596    CollectionItemsTerminatedBy,
7597    MapKeysTerminatedBy,
7598    LinesTerminatedBy,
7599    NullDefinedAs,
7600}
7601
7602impl fmt::Display for HiveDelimiter {
7603    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7604        use HiveDelimiter::*;
7605        f.write_str(match self {
7606            FieldsTerminatedBy => "FIELDS TERMINATED BY",
7607            FieldsEscapedBy => "ESCAPED BY",
7608            CollectionItemsTerminatedBy => "COLLECTION ITEMS TERMINATED BY",
7609            MapKeysTerminatedBy => "MAP KEYS TERMINATED BY",
7610            LinesTerminatedBy => "LINES TERMINATED BY",
7611            NullDefinedAs => "NULL DEFINED AS",
7612        })
7613    }
7614}
7615
7616#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7617#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7618#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7619pub enum HiveDescribeFormat {
7620    Extended,
7621    Formatted,
7622}
7623
7624impl fmt::Display for HiveDescribeFormat {
7625    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7626        use HiveDescribeFormat::*;
7627        f.write_str(match self {
7628            Extended => "EXTENDED",
7629            Formatted => "FORMATTED",
7630        })
7631    }
7632}
7633
7634#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7635#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7636#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7637pub enum DescribeAlias {
7638    Describe,
7639    Explain,
7640    Desc,
7641}
7642
7643impl fmt::Display for DescribeAlias {
7644    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7645        use DescribeAlias::*;
7646        f.write_str(match self {
7647            Describe => "DESCRIBE",
7648            Explain => "EXPLAIN",
7649            Desc => "DESC",
7650        })
7651    }
7652}
7653
7654#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7655#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7656#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7657#[allow(clippy::large_enum_variant)]
7658pub enum HiveIOFormat {
7659    IOF {
7660        input_format: Expr,
7661        output_format: Expr,
7662    },
7663    FileFormat {
7664        format: FileFormat,
7665    },
7666}
7667
7668#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
7669#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7670#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7671pub struct HiveFormat {
7672    pub row_format: Option<HiveRowFormat>,
7673    pub serde_properties: Option<Vec<SqlOption>>,
7674    pub storage: Option<HiveIOFormat>,
7675    pub location: Option<String>,
7676}
7677
7678#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7679#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7680#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7681pub struct ClusteredIndex {
7682    pub name: Ident,
7683    pub asc: Option<bool>,
7684}
7685
7686impl fmt::Display for ClusteredIndex {
7687    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7688        write!(f, "{}", self.name)?;
7689        match self.asc {
7690            Some(true) => write!(f, " ASC"),
7691            Some(false) => write!(f, " DESC"),
7692            _ => Ok(()),
7693        }
7694    }
7695}
7696
7697#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7698#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7699#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7700pub enum TableOptionsClustered {
7701    ColumnstoreIndex,
7702    ColumnstoreIndexOrder(Vec<Ident>),
7703    Index(Vec<ClusteredIndex>),
7704}
7705
7706impl fmt::Display for TableOptionsClustered {
7707    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7708        match self {
7709            TableOptionsClustered::ColumnstoreIndex => {
7710                write!(f, "CLUSTERED COLUMNSTORE INDEX")
7711            }
7712            TableOptionsClustered::ColumnstoreIndexOrder(values) => {
7713                write!(
7714                    f,
7715                    "CLUSTERED COLUMNSTORE INDEX ORDER ({})",
7716                    display_comma_separated(values)
7717                )
7718            }
7719            TableOptionsClustered::Index(values) => {
7720                write!(f, "CLUSTERED INDEX ({})", display_comma_separated(values))
7721            }
7722        }
7723    }
7724}
7725
7726/// Specifies which partition the boundary values on table partitioning belongs to.
7727#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7728#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7729#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7730pub enum PartitionRangeDirection {
7731    Left,
7732    Right,
7733}
7734
7735#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7736#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7737#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7738pub enum SqlOption {
7739    /// Clustered represents the clustered version of table storage for MSSQL.
7740    ///
7741    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#TableOptions>
7742    Clustered(TableOptionsClustered),
7743    /// Single identifier options, e.g. `HEAP` for MSSQL.
7744    ///
7745    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#TableOptions>
7746    Ident(Ident),
7747    /// Any option that consists of a key value pair where the value is an expression. e.g.
7748    ///
7749    ///   WITH(DISTRIBUTION = ROUND_ROBIN)
7750    KeyValue { key: Ident, value: Expr },
7751    /// One or more table partitions and represents which partition the boundary values belong to,
7752    /// e.g.
7753    ///
7754    ///   PARTITION (id RANGE LEFT FOR VALUES (10, 20, 30, 40))
7755    ///
7756    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#TablePartitionOptions>
7757    Partition {
7758        column_name: Ident,
7759        range_direction: Option<PartitionRangeDirection>,
7760        for_values: Vec<Expr>,
7761    },
7762    /// Comment parameter (supports `=` and no `=` syntax)
7763    Comment(CommentDef),
7764    /// MySQL TableSpace option
7765    /// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
7766    TableSpace(TablespaceOption),
7767    /// An option representing a key value pair, where the value is a parenthesized list and with an optional name
7768    /// e.g.
7769    ///
7770    ///   UNION  = (tbl_name\[,tbl_name\]...) <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
7771    ///   ENGINE = ReplicatedMergeTree('/table_name','{replica}', ver) <https://clickhouse.com/docs/engines/table-engines/mergetree-family/replication>
7772    ///   ENGINE = SummingMergeTree(\[columns\]) <https://clickhouse.com/docs/engines/table-engines/mergetree-family/summingmergetree>
7773    NamedParenthesizedList(NamedParenthesizedList),
7774}
7775
7776impl fmt::Display for SqlOption {
7777    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7778        match self {
7779            SqlOption::Clustered(c) => write!(f, "{c}"),
7780            SqlOption::Ident(ident) => {
7781                write!(f, "{ident}")
7782            }
7783            SqlOption::KeyValue { key: name, value } => {
7784                write!(f, "{name} = {value}")
7785            }
7786            SqlOption::Partition {
7787                column_name,
7788                range_direction,
7789                for_values,
7790            } => {
7791                let direction = match range_direction {
7792                    Some(PartitionRangeDirection::Left) => " LEFT",
7793                    Some(PartitionRangeDirection::Right) => " RIGHT",
7794                    None => "",
7795                };
7796
7797                write!(
7798                    f,
7799                    "PARTITION ({} RANGE{} FOR VALUES ({}))",
7800                    column_name,
7801                    direction,
7802                    display_comma_separated(for_values)
7803                )
7804            }
7805            SqlOption::TableSpace(tablespace_option) => {
7806                write!(f, "TABLESPACE {}", tablespace_option.name)?;
7807                match tablespace_option.storage {
7808                    Some(StorageType::Disk) => write!(f, " STORAGE DISK"),
7809                    Some(StorageType::Memory) => write!(f, " STORAGE MEMORY"),
7810                    None => Ok(()),
7811                }
7812            }
7813            SqlOption::Comment(comment) => match comment {
7814                CommentDef::WithEq(comment) => {
7815                    write!(f, "COMMENT = '{comment}'")
7816                }
7817                CommentDef::WithoutEq(comment) => {
7818                    write!(f, "COMMENT '{comment}'")
7819                }
7820            },
7821            SqlOption::NamedParenthesizedList(value) => {
7822                write!(f, "{} = ", value.key)?;
7823                if let Some(key) = &value.name {
7824                    write!(f, "{key}")?;
7825                }
7826                if !value.values.is_empty() {
7827                    write!(f, "({})", display_comma_separated(&value.values))?
7828                }
7829                Ok(())
7830            }
7831        }
7832    }
7833}
7834
7835#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
7836#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7837#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7838pub enum StorageType {
7839    Disk,
7840    Memory,
7841}
7842
7843#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
7844#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7845#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7846/// MySql TableSpace option
7847/// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
7848pub struct TablespaceOption {
7849    pub name: String,
7850    pub storage: Option<StorageType>,
7851}
7852
7853#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7854#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7855#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7856pub struct SecretOption {
7857    pub key: Ident,
7858    pub value: Ident,
7859}
7860
7861impl fmt::Display for SecretOption {
7862    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7863        write!(f, "{} {}", self.key, self.value)
7864    }
7865}
7866
7867/// A `CREATE SERVER` statement.
7868///
7869/// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-createserver.html)
7870#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7871#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7872#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7873pub struct CreateServerStatement {
7874    pub name: ObjectName,
7875    pub if_not_exists: bool,
7876    pub server_type: Option<Ident>,
7877    pub version: Option<Ident>,
7878    pub foreign_data_wrapper: ObjectName,
7879    pub options: Option<Vec<CreateServerOption>>,
7880}
7881
7882impl fmt::Display for CreateServerStatement {
7883    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7884        let CreateServerStatement {
7885            name,
7886            if_not_exists,
7887            server_type,
7888            version,
7889            foreign_data_wrapper,
7890            options,
7891        } = self;
7892
7893        write!(
7894            f,
7895            "CREATE SERVER {if_not_exists}{name} ",
7896            if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
7897        )?;
7898
7899        if let Some(st) = server_type {
7900            write!(f, "TYPE {st} ")?;
7901        }
7902
7903        if let Some(v) = version {
7904            write!(f, "VERSION {v} ")?;
7905        }
7906
7907        write!(f, "FOREIGN DATA WRAPPER {foreign_data_wrapper}")?;
7908
7909        if let Some(o) = options {
7910            write!(f, " OPTIONS ({o})", o = display_comma_separated(o))?;
7911        }
7912
7913        Ok(())
7914    }
7915}
7916
7917#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7918#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7919#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7920pub struct CreateServerOption {
7921    pub key: Ident,
7922    pub value: Ident,
7923}
7924
7925impl fmt::Display for CreateServerOption {
7926    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7927        write!(f, "{} {}", self.key, self.value)
7928    }
7929}
7930
7931#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7932#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7933#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7934pub enum AttachDuckDBDatabaseOption {
7935    ReadOnly(Option<bool>),
7936    Type(Ident),
7937}
7938
7939impl fmt::Display for AttachDuckDBDatabaseOption {
7940    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7941        match self {
7942            AttachDuckDBDatabaseOption::ReadOnly(Some(true)) => write!(f, "READ_ONLY true"),
7943            AttachDuckDBDatabaseOption::ReadOnly(Some(false)) => write!(f, "READ_ONLY false"),
7944            AttachDuckDBDatabaseOption::ReadOnly(None) => write!(f, "READ_ONLY"),
7945            AttachDuckDBDatabaseOption::Type(t) => write!(f, "TYPE {t}"),
7946        }
7947    }
7948}
7949
7950#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7951#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7952#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7953pub enum TransactionMode {
7954    AccessMode(TransactionAccessMode),
7955    IsolationLevel(TransactionIsolationLevel),
7956}
7957
7958impl fmt::Display for TransactionMode {
7959    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7960        use TransactionMode::*;
7961        match self {
7962            AccessMode(access_mode) => write!(f, "{access_mode}"),
7963            IsolationLevel(iso_level) => write!(f, "ISOLATION LEVEL {iso_level}"),
7964        }
7965    }
7966}
7967
7968#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7969#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7970#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7971pub enum TransactionAccessMode {
7972    ReadOnly,
7973    ReadWrite,
7974}
7975
7976impl fmt::Display for TransactionAccessMode {
7977    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7978        use TransactionAccessMode::*;
7979        f.write_str(match self {
7980            ReadOnly => "READ ONLY",
7981            ReadWrite => "READ WRITE",
7982        })
7983    }
7984}
7985
7986#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7987#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7988#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7989pub enum TransactionIsolationLevel {
7990    ReadUncommitted,
7991    ReadCommitted,
7992    RepeatableRead,
7993    Serializable,
7994    Snapshot,
7995}
7996
7997impl fmt::Display for TransactionIsolationLevel {
7998    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7999        use TransactionIsolationLevel::*;
8000        f.write_str(match self {
8001            ReadUncommitted => "READ UNCOMMITTED",
8002            ReadCommitted => "READ COMMITTED",
8003            RepeatableRead => "REPEATABLE READ",
8004            Serializable => "SERIALIZABLE",
8005            Snapshot => "SNAPSHOT",
8006        })
8007    }
8008}
8009
8010/// Modifier for the transaction in the `BEGIN` syntax
8011///
8012/// SQLite: <https://sqlite.org/lang_transaction.html>
8013/// MS-SQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql>
8014#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8015#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8016#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8017pub enum TransactionModifier {
8018    Deferred,
8019    Immediate,
8020    Exclusive,
8021    Try,
8022    Catch,
8023}
8024
8025impl fmt::Display for TransactionModifier {
8026    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8027        use TransactionModifier::*;
8028        f.write_str(match self {
8029            Deferred => "DEFERRED",
8030            Immediate => "IMMEDIATE",
8031            Exclusive => "EXCLUSIVE",
8032            Try => "TRY",
8033            Catch => "CATCH",
8034        })
8035    }
8036}
8037
8038#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8039#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8040#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8041pub enum ShowStatementFilter {
8042    Like(String),
8043    ILike(String),
8044    Where(Expr),
8045    NoKeyword(String),
8046}
8047
8048impl fmt::Display for ShowStatementFilter {
8049    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8050        use ShowStatementFilter::*;
8051        match self {
8052            Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
8053            ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
8054            Where(expr) => write!(f, "WHERE {expr}"),
8055            NoKeyword(pattern) => write!(f, "'{}'", value::escape_single_quote_string(pattern)),
8056        }
8057    }
8058}
8059
8060#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8061#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8062#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8063pub enum ShowStatementInClause {
8064    IN,
8065    FROM,
8066}
8067
8068impl fmt::Display for ShowStatementInClause {
8069    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8070        use ShowStatementInClause::*;
8071        match self {
8072            FROM => write!(f, "FROM"),
8073            IN => write!(f, "IN"),
8074        }
8075    }
8076}
8077
8078/// Sqlite specific syntax
8079///
8080/// See [Sqlite documentation](https://sqlite.org/lang_conflict.html)
8081/// for more details.
8082#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8083#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8084#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8085pub enum SqliteOnConflict {
8086    Rollback,
8087    Abort,
8088    Fail,
8089    Ignore,
8090    Replace,
8091}
8092
8093impl fmt::Display for SqliteOnConflict {
8094    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8095        use SqliteOnConflict::*;
8096        match self {
8097            Rollback => write!(f, "OR ROLLBACK"),
8098            Abort => write!(f, "OR ABORT"),
8099            Fail => write!(f, "OR FAIL"),
8100            Ignore => write!(f, "OR IGNORE"),
8101            Replace => write!(f, "OR REPLACE"),
8102        }
8103    }
8104}
8105
8106/// Mysql specific syntax
8107///
8108/// See [Mysql documentation](https://dev.mysql.com/doc/refman/8.0/en/replace.html)
8109/// See [Mysql documentation](https://dev.mysql.com/doc/refman/8.0/en/insert.html)
8110/// for more details.
8111#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8112#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8113#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8114pub enum MysqlInsertPriority {
8115    LowPriority,
8116    Delayed,
8117    HighPriority,
8118}
8119
8120impl fmt::Display for crate::ast::MysqlInsertPriority {
8121    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8122        use MysqlInsertPriority::*;
8123        match self {
8124            LowPriority => write!(f, "LOW_PRIORITY"),
8125            Delayed => write!(f, "DELAYED"),
8126            HighPriority => write!(f, "HIGH_PRIORITY"),
8127        }
8128    }
8129}
8130
8131#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8132#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8133#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8134pub enum CopySource {
8135    Table {
8136        /// The name of the table to copy from.
8137        table_name: ObjectName,
8138        /// A list of column names to copy. Empty list means that all columns
8139        /// are copied.
8140        columns: Vec<Ident>,
8141    },
8142    Query(Box<Query>),
8143}
8144
8145#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8146#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8147#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8148pub enum CopyTarget {
8149    Stdin,
8150    Stdout,
8151    File {
8152        /// The path name of the input or output file.
8153        filename: String,
8154    },
8155    Program {
8156        /// A command to execute
8157        command: String,
8158    },
8159}
8160
8161impl fmt::Display for CopyTarget {
8162    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8163        use CopyTarget::*;
8164        match self {
8165            Stdin => write!(f, "STDIN"),
8166            Stdout => write!(f, "STDOUT"),
8167            File { filename } => write!(f, "'{}'", value::escape_single_quote_string(filename)),
8168            Program { command } => write!(
8169                f,
8170                "PROGRAM '{}'",
8171                value::escape_single_quote_string(command)
8172            ),
8173        }
8174    }
8175}
8176
8177#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8178#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8179#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8180pub enum OnCommit {
8181    DeleteRows,
8182    PreserveRows,
8183    Drop,
8184}
8185
8186/// An option in `COPY` statement.
8187///
8188/// <https://www.postgresql.org/docs/14/sql-copy.html>
8189#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8190#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8191#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8192pub enum CopyOption {
8193    /// FORMAT format_name
8194    Format(Ident),
8195    /// FREEZE \[ boolean \]
8196    Freeze(bool),
8197    /// DELIMITER 'delimiter_character'
8198    Delimiter(char),
8199    /// NULL 'null_string'
8200    Null(String),
8201    /// HEADER \[ boolean \]
8202    Header(bool),
8203    /// QUOTE 'quote_character'
8204    Quote(char),
8205    /// ESCAPE 'escape_character'
8206    Escape(char),
8207    /// FORCE_QUOTE { ( column_name [, ...] ) | * }
8208    ForceQuote(Vec<Ident>),
8209    /// FORCE_NOT_NULL ( column_name [, ...] )
8210    ForceNotNull(Vec<Ident>),
8211    /// FORCE_NULL ( column_name [, ...] )
8212    ForceNull(Vec<Ident>),
8213    /// ENCODING 'encoding_name'
8214    Encoding(String),
8215}
8216
8217impl fmt::Display for CopyOption {
8218    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8219        use CopyOption::*;
8220        match self {
8221            Format(name) => write!(f, "FORMAT {name}"),
8222            Freeze(true) => write!(f, "FREEZE"),
8223            Freeze(false) => write!(f, "FREEZE FALSE"),
8224            Delimiter(char) => write!(f, "DELIMITER '{char}'"),
8225            Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
8226            Header(true) => write!(f, "HEADER"),
8227            Header(false) => write!(f, "HEADER FALSE"),
8228            Quote(char) => write!(f, "QUOTE '{char}'"),
8229            Escape(char) => write!(f, "ESCAPE '{char}'"),
8230            ForceQuote(columns) => write!(f, "FORCE_QUOTE ({})", display_comma_separated(columns)),
8231            ForceNotNull(columns) => {
8232                write!(f, "FORCE_NOT_NULL ({})", display_comma_separated(columns))
8233            }
8234            ForceNull(columns) => write!(f, "FORCE_NULL ({})", display_comma_separated(columns)),
8235            Encoding(name) => write!(f, "ENCODING '{}'", value::escape_single_quote_string(name)),
8236        }
8237    }
8238}
8239
8240/// An option in `COPY` statement before PostgreSQL version 9.0.
8241///
8242/// [PostgreSQL](https://www.postgresql.org/docs/8.4/sql-copy.html)
8243/// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_COPY-alphabetical-parm-list.html)
8244#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8245#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8246#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8247pub enum CopyLegacyOption {
8248    /// ACCEPTANYDATE
8249    AcceptAnyDate,
8250    /// ACCEPTINVCHARS
8251    AcceptInvChars(Option<String>),
8252    /// ADDQUOTES
8253    AddQuotes,
8254    /// ALLOWOVERWRITE
8255    AllowOverwrite,
8256    /// BINARY
8257    Binary,
8258    /// BLANKSASNULL
8259    BlankAsNull,
8260    /// BZIP2
8261    Bzip2,
8262    /// CLEANPATH
8263    CleanPath,
8264    /// COMPUPDATE [ PRESET | { ON | TRUE } | { OFF | FALSE } ]
8265    CompUpdate { preset: bool, enabled: Option<bool> },
8266    /// CSV ...
8267    Csv(Vec<CopyLegacyCsvOption>),
8268    /// DATEFORMAT \[ AS \] {'dateformat_string' | 'auto' }
8269    DateFormat(Option<String>),
8270    /// DELIMITER \[ AS \] 'delimiter_character'
8271    Delimiter(char),
8272    /// EMPTYASNULL
8273    EmptyAsNull,
8274    /// ENCRYPTED \[ AUTO \]
8275    Encrypted { auto: bool },
8276    /// ESCAPE
8277    Escape,
8278    /// EXTENSION 'extension-name'
8279    Extension(String),
8280    /// FIXEDWIDTH \[ AS \] 'fixedwidth-spec'
8281    FixedWidth(String),
8282    /// GZIP
8283    Gzip,
8284    /// HEADER
8285    Header,
8286    /// IAM_ROLE { DEFAULT | 'arn:aws:iam::123456789:role/role1' }
8287    IamRole(IamRoleKind),
8288    /// IGNOREHEADER \[ AS \] number_rows
8289    IgnoreHeader(u64),
8290    /// JSON
8291    Json,
8292    /// MANIFEST \[ VERBOSE \]
8293    Manifest { verbose: bool },
8294    /// MAXFILESIZE \[ AS \] max-size \[ MB | GB \]
8295    MaxFileSize(FileSize),
8296    /// NULL \[ AS \] 'null_string'
8297    Null(String),
8298    /// PARALLEL [ { ON | TRUE } | { OFF | FALSE } ]
8299    Parallel(Option<bool>),
8300    /// PARQUET
8301    Parquet,
8302    /// PARTITION BY ( column_name [, ... ] ) \[ INCLUDE \]
8303    PartitionBy(UnloadPartitionBy),
8304    /// REGION \[ AS \] 'aws-region' }
8305    Region(String),
8306    /// REMOVEQUOTES
8307    RemoveQuotes,
8308    /// ROWGROUPSIZE \[ AS \] size \[ MB | GB \]
8309    RowGroupSize(FileSize),
8310    /// STATUPDATE [ { ON | TRUE } | { OFF | FALSE } ]
8311    StatUpdate(Option<bool>),
8312    /// TIMEFORMAT \[ AS \] {'timeformat_string' | 'auto' | 'epochsecs' | 'epochmillisecs' }
8313    TimeFormat(Option<String>),
8314    /// TRUNCATECOLUMNS
8315    TruncateColumns,
8316    /// ZSTD
8317    Zstd,
8318}
8319
8320impl fmt::Display for CopyLegacyOption {
8321    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8322        use CopyLegacyOption::*;
8323        match self {
8324            AcceptAnyDate => write!(f, "ACCEPTANYDATE"),
8325            AcceptInvChars(ch) => {
8326                write!(f, "ACCEPTINVCHARS")?;
8327                if let Some(ch) = ch {
8328                    write!(f, " '{}'", value::escape_single_quote_string(ch))?;
8329                }
8330                Ok(())
8331            }
8332            AddQuotes => write!(f, "ADDQUOTES"),
8333            AllowOverwrite => write!(f, "ALLOWOVERWRITE"),
8334            Binary => write!(f, "BINARY"),
8335            BlankAsNull => write!(f, "BLANKSASNULL"),
8336            Bzip2 => write!(f, "BZIP2"),
8337            CleanPath => write!(f, "CLEANPATH"),
8338            CompUpdate { preset, enabled } => {
8339                write!(f, "COMPUPDATE")?;
8340                if *preset {
8341                    write!(f, " PRESET")?;
8342                } else if let Some(enabled) = enabled {
8343                    write!(
8344                        f,
8345                        "{}",
8346                        match enabled {
8347                            true => " TRUE",
8348                            false => " FALSE",
8349                        }
8350                    )?;
8351                }
8352                Ok(())
8353            }
8354            Csv(opts) => {
8355                write!(f, "CSV")?;
8356                if !opts.is_empty() {
8357                    write!(f, " {}", display_separated(opts, " "))?;
8358                }
8359                Ok(())
8360            }
8361            DateFormat(fmt) => {
8362                write!(f, "DATEFORMAT")?;
8363                if let Some(fmt) = fmt {
8364                    write!(f, " '{}'", value::escape_single_quote_string(fmt))?;
8365                }
8366                Ok(())
8367            }
8368            Delimiter(char) => write!(f, "DELIMITER '{char}'"),
8369            EmptyAsNull => write!(f, "EMPTYASNULL"),
8370            Encrypted { auto } => write!(f, "ENCRYPTED{}", if *auto { " AUTO" } else { "" }),
8371            Escape => write!(f, "ESCAPE"),
8372            Extension(ext) => write!(f, "EXTENSION '{}'", value::escape_single_quote_string(ext)),
8373            FixedWidth(spec) => write!(
8374                f,
8375                "FIXEDWIDTH '{}'",
8376                value::escape_single_quote_string(spec)
8377            ),
8378            Gzip => write!(f, "GZIP"),
8379            Header => write!(f, "HEADER"),
8380            IamRole(role) => write!(f, "IAM_ROLE {role}"),
8381            IgnoreHeader(num_rows) => write!(f, "IGNOREHEADER {num_rows}"),
8382            Json => write!(f, "JSON"),
8383            Manifest { verbose } => write!(f, "MANIFEST{}", if *verbose { " VERBOSE" } else { "" }),
8384            MaxFileSize(file_size) => write!(f, "MAXFILESIZE {file_size}"),
8385            Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
8386            Parallel(enabled) => {
8387                write!(
8388                    f,
8389                    "PARALLEL{}",
8390                    match enabled {
8391                        Some(true) => " TRUE",
8392                        Some(false) => " FALSE",
8393                        _ => "",
8394                    }
8395                )
8396            }
8397            Parquet => write!(f, "PARQUET"),
8398            PartitionBy(p) => write!(f, "{p}"),
8399            Region(region) => write!(f, "REGION '{}'", value::escape_single_quote_string(region)),
8400            RemoveQuotes => write!(f, "REMOVEQUOTES"),
8401            RowGroupSize(file_size) => write!(f, "ROWGROUPSIZE {file_size}"),
8402            StatUpdate(enabled) => {
8403                write!(
8404                    f,
8405                    "STATUPDATE{}",
8406                    match enabled {
8407                        Some(true) => " TRUE",
8408                        Some(false) => " FALSE",
8409                        _ => "",
8410                    }
8411                )
8412            }
8413            TimeFormat(fmt) => {
8414                write!(f, "TIMEFORMAT")?;
8415                if let Some(fmt) = fmt {
8416                    write!(f, " '{}'", value::escape_single_quote_string(fmt))?;
8417                }
8418                Ok(())
8419            }
8420            TruncateColumns => write!(f, "TRUNCATECOLUMNS"),
8421            Zstd => write!(f, "ZSTD"),
8422        }
8423    }
8424}
8425
8426/// ```sql
8427/// SIZE \[ MB | GB \]
8428/// ```
8429#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8430#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8431#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8432pub struct FileSize {
8433    pub size: Value,
8434    pub unit: Option<FileSizeUnit>,
8435}
8436
8437impl fmt::Display for FileSize {
8438    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8439        write!(f, "{}", self.size)?;
8440        if let Some(unit) = &self.unit {
8441            write!(f, " {unit}")?;
8442        }
8443        Ok(())
8444    }
8445}
8446
8447#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8448#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8449#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8450pub enum FileSizeUnit {
8451    MB,
8452    GB,
8453}
8454
8455impl fmt::Display for FileSizeUnit {
8456    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8457        match self {
8458            FileSizeUnit::MB => write!(f, "MB"),
8459            FileSizeUnit::GB => write!(f, "GB"),
8460        }
8461    }
8462}
8463
8464/// Specifies the partition keys for the unload operation
8465///
8466/// ```sql
8467/// PARTITION BY ( column_name [, ... ] ) [ INCLUDE ]
8468/// ```
8469#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8470#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8471#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8472pub struct UnloadPartitionBy {
8473    pub columns: Vec<Ident>,
8474    pub include: bool,
8475}
8476
8477impl fmt::Display for UnloadPartitionBy {
8478    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8479        write!(
8480            f,
8481            "PARTITION BY ({}){}",
8482            display_comma_separated(&self.columns),
8483            if self.include { " INCLUDE" } else { "" }
8484        )
8485    }
8486}
8487
8488/// An `IAM_ROLE` option in the AWS ecosystem
8489///
8490/// [Redshift COPY](https://docs.aws.amazon.com/redshift/latest/dg/copy-parameters-authorization.html#copy-iam-role)
8491#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8492#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8493#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8494pub enum IamRoleKind {
8495    /// Default role
8496    Default,
8497    /// Specific role ARN, for example: `arn:aws:iam::123456789:role/role1`
8498    Arn(String),
8499}
8500
8501impl fmt::Display for IamRoleKind {
8502    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8503        match self {
8504            IamRoleKind::Default => write!(f, "DEFAULT"),
8505            IamRoleKind::Arn(arn) => write!(f, "'{arn}'"),
8506        }
8507    }
8508}
8509
8510/// A `CSV` option in `COPY` statement before PostgreSQL version 9.0.
8511///
8512/// <https://www.postgresql.org/docs/8.4/sql-copy.html>
8513#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8514#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8515#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8516pub enum CopyLegacyCsvOption {
8517    /// HEADER
8518    Header,
8519    /// QUOTE \[ AS \] 'quote_character'
8520    Quote(char),
8521    /// ESCAPE \[ AS \] 'escape_character'
8522    Escape(char),
8523    /// FORCE QUOTE { column_name [, ...] | * }
8524    ForceQuote(Vec<Ident>),
8525    /// FORCE NOT NULL column_name [, ...]
8526    ForceNotNull(Vec<Ident>),
8527}
8528
8529impl fmt::Display for CopyLegacyCsvOption {
8530    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8531        use CopyLegacyCsvOption::*;
8532        match self {
8533            Header => write!(f, "HEADER"),
8534            Quote(char) => write!(f, "QUOTE '{char}'"),
8535            Escape(char) => write!(f, "ESCAPE '{char}'"),
8536            ForceQuote(columns) => write!(f, "FORCE QUOTE {}", display_comma_separated(columns)),
8537            ForceNotNull(columns) => {
8538                write!(f, "FORCE NOT NULL {}", display_comma_separated(columns))
8539            }
8540        }
8541    }
8542}
8543
8544#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8545#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8546#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8547pub enum DiscardObject {
8548    ALL,
8549    PLANS,
8550    SEQUENCES,
8551    TEMP,
8552}
8553
8554impl fmt::Display for DiscardObject {
8555    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8556        match self {
8557            DiscardObject::ALL => f.write_str("ALL"),
8558            DiscardObject::PLANS => f.write_str("PLANS"),
8559            DiscardObject::SEQUENCES => f.write_str("SEQUENCES"),
8560            DiscardObject::TEMP => f.write_str("TEMP"),
8561        }
8562    }
8563}
8564
8565#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8566#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8567#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8568pub enum FlushType {
8569    BinaryLogs,
8570    EngineLogs,
8571    ErrorLogs,
8572    GeneralLogs,
8573    Hosts,
8574    Logs,
8575    Privileges,
8576    OptimizerCosts,
8577    RelayLogs,
8578    SlowLogs,
8579    Status,
8580    UserResources,
8581    Tables,
8582}
8583
8584impl fmt::Display for FlushType {
8585    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8586        match self {
8587            FlushType::BinaryLogs => f.write_str("BINARY LOGS"),
8588            FlushType::EngineLogs => f.write_str("ENGINE LOGS"),
8589            FlushType::ErrorLogs => f.write_str("ERROR LOGS"),
8590            FlushType::GeneralLogs => f.write_str("GENERAL LOGS"),
8591            FlushType::Hosts => f.write_str("HOSTS"),
8592            FlushType::Logs => f.write_str("LOGS"),
8593            FlushType::Privileges => f.write_str("PRIVILEGES"),
8594            FlushType::OptimizerCosts => f.write_str("OPTIMIZER_COSTS"),
8595            FlushType::RelayLogs => f.write_str("RELAY LOGS"),
8596            FlushType::SlowLogs => f.write_str("SLOW LOGS"),
8597            FlushType::Status => f.write_str("STATUS"),
8598            FlushType::UserResources => f.write_str("USER_RESOURCES"),
8599            FlushType::Tables => f.write_str("TABLES"),
8600        }
8601    }
8602}
8603
8604#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8605#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8606#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8607pub enum FlushLocation {
8608    NoWriteToBinlog,
8609    Local,
8610}
8611
8612impl fmt::Display for FlushLocation {
8613    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8614        match self {
8615            FlushLocation::NoWriteToBinlog => f.write_str("NO_WRITE_TO_BINLOG"),
8616            FlushLocation::Local => f.write_str("LOCAL"),
8617        }
8618    }
8619}
8620
8621/// Optional context modifier for statements that can be or `LOCAL`, `GLOBAL`, or `SESSION`.
8622#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8623#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8624#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8625pub enum ContextModifier {
8626    /// `LOCAL` identifier, usually related to transactional states.
8627    Local,
8628    /// `SESSION` identifier
8629    Session,
8630    /// `GLOBAL` identifier
8631    Global,
8632}
8633
8634impl fmt::Display for ContextModifier {
8635    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8636        match self {
8637            Self::Local => {
8638                write!(f, "LOCAL ")
8639            }
8640            Self::Session => {
8641                write!(f, "SESSION ")
8642            }
8643            Self::Global => {
8644                write!(f, "GLOBAL ")
8645            }
8646        }
8647    }
8648}
8649
8650/// Function describe in DROP FUNCTION.
8651#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8652#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8653pub enum DropFunctionOption {
8654    Restrict,
8655    Cascade,
8656}
8657
8658impl fmt::Display for DropFunctionOption {
8659    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8660        match self {
8661            DropFunctionOption::Restrict => write!(f, "RESTRICT "),
8662            DropFunctionOption::Cascade => write!(f, "CASCADE  "),
8663        }
8664    }
8665}
8666
8667/// Generic function description for DROP FUNCTION and CREATE TRIGGER.
8668#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8669#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8670#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8671pub struct FunctionDesc {
8672    pub name: ObjectName,
8673    pub args: Option<Vec<OperateFunctionArg>>,
8674}
8675
8676impl fmt::Display for FunctionDesc {
8677    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8678        write!(f, "{}", self.name)?;
8679        if let Some(args) = &self.args {
8680            write!(f, "({})", display_comma_separated(args))?;
8681        }
8682        Ok(())
8683    }
8684}
8685
8686/// Function argument in CREATE OR DROP FUNCTION.
8687#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8688#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8689#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8690pub struct OperateFunctionArg {
8691    pub mode: Option<ArgMode>,
8692    pub name: Option<Ident>,
8693    pub data_type: DataType,
8694    pub default_expr: Option<Expr>,
8695}
8696
8697impl OperateFunctionArg {
8698    /// Returns an unnamed argument.
8699    pub fn unnamed(data_type: DataType) -> Self {
8700        Self {
8701            mode: None,
8702            name: None,
8703            data_type,
8704            default_expr: None,
8705        }
8706    }
8707
8708    /// Returns an argument with name.
8709    pub fn with_name(name: &str, data_type: DataType) -> Self {
8710        Self {
8711            mode: None,
8712            name: Some(name.into()),
8713            data_type,
8714            default_expr: None,
8715        }
8716    }
8717}
8718
8719impl fmt::Display for OperateFunctionArg {
8720    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8721        if let Some(mode) = &self.mode {
8722            write!(f, "{mode} ")?;
8723        }
8724        if let Some(name) = &self.name {
8725            write!(f, "{name} ")?;
8726        }
8727        write!(f, "{}", self.data_type)?;
8728        if let Some(default_expr) = &self.default_expr {
8729            write!(f, " = {default_expr}")?;
8730        }
8731        Ok(())
8732    }
8733}
8734
8735/// The mode of an argument in CREATE FUNCTION.
8736#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8737#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8738#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8739pub enum ArgMode {
8740    In,
8741    Out,
8742    InOut,
8743}
8744
8745impl fmt::Display for ArgMode {
8746    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8747        match self {
8748            ArgMode::In => write!(f, "IN"),
8749            ArgMode::Out => write!(f, "OUT"),
8750            ArgMode::InOut => write!(f, "INOUT"),
8751        }
8752    }
8753}
8754
8755/// These attributes inform the query optimizer about the behavior of the function.
8756#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8757#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8758#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8759pub enum FunctionBehavior {
8760    Immutable,
8761    Stable,
8762    Volatile,
8763}
8764
8765impl fmt::Display for FunctionBehavior {
8766    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8767        match self {
8768            FunctionBehavior::Immutable => write!(f, "IMMUTABLE"),
8769            FunctionBehavior::Stable => write!(f, "STABLE"),
8770            FunctionBehavior::Volatile => write!(f, "VOLATILE"),
8771        }
8772    }
8773}
8774
8775/// Specifies whether the function is SECURITY DEFINER or SECURITY INVOKER.
8776#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8777#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8778#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8779pub enum FunctionSecurity {
8780    Definer,
8781    Invoker,
8782}
8783
8784impl fmt::Display for FunctionSecurity {
8785    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8786        match self {
8787            FunctionSecurity::Definer => write!(f, "SECURITY DEFINER"),
8788            FunctionSecurity::Invoker => write!(f, "SECURITY INVOKER"),
8789        }
8790    }
8791}
8792
8793/// Value for a SET configuration parameter in a CREATE FUNCTION statement.
8794///
8795/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
8796#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8797#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8798#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8799pub enum FunctionSetValue {
8800    /// SET param = value1, value2, ...
8801    Values(Vec<Expr>),
8802    /// SET param FROM CURRENT
8803    FromCurrent,
8804}
8805
8806/// A SET configuration_parameter clause in a CREATE FUNCTION statement.
8807///
8808/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
8809#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8810#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8811#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8812pub struct FunctionDefinitionSetParam {
8813    pub name: Ident,
8814    pub value: FunctionSetValue,
8815}
8816
8817impl fmt::Display for FunctionDefinitionSetParam {
8818    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8819        write!(f, "SET {} ", self.name)?;
8820        match &self.value {
8821            FunctionSetValue::Values(values) => {
8822                write!(f, "= {}", display_comma_separated(values))
8823            }
8824            FunctionSetValue::FromCurrent => write!(f, "FROM CURRENT"),
8825        }
8826    }
8827}
8828
8829/// These attributes describe the behavior of the function when called with a null argument.
8830#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8831#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8832#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8833pub enum FunctionCalledOnNull {
8834    CalledOnNullInput,
8835    ReturnsNullOnNullInput,
8836    Strict,
8837}
8838
8839impl fmt::Display for FunctionCalledOnNull {
8840    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8841        match self {
8842            FunctionCalledOnNull::CalledOnNullInput => write!(f, "CALLED ON NULL INPUT"),
8843            FunctionCalledOnNull::ReturnsNullOnNullInput => write!(f, "RETURNS NULL ON NULL INPUT"),
8844            FunctionCalledOnNull::Strict => write!(f, "STRICT"),
8845        }
8846    }
8847}
8848
8849/// If it is safe for PostgreSQL to call the function from multiple threads at once
8850#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8851#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8852#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8853pub enum FunctionParallel {
8854    Unsafe,
8855    Restricted,
8856    Safe,
8857}
8858
8859impl fmt::Display for FunctionParallel {
8860    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8861        match self {
8862            FunctionParallel::Unsafe => write!(f, "PARALLEL UNSAFE"),
8863            FunctionParallel::Restricted => write!(f, "PARALLEL RESTRICTED"),
8864            FunctionParallel::Safe => write!(f, "PARALLEL SAFE"),
8865        }
8866    }
8867}
8868
8869/// [BigQuery] Determinism specifier used in a UDF definition.
8870///
8871/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
8872#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8873#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8874#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8875pub enum FunctionDeterminismSpecifier {
8876    Deterministic,
8877    NotDeterministic,
8878}
8879
8880impl fmt::Display for FunctionDeterminismSpecifier {
8881    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8882        match self {
8883            FunctionDeterminismSpecifier::Deterministic => {
8884                write!(f, "DETERMINISTIC")
8885            }
8886            FunctionDeterminismSpecifier::NotDeterministic => {
8887                write!(f, "NOT DETERMINISTIC")
8888            }
8889        }
8890    }
8891}
8892
8893/// Represent the expression body of a `CREATE FUNCTION` statement as well as
8894/// where within the statement, the body shows up.
8895///
8896/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
8897/// [PostgreSQL]: https://www.postgresql.org/docs/15/sql-createfunction.html
8898/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
8899#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8900#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8901#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8902pub enum CreateFunctionBody {
8903    /// A function body expression using the 'AS' keyword and shows up
8904    /// before any `OPTIONS` clause.
8905    ///
8906    /// Example:
8907    /// ```sql
8908    /// CREATE FUNCTION myfunc(x FLOAT64, y FLOAT64) RETURNS FLOAT64
8909    /// AS (x * y)
8910    /// OPTIONS(description="desc");
8911    /// ```
8912    ///
8913    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
8914    /// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
8915    AsBeforeOptions {
8916        /// The primary expression.
8917        body: Expr,
8918        /// Link symbol if the primary expression contains the name of shared library file.
8919        ///
8920        /// Example:
8921        /// ```sql
8922        /// CREATE FUNCTION cas_in(input cstring) RETURNS cas
8923        /// AS 'MODULE_PATHNAME', 'cas_in_wrapper'
8924        /// ```
8925        /// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
8926        link_symbol: Option<Expr>,
8927    },
8928    /// A function body expression using the 'AS' keyword and shows up
8929    /// after any `OPTIONS` clause.
8930    ///
8931    /// Example:
8932    /// ```sql
8933    /// CREATE FUNCTION myfunc(x FLOAT64, y FLOAT64) RETURNS FLOAT64
8934    /// OPTIONS(description="desc")
8935    /// AS (x * y);
8936    /// ```
8937    ///
8938    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
8939    AsAfterOptions(Expr),
8940    /// Function body with statements before the `RETURN` keyword.
8941    ///
8942    /// Example:
8943    /// ```sql
8944    /// CREATE FUNCTION my_scalar_udf(a INT, b INT)
8945    /// RETURNS INT
8946    /// AS
8947    /// BEGIN
8948    ///     DECLARE c INT;
8949    ///     SET c = a + b;
8950    ///     RETURN c;
8951    /// END
8952    /// ```
8953    ///
8954    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
8955    AsBeginEnd(BeginEndStatements),
8956    /// Function body expression using the 'RETURN' keyword.
8957    ///
8958    /// Example:
8959    /// ```sql
8960    /// CREATE FUNCTION myfunc(a INTEGER, IN b INTEGER = 1) RETURNS INTEGER
8961    /// LANGUAGE SQL
8962    /// RETURN a + b;
8963    /// ```
8964    ///
8965    /// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
8966    Return(Expr),
8967
8968    /// Function body expression using the 'AS RETURN' keywords
8969    ///
8970    /// Example:
8971    /// ```sql
8972    /// CREATE FUNCTION myfunc(a INT, b INT)
8973    /// RETURNS TABLE
8974    /// AS RETURN (SELECT a + b AS sum);
8975    /// ```
8976    ///
8977    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
8978    AsReturnExpr(Expr),
8979
8980    /// Function body expression using the 'AS RETURN' keywords, with an un-parenthesized SELECT query
8981    ///
8982    /// Example:
8983    /// ```sql
8984    /// CREATE FUNCTION myfunc(a INT, b INT)
8985    /// RETURNS TABLE
8986    /// AS RETURN SELECT a + b AS sum;
8987    /// ```
8988    ///
8989    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql?view=sql-server-ver16#select_stmt
8990    AsReturnSelect(Select),
8991}
8992
8993#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8994#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8995#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8996pub enum CreateFunctionUsing {
8997    Jar(String),
8998    File(String),
8999    Archive(String),
9000}
9001
9002impl fmt::Display for CreateFunctionUsing {
9003    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9004        write!(f, "USING ")?;
9005        match self {
9006            CreateFunctionUsing::Jar(uri) => write!(f, "JAR '{uri}'"),
9007            CreateFunctionUsing::File(uri) => write!(f, "FILE '{uri}'"),
9008            CreateFunctionUsing::Archive(uri) => write!(f, "ARCHIVE '{uri}'"),
9009        }
9010    }
9011}
9012
9013/// `NAME = <EXPR>` arguments for DuckDB macros
9014///
9015/// See [Create Macro - DuckDB](https://duckdb.org/docs/sql/statements/create_macro)
9016/// for more details
9017#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9018#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9019#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9020pub struct MacroArg {
9021    pub name: Ident,
9022    pub default_expr: Option<Expr>,
9023}
9024
9025impl MacroArg {
9026    /// Returns an argument with name.
9027    pub fn new(name: &str) -> Self {
9028        Self {
9029            name: name.into(),
9030            default_expr: None,
9031        }
9032    }
9033}
9034
9035impl fmt::Display for MacroArg {
9036    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9037        write!(f, "{}", self.name)?;
9038        if let Some(default_expr) = &self.default_expr {
9039            write!(f, " := {default_expr}")?;
9040        }
9041        Ok(())
9042    }
9043}
9044
9045#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9046#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9047#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9048pub enum MacroDefinition {
9049    Expr(Expr),
9050    Table(Box<Query>),
9051}
9052
9053impl fmt::Display for MacroDefinition {
9054    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9055        match self {
9056            MacroDefinition::Expr(expr) => write!(f, "{expr}")?,
9057            MacroDefinition::Table(query) => write!(f, "{query}")?,
9058        }
9059        Ok(())
9060    }
9061}
9062
9063/// Schema possible naming variants ([1]).
9064///
9065/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#schema-definition
9066#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9067#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9068#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9069pub enum SchemaName {
9070    /// Only schema name specified: `<schema name>`.
9071    Simple(ObjectName),
9072    /// Only authorization identifier specified: `AUTHORIZATION <schema authorization identifier>`.
9073    UnnamedAuthorization(Ident),
9074    /// Both schema name and authorization identifier specified: `<schema name>  AUTHORIZATION <schema authorization identifier>`.
9075    NamedAuthorization(ObjectName, Ident),
9076}
9077
9078impl fmt::Display for SchemaName {
9079    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9080        match self {
9081            SchemaName::Simple(name) => {
9082                write!(f, "{name}")
9083            }
9084            SchemaName::UnnamedAuthorization(authorization) => {
9085                write!(f, "AUTHORIZATION {authorization}")
9086            }
9087            SchemaName::NamedAuthorization(name, authorization) => {
9088                write!(f, "{name} AUTHORIZATION {authorization}")
9089            }
9090        }
9091    }
9092}
9093
9094/// Fulltext search modifiers ([1]).
9095///
9096/// [1]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html#function_match
9097#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9098#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9099#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9100pub enum SearchModifier {
9101    /// `IN NATURAL LANGUAGE MODE`.
9102    InNaturalLanguageMode,
9103    /// `IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION`.
9104    InNaturalLanguageModeWithQueryExpansion,
9105    ///`IN BOOLEAN MODE`.
9106    InBooleanMode,
9107    ///`WITH QUERY EXPANSION`.
9108    WithQueryExpansion,
9109}
9110
9111impl fmt::Display for SearchModifier {
9112    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9113        match self {
9114            Self::InNaturalLanguageMode => {
9115                write!(f, "IN NATURAL LANGUAGE MODE")?;
9116            }
9117            Self::InNaturalLanguageModeWithQueryExpansion => {
9118                write!(f, "IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION")?;
9119            }
9120            Self::InBooleanMode => {
9121                write!(f, "IN BOOLEAN MODE")?;
9122            }
9123            Self::WithQueryExpansion => {
9124                write!(f, "WITH QUERY EXPANSION")?;
9125            }
9126        }
9127
9128        Ok(())
9129    }
9130}
9131
9132#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9133#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9134#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9135pub struct LockTable {
9136    pub table: Ident,
9137    pub alias: Option<Ident>,
9138    pub lock_type: LockTableType,
9139}
9140
9141impl fmt::Display for LockTable {
9142    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9143        let Self {
9144            table: tbl_name,
9145            alias,
9146            lock_type,
9147        } = self;
9148
9149        write!(f, "{tbl_name} ")?;
9150        if let Some(alias) = alias {
9151            write!(f, "AS {alias} ")?;
9152        }
9153        write!(f, "{lock_type}")?;
9154        Ok(())
9155    }
9156}
9157
9158#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9159#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9160#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9161pub enum LockTableType {
9162    Read { local: bool },
9163    Write { low_priority: bool },
9164}
9165
9166impl fmt::Display for LockTableType {
9167    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9168        match self {
9169            Self::Read { local } => {
9170                write!(f, "READ")?;
9171                if *local {
9172                    write!(f, " LOCAL")?;
9173                }
9174            }
9175            Self::Write { low_priority } => {
9176                if *low_priority {
9177                    write!(f, "LOW_PRIORITY ")?;
9178                }
9179                write!(f, "WRITE")?;
9180            }
9181        }
9182
9183        Ok(())
9184    }
9185}
9186
9187#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9188#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9189#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9190pub struct HiveSetLocation {
9191    pub has_set: bool,
9192    pub location: Ident,
9193}
9194
9195impl fmt::Display for HiveSetLocation {
9196    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9197        if self.has_set {
9198            write!(f, "SET ")?;
9199        }
9200        write!(f, "LOCATION {}", self.location)
9201    }
9202}
9203
9204/// MySQL `ALTER TABLE` only  [FIRST | AFTER column_name]
9205#[allow(clippy::large_enum_variant)]
9206#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9207#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9208#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9209pub enum MySQLColumnPosition {
9210    First,
9211    After(Ident),
9212}
9213
9214impl Display for MySQLColumnPosition {
9215    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9216        match self {
9217            MySQLColumnPosition::First => write!(f, "FIRST"),
9218            MySQLColumnPosition::After(ident) => {
9219                let column_name = &ident.value;
9220                write!(f, "AFTER {column_name}")
9221            }
9222        }
9223    }
9224}
9225
9226/// MySQL `CREATE VIEW` algorithm parameter: [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
9227#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9228#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9229#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9230pub enum CreateViewAlgorithm {
9231    Undefined,
9232    Merge,
9233    TempTable,
9234}
9235
9236impl Display for CreateViewAlgorithm {
9237    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9238        match self {
9239            CreateViewAlgorithm::Undefined => write!(f, "UNDEFINED"),
9240            CreateViewAlgorithm::Merge => write!(f, "MERGE"),
9241            CreateViewAlgorithm::TempTable => write!(f, "TEMPTABLE"),
9242        }
9243    }
9244}
9245/// MySQL `CREATE VIEW` security parameter: [SQL SECURITY { DEFINER | INVOKER }]
9246#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9247#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9248#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9249pub enum CreateViewSecurity {
9250    Definer,
9251    Invoker,
9252}
9253
9254impl Display for CreateViewSecurity {
9255    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9256        match self {
9257            CreateViewSecurity::Definer => write!(f, "DEFINER"),
9258            CreateViewSecurity::Invoker => write!(f, "INVOKER"),
9259        }
9260    }
9261}
9262
9263/// [MySQL] `CREATE VIEW` additional parameters
9264///
9265/// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/create-view.html
9266#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9267#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9268#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9269pub struct CreateViewParams {
9270    pub algorithm: Option<CreateViewAlgorithm>,
9271    pub definer: Option<GranteeName>,
9272    pub security: Option<CreateViewSecurity>,
9273}
9274
9275impl Display for CreateViewParams {
9276    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9277        let CreateViewParams {
9278            algorithm,
9279            definer,
9280            security,
9281        } = self;
9282        if let Some(algorithm) = algorithm {
9283            write!(f, "ALGORITHM = {algorithm} ")?;
9284        }
9285        if let Some(definers) = definer {
9286            write!(f, "DEFINER = {definers} ")?;
9287        }
9288        if let Some(security) = security {
9289            write!(f, "SQL SECURITY {security} ")?;
9290        }
9291        Ok(())
9292    }
9293}
9294
9295#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9296#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9297#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9298/// Key/Value, where the value is a (optionally named) list of identifiers
9299///
9300/// ```sql
9301/// UNION = (tbl_name[,tbl_name]...)
9302/// ENGINE = ReplicatedMergeTree('/table_name','{replica}', ver)
9303/// ENGINE = SummingMergeTree([columns])
9304/// ```
9305pub struct NamedParenthesizedList {
9306    pub key: Ident,
9307    pub name: Option<Ident>,
9308    pub values: Vec<Ident>,
9309}
9310
9311/// Snowflake `WITH ROW ACCESS POLICY policy_name ON (identifier, ...)`
9312///
9313/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
9314/// <https://docs.snowflake.com/en/user-guide/security-row-intro>
9315#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9316#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9317#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9318pub struct RowAccessPolicy {
9319    pub policy: ObjectName,
9320    pub on: Vec<Ident>,
9321}
9322
9323impl RowAccessPolicy {
9324    pub fn new(policy: ObjectName, on: Vec<Ident>) -> Self {
9325        Self { policy, on }
9326    }
9327}
9328
9329impl Display for RowAccessPolicy {
9330    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9331        write!(
9332            f,
9333            "WITH ROW ACCESS POLICY {} ON ({})",
9334            self.policy,
9335            display_comma_separated(self.on.as_slice())
9336        )
9337    }
9338}
9339
9340/// Snowflake `WITH TAG ( tag_name = '<tag_value>', ...)`
9341///
9342/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
9343#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9344#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9345#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9346pub struct Tag {
9347    pub key: ObjectName,
9348    pub value: String,
9349}
9350
9351impl Tag {
9352    pub fn new(key: ObjectName, value: String) -> Self {
9353        Self { key, value }
9354    }
9355}
9356
9357impl Display for Tag {
9358    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9359        write!(f, "{}='{}'", self.key, self.value)
9360    }
9361}
9362
9363/// Snowflake `WITH CONTACT ( purpose = contact [ , purpose = contact ...] )`
9364///
9365/// <https://docs.snowflake.com/en/sql-reference/sql/create-database>
9366#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9367#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9368#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9369pub struct ContactEntry {
9370    pub purpose: String,
9371    pub contact: String,
9372}
9373
9374impl Display for ContactEntry {
9375    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9376        write!(f, "{} = {}", self.purpose, self.contact)
9377    }
9378}
9379
9380/// Helper to indicate if a comment includes the `=` in the display form
9381#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9382#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9383#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9384pub enum CommentDef {
9385    /// Includes `=` when printing the comment, as `COMMENT = 'comment'`
9386    /// Does not include `=` when printing the comment, as `COMMENT 'comment'`
9387    WithEq(String),
9388    WithoutEq(String),
9389}
9390
9391impl Display for CommentDef {
9392    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9393        match self {
9394            CommentDef::WithEq(comment) | CommentDef::WithoutEq(comment) => write!(f, "{comment}"),
9395        }
9396    }
9397}
9398
9399/// Helper to indicate if a collection should be wrapped by a symbol in the display form
9400///
9401/// [`Display`] is implemented for every [`Vec<T>`] where `T: Display`.
9402/// The string output is a comma separated list for the vec items
9403///
9404/// # Examples
9405/// ```
9406/// # use sqlparser::ast::WrappedCollection;
9407/// let items = WrappedCollection::Parentheses(vec!["one", "two", "three"]);
9408/// assert_eq!("(one, two, three)", items.to_string());
9409///
9410/// let items = WrappedCollection::NoWrapping(vec!["one", "two", "three"]);
9411/// assert_eq!("one, two, three", items.to_string());
9412/// ```
9413#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9414#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9415#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9416pub enum WrappedCollection<T> {
9417    /// Print the collection without wrapping symbols, as `item, item, item`
9418    NoWrapping(T),
9419    /// Wraps the collection in Parentheses, as `(item, item, item)`
9420    Parentheses(T),
9421}
9422
9423impl<T> Display for WrappedCollection<Vec<T>>
9424where
9425    T: Display,
9426{
9427    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9428        match self {
9429            WrappedCollection::NoWrapping(inner) => {
9430                write!(f, "{}", display_comma_separated(inner.as_slice()))
9431            }
9432            WrappedCollection::Parentheses(inner) => {
9433                write!(f, "({})", display_comma_separated(inner.as_slice()))
9434            }
9435        }
9436    }
9437}
9438
9439/// Represents a single PostgreSQL utility option.
9440///
9441/// A utility option is a key-value pair where the key is an identifier (IDENT) and the value
9442/// can be one of the following:
9443/// - A number with an optional sign (`+` or `-`). Example: `+10`, `-10.2`, `3`
9444/// - A non-keyword string. Example: `option1`, `'option2'`, `"option3"`
9445/// - keyword: `TRUE`, `FALSE`, `ON` (`off` is also accept).
9446/// - Empty. Example: `ANALYZE` (identifier only)
9447///
9448/// Utility options are used in various PostgreSQL DDL statements, including statements such as
9449/// `CLUSTER`, `EXPLAIN`, `VACUUM`, and `REINDEX`. These statements format options as `( option [, ...] )`.
9450///
9451/// [CLUSTER](https://www.postgresql.org/docs/current/sql-cluster.html)
9452/// [EXPLAIN](https://www.postgresql.org/docs/current/sql-explain.html)
9453/// [VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html)
9454/// [REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html)
9455///
9456/// For example, the `EXPLAIN` AND `VACUUM` statements with options might look like this:
9457/// ```sql
9458/// EXPLAIN (ANALYZE, VERBOSE TRUE, FORMAT TEXT) SELECT * FROM my_table;
9459///
9460/// VACUUM (VERBOSE, ANALYZE ON, PARALLEL 10) my_table;
9461/// ```
9462#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9463#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9464#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9465pub struct UtilityOption {
9466    pub name: Ident,
9467    pub arg: Option<Expr>,
9468}
9469
9470impl Display for UtilityOption {
9471    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9472        if let Some(ref arg) = self.arg {
9473            write!(f, "{} {}", self.name, arg)
9474        } else {
9475            write!(f, "{}", self.name)
9476        }
9477    }
9478}
9479
9480/// Represents the different options available for `SHOW`
9481/// statements to filter the results. Example from Snowflake:
9482/// <https://docs.snowflake.com/en/sql-reference/sql/show-tables>
9483#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9484#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9485#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9486pub struct ShowStatementOptions {
9487    pub show_in: Option<ShowStatementIn>,
9488    pub starts_with: Option<Value>,
9489    pub limit: Option<Expr>,
9490    pub limit_from: Option<Value>,
9491    pub filter_position: Option<ShowStatementFilterPosition>,
9492}
9493
9494impl Display for ShowStatementOptions {
9495    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9496        let (like_in_infix, like_in_suffix) = match &self.filter_position {
9497            Some(ShowStatementFilterPosition::Infix(filter)) => {
9498                (format!(" {filter}"), "".to_string())
9499            }
9500            Some(ShowStatementFilterPosition::Suffix(filter)) => {
9501                ("".to_string(), format!(" {filter}"))
9502            }
9503            None => ("".to_string(), "".to_string()),
9504        };
9505        write!(
9506            f,
9507            "{like_in_infix}{show_in}{starts_with}{limit}{from}{like_in_suffix}",
9508            show_in = match &self.show_in {
9509                Some(i) => format!(" {i}"),
9510                None => String::new(),
9511            },
9512            starts_with = match &self.starts_with {
9513                Some(s) => format!(" STARTS WITH {s}"),
9514                None => String::new(),
9515            },
9516            limit = match &self.limit {
9517                Some(l) => format!(" LIMIT {l}"),
9518                None => String::new(),
9519            },
9520            from = match &self.limit_from {
9521                Some(f) => format!(" FROM {f}"),
9522                None => String::new(),
9523            }
9524        )?;
9525        Ok(())
9526    }
9527}
9528
9529#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9530#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9531#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9532pub enum ShowStatementFilterPosition {
9533    Infix(ShowStatementFilter), // For example: SHOW COLUMNS LIKE '%name%' IN TABLE tbl
9534    Suffix(ShowStatementFilter), // For example: SHOW COLUMNS IN tbl LIKE '%name%'
9535}
9536
9537#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9538#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9539#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9540pub enum ShowStatementInParentType {
9541    Account,
9542    Database,
9543    Schema,
9544    Table,
9545    View,
9546}
9547
9548impl fmt::Display for ShowStatementInParentType {
9549    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9550        match self {
9551            ShowStatementInParentType::Account => write!(f, "ACCOUNT"),
9552            ShowStatementInParentType::Database => write!(f, "DATABASE"),
9553            ShowStatementInParentType::Schema => write!(f, "SCHEMA"),
9554            ShowStatementInParentType::Table => write!(f, "TABLE"),
9555            ShowStatementInParentType::View => write!(f, "VIEW"),
9556        }
9557    }
9558}
9559
9560#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9561#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9562#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9563pub struct ShowStatementIn {
9564    pub clause: ShowStatementInClause,
9565    pub parent_type: Option<ShowStatementInParentType>,
9566    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
9567    pub parent_name: Option<ObjectName>,
9568}
9569
9570impl fmt::Display for ShowStatementIn {
9571    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9572        write!(f, "{}", self.clause)?;
9573        if let Some(parent_type) = &self.parent_type {
9574            write!(f, " {parent_type}")?;
9575        }
9576        if let Some(parent_name) = &self.parent_name {
9577            write!(f, " {parent_name}")?;
9578        }
9579        Ok(())
9580    }
9581}
9582
9583/// A Show Charset statement
9584#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9585#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9586#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9587pub struct ShowCharset {
9588    /// The statement can be written as `SHOW CHARSET` or `SHOW CHARACTER SET`
9589    /// true means CHARSET was used and false means CHARACTER SET was used
9590    pub is_shorthand: bool,
9591    pub filter: Option<ShowStatementFilter>,
9592}
9593
9594impl fmt::Display for ShowCharset {
9595    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9596        write!(f, "SHOW")?;
9597        if self.is_shorthand {
9598            write!(f, " CHARSET")?;
9599        } else {
9600            write!(f, " CHARACTER SET")?;
9601        }
9602        if let Some(filter) = &self.filter {
9603            write!(f, " {filter}")?;
9604        }
9605        Ok(())
9606    }
9607}
9608
9609#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9610#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9611#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9612pub struct ShowObjects {
9613    pub terse: bool,
9614    pub show_options: ShowStatementOptions,
9615}
9616
9617/// MSSQL's json null clause
9618///
9619/// ```plaintext
9620/// <json_null_clause> ::=
9621///       NULL ON NULL
9622///     | ABSENT ON NULL
9623/// ```
9624///
9625/// <https://learn.microsoft.com/en-us/sql/t-sql/functions/json-object-transact-sql?view=sql-server-ver16#json_null_clause>
9626#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9627#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9628#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9629pub enum JsonNullClause {
9630    NullOnNull,
9631    AbsentOnNull,
9632}
9633
9634impl Display for JsonNullClause {
9635    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9636        match self {
9637            JsonNullClause::NullOnNull => write!(f, "NULL ON NULL"),
9638            JsonNullClause::AbsentOnNull => write!(f, "ABSENT ON NULL"),
9639        }
9640    }
9641}
9642
9643/// PostgreSQL JSON function RETURNING clause
9644///
9645/// Example:
9646/// ```sql
9647/// JSON_OBJECT('a': 1 RETURNING jsonb)
9648/// ```
9649#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9650#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9651#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9652pub struct JsonReturningClause {
9653    pub data_type: DataType,
9654}
9655
9656impl Display for JsonReturningClause {
9657    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9658        write!(f, "RETURNING {}", self.data_type)
9659    }
9660}
9661
9662/// rename object definition
9663#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9664#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9665#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9666pub struct RenameTable {
9667    pub old_name: ObjectName,
9668    pub new_name: ObjectName,
9669}
9670
9671impl fmt::Display for RenameTable {
9672    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9673        write!(f, "{} TO {}", self.old_name, self.new_name)?;
9674        Ok(())
9675    }
9676}
9677
9678/// Represents the referenced table in an `INSERT INTO` statement
9679#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9680#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9681#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9682pub enum TableObject {
9683    /// Table specified by name.
9684    /// Example:
9685    /// ```sql
9686    /// INSERT INTO my_table
9687    /// ```
9688    TableName(#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] ObjectName),
9689
9690    /// Table specified as a function.
9691    /// Example:
9692    /// ```sql
9693    /// INSERT INTO TABLE FUNCTION remote('localhost', default.simple_table)
9694    /// ```
9695    /// [Clickhouse](https://clickhouse.com/docs/en/sql-reference/table-functions)
9696    TableFunction(Function),
9697}
9698
9699impl fmt::Display for TableObject {
9700    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9701        match self {
9702            Self::TableName(table_name) => write!(f, "{table_name}"),
9703            Self::TableFunction(func) => write!(f, "FUNCTION {func}"),
9704        }
9705    }
9706}
9707
9708/// Represents a SET SESSION AUTHORIZATION statement
9709#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9710#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9711#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9712pub struct SetSessionAuthorizationParam {
9713    pub scope: ContextModifier,
9714    pub kind: SetSessionAuthorizationParamKind,
9715}
9716
9717impl fmt::Display for SetSessionAuthorizationParam {
9718    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9719        write!(f, "{}", self.kind)
9720    }
9721}
9722
9723/// Represents the parameter kind for SET SESSION AUTHORIZATION
9724#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9725#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9726#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9727pub enum SetSessionAuthorizationParamKind {
9728    /// Default authorization
9729    Default,
9730
9731    /// User name
9732    User(Ident),
9733}
9734
9735impl fmt::Display for SetSessionAuthorizationParamKind {
9736    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9737        match self {
9738            SetSessionAuthorizationParamKind::Default => write!(f, "DEFAULT"),
9739            SetSessionAuthorizationParamKind::User(name) => write!(f, "{}", name),
9740        }
9741    }
9742}
9743
9744#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9745#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9746#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9747pub enum SetSessionParamKind {
9748    Generic(SetSessionParamGeneric),
9749    IdentityInsert(SetSessionParamIdentityInsert),
9750    Offsets(SetSessionParamOffsets),
9751    Statistics(SetSessionParamStatistics),
9752}
9753
9754impl fmt::Display for SetSessionParamKind {
9755    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9756        match self {
9757            SetSessionParamKind::Generic(x) => write!(f, "{x}"),
9758            SetSessionParamKind::IdentityInsert(x) => write!(f, "{x}"),
9759            SetSessionParamKind::Offsets(x) => write!(f, "{x}"),
9760            SetSessionParamKind::Statistics(x) => write!(f, "{x}"),
9761        }
9762    }
9763}
9764
9765#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9766#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9767#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9768pub struct SetSessionParamGeneric {
9769    pub names: Vec<String>,
9770    pub value: String,
9771}
9772
9773impl fmt::Display for SetSessionParamGeneric {
9774    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9775        write!(f, "{} {}", display_comma_separated(&self.names), self.value)
9776    }
9777}
9778
9779#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9780#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9781#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9782pub struct SetSessionParamIdentityInsert {
9783    pub obj: ObjectName,
9784    pub value: SessionParamValue,
9785}
9786
9787impl fmt::Display for SetSessionParamIdentityInsert {
9788    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9789        write!(f, "IDENTITY_INSERT {} {}", self.obj, self.value)
9790    }
9791}
9792
9793#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9794#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9795#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9796pub struct SetSessionParamOffsets {
9797    pub keywords: Vec<String>,
9798    pub value: SessionParamValue,
9799}
9800
9801impl fmt::Display for SetSessionParamOffsets {
9802    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9803        write!(
9804            f,
9805            "OFFSETS {} {}",
9806            display_comma_separated(&self.keywords),
9807            self.value
9808        )
9809    }
9810}
9811
9812#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9813#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9814#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9815pub struct SetSessionParamStatistics {
9816    pub topic: SessionParamStatsTopic,
9817    pub value: SessionParamValue,
9818}
9819
9820impl fmt::Display for SetSessionParamStatistics {
9821    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9822        write!(f, "STATISTICS {} {}", self.topic, self.value)
9823    }
9824}
9825
9826#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9827#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9828#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9829pub enum SessionParamStatsTopic {
9830    IO,
9831    Profile,
9832    Time,
9833    Xml,
9834}
9835
9836impl fmt::Display for SessionParamStatsTopic {
9837    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9838        match self {
9839            SessionParamStatsTopic::IO => write!(f, "IO"),
9840            SessionParamStatsTopic::Profile => write!(f, "PROFILE"),
9841            SessionParamStatsTopic::Time => write!(f, "TIME"),
9842            SessionParamStatsTopic::Xml => write!(f, "XML"),
9843        }
9844    }
9845}
9846
9847#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9848#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9849#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9850pub enum SessionParamValue {
9851    On,
9852    Off,
9853}
9854
9855impl fmt::Display for SessionParamValue {
9856    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9857        match self {
9858            SessionParamValue::On => write!(f, "ON"),
9859            SessionParamValue::Off => write!(f, "OFF"),
9860        }
9861    }
9862}
9863
9864/// Snowflake StorageSerializationPolicy for Iceberg Tables
9865/// ```sql
9866/// [ STORAGE_SERIALIZATION_POLICY = { COMPATIBLE | OPTIMIZED } ]
9867/// ```
9868///
9869/// <https://docs.snowflake.com/en/sql-reference/sql/create-iceberg-table>
9870#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9871#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9872#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9873pub enum StorageSerializationPolicy {
9874    Compatible,
9875    Optimized,
9876}
9877
9878impl Display for StorageSerializationPolicy {
9879    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9880        match self {
9881            StorageSerializationPolicy::Compatible => write!(f, "COMPATIBLE"),
9882            StorageSerializationPolicy::Optimized => write!(f, "OPTIMIZED"),
9883        }
9884    }
9885}
9886
9887/// Snowflake CatalogSyncNamespaceMode
9888/// ```sql
9889/// [ CATALOG_SYNC_NAMESPACE_MODE = { NEST | FLATTEN } ]
9890/// ```
9891///
9892/// <https://docs.snowflake.com/en/sql-reference/sql/create-database>
9893#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9894#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9895#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9896pub enum CatalogSyncNamespaceMode {
9897    Nest,
9898    Flatten,
9899}
9900
9901impl Display for CatalogSyncNamespaceMode {
9902    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9903        match self {
9904            CatalogSyncNamespaceMode::Nest => write!(f, "NEST"),
9905            CatalogSyncNamespaceMode::Flatten => write!(f, "FLATTEN"),
9906        }
9907    }
9908}
9909
9910/// Variants of the Snowflake `COPY INTO` statement
9911#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9912#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9913#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9914pub enum CopyIntoSnowflakeKind {
9915    /// Loads data from files to a table
9916    /// See: <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table>
9917    Table,
9918    /// Unloads data from a table or query to external files
9919    /// See: <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location>
9920    Location,
9921}
9922
9923#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9924#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9925#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9926pub struct PrintStatement {
9927    pub message: Box<Expr>,
9928}
9929
9930impl fmt::Display for PrintStatement {
9931    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9932        write!(f, "PRINT {}", self.message)
9933    }
9934}
9935
9936/// Represents a `Return` statement.
9937///
9938/// [MsSql triggers](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql)
9939/// [MsSql functions](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql)
9940#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9941#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9942#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9943pub struct ReturnStatement {
9944    pub value: Option<ReturnStatementValue>,
9945}
9946
9947impl fmt::Display for ReturnStatement {
9948    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9949        match &self.value {
9950            Some(ReturnStatementValue::Expr(expr)) => write!(f, "RETURN {expr}"),
9951            None => write!(f, "RETURN"),
9952        }
9953    }
9954}
9955
9956/// Variants of a `RETURN` statement
9957#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9958#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9959#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9960pub enum ReturnStatementValue {
9961    Expr(Expr),
9962}
9963
9964/// Represents an `OPEN` statement.
9965#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9966#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9967#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9968pub struct OpenStatement {
9969    /// Cursor name
9970    pub cursor_name: Ident,
9971}
9972
9973impl fmt::Display for OpenStatement {
9974    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9975        write!(f, "OPEN {}", self.cursor_name)
9976    }
9977}
9978
9979/// Specifies Include / Exclude NULL within UNPIVOT command.
9980/// For example
9981/// `UNPIVOT (column1 FOR new_column IN (col3, col4, col5, col6))`
9982#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9983#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9984#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9985pub enum NullInclusion {
9986    IncludeNulls,
9987    ExcludeNulls,
9988}
9989
9990impl fmt::Display for NullInclusion {
9991    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9992        match self {
9993            NullInclusion::IncludeNulls => write!(f, "INCLUDE NULLS"),
9994            NullInclusion::ExcludeNulls => write!(f, "EXCLUDE NULLS"),
9995        }
9996    }
9997}
9998
9999/// Checks membership of a value in a JSON array
10000///
10001/// Syntax:
10002/// ```sql
10003/// <value> MEMBER OF(<array>)
10004/// ```
10005/// [MySQL](https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#operator_member-of)
10006#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10007#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10008#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10009pub struct MemberOf {
10010    pub value: Box<Expr>,
10011    pub array: Box<Expr>,
10012}
10013
10014impl fmt::Display for MemberOf {
10015    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10016        write!(f, "{} MEMBER OF({})", self.value, self.array)
10017    }
10018}
10019
10020#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10021#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10022#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10023pub struct ExportData {
10024    pub options: Vec<SqlOption>,
10025    pub query: Box<Query>,
10026    pub connection: Option<ObjectName>,
10027}
10028
10029impl fmt::Display for ExportData {
10030    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10031        if let Some(connection) = &self.connection {
10032            write!(
10033                f,
10034                "EXPORT DATA WITH CONNECTION {connection} OPTIONS({}) AS {}",
10035                display_comma_separated(&self.options),
10036                self.query
10037            )
10038        } else {
10039            write!(
10040                f,
10041                "EXPORT DATA OPTIONS({}) AS {}",
10042                display_comma_separated(&self.options),
10043                self.query
10044            )
10045        }
10046    }
10047}
10048/// Creates a user
10049///
10050/// Syntax:
10051/// ```sql
10052/// CREATE [OR REPLACE] USER [IF NOT EXISTS] <name> [OPTIONS]
10053/// ```
10054///
10055/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-user)
10056#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10057#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10058#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10059pub struct CreateUser {
10060    pub or_replace: bool,
10061    pub if_not_exists: bool,
10062    pub name: Ident,
10063    pub options: KeyValueOptions,
10064    pub with_tags: bool,
10065    pub tags: KeyValueOptions,
10066}
10067
10068impl fmt::Display for CreateUser {
10069    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10070        write!(f, "CREATE")?;
10071        if self.or_replace {
10072            write!(f, " OR REPLACE")?;
10073        }
10074        write!(f, " USER")?;
10075        if self.if_not_exists {
10076            write!(f, " IF NOT EXISTS")?;
10077        }
10078        write!(f, " {}", self.name)?;
10079        if !self.options.options.is_empty() {
10080            write!(f, " {}", self.options)?;
10081        }
10082        if !self.tags.options.is_empty() {
10083            if self.with_tags {
10084                write!(f, " WITH")?;
10085            }
10086            write!(f, " TAG ({})", self.tags)?;
10087        }
10088        Ok(())
10089    }
10090}
10091
10092/// Modifies the properties of a user
10093///
10094/// Syntax:
10095/// ```sql
10096/// ALTER USER [ IF EXISTS ] [ <name> ] [ OPTIONS ]
10097/// ```
10098///
10099/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/alter-user)
10100#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10101#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10102#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10103pub struct AlterUser {
10104    pub if_exists: bool,
10105    pub name: Ident,
10106    /// The following fields are Snowflake-specific: <https://docs.snowflake.com/en/sql-reference/sql/alter-user#syntax>
10107    pub rename_to: Option<Ident>,
10108    pub reset_password: bool,
10109    pub abort_all_queries: bool,
10110    pub add_role_delegation: Option<AlterUserAddRoleDelegation>,
10111    pub remove_role_delegation: Option<AlterUserRemoveRoleDelegation>,
10112    pub enroll_mfa: bool,
10113    pub set_default_mfa_method: Option<MfaMethodKind>,
10114    pub remove_mfa_method: Option<MfaMethodKind>,
10115    pub modify_mfa_method: Option<AlterUserModifyMfaMethod>,
10116    pub add_mfa_method_otp: Option<AlterUserAddMfaMethodOtp>,
10117    pub set_policy: Option<AlterUserSetPolicy>,
10118    pub unset_policy: Option<UserPolicyKind>,
10119    pub set_tag: KeyValueOptions,
10120    pub unset_tag: Vec<String>,
10121    pub set_props: KeyValueOptions,
10122    pub unset_props: Vec<String>,
10123}
10124
10125/// ```sql
10126/// ALTER USER [ IF EXISTS ] [ <name> ] ADD DELEGATED AUTHORIZATION OF ROLE <role_name> TO SECURITY INTEGRATION <integration_name>
10127/// ```
10128#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10129#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10130#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10131pub struct AlterUserAddRoleDelegation {
10132    pub role: Ident,
10133    pub integration: Ident,
10134}
10135
10136/// ```sql
10137/// ALTER USER [ IF EXISTS ] [ <name> ] REMOVE DELEGATED { AUTHORIZATION OF ROLE <role_name> | AUTHORIZATIONS } FROM SECURITY INTEGRATION <integration_name>
10138/// ```
10139#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10140#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10141#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10142pub struct AlterUserRemoveRoleDelegation {
10143    pub role: Option<Ident>,
10144    pub integration: Ident,
10145}
10146
10147/// ```sql
10148/// ADD MFA METHOD OTP [ COUNT = number ]
10149/// ```
10150#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10151#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10152#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10153pub struct AlterUserAddMfaMethodOtp {
10154    pub count: Option<Value>,
10155}
10156
10157/// ```sql
10158/// ALTER USER [ IF EXISTS ] [ <name> ] MODIFY MFA METHOD <mfa_method> SET COMMENT = '<string>'
10159/// ```
10160#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10161#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10162#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10163pub struct AlterUserModifyMfaMethod {
10164    pub method: MfaMethodKind,
10165    pub comment: String,
10166}
10167
10168/// Types of MFA methods
10169#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10170#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10171#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10172pub enum MfaMethodKind {
10173    PassKey,
10174    Totp,
10175    Duo,
10176}
10177
10178impl fmt::Display for MfaMethodKind {
10179    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10180        match self {
10181            MfaMethodKind::PassKey => write!(f, "PASSKEY"),
10182            MfaMethodKind::Totp => write!(f, "TOTP"),
10183            MfaMethodKind::Duo => write!(f, "DUO"),
10184        }
10185    }
10186}
10187
10188/// ```sql
10189/// ALTER USER [ IF EXISTS ] [ <name> ] SET { AUTHENTICATION | PASSWORD | SESSION } POLICY <policy_name>
10190/// ```
10191#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10192#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10193#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10194pub struct AlterUserSetPolicy {
10195    pub policy_kind: UserPolicyKind,
10196    pub policy: Ident,
10197}
10198
10199/// Types of user-based policies
10200#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10201#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10202#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10203pub enum UserPolicyKind {
10204    Authentication,
10205    Password,
10206    Session,
10207}
10208
10209impl fmt::Display for UserPolicyKind {
10210    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10211        match self {
10212            UserPolicyKind::Authentication => write!(f, "AUTHENTICATION"),
10213            UserPolicyKind::Password => write!(f, "PASSWORD"),
10214            UserPolicyKind::Session => write!(f, "SESSION"),
10215        }
10216    }
10217}
10218
10219impl fmt::Display for AlterUser {
10220    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10221        write!(f, "ALTER")?;
10222        write!(f, " USER")?;
10223        if self.if_exists {
10224            write!(f, " IF EXISTS")?;
10225        }
10226        write!(f, " {}", self.name)?;
10227        if let Some(new_name) = &self.rename_to {
10228            write!(f, " RENAME TO {new_name}")?;
10229        }
10230        if self.reset_password {
10231            write!(f, " RESET PASSWORD")?;
10232        }
10233        if self.abort_all_queries {
10234            write!(f, " ABORT ALL QUERIES")?;
10235        }
10236        if let Some(role_delegation) = &self.add_role_delegation {
10237            let role = &role_delegation.role;
10238            let integration = &role_delegation.integration;
10239            write!(
10240                f,
10241                " ADD DELEGATED AUTHORIZATION OF ROLE {role} TO SECURITY INTEGRATION {integration}"
10242            )?;
10243        }
10244        if let Some(role_delegation) = &self.remove_role_delegation {
10245            write!(f, " REMOVE DELEGATED")?;
10246            match &role_delegation.role {
10247                Some(role) => write!(f, " AUTHORIZATION OF ROLE {role}")?,
10248                None => write!(f, " AUTHORIZATIONS")?,
10249            }
10250            let integration = &role_delegation.integration;
10251            write!(f, " FROM SECURITY INTEGRATION {integration}")?;
10252        }
10253        if self.enroll_mfa {
10254            write!(f, " ENROLL MFA")?;
10255        }
10256        if let Some(method) = &self.set_default_mfa_method {
10257            write!(f, " SET DEFAULT_MFA_METHOD {method}")?
10258        }
10259        if let Some(method) = &self.remove_mfa_method {
10260            write!(f, " REMOVE MFA METHOD {method}")?;
10261        }
10262        if let Some(modify) = &self.modify_mfa_method {
10263            let method = &modify.method;
10264            let comment = &modify.comment;
10265            write!(
10266                f,
10267                " MODIFY MFA METHOD {method} SET COMMENT '{}'",
10268                value::escape_single_quote_string(comment)
10269            )?;
10270        }
10271        if let Some(add_mfa_method_otp) = &self.add_mfa_method_otp {
10272            write!(f, " ADD MFA METHOD OTP")?;
10273            if let Some(count) = &add_mfa_method_otp.count {
10274                write!(f, " COUNT = {count}")?;
10275            }
10276        }
10277        if let Some(policy) = &self.set_policy {
10278            let policy_kind = &policy.policy_kind;
10279            let name = &policy.policy;
10280            write!(f, " SET {policy_kind} POLICY {name}")?;
10281        }
10282        if let Some(policy_kind) = &self.unset_policy {
10283            write!(f, " UNSET {policy_kind} POLICY")?;
10284        }
10285        if !self.set_tag.options.is_empty() {
10286            write!(f, " SET TAG {}", self.set_tag)?;
10287        }
10288        if !self.unset_tag.is_empty() {
10289            write!(f, " UNSET TAG {}", display_comma_separated(&self.unset_tag))?;
10290        }
10291        let has_props = !self.set_props.options.is_empty();
10292        if has_props {
10293            write!(f, " SET")?;
10294            write!(f, " {}", &self.set_props)?;
10295        }
10296        if !self.unset_props.is_empty() {
10297            write!(f, " UNSET {}", display_comma_separated(&self.unset_props))?;
10298        }
10299        Ok(())
10300    }
10301}
10302
10303/// Specifies how to create a new table based on an existing table's schema.
10304/// '''sql
10305/// CREATE TABLE new LIKE old ...
10306/// '''
10307#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10308#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10309#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10310pub enum CreateTableLikeKind {
10311    /// '''sql
10312    /// CREATE TABLE new (LIKE old ...)
10313    /// '''
10314    /// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html)
10315    Parenthesized(CreateTableLike),
10316    /// '''sql
10317    /// CREATE TABLE new LIKE old ...
10318    /// '''
10319    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-table#label-create-table-like)
10320    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_like)
10321    Plain(CreateTableLike),
10322}
10323
10324#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10325#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10326#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10327pub enum CreateTableLikeDefaults {
10328    Including,
10329    Excluding,
10330}
10331
10332impl fmt::Display for CreateTableLikeDefaults {
10333    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10334        match self {
10335            CreateTableLikeDefaults::Including => write!(f, "INCLUDING DEFAULTS"),
10336            CreateTableLikeDefaults::Excluding => write!(f, "EXCLUDING DEFAULTS"),
10337        }
10338    }
10339}
10340
10341#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10342#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10343#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10344pub struct CreateTableLike {
10345    pub name: ObjectName,
10346    pub defaults: Option<CreateTableLikeDefaults>,
10347}
10348
10349impl fmt::Display for CreateTableLike {
10350    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10351        write!(f, "LIKE {}", self.name)?;
10352        if let Some(defaults) = &self.defaults {
10353            write!(f, " {defaults}")?;
10354        }
10355        Ok(())
10356    }
10357}
10358
10359/// Specifies the refresh mode for the dynamic table.
10360///
10361/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table)
10362#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10363#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10364#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10365pub enum RefreshModeKind {
10366    Auto,
10367    Full,
10368    Incremental,
10369}
10370
10371impl fmt::Display for RefreshModeKind {
10372    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10373        match self {
10374            RefreshModeKind::Auto => write!(f, "AUTO"),
10375            RefreshModeKind::Full => write!(f, "FULL"),
10376            RefreshModeKind::Incremental => write!(f, "INCREMENTAL"),
10377        }
10378    }
10379}
10380
10381/// Specifies the behavior of the initial refresh of the dynamic table.
10382///
10383/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table)
10384#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10385#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10386#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10387pub enum InitializeKind {
10388    OnCreate,
10389    OnSchedule,
10390}
10391
10392impl fmt::Display for InitializeKind {
10393    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10394        match self {
10395            InitializeKind::OnCreate => write!(f, "ON_CREATE"),
10396            InitializeKind::OnSchedule => write!(f, "ON_SCHEDULE"),
10397        }
10398    }
10399}
10400
10401/// Re-sorts rows and reclaims space in either a specified table or all tables in the current database
10402///
10403/// '''sql
10404/// VACUUM [ FULL | SORT ONLY | DELETE ONLY | REINDEX | RECLUSTER ] [ \[ table_name \] [ TO threshold PERCENT ] \[ BOOST \] ]
10405/// '''
10406/// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)
10407#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10408#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10409#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10410pub struct VacuumStatement {
10411    pub full: bool,
10412    pub sort_only: bool,
10413    pub delete_only: bool,
10414    pub reindex: bool,
10415    pub recluster: bool,
10416    pub table_name: Option<ObjectName>,
10417    pub threshold: Option<Value>,
10418    pub boost: bool,
10419}
10420
10421impl fmt::Display for VacuumStatement {
10422    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10423        write!(
10424            f,
10425            "VACUUM{}{}{}{}{}",
10426            if self.full { " FULL" } else { "" },
10427            if self.sort_only { " SORT ONLY" } else { "" },
10428            if self.delete_only { " DELETE ONLY" } else { "" },
10429            if self.reindex { " REINDEX" } else { "" },
10430            if self.recluster { " RECLUSTER" } else { "" },
10431        )?;
10432        if let Some(table_name) = &self.table_name {
10433            write!(f, " {table_name}")?;
10434        }
10435        if let Some(threshold) = &self.threshold {
10436            write!(f, " TO {threshold} PERCENT")?;
10437        }
10438        if self.boost {
10439            write!(f, " BOOST")?;
10440        }
10441        Ok(())
10442    }
10443}
10444
10445/// Variants of the RESET statement
10446#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10447#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10448#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10449pub enum Reset {
10450    /// Resets all session parameters to their default values.
10451    ALL,
10452
10453    /// Resets a specific session parameter to its default value.
10454    ConfigurationParameter(ObjectName),
10455}
10456
10457/// Resets a session parameter to its default value.
10458/// ```sql
10459/// RESET { ALL | <configuration_parameter> }
10460/// ```
10461#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10462#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10463#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10464pub struct ResetStatement {
10465    pub reset: Reset,
10466}
10467
10468impl fmt::Display for ResetStatement {
10469    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10470        match &self.reset {
10471            Reset::ALL => write!(f, "RESET ALL"),
10472            Reset::ConfigurationParameter(param) => write!(f, "RESET {}", param),
10473        }
10474    }
10475}
10476
10477impl From<Set> for Statement {
10478    fn from(s: Set) -> Self {
10479        Self::Set(s)
10480    }
10481}
10482
10483impl From<Query> for Statement {
10484    fn from(q: Query) -> Self {
10485        Box::new(q).into()
10486    }
10487}
10488
10489impl From<Box<Query>> for Statement {
10490    fn from(q: Box<Query>) -> Self {
10491        Self::Query(q)
10492    }
10493}
10494
10495impl From<Insert> for Statement {
10496    fn from(i: Insert) -> Self {
10497        Self::Insert(i)
10498    }
10499}
10500
10501impl From<Update> for Statement {
10502    fn from(u: Update) -> Self {
10503        Self::Update(u)
10504    }
10505}
10506
10507impl From<CreateView> for Statement {
10508    fn from(cv: CreateView) -> Self {
10509        Self::CreateView(cv)
10510    }
10511}
10512
10513impl From<CreateRole> for Statement {
10514    fn from(cr: CreateRole) -> Self {
10515        Self::CreateRole(cr)
10516    }
10517}
10518
10519impl From<AlterTable> for Statement {
10520    fn from(at: AlterTable) -> Self {
10521        Self::AlterTable(at)
10522    }
10523}
10524
10525impl From<DropFunction> for Statement {
10526    fn from(df: DropFunction) -> Self {
10527        Self::DropFunction(df)
10528    }
10529}
10530
10531impl From<CreateExtension> for Statement {
10532    fn from(ce: CreateExtension) -> Self {
10533        Self::CreateExtension(ce)
10534    }
10535}
10536
10537impl From<DropExtension> for Statement {
10538    fn from(de: DropExtension) -> Self {
10539        Self::DropExtension(de)
10540    }
10541}
10542
10543impl From<CaseStatement> for Statement {
10544    fn from(c: CaseStatement) -> Self {
10545        Self::Case(c)
10546    }
10547}
10548
10549impl From<IfStatement> for Statement {
10550    fn from(i: IfStatement) -> Self {
10551        Self::If(i)
10552    }
10553}
10554
10555impl From<WhileStatement> for Statement {
10556    fn from(w: WhileStatement) -> Self {
10557        Self::While(w)
10558    }
10559}
10560
10561impl From<RaiseStatement> for Statement {
10562    fn from(r: RaiseStatement) -> Self {
10563        Self::Raise(r)
10564    }
10565}
10566
10567impl From<Function> for Statement {
10568    fn from(f: Function) -> Self {
10569        Self::Call(f)
10570    }
10571}
10572
10573impl From<OpenStatement> for Statement {
10574    fn from(o: OpenStatement) -> Self {
10575        Self::Open(o)
10576    }
10577}
10578
10579impl From<Delete> for Statement {
10580    fn from(d: Delete) -> Self {
10581        Self::Delete(d)
10582    }
10583}
10584
10585impl From<CreateTable> for Statement {
10586    fn from(c: CreateTable) -> Self {
10587        Self::CreateTable(c)
10588    }
10589}
10590
10591impl From<CreateIndex> for Statement {
10592    fn from(c: CreateIndex) -> Self {
10593        Self::CreateIndex(c)
10594    }
10595}
10596
10597impl From<CreateServerStatement> for Statement {
10598    fn from(c: CreateServerStatement) -> Self {
10599        Self::CreateServer(c)
10600    }
10601}
10602
10603impl From<CreateConnector> for Statement {
10604    fn from(c: CreateConnector) -> Self {
10605        Self::CreateConnector(c)
10606    }
10607}
10608
10609impl From<AlterSchema> for Statement {
10610    fn from(a: AlterSchema) -> Self {
10611        Self::AlterSchema(a)
10612    }
10613}
10614
10615impl From<AlterType> for Statement {
10616    fn from(a: AlterType) -> Self {
10617        Self::AlterType(a)
10618    }
10619}
10620
10621impl From<DropDomain> for Statement {
10622    fn from(d: DropDomain) -> Self {
10623        Self::DropDomain(d)
10624    }
10625}
10626
10627impl From<ShowCharset> for Statement {
10628    fn from(s: ShowCharset) -> Self {
10629        Self::ShowCharset(s)
10630    }
10631}
10632
10633impl From<ShowObjects> for Statement {
10634    fn from(s: ShowObjects) -> Self {
10635        Self::ShowObjects(s)
10636    }
10637}
10638
10639impl From<Use> for Statement {
10640    fn from(u: Use) -> Self {
10641        Self::Use(u)
10642    }
10643}
10644
10645impl From<CreateFunction> for Statement {
10646    fn from(c: CreateFunction) -> Self {
10647        Self::CreateFunction(c)
10648    }
10649}
10650
10651impl From<CreateTrigger> for Statement {
10652    fn from(c: CreateTrigger) -> Self {
10653        Self::CreateTrigger(c)
10654    }
10655}
10656
10657impl From<DropTrigger> for Statement {
10658    fn from(d: DropTrigger) -> Self {
10659        Self::DropTrigger(d)
10660    }
10661}
10662
10663impl From<DenyStatement> for Statement {
10664    fn from(d: DenyStatement) -> Self {
10665        Self::Deny(d)
10666    }
10667}
10668
10669impl From<CreateDomain> for Statement {
10670    fn from(c: CreateDomain) -> Self {
10671        Self::CreateDomain(c)
10672    }
10673}
10674
10675impl From<RenameTable> for Statement {
10676    fn from(r: RenameTable) -> Self {
10677        vec![r].into()
10678    }
10679}
10680
10681impl From<Vec<RenameTable>> for Statement {
10682    fn from(r: Vec<RenameTable>) -> Self {
10683        Self::RenameTable(r)
10684    }
10685}
10686
10687impl From<PrintStatement> for Statement {
10688    fn from(p: PrintStatement) -> Self {
10689        Self::Print(p)
10690    }
10691}
10692
10693impl From<ReturnStatement> for Statement {
10694    fn from(r: ReturnStatement) -> Self {
10695        Self::Return(r)
10696    }
10697}
10698
10699impl From<ExportData> for Statement {
10700    fn from(e: ExportData) -> Self {
10701        Self::ExportData(e)
10702    }
10703}
10704
10705impl From<CreateUser> for Statement {
10706    fn from(c: CreateUser) -> Self {
10707        Self::CreateUser(c)
10708    }
10709}
10710
10711impl From<VacuumStatement> for Statement {
10712    fn from(v: VacuumStatement) -> Self {
10713        Self::Vacuum(v)
10714    }
10715}
10716
10717impl From<ResetStatement> for Statement {
10718    fn from(r: ResetStatement) -> Self {
10719        Self::Reset(r)
10720    }
10721}
10722
10723#[cfg(test)]
10724mod tests {
10725    use crate::tokenizer::Location;
10726
10727    use super::*;
10728
10729    #[test]
10730    fn test_window_frame_default() {
10731        let window_frame = WindowFrame::default();
10732        assert_eq!(WindowFrameBound::Preceding(None), window_frame.start_bound);
10733    }
10734
10735    #[test]
10736    fn test_grouping_sets_display() {
10737        // a and b in different group
10738        let grouping_sets = Expr::GroupingSets(vec![
10739            vec![Expr::Identifier(Ident::new("a"))],
10740            vec![Expr::Identifier(Ident::new("b"))],
10741        ]);
10742        assert_eq!("GROUPING SETS ((a), (b))", format!("{grouping_sets}"));
10743
10744        // a and b in the same group
10745        let grouping_sets = Expr::GroupingSets(vec![vec![
10746            Expr::Identifier(Ident::new("a")),
10747            Expr::Identifier(Ident::new("b")),
10748        ]]);
10749        assert_eq!("GROUPING SETS ((a, b))", format!("{grouping_sets}"));
10750
10751        // (a, b) and (c, d) in different group
10752        let grouping_sets = Expr::GroupingSets(vec![
10753            vec![
10754                Expr::Identifier(Ident::new("a")),
10755                Expr::Identifier(Ident::new("b")),
10756            ],
10757            vec![
10758                Expr::Identifier(Ident::new("c")),
10759                Expr::Identifier(Ident::new("d")),
10760            ],
10761        ]);
10762        assert_eq!("GROUPING SETS ((a, b), (c, d))", format!("{grouping_sets}"));
10763    }
10764
10765    #[test]
10766    fn test_rollup_display() {
10767        let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new("a"))]]);
10768        assert_eq!("ROLLUP (a)", format!("{rollup}"));
10769
10770        let rollup = Expr::Rollup(vec![vec![
10771            Expr::Identifier(Ident::new("a")),
10772            Expr::Identifier(Ident::new("b")),
10773        ]]);
10774        assert_eq!("ROLLUP ((a, b))", format!("{rollup}"));
10775
10776        let rollup = Expr::Rollup(vec![
10777            vec![Expr::Identifier(Ident::new("a"))],
10778            vec![Expr::Identifier(Ident::new("b"))],
10779        ]);
10780        assert_eq!("ROLLUP (a, b)", format!("{rollup}"));
10781
10782        let rollup = Expr::Rollup(vec![
10783            vec![Expr::Identifier(Ident::new("a"))],
10784            vec![
10785                Expr::Identifier(Ident::new("b")),
10786                Expr::Identifier(Ident::new("c")),
10787            ],
10788            vec![Expr::Identifier(Ident::new("d"))],
10789        ]);
10790        assert_eq!("ROLLUP (a, (b, c), d)", format!("{rollup}"));
10791    }
10792
10793    #[test]
10794    fn test_cube_display() {
10795        let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new("a"))]]);
10796        assert_eq!("CUBE (a)", format!("{cube}"));
10797
10798        let cube = Expr::Cube(vec![vec![
10799            Expr::Identifier(Ident::new("a")),
10800            Expr::Identifier(Ident::new("b")),
10801        ]]);
10802        assert_eq!("CUBE ((a, b))", format!("{cube}"));
10803
10804        let cube = Expr::Cube(vec![
10805            vec![Expr::Identifier(Ident::new("a"))],
10806            vec![Expr::Identifier(Ident::new("b"))],
10807        ]);
10808        assert_eq!("CUBE (a, b)", format!("{cube}"));
10809
10810        let cube = Expr::Cube(vec![
10811            vec![Expr::Identifier(Ident::new("a"))],
10812            vec![
10813                Expr::Identifier(Ident::new("b")),
10814                Expr::Identifier(Ident::new("c")),
10815            ],
10816            vec![Expr::Identifier(Ident::new("d"))],
10817        ]);
10818        assert_eq!("CUBE (a, (b, c), d)", format!("{cube}"));
10819    }
10820
10821    #[test]
10822    fn test_interval_display() {
10823        let interval = Expr::Interval(Interval {
10824            value: Box::new(Expr::Value(
10825                Value::SingleQuotedString(String::from("123:45.67")).with_empty_span(),
10826            )),
10827            leading_field: Some(DateTimeField::Minute),
10828            leading_precision: Some(10),
10829            last_field: Some(DateTimeField::Second),
10830            fractional_seconds_precision: Some(9),
10831        });
10832        assert_eq!(
10833            "INTERVAL '123:45.67' MINUTE (10) TO SECOND (9)",
10834            format!("{interval}"),
10835        );
10836
10837        let interval = Expr::Interval(Interval {
10838            value: Box::new(Expr::Value(
10839                Value::SingleQuotedString(String::from("5")).with_empty_span(),
10840            )),
10841            leading_field: Some(DateTimeField::Second),
10842            leading_precision: Some(1),
10843            last_field: None,
10844            fractional_seconds_precision: Some(3),
10845        });
10846        assert_eq!("INTERVAL '5' SECOND (1, 3)", format!("{interval}"));
10847    }
10848
10849    #[test]
10850    fn test_one_or_many_with_parens_deref() {
10851        use core::ops::Index;
10852
10853        let one = OneOrManyWithParens::One("a");
10854
10855        assert_eq!(one.deref(), &["a"]);
10856        assert_eq!(<OneOrManyWithParens<_> as Deref>::deref(&one), &["a"]);
10857
10858        assert_eq!(one[0], "a");
10859        assert_eq!(one.index(0), &"a");
10860        assert_eq!(
10861            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&one, 0),
10862            &"a"
10863        );
10864
10865        assert_eq!(one.len(), 1);
10866        assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&one), 1);
10867
10868        let many1 = OneOrManyWithParens::Many(vec!["b"]);
10869
10870        assert_eq!(many1.deref(), &["b"]);
10871        assert_eq!(<OneOrManyWithParens<_> as Deref>::deref(&many1), &["b"]);
10872
10873        assert_eq!(many1[0], "b");
10874        assert_eq!(many1.index(0), &"b");
10875        assert_eq!(
10876            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many1, 0),
10877            &"b"
10878        );
10879
10880        assert_eq!(many1.len(), 1);
10881        assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&many1), 1);
10882
10883        let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
10884
10885        assert_eq!(many2.deref(), &["c", "d"]);
10886        assert_eq!(
10887            <OneOrManyWithParens<_> as Deref>::deref(&many2),
10888            &["c", "d"]
10889        );
10890
10891        assert_eq!(many2[0], "c");
10892        assert_eq!(many2.index(0), &"c");
10893        assert_eq!(
10894            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many2, 0),
10895            &"c"
10896        );
10897
10898        assert_eq!(many2[1], "d");
10899        assert_eq!(many2.index(1), &"d");
10900        assert_eq!(
10901            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many2, 1),
10902            &"d"
10903        );
10904
10905        assert_eq!(many2.len(), 2);
10906        assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&many2), 2);
10907    }
10908
10909    #[test]
10910    fn test_one_or_many_with_parens_as_ref() {
10911        let one = OneOrManyWithParens::One("a");
10912
10913        assert_eq!(one.as_ref(), &["a"]);
10914        assert_eq!(<OneOrManyWithParens<_> as AsRef<_>>::as_ref(&one), &["a"]);
10915
10916        let many1 = OneOrManyWithParens::Many(vec!["b"]);
10917
10918        assert_eq!(many1.as_ref(), &["b"]);
10919        assert_eq!(<OneOrManyWithParens<_> as AsRef<_>>::as_ref(&many1), &["b"]);
10920
10921        let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
10922
10923        assert_eq!(many2.as_ref(), &["c", "d"]);
10924        assert_eq!(
10925            <OneOrManyWithParens<_> as AsRef<_>>::as_ref(&many2),
10926            &["c", "d"]
10927        );
10928    }
10929
10930    #[test]
10931    fn test_one_or_many_with_parens_ref_into_iter() {
10932        let one = OneOrManyWithParens::One("a");
10933
10934        assert_eq!(Vec::from_iter(&one), vec![&"a"]);
10935
10936        let many1 = OneOrManyWithParens::Many(vec!["b"]);
10937
10938        assert_eq!(Vec::from_iter(&many1), vec![&"b"]);
10939
10940        let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
10941
10942        assert_eq!(Vec::from_iter(&many2), vec![&"c", &"d"]);
10943    }
10944
10945    #[test]
10946    fn test_one_or_many_with_parens_value_into_iter() {
10947        use core::iter::once;
10948
10949        //tests that our iterator implemented methods behaves exactly as it's inner iterator, at every step up to n calls to next/next_back
10950        fn test_steps<I>(ours: OneOrManyWithParens<usize>, inner: I, n: usize)
10951        where
10952            I: IntoIterator<Item = usize, IntoIter: DoubleEndedIterator + Clone> + Clone,
10953        {
10954            fn checks<I>(ours: OneOrManyWithParensIntoIter<usize>, inner: I)
10955            where
10956                I: Iterator<Item = usize> + Clone + DoubleEndedIterator,
10957            {
10958                assert_eq!(ours.size_hint(), inner.size_hint());
10959                assert_eq!(ours.clone().count(), inner.clone().count());
10960
10961                assert_eq!(
10962                    ours.clone().fold(1, |a, v| a + v),
10963                    inner.clone().fold(1, |a, v| a + v)
10964                );
10965
10966                assert_eq!(Vec::from_iter(ours.clone()), Vec::from_iter(inner.clone()));
10967                assert_eq!(
10968                    Vec::from_iter(ours.clone().rev()),
10969                    Vec::from_iter(inner.clone().rev())
10970                );
10971            }
10972
10973            let mut ours_next = ours.clone().into_iter();
10974            let mut inner_next = inner.clone().into_iter();
10975
10976            for _ in 0..n {
10977                checks(ours_next.clone(), inner_next.clone());
10978
10979                assert_eq!(ours_next.next(), inner_next.next());
10980            }
10981
10982            let mut ours_next_back = ours.clone().into_iter();
10983            let mut inner_next_back = inner.clone().into_iter();
10984
10985            for _ in 0..n {
10986                checks(ours_next_back.clone(), inner_next_back.clone());
10987
10988                assert_eq!(ours_next_back.next_back(), inner_next_back.next_back());
10989            }
10990
10991            let mut ours_mixed = ours.clone().into_iter();
10992            let mut inner_mixed = inner.clone().into_iter();
10993
10994            for i in 0..n {
10995                checks(ours_mixed.clone(), inner_mixed.clone());
10996
10997                if i % 2 == 0 {
10998                    assert_eq!(ours_mixed.next_back(), inner_mixed.next_back());
10999                } else {
11000                    assert_eq!(ours_mixed.next(), inner_mixed.next());
11001                }
11002            }
11003
11004            let mut ours_mixed2 = ours.into_iter();
11005            let mut inner_mixed2 = inner.into_iter();
11006
11007            for i in 0..n {
11008                checks(ours_mixed2.clone(), inner_mixed2.clone());
11009
11010                if i % 2 == 0 {
11011                    assert_eq!(ours_mixed2.next(), inner_mixed2.next());
11012                } else {
11013                    assert_eq!(ours_mixed2.next_back(), inner_mixed2.next_back());
11014                }
11015            }
11016        }
11017
11018        test_steps(OneOrManyWithParens::One(1), once(1), 3);
11019        test_steps(OneOrManyWithParens::Many(vec![2]), vec![2], 3);
11020        test_steps(OneOrManyWithParens::Many(vec![3, 4]), vec![3, 4], 4);
11021    }
11022
11023    // Tests that the position in the code of an `Ident` does not affect its
11024    // ordering.
11025    #[test]
11026    fn test_ident_ord() {
11027        let mut a = Ident::with_span(Span::new(Location::new(1, 1), Location::new(1, 1)), "a");
11028        let mut b = Ident::with_span(Span::new(Location::new(2, 2), Location::new(2, 2)), "b");
11029
11030        assert!(a < b);
11031        std::mem::swap(&mut a.span, &mut b.span);
11032        assert!(a < b);
11033    }
11034}