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    AlterOperatorFamily, AlterOperatorFamilyOperation, AlterOperatorOperation,
64    AlterPolicyOperation, AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm,
65    AlterTableLock, AlterTableOperation, AlterTableType, AlterType, AlterTypeAddValue,
66    AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue,
67    ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy,
68    ColumnPolicyProperty, ConstraintCharacteristics, CreateConnector, CreateDomain,
69    CreateExtension, CreateFunction, CreateIndex, CreateOperator, CreateOperatorClass,
70    CreateOperatorFamily, CreateTable, CreateTrigger, CreateView, Deduplicate, DeferrableInitial,
71    DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily,
72    DropOperatorSignature, DropTrigger, ForValues, GeneratedAs, GeneratedExpressionMode,
73    IdentityParameters, IdentityProperty, IdentityPropertyFormatKind, IdentityPropertyKind,
74    IdentityPropertyOrder, IndexColumn, IndexOption, IndexType, KeyOrIndexDisplay, Msck,
75    NullsDistinctOption, OperatorArgTypes, OperatorClassItem, OperatorFamilyDropItem,
76    OperatorFamilyItem, OperatorOption, OperatorPurpose, Owner, Partition, PartitionBoundValue,
77    ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity, TagsColumnOption,
78    TriggerObjectKind, Truncate, UserDefinedTypeCompositeAttributeDef,
79    UserDefinedTypeInternalLength, UserDefinedTypeRangeOption, UserDefinedTypeRepresentation,
80    UserDefinedTypeSqlDefinitionOption, UserDefinedTypeStorage, ViewColumnDef,
81};
82pub use self::dml::{
83    Delete, Insert, Merge, MergeAction, MergeClause, MergeClauseKind, MergeInsertExpr,
84    MergeInsertKind, MergeUpdateExpr, OutputClause, Update,
85};
86pub use self::operator::{BinaryOperator, UnaryOperator};
87pub use self::query::{
88    AfterMatchSkip, ConnectBy, Cte, CteAsMaterialized, Distinct, EmptyMatchesMode,
89    ExceptSelectItem, ExcludeSelectItem, ExprWithAlias, ExprWithAliasAndOrderBy, Fetch, ForClause,
90    ForJson, ForXml, FormatClause, GroupByExpr, GroupByWithModifier, IdentWithAlias,
91    IlikeSelectItem, InputFormatClause, Interpolate, InterpolateExpr, Join, JoinConstraint,
92    JoinOperator, JsonTableColumn, JsonTableColumnErrorHandling, JsonTableNamedColumn,
93    JsonTableNestedColumn, LateralView, LimitClause, LockClause, LockType, MatchRecognizePattern,
94    MatchRecognizeSymbol, Measure, NamedWindowDefinition, NamedWindowExpr, NonBlock, Offset,
95    OffsetRows, OpenJsonTableColumn, OrderBy, OrderByExpr, OrderByKind, OrderByOptions,
96    PipeOperator, PivotValueSource, ProjectionSelect, Query, RenameSelectItem,
97    RepetitionQuantifier, ReplaceSelectElement, ReplaceSelectItem, RowsPerMatch, Select,
98    SelectFlavor, SelectInto, SelectItem, SelectItemQualifiedWildcardKind, SetExpr, SetOperator,
99    SetQuantifier, Setting, SymbolDefinition, Table, TableAlias, TableAliasColumnDef, TableFactor,
100    TableFunctionArgs, TableIndexHintForClause, TableIndexHintType, TableIndexHints,
101    TableIndexType, TableSample, TableSampleBucket, TableSampleKind, TableSampleMethod,
102    TableSampleModifier, TableSampleQuantity, TableSampleSeed, TableSampleSeedModifier,
103    TableSampleUnit, TableVersion, TableWithJoins, Top, TopQuantity, UpdateTableFromKind,
104    ValueTableMode, Values, WildcardAdditionalOptions, With, WithFill, XmlNamespaceDefinition,
105    XmlPassingArgument, XmlPassingClause, XmlTableColumn, XmlTableColumnOption,
106};
107
108pub use self::trigger::{
109    TriggerEvent, TriggerExecBody, TriggerExecBodyType, TriggerObject, TriggerPeriod,
110    TriggerReferencing, TriggerReferencingType,
111};
112
113pub use self::value::{
114    escape_double_quote_string, escape_quoted_string, DateTimeField, DollarQuotedString,
115    NormalizationForm, QuoteDelimitedString, TrimWhereField, Value, ValueWithSpan,
116};
117
118use crate::ast::helpers::key_value_options::KeyValueOptions;
119use crate::ast::helpers::stmt_data_loading::StageParamsObject;
120
121#[cfg(feature = "visitor")]
122pub use visitor::*;
123
124pub use self::data_type::GeometricTypeKind;
125
126mod data_type;
127mod dcl;
128mod ddl;
129mod dml;
130pub mod helpers;
131pub mod table_constraints;
132pub use table_constraints::{
133    CheckConstraint, ForeignKeyConstraint, FullTextOrSpatialConstraint, IndexConstraint,
134    PrimaryKeyConstraint, TableConstraint, UniqueConstraint,
135};
136mod operator;
137mod query;
138mod spans;
139pub use spans::Spanned;
140
141pub mod comments;
142mod trigger;
143mod value;
144
145#[cfg(feature = "visitor")]
146mod visitor;
147
148pub struct DisplaySeparated<'a, T>
149where
150    T: fmt::Display,
151{
152    slice: &'a [T],
153    sep: &'static str,
154}
155
156impl<T> fmt::Display for DisplaySeparated<'_, T>
157where
158    T: fmt::Display,
159{
160    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
161        let mut delim = "";
162        for t in self.slice {
163            f.write_str(delim)?;
164            delim = self.sep;
165            t.fmt(f)?;
166        }
167        Ok(())
168    }
169}
170
171pub(crate) fn display_separated<'a, T>(slice: &'a [T], sep: &'static str) -> DisplaySeparated<'a, T>
172where
173    T: fmt::Display,
174{
175    DisplaySeparated { slice, sep }
176}
177
178pub(crate) fn display_comma_separated<T>(slice: &[T]) -> DisplaySeparated<'_, T>
179where
180    T: fmt::Display,
181{
182    DisplaySeparated { slice, sep: ", " }
183}
184
185/// Writes the given statements to the formatter, each ending with
186/// a semicolon and space separated.
187fn format_statement_list(f: &mut fmt::Formatter, statements: &[Statement]) -> fmt::Result {
188    write!(f, "{}", display_separated(statements, "; "))?;
189    // We manually insert semicolon for the last statement,
190    // since display_separated doesn't handle that case.
191    write!(f, ";")
192}
193
194/// An identifier, decomposed into its value or character data and the quote style.
195#[derive(Debug, Clone)]
196#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
197#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
198pub struct Ident {
199    /// The value of the identifier without quotes.
200    pub value: String,
201    /// The starting quote if any. Valid quote characters are the single quote,
202    /// double quote, backtick, and opening square bracket.
203    pub quote_style: Option<char>,
204    /// The span of the identifier in the original SQL string.
205    pub span: Span,
206}
207
208impl PartialEq for Ident {
209    fn eq(&self, other: &Self) -> bool {
210        let Ident {
211            value,
212            quote_style,
213            // exhaustiveness check; we ignore spans in comparisons
214            span: _,
215        } = self;
216
217        value == &other.value && quote_style == &other.quote_style
218    }
219}
220
221impl core::hash::Hash for Ident {
222    fn hash<H: hash::Hasher>(&self, state: &mut H) {
223        let Ident {
224            value,
225            quote_style,
226            // exhaustiveness check; we ignore spans in hashes
227            span: _,
228        } = self;
229
230        value.hash(state);
231        quote_style.hash(state);
232    }
233}
234
235impl Eq for Ident {}
236
237impl PartialOrd for Ident {
238    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
239        Some(self.cmp(other))
240    }
241}
242
243impl Ord for Ident {
244    fn cmp(&self, other: &Self) -> Ordering {
245        let Ident {
246            value,
247            quote_style,
248            // exhaustiveness check; we ignore spans in ordering
249            span: _,
250        } = self;
251
252        let Ident {
253            value: other_value,
254            quote_style: other_quote_style,
255            // exhaustiveness check; we ignore spans in ordering
256            span: _,
257        } = other;
258
259        // First compare by value, then by quote_style
260        value
261            .cmp(other_value)
262            .then_with(|| quote_style.cmp(other_quote_style))
263    }
264}
265
266impl Ident {
267    /// Create a new identifier with the given value and no quotes and an empty span.
268    pub fn new<S>(value: S) -> Self
269    where
270        S: Into<String>,
271    {
272        Ident {
273            value: value.into(),
274            quote_style: None,
275            span: Span::empty(),
276        }
277    }
278
279    /// Create a new quoted identifier with the given quote and value. This function
280    /// panics if the given quote is not a valid quote character.
281    pub fn with_quote<S>(quote: char, value: S) -> Self
282    where
283        S: Into<String>,
284    {
285        assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
286        Ident {
287            value: value.into(),
288            quote_style: Some(quote),
289            span: Span::empty(),
290        }
291    }
292
293    pub fn with_span<S>(span: Span, value: S) -> Self
294    where
295        S: Into<String>,
296    {
297        Ident {
298            value: value.into(),
299            quote_style: None,
300            span,
301        }
302    }
303
304    pub fn with_quote_and_span<S>(quote: char, span: Span, value: S) -> Self
305    where
306        S: Into<String>,
307    {
308        assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
309        Ident {
310            value: value.into(),
311            quote_style: Some(quote),
312            span,
313        }
314    }
315}
316
317impl From<&str> for Ident {
318    fn from(value: &str) -> Self {
319        Ident {
320            value: value.to_string(),
321            quote_style: None,
322            span: Span::empty(),
323        }
324    }
325}
326
327impl fmt::Display for Ident {
328    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
329        match self.quote_style {
330            Some(q) if q == '"' || q == '\'' || q == '`' => {
331                let escaped = value::escape_quoted_string(&self.value, q);
332                write!(f, "{q}{escaped}{q}")
333            }
334            Some('[') => write!(f, "[{}]", self.value),
335            None => f.write_str(&self.value),
336            _ => panic!("unexpected quote style"),
337        }
338    }
339}
340
341/// A name of a table, view, custom type, etc., possibly multi-part, i.e. db.schema.obj
342#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
343#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
344#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
345pub struct ObjectName(pub Vec<ObjectNamePart>);
346
347impl From<Vec<Ident>> for ObjectName {
348    fn from(idents: Vec<Ident>) -> Self {
349        ObjectName(idents.into_iter().map(ObjectNamePart::Identifier).collect())
350    }
351}
352
353impl From<Ident> for ObjectName {
354    fn from(ident: Ident) -> Self {
355        ObjectName(vec![ObjectNamePart::Identifier(ident)])
356    }
357}
358
359impl fmt::Display for ObjectName {
360    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
361        write!(f, "{}", display_separated(&self.0, "."))
362    }
363}
364
365/// A single part of an ObjectName
366#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
367#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
368#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
369pub enum ObjectNamePart {
370    Identifier(Ident),
371    Function(ObjectNamePartFunction),
372}
373
374impl ObjectNamePart {
375    pub fn as_ident(&self) -> Option<&Ident> {
376        match self {
377            ObjectNamePart::Identifier(ident) => Some(ident),
378            ObjectNamePart::Function(_) => None,
379        }
380    }
381}
382
383impl fmt::Display for ObjectNamePart {
384    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
385        match self {
386            ObjectNamePart::Identifier(ident) => write!(f, "{ident}"),
387            ObjectNamePart::Function(func) => write!(f, "{func}"),
388        }
389    }
390}
391
392/// An object name part that consists of a function that dynamically
393/// constructs identifiers.
394///
395/// - [Snowflake](https://docs.snowflake.com/en/sql-reference/identifier-literal)
396#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
397#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
398#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
399pub struct ObjectNamePartFunction {
400    pub name: Ident,
401    pub args: Vec<FunctionArg>,
402}
403
404impl fmt::Display for ObjectNamePartFunction {
405    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
406        write!(f, "{}(", self.name)?;
407        write!(f, "{})", display_comma_separated(&self.args))
408    }
409}
410
411/// Represents an Array Expression, either
412/// `ARRAY[..]`, or `[..]`
413#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
414#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
415#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
416pub struct Array {
417    /// The list of expressions between brackets
418    pub elem: Vec<Expr>,
419
420    /// `true` for  `ARRAY[..]`, `false` for `[..]`
421    pub named: bool,
422}
423
424impl fmt::Display for Array {
425    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
426        write!(
427            f,
428            "{}[{}]",
429            if self.named { "ARRAY" } else { "" },
430            display_comma_separated(&self.elem)
431        )
432    }
433}
434
435/// Represents an INTERVAL expression, roughly in the following format:
436/// `INTERVAL '<value>' [ <leading_field> [ (<leading_precision>) ] ]
437/// [ TO <last_field> [ (<fractional_seconds_precision>) ] ]`,
438/// e.g. `INTERVAL '123:45.67' MINUTE(3) TO SECOND(2)`.
439///
440/// The parser does not validate the `<value>`, nor does it ensure
441/// that the `<leading_field>` units >= the units in `<last_field>`,
442/// so the user will have to reject intervals like `HOUR TO YEAR`.
443#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
444#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
445#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
446pub struct Interval {
447    pub value: Box<Expr>,
448    pub leading_field: Option<DateTimeField>,
449    pub leading_precision: Option<u64>,
450    pub last_field: Option<DateTimeField>,
451    /// The seconds precision can be specified in SQL source as
452    /// `INTERVAL '__' SECOND(_, x)` (in which case the `leading_field`
453    /// will be `Second` and the `last_field` will be `None`),
454    /// or as `__ TO SECOND(x)`.
455    pub fractional_seconds_precision: Option<u64>,
456}
457
458impl fmt::Display for Interval {
459    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
460        let value = self.value.as_ref();
461        match (
462            &self.leading_field,
463            self.leading_precision,
464            self.fractional_seconds_precision,
465        ) {
466            (
467                Some(DateTimeField::Second),
468                Some(leading_precision),
469                Some(fractional_seconds_precision),
470            ) => {
471                // When the leading field is SECOND, the parser guarantees that
472                // the last field is None.
473                assert!(self.last_field.is_none());
474                write!(
475                    f,
476                    "INTERVAL {value} SECOND ({leading_precision}, {fractional_seconds_precision})"
477                )
478            }
479            _ => {
480                write!(f, "INTERVAL {value}")?;
481                if let Some(leading_field) = &self.leading_field {
482                    write!(f, " {leading_field}")?;
483                }
484                if let Some(leading_precision) = self.leading_precision {
485                    write!(f, " ({leading_precision})")?;
486                }
487                if let Some(last_field) = &self.last_field {
488                    write!(f, " TO {last_field}")?;
489                }
490                if let Some(fractional_seconds_precision) = self.fractional_seconds_precision {
491                    write!(f, " ({fractional_seconds_precision})")?;
492                }
493                Ok(())
494            }
495        }
496    }
497}
498
499/// A field definition within a struct
500///
501/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
502#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
503#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
504#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
505pub struct StructField {
506    pub field_name: Option<Ident>,
507    pub field_type: DataType,
508    /// Struct field options.
509    /// See [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#column_name_and_column_schema)
510    pub options: Option<Vec<SqlOption>>,
511}
512
513impl fmt::Display for StructField {
514    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
515        if let Some(name) = &self.field_name {
516            write!(f, "{name} {}", self.field_type)?;
517        } else {
518            write!(f, "{}", self.field_type)?;
519        }
520        if let Some(options) = &self.options {
521            write!(f, " OPTIONS({})", display_separated(options, ", "))
522        } else {
523            Ok(())
524        }
525    }
526}
527
528/// A field definition within a union
529///
530/// [DuckDB]: https://duckdb.org/docs/sql/data_types/union.html
531#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
532#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
533#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
534pub struct UnionField {
535    pub field_name: Ident,
536    pub field_type: DataType,
537}
538
539impl fmt::Display for UnionField {
540    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
541        write!(f, "{} {}", self.field_name, self.field_type)
542    }
543}
544
545/// A dictionary field within a dictionary.
546///
547/// [DuckDB]: https://duckdb.org/docs/sql/data_types/struct#creating-structs
548#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
549#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
550#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
551pub struct DictionaryField {
552    pub key: Ident,
553    pub value: Box<Expr>,
554}
555
556impl fmt::Display for DictionaryField {
557    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
558        write!(f, "{}: {}", self.key, self.value)
559    }
560}
561
562/// Represents a Map expression.
563#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
564#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
565#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
566pub struct Map {
567    pub entries: Vec<MapEntry>,
568}
569
570impl Display for Map {
571    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
572        write!(f, "MAP {{{}}}", display_comma_separated(&self.entries))
573    }
574}
575
576/// A map field within a map.
577///
578/// [DuckDB]: https://duckdb.org/docs/sql/data_types/map.html#creating-maps
579#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
580#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
581#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
582pub struct MapEntry {
583    pub key: Box<Expr>,
584    pub value: Box<Expr>,
585}
586
587impl fmt::Display for MapEntry {
588    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
589        write!(f, "{}: {}", self.key, self.value)
590    }
591}
592
593/// Options for `CAST` / `TRY_CAST`
594/// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax>
595#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
596#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
597#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
598pub enum CastFormat {
599    Value(Value),
600    ValueAtTimeZone(Value, Value),
601}
602
603/// An element of a JSON path.
604#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
605#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
606#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
607pub enum JsonPathElem {
608    /// Accesses an object field using dot notation, e.g. `obj:foo.bar.baz`.
609    ///
610    /// See <https://docs.snowflake.com/en/user-guide/querying-semistructured#dot-notation>.
611    Dot { key: String, quoted: bool },
612    /// Accesses an object field or array element using bracket notation,
613    /// e.g. `obj['foo']`.
614    ///
615    /// See <https://docs.snowflake.com/en/user-guide/querying-semistructured#bracket-notation>.
616    Bracket { key: Expr },
617}
618
619/// A JSON path.
620///
621/// See <https://docs.snowflake.com/en/user-guide/querying-semistructured>.
622/// See <https://docs.databricks.com/en/sql/language-manual/sql-ref-json-path-expression.html>.
623#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
624#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
625#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
626pub struct JsonPath {
627    pub path: Vec<JsonPathElem>,
628}
629
630impl fmt::Display for JsonPath {
631    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
632        for (i, elem) in self.path.iter().enumerate() {
633            match elem {
634                JsonPathElem::Dot { key, quoted } => {
635                    if i == 0 {
636                        write!(f, ":")?;
637                    } else {
638                        write!(f, ".")?;
639                    }
640
641                    if *quoted {
642                        write!(f, "\"{}\"", escape_double_quote_string(key))?;
643                    } else {
644                        write!(f, "{key}")?;
645                    }
646                }
647                JsonPathElem::Bracket { key } => {
648                    write!(f, "[{key}]")?;
649                }
650            }
651        }
652        Ok(())
653    }
654}
655
656/// The syntax used for in a cast expression.
657#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
658#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
659#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
660pub enum CastKind {
661    /// The standard SQL cast syntax, e.g. `CAST(<expr> as <datatype>)`
662    Cast,
663    /// A cast that returns `NULL` on failure, e.g. `TRY_CAST(<expr> as <datatype>)`.
664    ///
665    /// See <https://docs.snowflake.com/en/sql-reference/functions/try_cast>.
666    /// See <https://learn.microsoft.com/en-us/sql/t-sql/functions/try-cast-transact-sql>.
667    TryCast,
668    /// A cast that returns `NULL` on failure, bigQuery-specific ,  e.g. `SAFE_CAST(<expr> as <datatype>)`.
669    ///
670    /// See <https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#safe_casting>.
671    SafeCast,
672    /// `<expr> :: <datatype>`
673    DoubleColon,
674}
675
676/// `MATCH` type for constraint references
677///
678/// See: <https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-PARMS-REFERENCES>
679#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
680#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
681#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
682pub enum ConstraintReferenceMatchKind {
683    /// `MATCH FULL`
684    Full,
685    /// `MATCH PARTIAL`
686    Partial,
687    /// `MATCH SIMPLE`
688    Simple,
689}
690
691impl fmt::Display for ConstraintReferenceMatchKind {
692    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
693        match self {
694            Self::Full => write!(f, "MATCH FULL"),
695            Self::Partial => write!(f, "MATCH PARTIAL"),
696            Self::Simple => write!(f, "MATCH SIMPLE"),
697        }
698    }
699}
700
701/// `EXTRACT` syntax variants.
702///
703/// In Snowflake dialect, the `EXTRACT` expression can support either the `from` syntax
704/// or the comma syntax.
705///
706/// See <https://docs.snowflake.com/en/sql-reference/functions/extract>
707#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
708#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
709#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
710pub enum ExtractSyntax {
711    /// `EXTRACT( <date_or_time_part> FROM <date_or_time_expr> )`
712    From,
713    /// `EXTRACT( <date_or_time_part> , <date_or_timestamp_expr> )`
714    Comma,
715}
716
717/// The syntax used in a CEIL or FLOOR expression.
718///
719/// The `CEIL/FLOOR(<datetime value expression> TO <time unit>)` is an Amazon Kinesis Data Analytics extension.
720/// See <https://docs.aws.amazon.com/kinesisanalytics/latest/sqlref/sql-reference-ceil.html> for
721/// details.
722///
723/// Other dialects either support `CEIL/FLOOR( <expr> [, <scale>])` format or just
724/// `CEIL/FLOOR(<expr>)`.
725#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
726#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
727#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
728pub enum CeilFloorKind {
729    /// `CEIL( <expr> TO <DateTimeField>)`
730    DateTimeField(DateTimeField),
731    /// `CEIL( <expr> [, <scale>])`
732    Scale(Value),
733}
734
735/// A WHEN clause in a CASE expression containing both
736/// the condition and its corresponding result
737#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
738#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
739#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
740pub struct CaseWhen {
741    pub condition: Expr,
742    pub result: Expr,
743}
744
745impl fmt::Display for CaseWhen {
746    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
747        f.write_str("WHEN ")?;
748        self.condition.fmt(f)?;
749        f.write_str(" THEN")?;
750        SpaceOrNewline.fmt(f)?;
751        Indent(&self.result).fmt(f)?;
752        Ok(())
753    }
754}
755
756/// An SQL expression of any type.
757///
758/// # Semantics / Type Checking
759///
760/// The parser does not distinguish between expressions of different types
761/// (e.g. boolean vs string). The caller is responsible for detecting and
762/// validating types as necessary (for example  `WHERE 1` vs `SELECT 1=1`)
763/// See the [README.md] for more details.
764///
765/// [README.md]: https://github.com/apache/datafusion-sqlparser-rs/blob/main/README.md#syntax-vs-semantics
766///
767/// # Equality and Hashing Does not Include Source Locations
768///
769/// The `Expr` type implements `PartialEq` and `Eq` based on the semantic value
770/// of the expression (not bitwise comparison). This means that `Expr` instances
771/// that are semantically equivalent but have different spans (locations in the
772/// source tree) will compare as equal.
773#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
774#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
775#[cfg_attr(
776    feature = "visitor",
777    derive(Visit, VisitMut),
778    visit(with = "visit_expr")
779)]
780pub enum Expr {
781    /// Identifier e.g. table name or column name
782    Identifier(Ident),
783    /// Multi-part identifier, e.g. `table_alias.column` or `schema.table.col`
784    CompoundIdentifier(Vec<Ident>),
785    /// Multi-part expression access.
786    ///
787    /// This structure represents an access chain in structured / nested types
788    /// such as maps, arrays, and lists:
789    /// - Array
790    ///     - A 1-dim array `a[1]` will be represented like:
791    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript(1)]`
792    ///     - A 2-dim array `a[1][2]` will be represented like:
793    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript(1), Subscript(2)]`
794    /// - Map or Struct (Bracket-style)
795    ///     - A map `a['field1']` will be represented like:
796    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript('field')]`
797    ///     - A 2-dim map `a['field1']['field2']` will be represented like:
798    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript('field1'), Subscript('field2')]`
799    /// - Struct (Dot-style) (only effect when the chain contains both subscript and expr)
800    ///     - A struct access `a[field1].field2` will be represented like:
801    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript('field1'), Ident('field2')]`
802    /// - If a struct access likes `a.field1.field2`, it will be represented by CompoundIdentifier([a, field1, field2])
803    CompoundFieldAccess {
804        root: Box<Expr>,
805        access_chain: Vec<AccessExpr>,
806    },
807    /// Access data nested in a value containing semi-structured data, such as
808    /// the `VARIANT` type on Snowflake. for example `src:customer[0].name`.
809    ///
810    /// See <https://docs.snowflake.com/en/user-guide/querying-semistructured>.
811    /// See <https://docs.databricks.com/en/sql/language-manual/functions/colonsign.html>.
812    JsonAccess {
813        /// The value being queried.
814        value: Box<Expr>,
815        /// The path to the data to extract.
816        path: JsonPath,
817    },
818    /// `IS FALSE` operator
819    IsFalse(Box<Expr>),
820    /// `IS NOT FALSE` operator
821    IsNotFalse(Box<Expr>),
822    /// `IS TRUE` operator
823    IsTrue(Box<Expr>),
824    /// `IS NOT TRUE` operator
825    IsNotTrue(Box<Expr>),
826    /// `IS NULL` operator
827    IsNull(Box<Expr>),
828    /// `IS NOT NULL` operator
829    IsNotNull(Box<Expr>),
830    /// `IS UNKNOWN` operator
831    IsUnknown(Box<Expr>),
832    /// `IS NOT UNKNOWN` operator
833    IsNotUnknown(Box<Expr>),
834    /// `IS DISTINCT FROM` operator
835    IsDistinctFrom(Box<Expr>, Box<Expr>),
836    /// `IS NOT DISTINCT FROM` operator
837    IsNotDistinctFrom(Box<Expr>, Box<Expr>),
838    /// `<expr> IS [ NOT ] [ form ] NORMALIZED`
839    IsNormalized {
840        expr: Box<Expr>,
841        form: Option<NormalizationForm>,
842        negated: bool,
843    },
844    /// `[ NOT ] IN (val1, val2, ...)`
845    InList {
846        expr: Box<Expr>,
847        list: Vec<Expr>,
848        negated: bool,
849    },
850    /// `[ NOT ] IN (SELECT ...)`
851    InSubquery {
852        expr: Box<Expr>,
853        subquery: Box<Query>,
854        negated: bool,
855    },
856    /// `[ NOT ] IN UNNEST(array_expression)`
857    InUnnest {
858        expr: Box<Expr>,
859        array_expr: Box<Expr>,
860        negated: bool,
861    },
862    /// `<expr> [ NOT ] BETWEEN <low> AND <high>`
863    Between {
864        expr: Box<Expr>,
865        negated: bool,
866        low: Box<Expr>,
867        high: Box<Expr>,
868    },
869    /// Binary operation e.g. `1 + 1` or `foo > bar`
870    BinaryOp {
871        left: Box<Expr>,
872        op: BinaryOperator,
873        right: Box<Expr>,
874    },
875    /// `[NOT] LIKE <pattern> [ESCAPE <escape_character>]`
876    Like {
877        negated: bool,
878        // Snowflake supports the ANY keyword to match against a list of patterns
879        // https://docs.snowflake.com/en/sql-reference/functions/like_any
880        any: bool,
881        expr: Box<Expr>,
882        pattern: Box<Expr>,
883        escape_char: Option<Value>,
884    },
885    /// `ILIKE` (case-insensitive `LIKE`)
886    ILike {
887        negated: bool,
888        // Snowflake supports the ANY keyword to match against a list of patterns
889        // https://docs.snowflake.com/en/sql-reference/functions/like_any
890        any: bool,
891        expr: Box<Expr>,
892        pattern: Box<Expr>,
893        escape_char: Option<Value>,
894    },
895    /// SIMILAR TO regex
896    SimilarTo {
897        negated: bool,
898        expr: Box<Expr>,
899        pattern: Box<Expr>,
900        escape_char: Option<Value>,
901    },
902    /// MySQL: RLIKE regex or REGEXP regex
903    RLike {
904        negated: bool,
905        expr: Box<Expr>,
906        pattern: Box<Expr>,
907        // true for REGEXP, false for RLIKE (no difference in semantics)
908        regexp: bool,
909    },
910    /// `ANY` operation e.g. `foo > ANY(bar)`, comparison operator is one of `[=, >, <, =>, =<, !=]`
911    /// <https://docs.snowflake.com/en/sql-reference/operators-subquery#all-any>
912    AnyOp {
913        left: Box<Expr>,
914        compare_op: BinaryOperator,
915        right: Box<Expr>,
916        // ANY and SOME are synonymous: https://docs.cloudera.com/cdw-runtime/cloud/using-hiveql/topics/hive_comparison_predicates.html
917        is_some: bool,
918    },
919    /// `ALL` operation e.g. `foo > ALL(bar)`, comparison operator is one of `[=, >, <, =>, =<, !=]`
920    /// <https://docs.snowflake.com/en/sql-reference/operators-subquery#all-any>
921    AllOp {
922        left: Box<Expr>,
923        compare_op: BinaryOperator,
924        right: Box<Expr>,
925    },
926    /// Unary operation e.g. `NOT foo`
927    UnaryOp {
928        op: UnaryOperator,
929        expr: Box<Expr>,
930    },
931    /// CONVERT a value to a different data type or character encoding. e.g. `CONVERT(foo USING utf8mb4)`
932    Convert {
933        /// CONVERT (false) or TRY_CONVERT (true)
934        /// <https://learn.microsoft.com/en-us/sql/t-sql/functions/try-convert-transact-sql?view=sql-server-ver16>
935        is_try: bool,
936        /// The expression to convert
937        expr: Box<Expr>,
938        /// The target data type
939        data_type: Option<DataType>,
940        /// The target character encoding
941        charset: Option<ObjectName>,
942        /// whether the target comes before the expr (MSSQL syntax)
943        target_before_value: bool,
944        /// How to translate the expression.
945        ///
946        /// [MSSQL]: https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#style
947        styles: Vec<Expr>,
948    },
949    /// `CAST` an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))`
950    Cast {
951        kind: CastKind,
952        expr: Box<Expr>,
953        data_type: DataType,
954        /// Optional CAST(string_expression AS type FORMAT format_string_expression) as used by [BigQuery]
955        ///
956        /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax
957        format: Option<CastFormat>,
958    },
959    /// AT a timestamp to a different timezone e.g. `FROM_UNIXTIME(0) AT TIME ZONE 'UTC-06:00'`
960    AtTimeZone {
961        timestamp: Box<Expr>,
962        time_zone: Box<Expr>,
963    },
964    /// Extract a field from a timestamp e.g. `EXTRACT(MONTH FROM foo)`
965    /// Or `EXTRACT(MONTH, foo)`
966    ///
967    /// Syntax:
968    /// ```sql
969    /// EXTRACT(DateTimeField FROM <expr>) | EXTRACT(DateTimeField, <expr>)
970    /// ```
971    Extract {
972        field: DateTimeField,
973        syntax: ExtractSyntax,
974        expr: Box<Expr>,
975    },
976    /// ```sql
977    /// CEIL(<expr> [TO DateTimeField])
978    /// ```
979    /// ```sql
980    /// CEIL( <input_expr> [, <scale_expr> ] )
981    /// ```
982    Ceil {
983        expr: Box<Expr>,
984        field: CeilFloorKind,
985    },
986    /// ```sql
987    /// FLOOR(<expr> [TO DateTimeField])
988    /// ```
989    /// ```sql
990    /// FLOOR( <input_expr> [, <scale_expr> ] )
991    ///
992    Floor {
993        expr: Box<Expr>,
994        field: CeilFloorKind,
995    },
996    /// ```sql
997    /// POSITION(<expr> in <expr>)
998    /// ```
999    Position {
1000        expr: Box<Expr>,
1001        r#in: Box<Expr>,
1002    },
1003    /// ```sql
1004    /// SUBSTRING(<expr> [FROM <expr>] [FOR <expr>])
1005    /// ```
1006    /// or
1007    /// ```sql
1008    /// SUBSTRING(<expr>, <expr>, <expr>)
1009    /// ```
1010    Substring {
1011        expr: Box<Expr>,
1012        substring_from: Option<Box<Expr>>,
1013        substring_for: Option<Box<Expr>>,
1014
1015        /// false if the expression is represented using the `SUBSTRING(expr [FROM start] [FOR len])` syntax
1016        /// true if the expression is represented using the `SUBSTRING(expr, start, len)` syntax
1017        /// This flag is used for formatting.
1018        special: bool,
1019
1020        /// true if the expression is represented using the `SUBSTR` shorthand
1021        /// This flag is used for formatting.
1022        shorthand: bool,
1023    },
1024    /// ```sql
1025    /// TRIM([BOTH | LEADING | TRAILING] [<expr> FROM] <expr>)
1026    /// TRIM(<expr>)
1027    /// TRIM(<expr>, [, characters]) -- only Snowflake or Bigquery
1028    /// ```
1029    Trim {
1030        expr: Box<Expr>,
1031        // ([BOTH | LEADING | TRAILING]
1032        trim_where: Option<TrimWhereField>,
1033        trim_what: Option<Box<Expr>>,
1034        trim_characters: Option<Vec<Expr>>,
1035    },
1036    /// ```sql
1037    /// OVERLAY(<expr> PLACING <expr> FROM <expr>[ FOR <expr> ]
1038    /// ```
1039    Overlay {
1040        expr: Box<Expr>,
1041        overlay_what: Box<Expr>,
1042        overlay_from: Box<Expr>,
1043        overlay_for: Option<Box<Expr>>,
1044    },
1045    /// `expr COLLATE collation`
1046    Collate {
1047        expr: Box<Expr>,
1048        collation: ObjectName,
1049    },
1050    /// Nested expression e.g. `(foo > bar)` or `(1)`
1051    Nested(Box<Expr>),
1052    /// A literal value, such as string, number, date or NULL
1053    Value(ValueWithSpan),
1054    /// Prefixed expression, e.g. introducer strings, projection prefix
1055    /// <https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html>
1056    /// <https://docs.snowflake.com/en/sql-reference/constructs/connect-by>
1057    Prefixed {
1058        prefix: Ident,
1059        /// The value of the constant.
1060        /// Hint: you can unwrap the string value using `value.into_string()`.
1061        value: Box<Expr>,
1062    },
1063    /// A constant of form `<data_type> 'value'`.
1064    /// This can represent ANSI SQL `DATE`, `TIME`, and `TIMESTAMP` literals (such as `DATE '2020-01-01'`),
1065    /// as well as constants of other types (a non-standard PostgreSQL extension).
1066    TypedString(TypedString),
1067    /// Scalar function call e.g. `LEFT(foo, 5)`
1068    Function(Function),
1069    /// `CASE [<operand>] WHEN <condition> THEN <result> ... [ELSE <result>] END`
1070    ///
1071    /// Note we only recognize a complete single expression as `<condition>`,
1072    /// not `< 0` nor `1, 2, 3` as allowed in a `<simple when clause>` per
1073    /// <https://jakewheat.github.io/sql-overview/sql-2011-foundation-grammar.html#simple-when-clause>
1074    Case {
1075        case_token: AttachedToken,
1076        end_token: AttachedToken,
1077        operand: Option<Box<Expr>>,
1078        conditions: Vec<CaseWhen>,
1079        else_result: Option<Box<Expr>>,
1080    },
1081    /// An exists expression `[ NOT ] EXISTS(SELECT ...)`, used in expressions like
1082    /// `WHERE [ NOT ] EXISTS (SELECT ...)`.
1083    Exists {
1084        subquery: Box<Query>,
1085        negated: bool,
1086    },
1087    /// A parenthesized subquery `(SELECT ...)`, used in expression like
1088    /// `SELECT (subquery) AS x` or `WHERE (subquery) = x`
1089    Subquery(Box<Query>),
1090    /// The `GROUPING SETS` expr.
1091    GroupingSets(Vec<Vec<Expr>>),
1092    /// The `CUBE` expr.
1093    Cube(Vec<Vec<Expr>>),
1094    /// The `ROLLUP` expr.
1095    Rollup(Vec<Vec<Expr>>),
1096    /// ROW / TUPLE a single value, such as `SELECT (1, 2)`
1097    Tuple(Vec<Expr>),
1098    /// `Struct` literal expression
1099    /// Syntax:
1100    /// ```sql
1101    /// STRUCT<[field_name] field_type, ...>( expr1 [, ... ])
1102    ///
1103    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type)
1104    /// [Databricks](https://docs.databricks.com/en/sql/language-manual/functions/struct.html)
1105    /// ```
1106    Struct {
1107        /// Struct values.
1108        values: Vec<Expr>,
1109        /// Struct field definitions.
1110        fields: Vec<StructField>,
1111    },
1112    /// `BigQuery` specific: An named expression in a typeless struct [1]
1113    ///
1114    /// Syntax
1115    /// ```sql
1116    /// 1 AS A
1117    /// ```
1118    /// [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
1119    Named {
1120        expr: Box<Expr>,
1121        name: Ident,
1122    },
1123    /// `DuckDB` specific `Struct` literal expression [1]
1124    ///
1125    /// Syntax:
1126    /// ```sql
1127    /// syntax: {'field_name': expr1[, ... ]}
1128    /// ```
1129    /// [1]: https://duckdb.org/docs/sql/data_types/struct#creating-structs
1130    Dictionary(Vec<DictionaryField>),
1131    /// `DuckDB` specific `Map` literal expression [1]
1132    ///
1133    /// Syntax:
1134    /// ```sql
1135    /// syntax: Map {key1: value1[, ... ]}
1136    /// ```
1137    /// [1]: https://duckdb.org/docs/sql/data_types/map#creating-maps
1138    Map(Map),
1139    /// An array expression e.g. `ARRAY[1, 2]`
1140    Array(Array),
1141    /// An interval expression e.g. `INTERVAL '1' YEAR`
1142    Interval(Interval),
1143    /// `MySQL` specific text search function [(1)].
1144    ///
1145    /// Syntax:
1146    /// ```sql
1147    /// MATCH (<col>, <col>, ...) AGAINST (<expr> [<search modifier>])
1148    ///
1149    /// <col> = CompoundIdentifier
1150    /// <expr> = String literal
1151    /// ```
1152    /// [(1)]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html#function_match
1153    MatchAgainst {
1154        /// `(<col>, <col>, ...)`.
1155        columns: Vec<ObjectName>,
1156        /// `<expr>`.
1157        match_value: Value,
1158        /// `<search modifier>`
1159        opt_search_modifier: Option<SearchModifier>,
1160    },
1161    Wildcard(AttachedToken),
1162    /// Qualified wildcard, e.g. `alias.*` or `schema.table.*`.
1163    /// (Same caveats apply to `QualifiedWildcard` as to `Wildcard`.)
1164    QualifiedWildcard(ObjectName, AttachedToken),
1165    /// Some dialects support an older syntax for outer joins where columns are
1166    /// marked with the `(+)` operator in the WHERE clause, for example:
1167    ///
1168    /// ```sql
1169    /// SELECT t1.c1, t2.c2 FROM t1, t2 WHERE t1.c1 = t2.c2 (+)
1170    /// ```
1171    ///
1172    /// which is equivalent to
1173    ///
1174    /// ```sql
1175    /// SELECT t1.c1, t2.c2 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c2
1176    /// ```
1177    ///
1178    /// See <https://docs.snowflake.com/en/sql-reference/constructs/where#joins-in-the-where-clause>.
1179    OuterJoin(Box<Expr>),
1180    /// A reference to the prior level in a CONNECT BY clause.
1181    Prior(Box<Expr>),
1182    /// A lambda function.
1183    ///
1184    /// Syntax:
1185    /// ```plaintext
1186    /// param -> expr | (param1, ...) -> expr
1187    /// ```
1188    ///
1189    /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/functions#higher-order-functions---operator-and-lambdaparams-expr-function)
1190    /// [Databricks](https://docs.databricks.com/en/sql/language-manual/sql-ref-lambda-functions.html)
1191    /// [DuckDB](https://duckdb.org/docs/stable/sql/functions/lambda)
1192    Lambda(LambdaFunction),
1193    /// Checks membership of a value in a JSON array
1194    MemberOf(MemberOf),
1195}
1196
1197impl Expr {
1198    /// Creates a new [`Expr::Value`]
1199    pub fn value(value: impl Into<ValueWithSpan>) -> Self {
1200        Expr::Value(value.into())
1201    }
1202}
1203
1204/// The contents inside the `[` and `]` in a subscript expression.
1205#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1206#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1207#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1208pub enum Subscript {
1209    /// Accesses the element of the array at the given index.
1210    Index { index: Expr },
1211
1212    /// Accesses a slice of an array on PostgreSQL, e.g.
1213    ///
1214    /// ```plaintext
1215    /// => select (array[1,2,3,4,5,6])[2:5];
1216    /// -----------
1217    /// {2,3,4,5}
1218    /// ```
1219    ///
1220    /// The lower and/or upper bound can be omitted to slice from the start or
1221    /// end of the array respectively.
1222    ///
1223    /// See <https://www.postgresql.org/docs/current/arrays.html#ARRAYS-ACCESSING>.
1224    ///
1225    /// Also supports an optional "stride" as the last element (this is not
1226    /// supported by postgres), e.g.
1227    ///
1228    /// ```plaintext
1229    /// => select (array[1,2,3,4,5,6])[1:6:2];
1230    /// -----------
1231    /// {1,3,5}
1232    /// ```
1233    Slice {
1234        lower_bound: Option<Expr>,
1235        upper_bound: Option<Expr>,
1236        stride: Option<Expr>,
1237    },
1238}
1239
1240impl fmt::Display for Subscript {
1241    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1242        match self {
1243            Subscript::Index { index } => write!(f, "{index}"),
1244            Subscript::Slice {
1245                lower_bound,
1246                upper_bound,
1247                stride,
1248            } => {
1249                if let Some(lower) = lower_bound {
1250                    write!(f, "{lower}")?;
1251                }
1252                write!(f, ":")?;
1253                if let Some(upper) = upper_bound {
1254                    write!(f, "{upper}")?;
1255                }
1256                if let Some(stride) = stride {
1257                    write!(f, ":")?;
1258                    write!(f, "{stride}")?;
1259                }
1260                Ok(())
1261            }
1262        }
1263    }
1264}
1265
1266/// An element of a [`Expr::CompoundFieldAccess`].
1267/// It can be an expression or a subscript.
1268#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1269#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1270#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1271pub enum AccessExpr {
1272    /// Accesses a field using dot notation, e.g. `foo.bar.baz`.
1273    Dot(Expr),
1274    /// Accesses a field or array element using bracket notation, e.g. `foo['bar']`.
1275    Subscript(Subscript),
1276}
1277
1278impl fmt::Display for AccessExpr {
1279    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1280        match self {
1281            AccessExpr::Dot(expr) => write!(f, ".{expr}"),
1282            AccessExpr::Subscript(subscript) => write!(f, "[{subscript}]"),
1283        }
1284    }
1285}
1286
1287/// A lambda function.
1288#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1289#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1290#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1291pub struct LambdaFunction {
1292    /// The parameters to the lambda function.
1293    pub params: OneOrManyWithParens<Ident>,
1294    /// The body of the lambda function.
1295    pub body: Box<Expr>,
1296}
1297
1298impl fmt::Display for LambdaFunction {
1299    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1300        write!(f, "{} -> {}", self.params, self.body)
1301    }
1302}
1303
1304/// Encapsulates the common pattern in SQL where either one unparenthesized item
1305/// such as an identifier or expression is permitted, or multiple of the same
1306/// item in a parenthesized list. For accessing items regardless of the form,
1307/// `OneOrManyWithParens` implements `Deref<Target = [T]>` and `IntoIterator`,
1308/// so you can call slice methods on it and iterate over items
1309/// # Examples
1310/// Accessing as a slice:
1311/// ```
1312/// # use sqlparser::ast::OneOrManyWithParens;
1313/// let one = OneOrManyWithParens::One("a");
1314///
1315/// assert_eq!(one[0], "a");
1316/// assert_eq!(one.len(), 1);
1317/// ```
1318/// Iterating:
1319/// ```
1320/// # use sqlparser::ast::OneOrManyWithParens;
1321/// let one = OneOrManyWithParens::One("a");
1322/// let many = OneOrManyWithParens::Many(vec!["a", "b"]);
1323///
1324/// assert_eq!(one.into_iter().chain(many).collect::<Vec<_>>(), vec!["a", "a", "b"] );
1325/// ```
1326#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1327#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1328#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1329pub enum OneOrManyWithParens<T> {
1330    /// A single `T`, unparenthesized.
1331    One(T),
1332    /// One or more `T`s, parenthesized.
1333    Many(Vec<T>),
1334}
1335
1336impl<T> Deref for OneOrManyWithParens<T> {
1337    type Target = [T];
1338
1339    fn deref(&self) -> &[T] {
1340        match self {
1341            OneOrManyWithParens::One(one) => core::slice::from_ref(one),
1342            OneOrManyWithParens::Many(many) => many,
1343        }
1344    }
1345}
1346
1347impl<T> AsRef<[T]> for OneOrManyWithParens<T> {
1348    fn as_ref(&self) -> &[T] {
1349        self
1350    }
1351}
1352
1353impl<'a, T> IntoIterator for &'a OneOrManyWithParens<T> {
1354    type Item = &'a T;
1355    type IntoIter = core::slice::Iter<'a, T>;
1356
1357    fn into_iter(self) -> Self::IntoIter {
1358        self.iter()
1359    }
1360}
1361
1362/// Owned iterator implementation of `OneOrManyWithParens`
1363#[derive(Debug, Clone)]
1364pub struct OneOrManyWithParensIntoIter<T> {
1365    inner: OneOrManyWithParensIntoIterInner<T>,
1366}
1367
1368#[derive(Debug, Clone)]
1369enum OneOrManyWithParensIntoIterInner<T> {
1370    One(core::iter::Once<T>),
1371    Many(<Vec<T> as IntoIterator>::IntoIter),
1372}
1373
1374impl<T> core::iter::FusedIterator for OneOrManyWithParensIntoIter<T>
1375where
1376    core::iter::Once<T>: core::iter::FusedIterator,
1377    <Vec<T> as IntoIterator>::IntoIter: core::iter::FusedIterator,
1378{
1379}
1380
1381impl<T> core::iter::ExactSizeIterator for OneOrManyWithParensIntoIter<T>
1382where
1383    core::iter::Once<T>: core::iter::ExactSizeIterator,
1384    <Vec<T> as IntoIterator>::IntoIter: core::iter::ExactSizeIterator,
1385{
1386}
1387
1388impl<T> core::iter::Iterator for OneOrManyWithParensIntoIter<T> {
1389    type Item = T;
1390
1391    fn next(&mut self) -> Option<Self::Item> {
1392        match &mut self.inner {
1393            OneOrManyWithParensIntoIterInner::One(one) => one.next(),
1394            OneOrManyWithParensIntoIterInner::Many(many) => many.next(),
1395        }
1396    }
1397
1398    fn size_hint(&self) -> (usize, Option<usize>) {
1399        match &self.inner {
1400            OneOrManyWithParensIntoIterInner::One(one) => one.size_hint(),
1401            OneOrManyWithParensIntoIterInner::Many(many) => many.size_hint(),
1402        }
1403    }
1404
1405    fn count(self) -> usize
1406    where
1407        Self: Sized,
1408    {
1409        match self.inner {
1410            OneOrManyWithParensIntoIterInner::One(one) => one.count(),
1411            OneOrManyWithParensIntoIterInner::Many(many) => many.count(),
1412        }
1413    }
1414
1415    fn fold<B, F>(mut self, init: B, f: F) -> B
1416    where
1417        Self: Sized,
1418        F: FnMut(B, Self::Item) -> B,
1419    {
1420        match &mut self.inner {
1421            OneOrManyWithParensIntoIterInner::One(one) => one.fold(init, f),
1422            OneOrManyWithParensIntoIterInner::Many(many) => many.fold(init, f),
1423        }
1424    }
1425}
1426
1427impl<T> core::iter::DoubleEndedIterator for OneOrManyWithParensIntoIter<T> {
1428    fn next_back(&mut self) -> Option<Self::Item> {
1429        match &mut self.inner {
1430            OneOrManyWithParensIntoIterInner::One(one) => one.next_back(),
1431            OneOrManyWithParensIntoIterInner::Many(many) => many.next_back(),
1432        }
1433    }
1434}
1435
1436impl<T> IntoIterator for OneOrManyWithParens<T> {
1437    type Item = T;
1438
1439    type IntoIter = OneOrManyWithParensIntoIter<T>;
1440
1441    fn into_iter(self) -> Self::IntoIter {
1442        let inner = match self {
1443            OneOrManyWithParens::One(one) => {
1444                OneOrManyWithParensIntoIterInner::One(core::iter::once(one))
1445            }
1446            OneOrManyWithParens::Many(many) => {
1447                OneOrManyWithParensIntoIterInner::Many(many.into_iter())
1448            }
1449        };
1450
1451        OneOrManyWithParensIntoIter { inner }
1452    }
1453}
1454
1455impl<T> fmt::Display for OneOrManyWithParens<T>
1456where
1457    T: fmt::Display,
1458{
1459    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1460        match self {
1461            OneOrManyWithParens::One(value) => write!(f, "{value}"),
1462            OneOrManyWithParens::Many(values) => {
1463                write!(f, "({})", display_comma_separated(values))
1464            }
1465        }
1466    }
1467}
1468
1469impl fmt::Display for CastFormat {
1470    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1471        match self {
1472            CastFormat::Value(v) => write!(f, "{v}"),
1473            CastFormat::ValueAtTimeZone(v, tz) => write!(f, "{v} AT TIME ZONE {tz}"),
1474        }
1475    }
1476}
1477
1478impl fmt::Display for Expr {
1479    #[cfg_attr(feature = "recursive-protection", recursive::recursive)]
1480    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1481        match self {
1482            Expr::Identifier(s) => write!(f, "{s}"),
1483            Expr::Wildcard(_) => f.write_str("*"),
1484            Expr::QualifiedWildcard(prefix, _) => write!(f, "{prefix}.*"),
1485            Expr::CompoundIdentifier(s) => write!(f, "{}", display_separated(s, ".")),
1486            Expr::CompoundFieldAccess { root, access_chain } => {
1487                write!(f, "{root}")?;
1488                for field in access_chain {
1489                    write!(f, "{field}")?;
1490                }
1491                Ok(())
1492            }
1493            Expr::IsTrue(ast) => write!(f, "{ast} IS TRUE"),
1494            Expr::IsNotTrue(ast) => write!(f, "{ast} IS NOT TRUE"),
1495            Expr::IsFalse(ast) => write!(f, "{ast} IS FALSE"),
1496            Expr::IsNotFalse(ast) => write!(f, "{ast} IS NOT FALSE"),
1497            Expr::IsNull(ast) => write!(f, "{ast} IS NULL"),
1498            Expr::IsNotNull(ast) => write!(f, "{ast} IS NOT NULL"),
1499            Expr::IsUnknown(ast) => write!(f, "{ast} IS UNKNOWN"),
1500            Expr::IsNotUnknown(ast) => write!(f, "{ast} IS NOT UNKNOWN"),
1501            Expr::InList {
1502                expr,
1503                list,
1504                negated,
1505            } => write!(
1506                f,
1507                "{} {}IN ({})",
1508                expr,
1509                if *negated { "NOT " } else { "" },
1510                display_comma_separated(list)
1511            ),
1512            Expr::InSubquery {
1513                expr,
1514                subquery,
1515                negated,
1516            } => write!(
1517                f,
1518                "{} {}IN ({})",
1519                expr,
1520                if *negated { "NOT " } else { "" },
1521                subquery
1522            ),
1523            Expr::InUnnest {
1524                expr,
1525                array_expr,
1526                negated,
1527            } => write!(
1528                f,
1529                "{} {}IN UNNEST({})",
1530                expr,
1531                if *negated { "NOT " } else { "" },
1532                array_expr
1533            ),
1534            Expr::Between {
1535                expr,
1536                negated,
1537                low,
1538                high,
1539            } => write!(
1540                f,
1541                "{} {}BETWEEN {} AND {}",
1542                expr,
1543                if *negated { "NOT " } else { "" },
1544                low,
1545                high
1546            ),
1547            Expr::BinaryOp { left, op, right } => write!(f, "{left} {op} {right}"),
1548            Expr::Like {
1549                negated,
1550                expr,
1551                pattern,
1552                escape_char,
1553                any,
1554            } => match escape_char {
1555                Some(ch) => write!(
1556                    f,
1557                    "{} {}LIKE {}{} ESCAPE {}",
1558                    expr,
1559                    if *negated { "NOT " } else { "" },
1560                    if *any { "ANY " } else { "" },
1561                    pattern,
1562                    ch
1563                ),
1564                _ => write!(
1565                    f,
1566                    "{} {}LIKE {}{}",
1567                    expr,
1568                    if *negated { "NOT " } else { "" },
1569                    if *any { "ANY " } else { "" },
1570                    pattern
1571                ),
1572            },
1573            Expr::ILike {
1574                negated,
1575                expr,
1576                pattern,
1577                escape_char,
1578                any,
1579            } => match escape_char {
1580                Some(ch) => write!(
1581                    f,
1582                    "{} {}ILIKE {}{} ESCAPE {}",
1583                    expr,
1584                    if *negated { "NOT " } else { "" },
1585                    if *any { "ANY" } else { "" },
1586                    pattern,
1587                    ch
1588                ),
1589                _ => write!(
1590                    f,
1591                    "{} {}ILIKE {}{}",
1592                    expr,
1593                    if *negated { "NOT " } else { "" },
1594                    if *any { "ANY " } else { "" },
1595                    pattern
1596                ),
1597            },
1598            Expr::RLike {
1599                negated,
1600                expr,
1601                pattern,
1602                regexp,
1603            } => write!(
1604                f,
1605                "{} {}{} {}",
1606                expr,
1607                if *negated { "NOT " } else { "" },
1608                if *regexp { "REGEXP" } else { "RLIKE" },
1609                pattern
1610            ),
1611            Expr::IsNormalized {
1612                expr,
1613                form,
1614                negated,
1615            } => {
1616                let not_ = if *negated { "NOT " } else { "" };
1617                if form.is_none() {
1618                    write!(f, "{expr} IS {not_}NORMALIZED")
1619                } else {
1620                    write!(
1621                        f,
1622                        "{} IS {}{} NORMALIZED",
1623                        expr,
1624                        not_,
1625                        form.as_ref().unwrap()
1626                    )
1627                }
1628            }
1629            Expr::SimilarTo {
1630                negated,
1631                expr,
1632                pattern,
1633                escape_char,
1634            } => match escape_char {
1635                Some(ch) => write!(
1636                    f,
1637                    "{} {}SIMILAR TO {} ESCAPE {}",
1638                    expr,
1639                    if *negated { "NOT " } else { "" },
1640                    pattern,
1641                    ch
1642                ),
1643                _ => write!(
1644                    f,
1645                    "{} {}SIMILAR TO {}",
1646                    expr,
1647                    if *negated { "NOT " } else { "" },
1648                    pattern
1649                ),
1650            },
1651            Expr::AnyOp {
1652                left,
1653                compare_op,
1654                right,
1655                is_some,
1656            } => {
1657                let add_parens = !matches!(right.as_ref(), Expr::Subquery(_));
1658                write!(
1659                    f,
1660                    "{left} {compare_op} {}{}{right}{}",
1661                    if *is_some { "SOME" } else { "ANY" },
1662                    if add_parens { "(" } else { "" },
1663                    if add_parens { ")" } else { "" },
1664                )
1665            }
1666            Expr::AllOp {
1667                left,
1668                compare_op,
1669                right,
1670            } => {
1671                let add_parens = !matches!(right.as_ref(), Expr::Subquery(_));
1672                write!(
1673                    f,
1674                    "{left} {compare_op} ALL{}{right}{}",
1675                    if add_parens { "(" } else { "" },
1676                    if add_parens { ")" } else { "" },
1677                )
1678            }
1679            Expr::UnaryOp { op, expr } => {
1680                if op == &UnaryOperator::PGPostfixFactorial {
1681                    write!(f, "{expr}{op}")
1682                } else if matches!(
1683                    op,
1684                    UnaryOperator::Not
1685                        | UnaryOperator::Hash
1686                        | UnaryOperator::AtDashAt
1687                        | UnaryOperator::DoubleAt
1688                        | UnaryOperator::QuestionDash
1689                        | UnaryOperator::QuestionPipe
1690                ) {
1691                    write!(f, "{op} {expr}")
1692                } else {
1693                    write!(f, "{op}{expr}")
1694                }
1695            }
1696            Expr::Convert {
1697                is_try,
1698                expr,
1699                target_before_value,
1700                data_type,
1701                charset,
1702                styles,
1703            } => {
1704                write!(f, "{}CONVERT(", if *is_try { "TRY_" } else { "" })?;
1705                if let Some(data_type) = data_type {
1706                    if let Some(charset) = charset {
1707                        write!(f, "{expr}, {data_type} CHARACTER SET {charset}")
1708                    } else if *target_before_value {
1709                        write!(f, "{data_type}, {expr}")
1710                    } else {
1711                        write!(f, "{expr}, {data_type}")
1712                    }
1713                } else if let Some(charset) = charset {
1714                    write!(f, "{expr} USING {charset}")
1715                } else {
1716                    write!(f, "{expr}") // This should never happen
1717                }?;
1718                if !styles.is_empty() {
1719                    write!(f, ", {}", display_comma_separated(styles))?;
1720                }
1721                write!(f, ")")
1722            }
1723            Expr::Cast {
1724                kind,
1725                expr,
1726                data_type,
1727                format,
1728            } => match kind {
1729                CastKind::Cast => {
1730                    if let Some(format) = format {
1731                        write!(f, "CAST({expr} AS {data_type} FORMAT {format})")
1732                    } else {
1733                        write!(f, "CAST({expr} AS {data_type})")
1734                    }
1735                }
1736                CastKind::TryCast => {
1737                    if let Some(format) = format {
1738                        write!(f, "TRY_CAST({expr} AS {data_type} FORMAT {format})")
1739                    } else {
1740                        write!(f, "TRY_CAST({expr} AS {data_type})")
1741                    }
1742                }
1743                CastKind::SafeCast => {
1744                    if let Some(format) = format {
1745                        write!(f, "SAFE_CAST({expr} AS {data_type} FORMAT {format})")
1746                    } else {
1747                        write!(f, "SAFE_CAST({expr} AS {data_type})")
1748                    }
1749                }
1750                CastKind::DoubleColon => {
1751                    write!(f, "{expr}::{data_type}")
1752                }
1753            },
1754            Expr::Extract {
1755                field,
1756                syntax,
1757                expr,
1758            } => match syntax {
1759                ExtractSyntax::From => write!(f, "EXTRACT({field} FROM {expr})"),
1760                ExtractSyntax::Comma => write!(f, "EXTRACT({field}, {expr})"),
1761            },
1762            Expr::Ceil { expr, field } => match field {
1763                CeilFloorKind::DateTimeField(DateTimeField::NoDateTime) => {
1764                    write!(f, "CEIL({expr})")
1765                }
1766                CeilFloorKind::DateTimeField(dt_field) => write!(f, "CEIL({expr} TO {dt_field})"),
1767                CeilFloorKind::Scale(s) => write!(f, "CEIL({expr}, {s})"),
1768            },
1769            Expr::Floor { expr, field } => match field {
1770                CeilFloorKind::DateTimeField(DateTimeField::NoDateTime) => {
1771                    write!(f, "FLOOR({expr})")
1772                }
1773                CeilFloorKind::DateTimeField(dt_field) => write!(f, "FLOOR({expr} TO {dt_field})"),
1774                CeilFloorKind::Scale(s) => write!(f, "FLOOR({expr}, {s})"),
1775            },
1776            Expr::Position { expr, r#in } => write!(f, "POSITION({expr} IN {in})"),
1777            Expr::Collate { expr, collation } => write!(f, "{expr} COLLATE {collation}"),
1778            Expr::Nested(ast) => write!(f, "({ast})"),
1779            Expr::Value(v) => write!(f, "{v}"),
1780            Expr::Prefixed { prefix, value } => write!(f, "{prefix} {value}"),
1781            Expr::TypedString(ts) => ts.fmt(f),
1782            Expr::Function(fun) => fun.fmt(f),
1783            Expr::Case {
1784                case_token: _,
1785                end_token: _,
1786                operand,
1787                conditions,
1788                else_result,
1789            } => {
1790                f.write_str("CASE")?;
1791                if let Some(operand) = operand {
1792                    f.write_str(" ")?;
1793                    operand.fmt(f)?;
1794                }
1795                for when in conditions {
1796                    SpaceOrNewline.fmt(f)?;
1797                    Indent(when).fmt(f)?;
1798                }
1799                if let Some(else_result) = else_result {
1800                    SpaceOrNewline.fmt(f)?;
1801                    Indent("ELSE").fmt(f)?;
1802                    SpaceOrNewline.fmt(f)?;
1803                    Indent(Indent(else_result)).fmt(f)?;
1804                }
1805                SpaceOrNewline.fmt(f)?;
1806                f.write_str("END")
1807            }
1808            Expr::Exists { subquery, negated } => write!(
1809                f,
1810                "{}EXISTS ({})",
1811                if *negated { "NOT " } else { "" },
1812                subquery
1813            ),
1814            Expr::Subquery(s) => write!(f, "({s})"),
1815            Expr::GroupingSets(sets) => {
1816                write!(f, "GROUPING SETS (")?;
1817                let mut sep = "";
1818                for set in sets {
1819                    write!(f, "{sep}")?;
1820                    sep = ", ";
1821                    write!(f, "({})", display_comma_separated(set))?;
1822                }
1823                write!(f, ")")
1824            }
1825            Expr::Cube(sets) => {
1826                write!(f, "CUBE (")?;
1827                let mut sep = "";
1828                for set in sets {
1829                    write!(f, "{sep}")?;
1830                    sep = ", ";
1831                    if set.len() == 1 {
1832                        write!(f, "{}", set[0])?;
1833                    } else {
1834                        write!(f, "({})", display_comma_separated(set))?;
1835                    }
1836                }
1837                write!(f, ")")
1838            }
1839            Expr::Rollup(sets) => {
1840                write!(f, "ROLLUP (")?;
1841                let mut sep = "";
1842                for set in sets {
1843                    write!(f, "{sep}")?;
1844                    sep = ", ";
1845                    if set.len() == 1 {
1846                        write!(f, "{}", set[0])?;
1847                    } else {
1848                        write!(f, "({})", display_comma_separated(set))?;
1849                    }
1850                }
1851                write!(f, ")")
1852            }
1853            Expr::Substring {
1854                expr,
1855                substring_from,
1856                substring_for,
1857                special,
1858                shorthand,
1859            } => {
1860                f.write_str("SUBSTR")?;
1861                if !*shorthand {
1862                    f.write_str("ING")?;
1863                }
1864                write!(f, "({expr}")?;
1865                if let Some(from_part) = substring_from {
1866                    if *special {
1867                        write!(f, ", {from_part}")?;
1868                    } else {
1869                        write!(f, " FROM {from_part}")?;
1870                    }
1871                }
1872                if let Some(for_part) = substring_for {
1873                    if *special {
1874                        write!(f, ", {for_part}")?;
1875                    } else {
1876                        write!(f, " FOR {for_part}")?;
1877                    }
1878                }
1879
1880                write!(f, ")")
1881            }
1882            Expr::Overlay {
1883                expr,
1884                overlay_what,
1885                overlay_from,
1886                overlay_for,
1887            } => {
1888                write!(
1889                    f,
1890                    "OVERLAY({expr} PLACING {overlay_what} FROM {overlay_from}"
1891                )?;
1892                if let Some(for_part) = overlay_for {
1893                    write!(f, " FOR {for_part}")?;
1894                }
1895
1896                write!(f, ")")
1897            }
1898            Expr::IsDistinctFrom(a, b) => write!(f, "{a} IS DISTINCT FROM {b}"),
1899            Expr::IsNotDistinctFrom(a, b) => write!(f, "{a} IS NOT DISTINCT FROM {b}"),
1900            Expr::Trim {
1901                expr,
1902                trim_where,
1903                trim_what,
1904                trim_characters,
1905            } => {
1906                write!(f, "TRIM(")?;
1907                if let Some(ident) = trim_where {
1908                    write!(f, "{ident} ")?;
1909                }
1910                if let Some(trim_char) = trim_what {
1911                    write!(f, "{trim_char} FROM {expr}")?;
1912                } else {
1913                    write!(f, "{expr}")?;
1914                }
1915                if let Some(characters) = trim_characters {
1916                    write!(f, ", {}", display_comma_separated(characters))?;
1917                }
1918
1919                write!(f, ")")
1920            }
1921            Expr::Tuple(exprs) => {
1922                write!(f, "({})", display_comma_separated(exprs))
1923            }
1924            Expr::Struct { values, fields } => {
1925                if !fields.is_empty() {
1926                    write!(
1927                        f,
1928                        "STRUCT<{}>({})",
1929                        display_comma_separated(fields),
1930                        display_comma_separated(values)
1931                    )
1932                } else {
1933                    write!(f, "STRUCT({})", display_comma_separated(values))
1934                }
1935            }
1936            Expr::Named { expr, name } => {
1937                write!(f, "{expr} AS {name}")
1938            }
1939            Expr::Dictionary(fields) => {
1940                write!(f, "{{{}}}", display_comma_separated(fields))
1941            }
1942            Expr::Map(map) => {
1943                write!(f, "{map}")
1944            }
1945            Expr::Array(set) => {
1946                write!(f, "{set}")
1947            }
1948            Expr::JsonAccess { value, path } => {
1949                write!(f, "{value}{path}")
1950            }
1951            Expr::AtTimeZone {
1952                timestamp,
1953                time_zone,
1954            } => {
1955                write!(f, "{timestamp} AT TIME ZONE {time_zone}")
1956            }
1957            Expr::Interval(interval) => {
1958                write!(f, "{interval}")
1959            }
1960            Expr::MatchAgainst {
1961                columns,
1962                match_value: match_expr,
1963                opt_search_modifier,
1964            } => {
1965                write!(f, "MATCH ({}) AGAINST ", display_comma_separated(columns),)?;
1966
1967                if let Some(search_modifier) = opt_search_modifier {
1968                    write!(f, "({match_expr} {search_modifier})")?;
1969                } else {
1970                    write!(f, "({match_expr})")?;
1971                }
1972
1973                Ok(())
1974            }
1975            Expr::OuterJoin(expr) => {
1976                write!(f, "{expr} (+)")
1977            }
1978            Expr::Prior(expr) => write!(f, "PRIOR {expr}"),
1979            Expr::Lambda(lambda) => write!(f, "{lambda}"),
1980            Expr::MemberOf(member_of) => write!(f, "{member_of}"),
1981        }
1982    }
1983}
1984
1985#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1986#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1987#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1988pub enum WindowType {
1989    WindowSpec(WindowSpec),
1990    NamedWindow(Ident),
1991}
1992
1993impl Display for WindowType {
1994    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1995        match self {
1996            WindowType::WindowSpec(spec) => {
1997                f.write_str("(")?;
1998                NewLine.fmt(f)?;
1999                Indent(spec).fmt(f)?;
2000                NewLine.fmt(f)?;
2001                f.write_str(")")
2002            }
2003            WindowType::NamedWindow(name) => name.fmt(f),
2004        }
2005    }
2006}
2007
2008/// A window specification (i.e. `OVER ([window_name] PARTITION BY .. ORDER BY .. etc.)`)
2009#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2010#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2011#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2012pub struct WindowSpec {
2013    /// Optional window name.
2014    ///
2015    /// You can find it at least in [MySQL][1], [BigQuery][2], [PostgreSQL][3]
2016    ///
2017    /// [1]: https://dev.mysql.com/doc/refman/8.0/en/window-functions-named-windows.html
2018    /// [2]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
2019    /// [3]: https://www.postgresql.org/docs/current/sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS
2020    pub window_name: Option<Ident>,
2021    /// `OVER (PARTITION BY ...)`
2022    pub partition_by: Vec<Expr>,
2023    /// `OVER (ORDER BY ...)`
2024    pub order_by: Vec<OrderByExpr>,
2025    /// `OVER (window frame)`
2026    pub window_frame: Option<WindowFrame>,
2027}
2028
2029impl fmt::Display for WindowSpec {
2030    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2031        let mut is_first = true;
2032        if let Some(window_name) = &self.window_name {
2033            if !is_first {
2034                SpaceOrNewline.fmt(f)?;
2035            }
2036            is_first = false;
2037            write!(f, "{window_name}")?;
2038        }
2039        if !self.partition_by.is_empty() {
2040            if !is_first {
2041                SpaceOrNewline.fmt(f)?;
2042            }
2043            is_first = false;
2044            write!(
2045                f,
2046                "PARTITION BY {}",
2047                display_comma_separated(&self.partition_by)
2048            )?;
2049        }
2050        if !self.order_by.is_empty() {
2051            if !is_first {
2052                SpaceOrNewline.fmt(f)?;
2053            }
2054            is_first = false;
2055            write!(f, "ORDER BY {}", display_comma_separated(&self.order_by))?;
2056        }
2057        if let Some(window_frame) = &self.window_frame {
2058            if !is_first {
2059                SpaceOrNewline.fmt(f)?;
2060            }
2061            if let Some(end_bound) = &window_frame.end_bound {
2062                write!(
2063                    f,
2064                    "{} BETWEEN {} AND {}",
2065                    window_frame.units, window_frame.start_bound, end_bound
2066                )?;
2067            } else {
2068                write!(f, "{} {}", window_frame.units, window_frame.start_bound)?;
2069            }
2070        }
2071        Ok(())
2072    }
2073}
2074
2075/// Specifies the data processed by a window function, e.g.
2076/// `RANGE UNBOUNDED PRECEDING` or `ROWS BETWEEN 5 PRECEDING AND CURRENT ROW`.
2077///
2078/// Note: The parser does not validate the specified bounds; the caller should
2079/// reject invalid bounds like `ROWS UNBOUNDED FOLLOWING` before execution.
2080#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2081#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2082#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2083pub struct WindowFrame {
2084    pub units: WindowFrameUnits,
2085    pub start_bound: WindowFrameBound,
2086    /// The right bound of the `BETWEEN .. AND` clause. The end bound of `None`
2087    /// indicates the shorthand form (e.g. `ROWS 1 PRECEDING`), which must
2088    /// behave the same as `end_bound = WindowFrameBound::CurrentRow`.
2089    pub end_bound: Option<WindowFrameBound>,
2090    // TBD: EXCLUDE
2091}
2092
2093impl Default for WindowFrame {
2094    /// Returns default value for window frame
2095    ///
2096    /// See [this page](https://www.sqlite.org/windowfunctions.html#frame_specifications) for more details.
2097    fn default() -> Self {
2098        Self {
2099            units: WindowFrameUnits::Range,
2100            start_bound: WindowFrameBound::Preceding(None),
2101            end_bound: None,
2102        }
2103    }
2104}
2105
2106#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2107#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2108#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2109pub enum WindowFrameUnits {
2110    Rows,
2111    Range,
2112    Groups,
2113}
2114
2115impl fmt::Display for WindowFrameUnits {
2116    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2117        f.write_str(match self {
2118            WindowFrameUnits::Rows => "ROWS",
2119            WindowFrameUnits::Range => "RANGE",
2120            WindowFrameUnits::Groups => "GROUPS",
2121        })
2122    }
2123}
2124
2125/// Specifies Ignore / Respect NULL within window functions.
2126/// For example
2127/// `FIRST_VALUE(column2) IGNORE NULLS OVER (PARTITION BY column1)`
2128#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2129#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2130#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2131pub enum NullTreatment {
2132    IgnoreNulls,
2133    RespectNulls,
2134}
2135
2136impl fmt::Display for NullTreatment {
2137    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2138        f.write_str(match self {
2139            NullTreatment::IgnoreNulls => "IGNORE NULLS",
2140            NullTreatment::RespectNulls => "RESPECT NULLS",
2141        })
2142    }
2143}
2144
2145/// Specifies [WindowFrame]'s `start_bound` and `end_bound`
2146#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2147#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2148#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2149pub enum WindowFrameBound {
2150    /// `CURRENT ROW`
2151    CurrentRow,
2152    /// `<N> PRECEDING` or `UNBOUNDED PRECEDING`
2153    Preceding(Option<Box<Expr>>),
2154    /// `<N> FOLLOWING` or `UNBOUNDED FOLLOWING`.
2155    Following(Option<Box<Expr>>),
2156}
2157
2158impl fmt::Display for WindowFrameBound {
2159    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2160        match self {
2161            WindowFrameBound::CurrentRow => f.write_str("CURRENT ROW"),
2162            WindowFrameBound::Preceding(None) => f.write_str("UNBOUNDED PRECEDING"),
2163            WindowFrameBound::Following(None) => f.write_str("UNBOUNDED FOLLOWING"),
2164            WindowFrameBound::Preceding(Some(n)) => write!(f, "{n} PRECEDING"),
2165            WindowFrameBound::Following(Some(n)) => write!(f, "{n} FOLLOWING"),
2166        }
2167    }
2168}
2169
2170#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2171#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2172#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2173pub enum AddDropSync {
2174    ADD,
2175    DROP,
2176    SYNC,
2177}
2178
2179impl fmt::Display for AddDropSync {
2180    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2181        match self {
2182            AddDropSync::SYNC => f.write_str("SYNC PARTITIONS"),
2183            AddDropSync::DROP => f.write_str("DROP PARTITIONS"),
2184            AddDropSync::ADD => f.write_str("ADD PARTITIONS"),
2185        }
2186    }
2187}
2188
2189#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2190#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2191#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2192pub enum ShowCreateObject {
2193    Event,
2194    Function,
2195    Procedure,
2196    Table,
2197    Trigger,
2198    View,
2199}
2200
2201impl fmt::Display for ShowCreateObject {
2202    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2203        match self {
2204            ShowCreateObject::Event => f.write_str("EVENT"),
2205            ShowCreateObject::Function => f.write_str("FUNCTION"),
2206            ShowCreateObject::Procedure => f.write_str("PROCEDURE"),
2207            ShowCreateObject::Table => f.write_str("TABLE"),
2208            ShowCreateObject::Trigger => f.write_str("TRIGGER"),
2209            ShowCreateObject::View => f.write_str("VIEW"),
2210        }
2211    }
2212}
2213
2214#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2215#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2216#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2217pub enum CommentObject {
2218    Column,
2219    Table,
2220    Extension,
2221    Schema,
2222    Database,
2223    User,
2224    Role,
2225}
2226
2227impl fmt::Display for CommentObject {
2228    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2229        match self {
2230            CommentObject::Column => f.write_str("COLUMN"),
2231            CommentObject::Table => f.write_str("TABLE"),
2232            CommentObject::Extension => f.write_str("EXTENSION"),
2233            CommentObject::Schema => f.write_str("SCHEMA"),
2234            CommentObject::Database => f.write_str("DATABASE"),
2235            CommentObject::User => f.write_str("USER"),
2236            CommentObject::Role => f.write_str("ROLE"),
2237        }
2238    }
2239}
2240
2241#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2242#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2243#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2244pub enum Password {
2245    Password(Expr),
2246    NullPassword,
2247}
2248
2249/// A `CASE` statement.
2250///
2251/// Examples:
2252/// ```sql
2253/// CASE
2254///     WHEN EXISTS(SELECT 1)
2255///         THEN SELECT 1 FROM T;
2256///     WHEN EXISTS(SELECT 2)
2257///         THEN SELECT 1 FROM U;
2258///     ELSE
2259///         SELECT 1 FROM V;
2260/// END CASE;
2261/// ```
2262///
2263/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#case_search_expression)
2264/// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/case)
2265#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2267#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2268pub struct CaseStatement {
2269    /// The `CASE` token that starts the statement.
2270    pub case_token: AttachedToken,
2271    pub match_expr: Option<Expr>,
2272    pub when_blocks: Vec<ConditionalStatementBlock>,
2273    pub else_block: Option<ConditionalStatementBlock>,
2274    /// The last token of the statement (`END` or `CASE`).
2275    pub end_case_token: AttachedToken,
2276}
2277
2278impl fmt::Display for CaseStatement {
2279    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2280        let CaseStatement {
2281            case_token: _,
2282            match_expr,
2283            when_blocks,
2284            else_block,
2285            end_case_token: AttachedToken(end),
2286        } = self;
2287
2288        write!(f, "CASE")?;
2289
2290        if let Some(expr) = match_expr {
2291            write!(f, " {expr}")?;
2292        }
2293
2294        if !when_blocks.is_empty() {
2295            write!(f, " {}", display_separated(when_blocks, " "))?;
2296        }
2297
2298        if let Some(else_block) = else_block {
2299            write!(f, " {else_block}")?;
2300        }
2301
2302        write!(f, " END")?;
2303
2304        if let Token::Word(w) = &end.token {
2305            if w.keyword == Keyword::CASE {
2306                write!(f, " CASE")?;
2307            }
2308        }
2309
2310        Ok(())
2311    }
2312}
2313
2314/// An `IF` statement.
2315///
2316/// Example (BigQuery or Snowflake):
2317/// ```sql
2318/// IF TRUE THEN
2319///     SELECT 1;
2320///     SELECT 2;
2321/// ELSEIF TRUE THEN
2322///     SELECT 3;
2323/// ELSE
2324///     SELECT 4;
2325/// END IF
2326/// ```
2327/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#if)
2328/// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/if)
2329///
2330/// Example (MSSQL):
2331/// ```sql
2332/// IF 1=1 SELECT 1 ELSE SELECT 2
2333/// ```
2334/// [MSSQL](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/if-else-transact-sql?view=sql-server-ver16)
2335#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2336#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2337#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2338pub struct IfStatement {
2339    pub if_block: ConditionalStatementBlock,
2340    pub elseif_blocks: Vec<ConditionalStatementBlock>,
2341    pub else_block: Option<ConditionalStatementBlock>,
2342    pub end_token: Option<AttachedToken>,
2343}
2344
2345impl fmt::Display for IfStatement {
2346    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2347        let IfStatement {
2348            if_block,
2349            elseif_blocks,
2350            else_block,
2351            end_token,
2352        } = self;
2353
2354        write!(f, "{if_block}")?;
2355
2356        for elseif_block in elseif_blocks {
2357            write!(f, " {elseif_block}")?;
2358        }
2359
2360        if let Some(else_block) = else_block {
2361            write!(f, " {else_block}")?;
2362        }
2363
2364        if let Some(AttachedToken(end_token)) = end_token {
2365            write!(f, " END {end_token}")?;
2366        }
2367
2368        Ok(())
2369    }
2370}
2371
2372/// A `WHILE` statement.
2373///
2374/// Example:
2375/// ```sql
2376/// WHILE @@FETCH_STATUS = 0
2377/// BEGIN
2378///    FETCH NEXT FROM c1 INTO @var1, @var2;
2379/// END
2380/// ```
2381///
2382/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/while-transact-sql)
2383#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2384#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2385#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2386pub struct WhileStatement {
2387    pub while_block: ConditionalStatementBlock,
2388}
2389
2390impl fmt::Display for WhileStatement {
2391    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2392        let WhileStatement { while_block } = self;
2393        write!(f, "{while_block}")?;
2394        Ok(())
2395    }
2396}
2397
2398/// A block within a [Statement::Case] or [Statement::If] or [Statement::While]-like statement
2399///
2400/// Example 1:
2401/// ```sql
2402/// WHEN EXISTS(SELECT 1) THEN SELECT 1;
2403/// ```
2404///
2405/// Example 2:
2406/// ```sql
2407/// IF TRUE THEN SELECT 1; SELECT 2;
2408/// ```
2409///
2410/// Example 3:
2411/// ```sql
2412/// ELSE SELECT 1; SELECT 2;
2413/// ```
2414///
2415/// Example 4:
2416/// ```sql
2417/// WHILE @@FETCH_STATUS = 0
2418/// BEGIN
2419///    FETCH NEXT FROM c1 INTO @var1, @var2;
2420/// END
2421/// ```
2422#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2423#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2424#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2425pub struct ConditionalStatementBlock {
2426    pub start_token: AttachedToken,
2427    pub condition: Option<Expr>,
2428    pub then_token: Option<AttachedToken>,
2429    pub conditional_statements: ConditionalStatements,
2430}
2431
2432impl ConditionalStatementBlock {
2433    pub fn statements(&self) -> &Vec<Statement> {
2434        self.conditional_statements.statements()
2435    }
2436}
2437
2438impl fmt::Display for ConditionalStatementBlock {
2439    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2440        let ConditionalStatementBlock {
2441            start_token: AttachedToken(start_token),
2442            condition,
2443            then_token,
2444            conditional_statements,
2445        } = self;
2446
2447        write!(f, "{start_token}")?;
2448
2449        if let Some(condition) = condition {
2450            write!(f, " {condition}")?;
2451        }
2452
2453        if then_token.is_some() {
2454            write!(f, " THEN")?;
2455        }
2456
2457        if !conditional_statements.statements().is_empty() {
2458            write!(f, " {conditional_statements}")?;
2459        }
2460
2461        Ok(())
2462    }
2463}
2464
2465/// A list of statements in a [ConditionalStatementBlock].
2466#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2467#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2468#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2469pub enum ConditionalStatements {
2470    /// SELECT 1; SELECT 2; SELECT 3; ...
2471    Sequence { statements: Vec<Statement> },
2472    /// BEGIN SELECT 1; SELECT 2; SELECT 3; ... END
2473    BeginEnd(BeginEndStatements),
2474}
2475
2476impl ConditionalStatements {
2477    pub fn statements(&self) -> &Vec<Statement> {
2478        match self {
2479            ConditionalStatements::Sequence { statements } => statements,
2480            ConditionalStatements::BeginEnd(bes) => &bes.statements,
2481        }
2482    }
2483}
2484
2485impl fmt::Display for ConditionalStatements {
2486    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2487        match self {
2488            ConditionalStatements::Sequence { statements } => {
2489                if !statements.is_empty() {
2490                    format_statement_list(f, statements)?;
2491                }
2492                Ok(())
2493            }
2494            ConditionalStatements::BeginEnd(bes) => write!(f, "{bes}"),
2495        }
2496    }
2497}
2498
2499/// Represents a list of statements enclosed within `BEGIN` and `END` keywords.
2500/// Example:
2501/// ```sql
2502/// BEGIN
2503///     SELECT 1;
2504///     SELECT 2;
2505/// END
2506/// ```
2507#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2508#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2509#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2510pub struct BeginEndStatements {
2511    pub begin_token: AttachedToken,
2512    pub statements: Vec<Statement>,
2513    pub end_token: AttachedToken,
2514}
2515
2516impl fmt::Display for BeginEndStatements {
2517    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2518        let BeginEndStatements {
2519            begin_token: AttachedToken(begin_token),
2520            statements,
2521            end_token: AttachedToken(end_token),
2522        } = self;
2523
2524        if begin_token.token != Token::EOF {
2525            write!(f, "{begin_token} ")?;
2526        }
2527        if !statements.is_empty() {
2528            format_statement_list(f, statements)?;
2529        }
2530        if end_token.token != Token::EOF {
2531            write!(f, " {end_token}")?;
2532        }
2533        Ok(())
2534    }
2535}
2536
2537/// A `RAISE` statement.
2538///
2539/// Examples:
2540/// ```sql
2541/// RAISE USING MESSAGE = 'error';
2542///
2543/// RAISE myerror;
2544/// ```
2545///
2546/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#raise)
2547/// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/raise)
2548#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2549#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2550#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2551pub struct RaiseStatement {
2552    pub value: Option<RaiseStatementValue>,
2553}
2554
2555impl fmt::Display for RaiseStatement {
2556    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2557        let RaiseStatement { value } = self;
2558
2559        write!(f, "RAISE")?;
2560        if let Some(value) = value {
2561            write!(f, " {value}")?;
2562        }
2563
2564        Ok(())
2565    }
2566}
2567
2568/// Represents the error value of a [RaiseStatement].
2569#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2570#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2571#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2572pub enum RaiseStatementValue {
2573    /// `RAISE USING MESSAGE = 'error'`
2574    UsingMessage(Expr),
2575    /// `RAISE myerror`
2576    Expr(Expr),
2577}
2578
2579impl fmt::Display for RaiseStatementValue {
2580    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2581        match self {
2582            RaiseStatementValue::Expr(expr) => write!(f, "{expr}"),
2583            RaiseStatementValue::UsingMessage(expr) => write!(f, "USING MESSAGE = {expr}"),
2584        }
2585    }
2586}
2587
2588/// Represents an expression assignment within a variable `DECLARE` statement.
2589///
2590/// Examples:
2591/// ```sql
2592/// DECLARE variable_name := 42
2593/// DECLARE variable_name DEFAULT 42
2594/// ```
2595#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2596#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2597#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2598pub enum DeclareAssignment {
2599    /// Plain expression specified.
2600    Expr(Box<Expr>),
2601
2602    /// Expression assigned via the `DEFAULT` keyword
2603    Default(Box<Expr>),
2604
2605    /// Expression assigned via the `:=` syntax
2606    ///
2607    /// Example:
2608    /// ```sql
2609    /// DECLARE variable_name := 42;
2610    /// ```
2611    DuckAssignment(Box<Expr>),
2612
2613    /// Expression via the `FOR` keyword
2614    ///
2615    /// Example:
2616    /// ```sql
2617    /// DECLARE c1 CURSOR FOR res
2618    /// ```
2619    For(Box<Expr>),
2620
2621    /// Expression via the `=` syntax.
2622    ///
2623    /// Example:
2624    /// ```sql
2625    /// DECLARE @variable AS INT = 100
2626    /// ```
2627    MsSqlAssignment(Box<Expr>),
2628}
2629
2630impl fmt::Display for DeclareAssignment {
2631    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2632        match self {
2633            DeclareAssignment::Expr(expr) => {
2634                write!(f, "{expr}")
2635            }
2636            DeclareAssignment::Default(expr) => {
2637                write!(f, "DEFAULT {expr}")
2638            }
2639            DeclareAssignment::DuckAssignment(expr) => {
2640                write!(f, ":= {expr}")
2641            }
2642            DeclareAssignment::MsSqlAssignment(expr) => {
2643                write!(f, "= {expr}")
2644            }
2645            DeclareAssignment::For(expr) => {
2646                write!(f, "FOR {expr}")
2647            }
2648        }
2649    }
2650}
2651
2652/// Represents the type of a `DECLARE` statement.
2653#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2654#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2655#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2656pub enum DeclareType {
2657    /// Cursor variable type. e.g. [Snowflake] [PostgreSQL] [MsSql]
2658    ///
2659    /// [Snowflake]: https://docs.snowflake.com/en/developer-guide/snowflake-scripting/cursors#declaring-a-cursor
2660    /// [PostgreSQL]: https://www.postgresql.org/docs/current/plpgsql-cursors.html
2661    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-cursor-transact-sql
2662    Cursor,
2663
2664    /// Result set variable type. [Snowflake]
2665    ///
2666    /// Syntax:
2667    /// ```text
2668    /// <resultset_name> RESULTSET [ { DEFAULT | := } ( <query> ) ] ;
2669    /// ```
2670    /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare#resultset-declaration-syntax
2671    ResultSet,
2672
2673    /// Exception declaration syntax. [Snowflake]
2674    ///
2675    /// Syntax:
2676    /// ```text
2677    /// <exception_name> EXCEPTION [ ( <exception_number> , '<exception_message>' ) ] ;
2678    /// ```
2679    /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare#exception-declaration-syntax
2680    Exception,
2681}
2682
2683impl fmt::Display for DeclareType {
2684    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2685        match self {
2686            DeclareType::Cursor => {
2687                write!(f, "CURSOR")
2688            }
2689            DeclareType::ResultSet => {
2690                write!(f, "RESULTSET")
2691            }
2692            DeclareType::Exception => {
2693                write!(f, "EXCEPTION")
2694            }
2695        }
2696    }
2697}
2698
2699/// A `DECLARE` statement.
2700/// [PostgreSQL] [Snowflake] [BigQuery]
2701///
2702/// Examples:
2703/// ```sql
2704/// DECLARE variable_name := 42
2705/// DECLARE liahona CURSOR FOR SELECT * FROM films;
2706/// ```
2707///
2708/// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-declare.html
2709/// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare
2710/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#declare
2711#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2712#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2713#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2714pub struct Declare {
2715    /// The name(s) being declared.
2716    /// Example: `DECLARE a, b, c DEFAULT 42;
2717    pub names: Vec<Ident>,
2718    /// Data-type assigned to the declared variable.
2719    /// Example: `DECLARE x INT64 DEFAULT 42;
2720    pub data_type: Option<DataType>,
2721    /// Expression being assigned to the declared variable.
2722    pub assignment: Option<DeclareAssignment>,
2723    /// Represents the type of the declared variable.
2724    pub declare_type: Option<DeclareType>,
2725    /// Causes the cursor to return data in binary rather than in text format.
2726    pub binary: Option<bool>,
2727    /// None = Not specified
2728    /// Some(true) = INSENSITIVE
2729    /// Some(false) = ASENSITIVE
2730    pub sensitive: Option<bool>,
2731    /// None = Not specified
2732    /// Some(true) = SCROLL
2733    /// Some(false) = NO SCROLL
2734    pub scroll: Option<bool>,
2735    /// None = Not specified
2736    /// Some(true) = WITH HOLD, specifies that the cursor can continue to be used after the transaction that created it successfully commits
2737    /// Some(false) = WITHOUT HOLD, specifies that the cursor cannot be used outside of the transaction that created it
2738    pub hold: Option<bool>,
2739    /// `FOR <query>` clause in a CURSOR declaration.
2740    pub for_query: Option<Box<Query>>,
2741}
2742
2743impl fmt::Display for Declare {
2744    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2745        let Declare {
2746            names,
2747            data_type,
2748            assignment,
2749            declare_type,
2750            binary,
2751            sensitive,
2752            scroll,
2753            hold,
2754            for_query,
2755        } = self;
2756        write!(f, "{}", display_comma_separated(names))?;
2757
2758        if let Some(true) = binary {
2759            write!(f, " BINARY")?;
2760        }
2761
2762        if let Some(sensitive) = sensitive {
2763            if *sensitive {
2764                write!(f, " INSENSITIVE")?;
2765            } else {
2766                write!(f, " ASENSITIVE")?;
2767            }
2768        }
2769
2770        if let Some(scroll) = scroll {
2771            if *scroll {
2772                write!(f, " SCROLL")?;
2773            } else {
2774                write!(f, " NO SCROLL")?;
2775            }
2776        }
2777
2778        if let Some(declare_type) = declare_type {
2779            write!(f, " {declare_type}")?;
2780        }
2781
2782        if let Some(hold) = hold {
2783            if *hold {
2784                write!(f, " WITH HOLD")?;
2785            } else {
2786                write!(f, " WITHOUT HOLD")?;
2787            }
2788        }
2789
2790        if let Some(query) = for_query {
2791            write!(f, " FOR {query}")?;
2792        }
2793
2794        if let Some(data_type) = data_type {
2795            write!(f, " {data_type}")?;
2796        }
2797
2798        if let Some(expr) = assignment {
2799            write!(f, " {expr}")?;
2800        }
2801        Ok(())
2802    }
2803}
2804
2805/// Sql options of a `CREATE TABLE` statement.
2806#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2807#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2808#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2809pub enum CreateTableOptions {
2810    #[default]
2811    None,
2812    /// Options specified using the `WITH` keyword.
2813    /// e.g. `WITH (description = "123")`
2814    ///
2815    /// <https://www.postgresql.org/docs/current/sql-createtable.html>
2816    ///
2817    /// MSSQL supports more specific options that's not only key-value pairs.
2818    ///
2819    /// WITH (
2820    ///     DISTRIBUTION = ROUND_ROBIN,
2821    ///     CLUSTERED INDEX (column_a DESC, column_b)
2822    /// )
2823    ///
2824    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#syntax>
2825    With(Vec<SqlOption>),
2826    /// Options specified using the `OPTIONS` keyword.
2827    /// e.g. `OPTIONS(description = "123")`
2828    ///
2829    /// <https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#table_option_list>
2830    Options(Vec<SqlOption>),
2831
2832    /// Plain options, options which are not part on any declerative statement e.g. WITH/OPTIONS/...
2833    /// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
2834    Plain(Vec<SqlOption>),
2835
2836    TableProperties(Vec<SqlOption>),
2837}
2838
2839impl fmt::Display for CreateTableOptions {
2840    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2841        match self {
2842            CreateTableOptions::With(with_options) => {
2843                write!(f, "WITH ({})", display_comma_separated(with_options))
2844            }
2845            CreateTableOptions::Options(options) => {
2846                write!(f, "OPTIONS({})", display_comma_separated(options))
2847            }
2848            CreateTableOptions::TableProperties(options) => {
2849                write!(f, "TBLPROPERTIES ({})", display_comma_separated(options))
2850            }
2851            CreateTableOptions::Plain(options) => {
2852                write!(f, "{}", display_separated(options, " "))
2853            }
2854            CreateTableOptions::None => Ok(()),
2855        }
2856    }
2857}
2858
2859/// A `FROM` clause within a `DELETE` statement.
2860///
2861/// Syntax
2862/// ```sql
2863/// [FROM] table
2864/// ```
2865#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2866#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2867#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2868pub enum FromTable {
2869    /// An explicit `FROM` keyword was specified.
2870    WithFromKeyword(Vec<TableWithJoins>),
2871    /// BigQuery: `FROM` keyword was omitted.
2872    /// <https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#delete_statement>
2873    WithoutKeyword(Vec<TableWithJoins>),
2874}
2875impl Display for FromTable {
2876    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2877        match self {
2878            FromTable::WithFromKeyword(tables) => {
2879                write!(f, "FROM {}", display_comma_separated(tables))
2880            }
2881            FromTable::WithoutKeyword(tables) => {
2882                write!(f, "{}", display_comma_separated(tables))
2883            }
2884        }
2885    }
2886}
2887
2888/// Policy type for a `CREATE POLICY` statement.
2889/// ```sql
2890/// AS [ PERMISSIVE | RESTRICTIVE ]
2891/// ```
2892/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)
2893#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2894#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2895#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2896pub enum CreatePolicyType {
2897    Permissive,
2898    Restrictive,
2899}
2900
2901/// Policy command for a `CREATE POLICY` statement.
2902/// ```sql
2903/// FOR [ALL | SELECT | INSERT | UPDATE | DELETE]
2904/// ```
2905/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)
2906#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2907#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2908#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2909pub enum CreatePolicyCommand {
2910    All,
2911    Select,
2912    Insert,
2913    Update,
2914    Delete,
2915}
2916
2917#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2918#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2919#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2920pub enum Set {
2921    /// SQL Standard-style
2922    /// SET a = 1;
2923    SingleAssignment {
2924        scope: Option<ContextModifier>,
2925        hivevar: bool,
2926        variable: ObjectName,
2927        values: Vec<Expr>,
2928    },
2929    /// Snowflake-style
2930    /// SET (a, b, ..) = (1, 2, ..);
2931    ParenthesizedAssignments {
2932        variables: Vec<ObjectName>,
2933        values: Vec<Expr>,
2934    },
2935    /// MySQL-style
2936    /// SET a = 1, b = 2, ..;
2937    MultipleAssignments { assignments: Vec<SetAssignment> },
2938    /// Session authorization for Postgres/Redshift
2939    ///
2940    /// ```sql
2941    /// SET SESSION AUTHORIZATION { user_name | DEFAULT }
2942    /// ```
2943    ///
2944    /// See <https://www.postgresql.org/docs/current/sql-set-session-authorization.html>
2945    /// See <https://docs.aws.amazon.com/redshift/latest/dg/r_SET_SESSION_AUTHORIZATION.html>
2946    SetSessionAuthorization(SetSessionAuthorizationParam),
2947    /// MS-SQL session
2948    ///
2949    /// See <https://learn.microsoft.com/en-us/sql/t-sql/statements/set-statements-transact-sql>
2950    SetSessionParam(SetSessionParamKind),
2951    /// ```sql
2952    /// SET [ SESSION | LOCAL ] ROLE role_name
2953    /// ```
2954    ///
2955    /// Sets session state. Examples: [ANSI][1], [Postgresql][2], [MySQL][3], and [Oracle][4]
2956    ///
2957    /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#set-role-statement
2958    /// [2]: https://www.postgresql.org/docs/14/sql-set-role.html
2959    /// [3]: https://dev.mysql.com/doc/refman/8.0/en/set-role.html
2960    /// [4]: https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_10004.htm
2961    SetRole {
2962        /// Non-ANSI optional identifier to inform if the role is defined inside the current session (`SESSION`) or transaction (`LOCAL`).
2963        context_modifier: Option<ContextModifier>,
2964        /// Role name. If NONE is specified, then the current role name is removed.
2965        role_name: Option<Ident>,
2966    },
2967    /// ```sql
2968    /// SET TIME ZONE <value>
2969    /// ```
2970    ///
2971    /// Note: this is a PostgreSQL-specific statements
2972    /// `SET TIME ZONE <value>` is an alias for `SET timezone TO <value>` in PostgreSQL
2973    /// However, we allow it for all dialects.
2974    SetTimeZone { local: bool, value: Expr },
2975    /// ```sql
2976    /// SET NAMES 'charset_name' [COLLATE 'collation_name']
2977    /// ```
2978    SetNames {
2979        charset_name: Ident,
2980        collation_name: Option<String>,
2981    },
2982    /// ```sql
2983    /// SET NAMES DEFAULT
2984    /// ```
2985    ///
2986    /// Note: this is a MySQL-specific statement.
2987    SetNamesDefault {},
2988    /// ```sql
2989    /// SET TRANSACTION ...
2990    /// ```
2991    SetTransaction {
2992        modes: Vec<TransactionMode>,
2993        snapshot: Option<Value>,
2994        session: bool,
2995    },
2996}
2997
2998impl Display for Set {
2999    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3000        match self {
3001            Self::ParenthesizedAssignments { variables, values } => write!(
3002                f,
3003                "SET ({}) = ({})",
3004                display_comma_separated(variables),
3005                display_comma_separated(values)
3006            ),
3007            Self::MultipleAssignments { assignments } => {
3008                write!(f, "SET {}", display_comma_separated(assignments))
3009            }
3010            Self::SetRole {
3011                context_modifier,
3012                role_name,
3013            } => {
3014                let role_name = role_name.clone().unwrap_or_else(|| Ident::new("NONE"));
3015                write!(
3016                    f,
3017                    "SET {modifier}ROLE {role_name}",
3018                    modifier = context_modifier.map(|m| format!("{m}")).unwrap_or_default()
3019                )
3020            }
3021            Self::SetSessionAuthorization(kind) => write!(f, "SET SESSION AUTHORIZATION {kind}"),
3022            Self::SetSessionParam(kind) => write!(f, "SET {kind}"),
3023            Self::SetTransaction {
3024                modes,
3025                snapshot,
3026                session,
3027            } => {
3028                if *session {
3029                    write!(f, "SET SESSION CHARACTERISTICS AS TRANSACTION")?;
3030                } else {
3031                    write!(f, "SET TRANSACTION")?;
3032                }
3033                if !modes.is_empty() {
3034                    write!(f, " {}", display_comma_separated(modes))?;
3035                }
3036                if let Some(snapshot_id) = snapshot {
3037                    write!(f, " SNAPSHOT {snapshot_id}")?;
3038                }
3039                Ok(())
3040            }
3041            Self::SetTimeZone { local, value } => {
3042                f.write_str("SET ")?;
3043                if *local {
3044                    f.write_str("LOCAL ")?;
3045                }
3046                write!(f, "TIME ZONE {value}")
3047            }
3048            Self::SetNames {
3049                charset_name,
3050                collation_name,
3051            } => {
3052                write!(f, "SET NAMES {charset_name}")?;
3053
3054                if let Some(collation) = collation_name {
3055                    f.write_str(" COLLATE ")?;
3056                    f.write_str(collation)?;
3057                };
3058
3059                Ok(())
3060            }
3061            Self::SetNamesDefault {} => {
3062                f.write_str("SET NAMES DEFAULT")?;
3063
3064                Ok(())
3065            }
3066            Set::SingleAssignment {
3067                scope,
3068                hivevar,
3069                variable,
3070                values,
3071            } => {
3072                write!(
3073                    f,
3074                    "SET {}{}{} = {}",
3075                    scope.map(|s| format!("{s}")).unwrap_or_default(),
3076                    if *hivevar { "HIVEVAR:" } else { "" },
3077                    variable,
3078                    display_comma_separated(values)
3079                )
3080            }
3081        }
3082    }
3083}
3084
3085/// A representation of a `WHEN` arm with all the identifiers catched and the statements to execute
3086/// for the arm.
3087///
3088/// Snowflake: <https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
3089/// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
3090#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3091#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3092#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3093pub struct ExceptionWhen {
3094    pub idents: Vec<Ident>,
3095    pub statements: Vec<Statement>,
3096}
3097
3098impl Display for ExceptionWhen {
3099    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3100        write!(
3101            f,
3102            "WHEN {idents} THEN",
3103            idents = display_separated(&self.idents, " OR ")
3104        )?;
3105
3106        if !self.statements.is_empty() {
3107            write!(f, " ")?;
3108            format_statement_list(f, &self.statements)?;
3109        }
3110
3111        Ok(())
3112    }
3113}
3114
3115/// ANALYZE TABLE statement (Hive-specific)
3116#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3117#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3118#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3119pub struct Analyze {
3120    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3121    pub table_name: ObjectName,
3122    pub partitions: Option<Vec<Expr>>,
3123    pub for_columns: bool,
3124    pub columns: Vec<Ident>,
3125    pub cache_metadata: bool,
3126    pub noscan: bool,
3127    pub compute_statistics: bool,
3128    pub has_table_keyword: bool,
3129}
3130
3131impl fmt::Display for Analyze {
3132    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3133        write!(
3134            f,
3135            "ANALYZE{}{table_name}",
3136            if self.has_table_keyword {
3137                " TABLE "
3138            } else {
3139                " "
3140            },
3141            table_name = self.table_name
3142        )?;
3143        if let Some(ref parts) = self.partitions {
3144            if !parts.is_empty() {
3145                write!(f, " PARTITION ({})", display_comma_separated(parts))?;
3146            }
3147        }
3148
3149        if self.compute_statistics {
3150            write!(f, " COMPUTE STATISTICS")?;
3151        }
3152        if self.noscan {
3153            write!(f, " NOSCAN")?;
3154        }
3155        if self.cache_metadata {
3156            write!(f, " CACHE METADATA")?;
3157        }
3158        if self.for_columns {
3159            write!(f, " FOR COLUMNS")?;
3160            if !self.columns.is_empty() {
3161                write!(f, " {}", display_comma_separated(&self.columns))?;
3162            }
3163        }
3164        Ok(())
3165    }
3166}
3167
3168/// A top-level statement (SELECT, INSERT, CREATE, etc.)
3169#[allow(clippy::large_enum_variant)]
3170#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3171#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3172#[cfg_attr(
3173    feature = "visitor",
3174    derive(Visit, VisitMut),
3175    visit(with = "visit_statement")
3176)]
3177pub enum Statement {
3178    /// ```sql
3179    /// ANALYZE
3180    /// ```
3181    /// Analyze (Hive)
3182    Analyze(Analyze),
3183    Set(Set),
3184    /// ```sql
3185    /// TRUNCATE
3186    /// ```
3187    /// Truncate (Hive)
3188    Truncate(Truncate),
3189    /// ```sql
3190    /// MSCK
3191    /// ```
3192    /// Msck (Hive)
3193    Msck(Msck),
3194    /// ```sql
3195    /// SELECT
3196    /// ```
3197    Query(Box<Query>),
3198    /// ```sql
3199    /// INSERT
3200    /// ```
3201    Insert(Insert),
3202    /// ```sql
3203    /// INSTALL
3204    /// ```
3205    Install {
3206        /// Only for DuckDB
3207        extension_name: Ident,
3208    },
3209    /// ```sql
3210    /// LOAD
3211    /// ```
3212    Load {
3213        /// Only for DuckDB
3214        extension_name: Ident,
3215    },
3216    // TODO: Support ROW FORMAT
3217    Directory {
3218        overwrite: bool,
3219        local: bool,
3220        path: String,
3221        file_format: Option<FileFormat>,
3222        source: Box<Query>,
3223    },
3224    /// A `CASE` statement.
3225    Case(CaseStatement),
3226    /// An `IF` statement.
3227    If(IfStatement),
3228    /// A `WHILE` statement.
3229    While(WhileStatement),
3230    /// A `RAISE` statement.
3231    Raise(RaiseStatement),
3232    /// ```sql
3233    /// CALL <function>
3234    /// ```
3235    Call(Function),
3236    /// ```sql
3237    /// COPY [TO | FROM] ...
3238    /// ```
3239    Copy {
3240        /// The source of 'COPY TO', or the target of 'COPY FROM'
3241        source: CopySource,
3242        /// If true, is a 'COPY TO' statement. If false is a 'COPY FROM'
3243        to: bool,
3244        /// The target of 'COPY TO', or the source of 'COPY FROM'
3245        target: CopyTarget,
3246        /// WITH options (from PostgreSQL version 9.0)
3247        options: Vec<CopyOption>,
3248        /// WITH options (before PostgreSQL version 9.0)
3249        legacy_options: Vec<CopyLegacyOption>,
3250        /// VALUES a vector of values to be copied
3251        values: Vec<Option<String>>,
3252    },
3253    /// ```sql
3254    /// COPY INTO <table> | <location>
3255    /// ```
3256    /// See:
3257    /// <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table>
3258    /// <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location>
3259    ///
3260    /// Copy Into syntax available for Snowflake is different than the one implemented in
3261    /// Postgres. Although they share common prefix, it is reasonable to implement them
3262    /// in different enums. This can be refactored later once custom dialects
3263    /// are allowed to have custom Statements.
3264    CopyIntoSnowflake {
3265        kind: CopyIntoSnowflakeKind,
3266        into: ObjectName,
3267        into_columns: Option<Vec<Ident>>,
3268        from_obj: Option<ObjectName>,
3269        from_obj_alias: Option<Ident>,
3270        stage_params: StageParamsObject,
3271        from_transformations: Option<Vec<StageLoadSelectItemKind>>,
3272        from_query: Option<Box<Query>>,
3273        files: Option<Vec<String>>,
3274        pattern: Option<String>,
3275        file_format: KeyValueOptions,
3276        copy_options: KeyValueOptions,
3277        validation_mode: Option<String>,
3278        partition: Option<Box<Expr>>,
3279    },
3280    /// ```sql
3281    /// OPEN cursor_name
3282    /// ```
3283    /// Opens a cursor.
3284    Open(OpenStatement),
3285    /// ```sql
3286    /// CLOSE
3287    /// ```
3288    /// Closes the portal underlying an open cursor.
3289    Close {
3290        /// Cursor name
3291        cursor: CloseCursor,
3292    },
3293    /// ```sql
3294    /// UPDATE
3295    /// ```
3296    Update(Update),
3297    /// ```sql
3298    /// DELETE
3299    /// ```
3300    Delete(Delete),
3301    /// ```sql
3302    /// CREATE VIEW
3303    /// ```
3304    CreateView(CreateView),
3305    /// ```sql
3306    /// CREATE TABLE
3307    /// ```
3308    CreateTable(CreateTable),
3309    /// ```sql
3310    /// CREATE VIRTUAL TABLE .. USING <module_name> (<module_args>)`
3311    /// ```
3312    /// Sqlite specific statement
3313    CreateVirtualTable {
3314        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3315        name: ObjectName,
3316        if_not_exists: bool,
3317        module_name: Ident,
3318        module_args: Vec<Ident>,
3319    },
3320    /// ```sql
3321    /// `CREATE INDEX`
3322    /// ```
3323    CreateIndex(CreateIndex),
3324    /// ```sql
3325    /// CREATE ROLE
3326    /// ```
3327    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createrole.html)
3328    CreateRole(CreateRole),
3329    /// ```sql
3330    /// CREATE SECRET
3331    /// ```
3332    /// See [DuckDB](https://duckdb.org/docs/sql/statements/create_secret.html)
3333    CreateSecret {
3334        or_replace: bool,
3335        temporary: Option<bool>,
3336        if_not_exists: bool,
3337        name: Option<Ident>,
3338        storage_specifier: Option<Ident>,
3339        secret_type: Ident,
3340        options: Vec<SecretOption>,
3341    },
3342    /// A `CREATE SERVER` statement.
3343    CreateServer(CreateServerStatement),
3344    /// ```sql
3345    /// CREATE POLICY
3346    /// ```
3347    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)
3348    CreatePolicy {
3349        name: Ident,
3350        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3351        table_name: ObjectName,
3352        policy_type: Option<CreatePolicyType>,
3353        command: Option<CreatePolicyCommand>,
3354        to: Option<Vec<Owner>>,
3355        using: Option<Expr>,
3356        with_check: Option<Expr>,
3357    },
3358    /// ```sql
3359    /// CREATE CONNECTOR
3360    /// ```
3361    /// See [Hive](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-CreateDataConnectorCreateConnector)
3362    CreateConnector(CreateConnector),
3363    /// ```sql
3364    /// CREATE OPERATOR
3365    /// ```
3366    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createoperator.html)
3367    CreateOperator(CreateOperator),
3368    /// ```sql
3369    /// CREATE OPERATOR FAMILY
3370    /// ```
3371    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopfamily.html)
3372    CreateOperatorFamily(CreateOperatorFamily),
3373    /// ```sql
3374    /// CREATE OPERATOR CLASS
3375    /// ```
3376    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopclass.html)
3377    CreateOperatorClass(CreateOperatorClass),
3378    /// ```sql
3379    /// ALTER TABLE
3380    /// ```
3381    AlterTable(AlterTable),
3382    /// ```sql
3383    /// ALTER SCHEMA
3384    /// ```
3385    /// See [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#alter_schema_collate_statement)
3386    AlterSchema(AlterSchema),
3387    /// ```sql
3388    /// ALTER INDEX
3389    /// ```
3390    AlterIndex {
3391        name: ObjectName,
3392        operation: AlterIndexOperation,
3393    },
3394    /// ```sql
3395    /// ALTER VIEW
3396    /// ```
3397    AlterView {
3398        /// View name
3399        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3400        name: ObjectName,
3401        columns: Vec<Ident>,
3402        query: Box<Query>,
3403        with_options: Vec<SqlOption>,
3404    },
3405    /// ```sql
3406    /// ALTER TYPE
3407    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-altertype.html)
3408    /// ```
3409    AlterType(AlterType),
3410    /// ```sql
3411    /// ALTER OPERATOR
3412    /// ```
3413    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteroperator.html)
3414    AlterOperator(AlterOperator),
3415    /// ```sql
3416    /// ALTER OPERATOR FAMILY
3417    /// ```
3418    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteropfamily.html)
3419    AlterOperatorFamily(AlterOperatorFamily),
3420    /// ```sql
3421    /// ALTER ROLE
3422    /// ```
3423    AlterRole {
3424        name: Ident,
3425        operation: AlterRoleOperation,
3426    },
3427    /// ```sql
3428    /// ALTER POLICY <NAME> ON <TABLE NAME> [<OPERATION>]
3429    /// ```
3430    /// (Postgresql-specific)
3431    AlterPolicy {
3432        name: Ident,
3433        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3434        table_name: ObjectName,
3435        operation: AlterPolicyOperation,
3436    },
3437    /// ```sql
3438    /// ALTER CONNECTOR connector_name SET DCPROPERTIES(property_name=property_value, ...);
3439    /// or
3440    /// ALTER CONNECTOR connector_name SET URL new_url;
3441    /// or
3442    /// ALTER CONNECTOR connector_name SET OWNER [USER|ROLE] user_or_role;
3443    /// ```
3444    /// (Hive-specific)
3445    AlterConnector {
3446        name: Ident,
3447        properties: Option<Vec<SqlOption>>,
3448        url: Option<String>,
3449        owner: Option<ddl::AlterConnectorOwner>,
3450    },
3451    /// ```sql
3452    /// ALTER SESSION SET sessionParam
3453    /// ALTER SESSION UNSET <param_name> [ , <param_name> , ... ]
3454    /// ```
3455    /// See <https://docs.snowflake.com/en/sql-reference/sql/alter-session>
3456    AlterSession {
3457        /// true is to set for the session parameters, false is to unset
3458        set: bool,
3459        /// The session parameters to set or unset
3460        session_params: KeyValueOptions,
3461    },
3462    /// ```sql
3463    /// ATTACH DATABASE 'path/to/file' AS alias
3464    /// ```
3465    /// (SQLite-specific)
3466    AttachDatabase {
3467        /// The name to bind to the newly attached database
3468        schema_name: Ident,
3469        /// An expression that indicates the path to the database file
3470        database_file_name: Expr,
3471        /// true if the syntax is 'ATTACH DATABASE', false if it's just 'ATTACH'
3472        database: bool,
3473    },
3474    /// (DuckDB-specific)
3475    /// ```sql
3476    /// ATTACH 'sqlite_file.db' AS sqlite_db (READ_ONLY, TYPE SQLITE);
3477    /// ```
3478    /// See <https://duckdb.org/docs/sql/statements/attach.html>
3479    AttachDuckDBDatabase {
3480        if_not_exists: bool,
3481        /// true if the syntax is 'ATTACH DATABASE', false if it's just 'ATTACH'
3482        database: bool,
3483        /// An expression that indicates the path to the database file
3484        database_path: Ident,
3485        database_alias: Option<Ident>,
3486        attach_options: Vec<AttachDuckDBDatabaseOption>,
3487    },
3488    /// (DuckDB-specific)
3489    /// ```sql
3490    /// DETACH db_alias;
3491    /// ```
3492    /// See <https://duckdb.org/docs/sql/statements/attach.html>
3493    DetachDuckDBDatabase {
3494        if_exists: bool,
3495        /// true if the syntax is 'DETACH DATABASE', false if it's just 'DETACH'
3496        database: bool,
3497        database_alias: Ident,
3498    },
3499    /// ```sql
3500    /// DROP [TABLE, VIEW, ...]
3501    /// ```
3502    Drop {
3503        /// The type of the object to drop: TABLE, VIEW, etc.
3504        object_type: ObjectType,
3505        /// An optional `IF EXISTS` clause. (Non-standard.)
3506        if_exists: bool,
3507        /// One or more objects to drop. (ANSI SQL requires exactly one.)
3508        names: Vec<ObjectName>,
3509        /// Whether `CASCADE` was specified. This will be `false` when
3510        /// `RESTRICT` or no drop behavior at all was specified.
3511        cascade: bool,
3512        /// Whether `RESTRICT` was specified. This will be `false` when
3513        /// `CASCADE` or no drop behavior at all was specified.
3514        restrict: bool,
3515        /// Hive allows you specify whether the table's stored data will be
3516        /// deleted along with the dropped table
3517        purge: bool,
3518        /// MySQL-specific "TEMPORARY" keyword
3519        temporary: bool,
3520        /// MySQL-specific drop index syntax, which requires table specification
3521        /// See <https://dev.mysql.com/doc/refman/8.4/en/drop-index.html>
3522        table: Option<ObjectName>,
3523    },
3524    /// ```sql
3525    /// DROP FUNCTION
3526    /// ```
3527    DropFunction(DropFunction),
3528    /// ```sql
3529    /// DROP DOMAIN
3530    /// ```
3531    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-dropdomain.html)
3532    ///
3533    /// DROP DOMAIN [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
3534    ///
3535    DropDomain(DropDomain),
3536    /// ```sql
3537    /// DROP PROCEDURE
3538    /// ```
3539    DropProcedure {
3540        if_exists: bool,
3541        /// One or more function to drop
3542        proc_desc: Vec<FunctionDesc>,
3543        /// `CASCADE` or `RESTRICT`
3544        drop_behavior: Option<DropBehavior>,
3545    },
3546    /// ```sql
3547    /// DROP SECRET
3548    /// ```
3549    DropSecret {
3550        if_exists: bool,
3551        temporary: Option<bool>,
3552        name: Ident,
3553        storage_specifier: Option<Ident>,
3554    },
3555    ///```sql
3556    /// DROP POLICY
3557    /// ```
3558    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-droppolicy.html)
3559    DropPolicy {
3560        if_exists: bool,
3561        name: Ident,
3562        table_name: ObjectName,
3563        drop_behavior: Option<DropBehavior>,
3564    },
3565    /// ```sql
3566    /// DROP CONNECTOR
3567    /// ```
3568    /// See [Hive](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-DropConnector)
3569    DropConnector {
3570        if_exists: bool,
3571        name: Ident,
3572    },
3573    /// ```sql
3574    /// DECLARE
3575    /// ```
3576    /// Declare Cursor Variables
3577    ///
3578    /// Note: this is a PostgreSQL-specific statement,
3579    /// but may also compatible with other SQL.
3580    Declare {
3581        stmts: Vec<Declare>,
3582    },
3583    /// ```sql
3584    /// CREATE EXTENSION [ IF NOT EXISTS ] extension_name
3585    ///     [ WITH ] [ SCHEMA schema_name ]
3586    ///              [ VERSION version ]
3587    ///              [ CASCADE ]
3588    /// ```
3589    ///
3590    /// Note: this is a PostgreSQL-specific statement,
3591    CreateExtension(CreateExtension),
3592    /// ```sql
3593    /// DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
3594    /// ```
3595    /// Note: this is a PostgreSQL-specific statement.
3596    /// <https://www.postgresql.org/docs/current/sql-dropextension.html>
3597    DropExtension(DropExtension),
3598    /// ```sql
3599    /// DROP OPERATOR [ IF EXISTS ] name ( { left_type | NONE } , right_type ) [, ...] [ CASCADE | RESTRICT ]
3600    /// ```
3601    /// Note: this is a PostgreSQL-specific statement.
3602    /// <https://www.postgresql.org/docs/current/sql-dropoperator.html>
3603    DropOperator(DropOperator),
3604    /// ```sql
3605    /// DROP OPERATOR FAMILY [ 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-dropopfamily.html>
3609    DropOperatorFamily(DropOperatorFamily),
3610    /// ```sql
3611    /// DROP OPERATOR CLASS [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]
3612    /// ```
3613    /// Note: this is a PostgreSQL-specific statement.
3614    /// <https://www.postgresql.org/docs/current/sql-dropopclass.html>
3615    DropOperatorClass(DropOperatorClass),
3616    /// ```sql
3617    /// FETCH
3618    /// ```
3619    /// Retrieve rows from a query using a cursor
3620    ///
3621    /// Note: this is a PostgreSQL-specific statement,
3622    /// but may also compatible with other SQL.
3623    Fetch {
3624        /// Cursor name
3625        name: Ident,
3626        direction: FetchDirection,
3627        position: FetchPosition,
3628        /// Optional, It's possible to fetch rows form cursor to the table
3629        into: Option<ObjectName>,
3630    },
3631    /// ```sql
3632    /// FLUSH [NO_WRITE_TO_BINLOG | LOCAL] flush_option [, flush_option] ... | tables_option
3633    /// ```
3634    ///
3635    /// Note: this is a Mysql-specific statement,
3636    /// but may also compatible with other SQL.
3637    Flush {
3638        object_type: FlushType,
3639        location: Option<FlushLocation>,
3640        channel: Option<String>,
3641        read_lock: bool,
3642        export: bool,
3643        tables: Vec<ObjectName>,
3644    },
3645    /// ```sql
3646    /// DISCARD [ ALL | PLANS | SEQUENCES | TEMPORARY | TEMP ]
3647    /// ```
3648    ///
3649    /// Note: this is a PostgreSQL-specific statement,
3650    /// but may also compatible with other SQL.
3651    Discard {
3652        object_type: DiscardObject,
3653    },
3654    /// `SHOW FUNCTIONS`
3655    ///
3656    /// Note: this is a Presto-specific statement.
3657    ShowFunctions {
3658        filter: Option<ShowStatementFilter>,
3659    },
3660    /// ```sql
3661    /// SHOW <variable>
3662    /// ```
3663    ///
3664    /// Note: this is a PostgreSQL-specific statement.
3665    ShowVariable {
3666        variable: Vec<Ident>,
3667    },
3668    /// ```sql
3669    /// SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern' | WHERE expr]
3670    /// ```
3671    ///
3672    /// Note: this is a MySQL-specific statement.
3673    ShowStatus {
3674        filter: Option<ShowStatementFilter>,
3675        global: bool,
3676        session: bool,
3677    },
3678    /// ```sql
3679    /// SHOW VARIABLES
3680    /// ```
3681    ///
3682    /// Note: this is a MySQL-specific statement.
3683    ShowVariables {
3684        filter: Option<ShowStatementFilter>,
3685        global: bool,
3686        session: bool,
3687    },
3688    /// ```sql
3689    /// SHOW CREATE TABLE
3690    /// ```
3691    ///
3692    /// Note: this is a MySQL-specific statement.
3693    ShowCreate {
3694        obj_type: ShowCreateObject,
3695        obj_name: ObjectName,
3696    },
3697    /// ```sql
3698    /// SHOW COLUMNS
3699    /// ```
3700    ShowColumns {
3701        extended: bool,
3702        full: bool,
3703        show_options: ShowStatementOptions,
3704    },
3705    /// ```sql
3706    /// SHOW DATABASES
3707    /// ```
3708    ShowDatabases {
3709        terse: bool,
3710        history: bool,
3711        show_options: ShowStatementOptions,
3712    },
3713    /// ```sql
3714    /// SHOW SCHEMAS
3715    /// ```
3716    ShowSchemas {
3717        terse: bool,
3718        history: bool,
3719        show_options: ShowStatementOptions,
3720    },
3721    // ```sql
3722    // SHOW {CHARACTER SET | CHARSET}
3723    // ```
3724    // [MySQL]:
3725    // <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>
3726    ShowCharset(ShowCharset),
3727    /// ```sql
3728    /// SHOW OBJECTS LIKE 'line%' IN mydb.public
3729    /// ```
3730    /// Snowflake-specific statement
3731    /// <https://docs.snowflake.com/en/sql-reference/sql/show-objects>
3732    ShowObjects(ShowObjects),
3733    /// ```sql
3734    /// SHOW TABLES
3735    /// ```
3736    ShowTables {
3737        terse: bool,
3738        history: bool,
3739        extended: bool,
3740        full: bool,
3741        external: bool,
3742        show_options: ShowStatementOptions,
3743    },
3744    /// ```sql
3745    /// SHOW VIEWS
3746    /// ```
3747    ShowViews {
3748        terse: bool,
3749        materialized: bool,
3750        show_options: ShowStatementOptions,
3751    },
3752    /// ```sql
3753    /// SHOW COLLATION
3754    /// ```
3755    ///
3756    /// Note: this is a MySQL-specific statement.
3757    ShowCollation {
3758        filter: Option<ShowStatementFilter>,
3759    },
3760    /// ```sql
3761    /// `USE ...`
3762    /// ```
3763    Use(Use),
3764    /// ```sql
3765    /// START  [ TRANSACTION | WORK ] | START TRANSACTION } ...
3766    /// ```
3767    /// If `begin` is false.
3768    ///
3769    /// ```sql
3770    /// `BEGIN  [ TRANSACTION | WORK ] | START TRANSACTION } ...`
3771    /// ```
3772    /// If `begin` is true
3773    StartTransaction {
3774        modes: Vec<TransactionMode>,
3775        begin: bool,
3776        transaction: Option<BeginTransactionKind>,
3777        modifier: Option<TransactionModifier>,
3778        /// List of statements belonging to the `BEGIN` block.
3779        /// Example:
3780        /// ```sql
3781        /// BEGIN
3782        ///     SELECT 1;
3783        ///     SELECT 2;
3784        /// END;
3785        /// ```
3786        statements: Vec<Statement>,
3787        /// Exception handling with exception clauses.
3788        /// Example:
3789        /// ```sql
3790        /// EXCEPTION
3791        ///     WHEN EXCEPTION_1 THEN
3792        ///         SELECT 2;
3793        ///     WHEN EXCEPTION_2 OR EXCEPTION_3 THEN
3794        ///         SELECT 3;
3795        ///     WHEN OTHER THEN
3796        ///         SELECT 4;
3797        /// ```
3798        /// <https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
3799        /// <https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
3800        exception: Option<Vec<ExceptionWhen>>,
3801        /// TRUE if the statement has an `END` keyword.
3802        has_end_keyword: bool,
3803    },
3804    /// ```sql
3805    /// COMMENT ON ...
3806    /// ```
3807    ///
3808    /// Note: this is a PostgreSQL-specific statement.
3809    Comment {
3810        object_type: CommentObject,
3811        object_name: ObjectName,
3812        comment: Option<String>,
3813        /// An optional `IF EXISTS` clause. (Non-standard.)
3814        /// See <https://docs.snowflake.com/en/sql-reference/sql/comment>
3815        if_exists: bool,
3816    },
3817    /// ```sql
3818    /// COMMIT [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]
3819    /// ```
3820    /// If `end` is false
3821    ///
3822    /// ```sql
3823    /// END [ TRY | CATCH ]
3824    /// ```
3825    /// If `end` is true
3826    Commit {
3827        chain: bool,
3828        end: bool,
3829        modifier: Option<TransactionModifier>,
3830    },
3831    /// ```sql
3832    /// ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ] [ TO [ SAVEPOINT ] savepoint_name ]
3833    /// ```
3834    Rollback {
3835        chain: bool,
3836        savepoint: Option<Ident>,
3837    },
3838    /// ```sql
3839    /// CREATE SCHEMA
3840    /// ```
3841    CreateSchema {
3842        /// `<schema name> | AUTHORIZATION <schema authorization identifier>  | <schema name>  AUTHORIZATION <schema authorization identifier>`
3843        schema_name: SchemaName,
3844        if_not_exists: bool,
3845        /// Schema properties.
3846        ///
3847        /// ```sql
3848        /// CREATE SCHEMA myschema WITH (key1='value1');
3849        /// ```
3850        ///
3851        /// [Trino](https://trino.io/docs/current/sql/create-schema.html)
3852        with: Option<Vec<SqlOption>>,
3853        /// Schema options.
3854        ///
3855        /// ```sql
3856        /// CREATE SCHEMA myschema OPTIONS(key1='value1');
3857        /// ```
3858        ///
3859        /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_schema_statement)
3860        options: Option<Vec<SqlOption>>,
3861        /// Default collation specification for the schema.
3862        ///
3863        /// ```sql
3864        /// CREATE SCHEMA myschema DEFAULT COLLATE 'und:ci';
3865        /// ```
3866        ///
3867        /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_schema_statement)
3868        default_collate_spec: Option<Expr>,
3869        /// Clones a schema
3870        ///
3871        /// ```sql
3872        /// CREATE SCHEMA myschema CLONE otherschema
3873        /// ```
3874        ///
3875        /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-clone#databases-schemas)
3876        clone: Option<ObjectName>,
3877    },
3878    /// ```sql
3879    /// CREATE DATABASE
3880    /// ```
3881    /// See:
3882    /// <https://docs.snowflake.com/en/sql-reference/sql/create-database>
3883    CreateDatabase {
3884        db_name: ObjectName,
3885        if_not_exists: bool,
3886        location: Option<String>,
3887        managed_location: Option<String>,
3888        or_replace: bool,
3889        transient: bool,
3890        clone: Option<ObjectName>,
3891        data_retention_time_in_days: Option<u64>,
3892        max_data_extension_time_in_days: Option<u64>,
3893        external_volume: Option<String>,
3894        catalog: Option<String>,
3895        replace_invalid_characters: Option<bool>,
3896        default_ddl_collation: Option<String>,
3897        storage_serialization_policy: Option<StorageSerializationPolicy>,
3898        comment: Option<String>,
3899        catalog_sync: Option<String>,
3900        catalog_sync_namespace_mode: Option<CatalogSyncNamespaceMode>,
3901        catalog_sync_namespace_flatten_delimiter: Option<String>,
3902        with_tags: Option<Vec<Tag>>,
3903        with_contacts: Option<Vec<ContactEntry>>,
3904    },
3905    /// ```sql
3906    /// CREATE FUNCTION
3907    /// ```
3908    ///
3909    /// Supported variants:
3910    /// 1. [Hive](https://cwiki.apache.org/confluence/display/hive/languagemanual+ddl#LanguageManualDDL-Create/Drop/ReloadFunction)
3911    /// 2. [PostgreSQL](https://www.postgresql.org/docs/15/sql-createfunction.html)
3912    /// 3. [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_function_statement)
3913    /// 4. [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql)
3914    CreateFunction(CreateFunction),
3915    /// CREATE TRIGGER statement. See struct [CreateTrigger] for details.
3916    CreateTrigger(CreateTrigger),
3917    /// DROP TRIGGER statement. See struct [DropTrigger] for details.
3918    DropTrigger(DropTrigger),
3919    /// ```sql
3920    /// CREATE PROCEDURE
3921    /// ```
3922    CreateProcedure {
3923        or_alter: bool,
3924        name: ObjectName,
3925        params: Option<Vec<ProcedureParam>>,
3926        language: Option<Ident>,
3927        body: ConditionalStatements,
3928    },
3929    /// ```sql
3930    /// CREATE MACRO
3931    /// ```
3932    ///
3933    /// Supported variants:
3934    /// 1. [DuckDB](https://duckdb.org/docs/sql/statements/create_macro)
3935    CreateMacro {
3936        or_replace: bool,
3937        temporary: bool,
3938        name: ObjectName,
3939        args: Option<Vec<MacroArg>>,
3940        definition: MacroDefinition,
3941    },
3942    /// ```sql
3943    /// CREATE STAGE
3944    /// ```
3945    /// See <https://docs.snowflake.com/en/sql-reference/sql/create-stage>
3946    CreateStage {
3947        or_replace: bool,
3948        temporary: bool,
3949        if_not_exists: bool,
3950        name: ObjectName,
3951        stage_params: StageParamsObject,
3952        directory_table_params: KeyValueOptions,
3953        file_format: KeyValueOptions,
3954        copy_options: KeyValueOptions,
3955        comment: Option<String>,
3956    },
3957    /// ```sql
3958    /// ASSERT <condition> [AS <message>]
3959    /// ```
3960    Assert {
3961        condition: Expr,
3962        message: Option<Expr>,
3963    },
3964    /// ```sql
3965    /// GRANT privileges ON objects TO grantees
3966    /// ```
3967    Grant {
3968        privileges: Privileges,
3969        objects: Option<GrantObjects>,
3970        grantees: Vec<Grantee>,
3971        with_grant_option: bool,
3972        as_grantor: Option<Ident>,
3973        granted_by: Option<Ident>,
3974        current_grants: Option<CurrentGrantsKind>,
3975    },
3976    /// ```sql
3977    /// DENY privileges ON object TO grantees
3978    /// ```
3979    Deny(DenyStatement),
3980    /// ```sql
3981    /// REVOKE privileges ON objects FROM grantees
3982    /// ```
3983    Revoke {
3984        privileges: Privileges,
3985        objects: Option<GrantObjects>,
3986        grantees: Vec<Grantee>,
3987        granted_by: Option<Ident>,
3988        cascade: Option<CascadeOption>,
3989    },
3990    /// ```sql
3991    /// DEALLOCATE [ PREPARE ] { name | ALL }
3992    /// ```
3993    ///
3994    /// Note: this is a PostgreSQL-specific statement.
3995    Deallocate {
3996        name: Ident,
3997        prepare: bool,
3998    },
3999    /// ```sql
4000    /// An `EXECUTE` statement
4001    /// ```
4002    ///
4003    /// Postgres: <https://www.postgresql.org/docs/current/sql-execute.html>
4004    /// MSSQL: <https://learn.microsoft.com/en-us/sql/relational-databases/stored-procedures/execute-a-stored-procedure>
4005    /// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#execute_immediate>
4006    /// Snowflake: <https://docs.snowflake.com/en/sql-reference/sql/execute-immediate>
4007    Execute {
4008        name: Option<ObjectName>,
4009        parameters: Vec<Expr>,
4010        has_parentheses: bool,
4011        /// Is this an `EXECUTE IMMEDIATE`
4012        immediate: bool,
4013        into: Vec<Ident>,
4014        using: Vec<ExprWithAlias>,
4015        /// Whether the last parameter is the return value of the procedure
4016        /// MSSQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver17#output>
4017        output: bool,
4018        /// Whether to invoke the procedure with the default parameter values
4019        /// MSSQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver17#default>
4020        default: bool,
4021    },
4022    /// ```sql
4023    /// PREPARE name [ ( data_type [, ...] ) ] AS statement
4024    /// ```
4025    ///
4026    /// Note: this is a PostgreSQL-specific statement.
4027    Prepare {
4028        name: Ident,
4029        data_types: Vec<DataType>,
4030        statement: Box<Statement>,
4031    },
4032    /// ```sql
4033    /// KILL [CONNECTION | QUERY | MUTATION]
4034    /// ```
4035    ///
4036    /// See <https://clickhouse.com/docs/en/sql-reference/statements/kill/>
4037    /// See <https://dev.mysql.com/doc/refman/8.0/en/kill.html>
4038    Kill {
4039        modifier: Option<KillType>,
4040        // processlist_id
4041        id: u64,
4042    },
4043    /// ```sql
4044    /// [EXPLAIN | DESC | DESCRIBE] TABLE
4045    /// ```
4046    /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/explain.html>
4047    ExplainTable {
4048        /// `EXPLAIN | DESC | DESCRIBE`
4049        describe_alias: DescribeAlias,
4050        /// Hive style `FORMATTED | EXTENDED`
4051        hive_format: Option<HiveDescribeFormat>,
4052        /// Snowflake and ClickHouse support `DESC|DESCRIBE TABLE <table_name>` syntax
4053        ///
4054        /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/desc-table.html)
4055        /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/describe-table)
4056        has_table_keyword: bool,
4057        /// Table name
4058        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
4059        table_name: ObjectName,
4060    },
4061    /// ```sql
4062    /// [EXPLAIN | DESC | DESCRIBE]  <statement>
4063    /// ```
4064    Explain {
4065        /// `EXPLAIN | DESC | DESCRIBE`
4066        describe_alias: DescribeAlias,
4067        /// Carry out the command and show actual run times and other statistics.
4068        analyze: bool,
4069        // Display additional information regarding the plan.
4070        verbose: bool,
4071        /// `EXPLAIN QUERY PLAN`
4072        /// Display the query plan without running the query.
4073        ///
4074        /// [SQLite](https://sqlite.org/lang_explain.html)
4075        query_plan: bool,
4076        /// `EXPLAIN ESTIMATE`
4077        /// [Clickhouse](https://clickhouse.com/docs/en/sql-reference/statements/explain#explain-estimate)
4078        estimate: bool,
4079        /// A SQL query that specifies what to explain
4080        statement: Box<Statement>,
4081        /// Optional output format of explain
4082        format: Option<AnalyzeFormatKind>,
4083        /// Postgres style utility options, `(analyze, verbose true)`
4084        options: Option<Vec<UtilityOption>>,
4085    },
4086    /// ```sql
4087    /// SAVEPOINT
4088    /// ```
4089    /// Define a new savepoint within the current transaction
4090    Savepoint {
4091        name: Ident,
4092    },
4093    /// ```sql
4094    /// RELEASE [ SAVEPOINT ] savepoint_name
4095    /// ```
4096    ReleaseSavepoint {
4097        name: Ident,
4098    },
4099    /// A `MERGE` statement.
4100    ///
4101    /// ```sql
4102    /// MERGE INTO <target_table> USING <source> ON <join_expr> { matchedClause | notMatchedClause } [ ... ]
4103    /// ```
4104    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/merge)
4105    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
4106    /// [MSSQL](https://learn.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver16)
4107    Merge(Merge),
4108    /// ```sql
4109    /// CACHE [ FLAG ] TABLE <table_name> [ OPTIONS('K1' = 'V1', 'K2' = V2) ] [ AS ] [ <query> ]
4110    /// ```
4111    ///
4112    /// See [Spark SQL docs] for more details.
4113    ///
4114    /// [Spark SQL docs]: https://docs.databricks.com/spark/latest/spark-sql/language-manual/sql-ref-syntax-aux-cache-cache-table.html
4115    Cache {
4116        /// Table flag
4117        table_flag: Option<ObjectName>,
4118        /// Table name
4119        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
4120        table_name: ObjectName,
4121        has_as: bool,
4122        /// Table confs
4123        options: Vec<SqlOption>,
4124        /// Cache table as a Query
4125        query: Option<Box<Query>>,
4126    },
4127    /// ```sql
4128    /// UNCACHE TABLE [ IF EXISTS ]  <table_name>
4129    /// ```
4130    UNCache {
4131        /// Table name
4132        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
4133        table_name: ObjectName,
4134        if_exists: bool,
4135    },
4136    /// ```sql
4137    /// CREATE [ { TEMPORARY | TEMP } ] SEQUENCE [ IF NOT EXISTS ] <sequence_name>
4138    /// ```
4139    /// Define a new sequence:
4140    CreateSequence {
4141        temporary: bool,
4142        if_not_exists: bool,
4143        name: ObjectName,
4144        data_type: Option<DataType>,
4145        sequence_options: Vec<SequenceOptions>,
4146        owned_by: Option<ObjectName>,
4147    },
4148    /// A `CREATE DOMAIN` statement.
4149    CreateDomain(CreateDomain),
4150    /// ```sql
4151    /// CREATE TYPE <name>
4152    /// ```
4153    CreateType {
4154        name: ObjectName,
4155        representation: Option<UserDefinedTypeRepresentation>,
4156    },
4157    /// ```sql
4158    /// PRAGMA <schema-name>.<pragma-name> = <pragma-value>
4159    /// ```
4160    Pragma {
4161        name: ObjectName,
4162        value: Option<Value>,
4163        is_eq: bool,
4164    },
4165    /// ```sql
4166    /// LOCK TABLES <table_name> [READ [LOCAL] | [LOW_PRIORITY] WRITE]
4167    /// ```
4168    /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html>
4169    LockTables {
4170        tables: Vec<LockTable>,
4171    },
4172    /// ```sql
4173    /// UNLOCK TABLES
4174    /// ```
4175    /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html>
4176    UnlockTables,
4177    /// Unloads the result of a query to file
4178    ///
4179    /// [Athena](https://docs.aws.amazon.com/athena/latest/ug/unload.html):
4180    /// ```sql
4181    /// UNLOAD(statement) TO <destination> [ WITH options ]
4182    /// ```
4183    ///
4184    /// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD.html):
4185    /// ```sql
4186    /// UNLOAD('statement') TO <destination> [ OPTIONS ]
4187    /// ```
4188    Unload {
4189        query: Option<Box<Query>>,
4190        query_text: Option<String>,
4191        to: Ident,
4192        auth: Option<IamRoleKind>,
4193        with: Vec<SqlOption>,
4194        options: Vec<CopyLegacyOption>,
4195    },
4196    /// ```sql
4197    /// OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition | PARTITION ID 'partition_id'] [FINAL] [DEDUPLICATE [BY expression]]
4198    /// ```
4199    ///
4200    /// See ClickHouse <https://clickhouse.com/docs/en/sql-reference/statements/optimize>
4201    OptimizeTable {
4202        name: ObjectName,
4203        on_cluster: Option<Ident>,
4204        partition: Option<Partition>,
4205        include_final: bool,
4206        deduplicate: Option<Deduplicate>,
4207    },
4208    /// ```sql
4209    /// LISTEN
4210    /// ```
4211    /// listen for a notification channel
4212    ///
4213    /// See Postgres <https://www.postgresql.org/docs/current/sql-listen.html>
4214    LISTEN {
4215        channel: Ident,
4216    },
4217    /// ```sql
4218    /// UNLISTEN
4219    /// ```
4220    /// stop listening for a notification
4221    ///
4222    /// See Postgres <https://www.postgresql.org/docs/current/sql-unlisten.html>
4223    UNLISTEN {
4224        channel: Ident,
4225    },
4226    /// ```sql
4227    /// NOTIFY channel [ , payload ]
4228    /// ```
4229    /// send a notification event together with an optional "payload" string to channel
4230    ///
4231    /// See Postgres <https://www.postgresql.org/docs/current/sql-notify.html>
4232    NOTIFY {
4233        channel: Ident,
4234        payload: Option<String>,
4235    },
4236    /// ```sql
4237    /// LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename
4238    /// [PARTITION (partcol1=val1, partcol2=val2 ...)]
4239    /// [INPUTFORMAT 'inputformat' SERDE 'serde']
4240    /// ```
4241    /// Loading files into tables
4242    ///
4243    /// See Hive <https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362036#LanguageManualDML-Loadingfilesintotables>
4244    LoadData {
4245        local: bool,
4246        inpath: String,
4247        overwrite: bool,
4248        table_name: ObjectName,
4249        partitioned: Option<Vec<Expr>>,
4250        table_format: Option<HiveLoadDataFormat>,
4251    },
4252    /// ```sql
4253    /// Rename TABLE tbl_name TO new_tbl_name[, tbl_name2 TO new_tbl_name2] ...
4254    /// ```
4255    /// Renames one or more tables
4256    ///
4257    /// See Mysql <https://dev.mysql.com/doc/refman/9.1/en/rename-table.html>
4258    RenameTable(Vec<RenameTable>),
4259    /// Snowflake `LIST`
4260    /// See: <https://docs.snowflake.com/en/sql-reference/sql/list>
4261    List(FileStagingCommand),
4262    /// Snowflake `REMOVE`
4263    /// See: <https://docs.snowflake.com/en/sql-reference/sql/remove>
4264    Remove(FileStagingCommand),
4265    /// RaiseError (MSSQL)
4266    /// RAISERROR ( { msg_id | msg_str | @local_variable }
4267    /// { , severity , state }
4268    /// [ , argument [ , ...n ] ] )
4269    /// [ WITH option [ , ...n ] ]
4270    /// See <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/raiserror-transact-sql?view=sql-server-ver16>
4271    RaisError {
4272        message: Box<Expr>,
4273        severity: Box<Expr>,
4274        state: Box<Expr>,
4275        arguments: Vec<Expr>,
4276        options: Vec<RaisErrorOption>,
4277    },
4278    /// ```sql
4279    /// PRINT msg_str | @local_variable | string_expr
4280    /// ```
4281    ///
4282    /// See: <https://learn.microsoft.com/en-us/sql/t-sql/statements/print-transact-sql>
4283    Print(PrintStatement),
4284    /// ```sql
4285    /// RETURN [ expression ]
4286    /// ```
4287    ///
4288    /// See [ReturnStatement]
4289    Return(ReturnStatement),
4290    /// Export data statement
4291    ///
4292    /// Example:
4293    /// ```sql
4294    /// EXPORT DATA OPTIONS(uri='gs://bucket/folder/*', format='PARQUET', overwrite=true) AS
4295    /// SELECT field1, field2 FROM mydataset.table1 ORDER BY field1 LIMIT 10
4296    /// ```
4297    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/export-statements)
4298    ExportData(ExportData),
4299    /// ```sql
4300    /// CREATE [OR REPLACE] USER <user> [IF NOT EXISTS]
4301    /// ```
4302    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-user)
4303    CreateUser(CreateUser),
4304    /// ```sql
4305    /// ALTER USER \[ IF EXISTS \] \[ <name> \]
4306    /// ```
4307    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/alter-user)
4308    AlterUser(AlterUser),
4309    /// Re-sorts rows and reclaims space in either a specified table or all tables in the current database
4310    ///
4311    /// ```sql
4312    /// VACUUM tbl
4313    /// ```
4314    /// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)
4315    Vacuum(VacuumStatement),
4316    /// Restore the value of a run-time parameter to the default value.
4317    ///
4318    /// ```sql
4319    /// RESET configuration_parameter;
4320    /// RESET ALL;
4321    /// ```
4322    /// [PostgreSQL](https://www.postgresql.org/docs/current/sql-reset.html)
4323    Reset(ResetStatement),
4324}
4325
4326impl From<Analyze> for Statement {
4327    fn from(analyze: Analyze) -> Self {
4328        Statement::Analyze(analyze)
4329    }
4330}
4331
4332impl From<ddl::Truncate> for Statement {
4333    fn from(truncate: ddl::Truncate) -> Self {
4334        Statement::Truncate(truncate)
4335    }
4336}
4337
4338impl From<ddl::Msck> for Statement {
4339    fn from(msck: ddl::Msck) -> Self {
4340        Statement::Msck(msck)
4341    }
4342}
4343
4344/// ```sql
4345/// {COPY | REVOKE} CURRENT GRANTS
4346/// ```
4347///
4348/// - [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/grant-ownership#optional-parameters)
4349#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4350#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4351#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4352pub enum CurrentGrantsKind {
4353    CopyCurrentGrants,
4354    RevokeCurrentGrants,
4355}
4356
4357impl fmt::Display for CurrentGrantsKind {
4358    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4359        match self {
4360            CurrentGrantsKind::CopyCurrentGrants => write!(f, "COPY CURRENT GRANTS"),
4361            CurrentGrantsKind::RevokeCurrentGrants => write!(f, "REVOKE CURRENT GRANTS"),
4362        }
4363    }
4364}
4365
4366#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4367#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4368#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4369pub enum RaisErrorOption {
4370    Log,
4371    NoWait,
4372    SetError,
4373}
4374
4375impl fmt::Display for RaisErrorOption {
4376    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4377        match self {
4378            RaisErrorOption::Log => write!(f, "LOG"),
4379            RaisErrorOption::NoWait => write!(f, "NOWAIT"),
4380            RaisErrorOption::SetError => write!(f, "SETERROR"),
4381        }
4382    }
4383}
4384
4385impl fmt::Display for Statement {
4386    /// Formats a SQL statement with support for pretty printing.
4387    ///
4388    /// When using the alternate flag (`{:#}`), the statement will be formatted with proper
4389    /// indentation and line breaks. For example:
4390    ///
4391    /// ```
4392    /// # use sqlparser::dialect::GenericDialect;
4393    /// # use sqlparser::parser::Parser;
4394    /// let sql = "SELECT a, b FROM table_1";
4395    /// let ast = Parser::parse_sql(&GenericDialect, sql).unwrap();
4396    ///
4397    /// // Regular formatting
4398    /// assert_eq!(format!("{}", ast[0]), "SELECT a, b FROM table_1");
4399    ///
4400    /// // Pretty printing
4401    /// assert_eq!(format!("{:#}", ast[0]),
4402    /// r#"SELECT
4403    ///   a,
4404    ///   b
4405    /// FROM
4406    ///   table_1"#);
4407    /// ```
4408    // Clippy thinks this function is too complicated, but it is painful to
4409    // split up without extracting structs for each `Statement` variant.
4410    #[allow(clippy::cognitive_complexity)]
4411    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4412        match self {
4413            Statement::Flush {
4414                object_type,
4415                location,
4416                channel,
4417                read_lock,
4418                export,
4419                tables,
4420            } => {
4421                write!(f, "FLUSH")?;
4422                if let Some(location) = location {
4423                    f.write_str(" ")?;
4424                    location.fmt(f)?;
4425                }
4426                write!(f, " {object_type}")?;
4427
4428                if let Some(channel) = channel {
4429                    write!(f, " FOR CHANNEL {channel}")?;
4430                }
4431
4432                write!(
4433                    f,
4434                    "{tables}{read}{export}",
4435                    tables = if !tables.is_empty() {
4436                        " ".to_string() + &display_comma_separated(tables).to_string()
4437                    } else {
4438                        "".to_string()
4439                    },
4440                    export = if *export { " FOR EXPORT" } else { "" },
4441                    read = if *read_lock { " WITH READ LOCK" } else { "" }
4442                )
4443            }
4444            Statement::Kill { modifier, id } => {
4445                write!(f, "KILL ")?;
4446
4447                if let Some(m) = modifier {
4448                    write!(f, "{m} ")?;
4449                }
4450
4451                write!(f, "{id}")
4452            }
4453            Statement::ExplainTable {
4454                describe_alias,
4455                hive_format,
4456                has_table_keyword,
4457                table_name,
4458            } => {
4459                write!(f, "{describe_alias} ")?;
4460
4461                if let Some(format) = hive_format {
4462                    write!(f, "{format} ")?;
4463                }
4464                if *has_table_keyword {
4465                    write!(f, "TABLE ")?;
4466                }
4467
4468                write!(f, "{table_name}")
4469            }
4470            Statement::Explain {
4471                describe_alias,
4472                verbose,
4473                analyze,
4474                query_plan,
4475                estimate,
4476                statement,
4477                format,
4478                options,
4479            } => {
4480                write!(f, "{describe_alias} ")?;
4481
4482                if *query_plan {
4483                    write!(f, "QUERY PLAN ")?;
4484                }
4485                if *analyze {
4486                    write!(f, "ANALYZE ")?;
4487                }
4488                if *estimate {
4489                    write!(f, "ESTIMATE ")?;
4490                }
4491
4492                if *verbose {
4493                    write!(f, "VERBOSE ")?;
4494                }
4495
4496                if let Some(format) = format {
4497                    write!(f, "{format} ")?;
4498                }
4499
4500                if let Some(options) = options {
4501                    write!(f, "({}) ", display_comma_separated(options))?;
4502                }
4503
4504                write!(f, "{statement}")
4505            }
4506            Statement::Query(s) => s.fmt(f),
4507            Statement::Declare { stmts } => {
4508                write!(f, "DECLARE ")?;
4509                write!(f, "{}", display_separated(stmts, "; "))
4510            }
4511            Statement::Fetch {
4512                name,
4513                direction,
4514                position,
4515                into,
4516            } => {
4517                write!(f, "FETCH {direction} {position} {name}")?;
4518
4519                if let Some(into) = into {
4520                    write!(f, " INTO {into}")?;
4521                }
4522
4523                Ok(())
4524            }
4525            Statement::Directory {
4526                overwrite,
4527                local,
4528                path,
4529                file_format,
4530                source,
4531            } => {
4532                write!(
4533                    f,
4534                    "INSERT{overwrite}{local} DIRECTORY '{path}'",
4535                    overwrite = if *overwrite { " OVERWRITE" } else { "" },
4536                    local = if *local { " LOCAL" } else { "" },
4537                    path = path
4538                )?;
4539                if let Some(ref ff) = file_format {
4540                    write!(f, " STORED AS {ff}")?
4541                }
4542                write!(f, " {source}")
4543            }
4544            Statement::Msck(msck) => msck.fmt(f),
4545            Statement::Truncate(truncate) => truncate.fmt(f),
4546            Statement::Case(stmt) => {
4547                write!(f, "{stmt}")
4548            }
4549            Statement::If(stmt) => {
4550                write!(f, "{stmt}")
4551            }
4552            Statement::While(stmt) => {
4553                write!(f, "{stmt}")
4554            }
4555            Statement::Raise(stmt) => {
4556                write!(f, "{stmt}")
4557            }
4558            Statement::AttachDatabase {
4559                schema_name,
4560                database_file_name,
4561                database,
4562            } => {
4563                let keyword = if *database { "DATABASE " } else { "" };
4564                write!(f, "ATTACH {keyword}{database_file_name} AS {schema_name}")
4565            }
4566            Statement::AttachDuckDBDatabase {
4567                if_not_exists,
4568                database,
4569                database_path,
4570                database_alias,
4571                attach_options,
4572            } => {
4573                write!(
4574                    f,
4575                    "ATTACH{database}{if_not_exists} {database_path}",
4576                    database = if *database { " DATABASE" } else { "" },
4577                    if_not_exists = if *if_not_exists { " IF NOT EXISTS" } else { "" },
4578                )?;
4579                if let Some(alias) = database_alias {
4580                    write!(f, " AS {alias}")?;
4581                }
4582                if !attach_options.is_empty() {
4583                    write!(f, " ({})", display_comma_separated(attach_options))?;
4584                }
4585                Ok(())
4586            }
4587            Statement::DetachDuckDBDatabase {
4588                if_exists,
4589                database,
4590                database_alias,
4591            } => {
4592                write!(
4593                    f,
4594                    "DETACH{database}{if_exists} {database_alias}",
4595                    database = if *database { " DATABASE" } else { "" },
4596                    if_exists = if *if_exists { " IF EXISTS" } else { "" },
4597                )?;
4598                Ok(())
4599            }
4600            Statement::Analyze(analyze) => analyze.fmt(f),
4601            Statement::Insert(insert) => insert.fmt(f),
4602            Statement::Install {
4603                extension_name: name,
4604            } => write!(f, "INSTALL {name}"),
4605
4606            Statement::Load {
4607                extension_name: name,
4608            } => write!(f, "LOAD {name}"),
4609
4610            Statement::Call(function) => write!(f, "CALL {function}"),
4611
4612            Statement::Copy {
4613                source,
4614                to,
4615                target,
4616                options,
4617                legacy_options,
4618                values,
4619            } => {
4620                write!(f, "COPY")?;
4621                match source {
4622                    CopySource::Query(query) => write!(f, " ({query})")?,
4623                    CopySource::Table {
4624                        table_name,
4625                        columns,
4626                    } => {
4627                        write!(f, " {table_name}")?;
4628                        if !columns.is_empty() {
4629                            write!(f, " ({})", display_comma_separated(columns))?;
4630                        }
4631                    }
4632                }
4633                write!(f, " {} {}", if *to { "TO" } else { "FROM" }, target)?;
4634                if !options.is_empty() {
4635                    write!(f, " ({})", display_comma_separated(options))?;
4636                }
4637                if !legacy_options.is_empty() {
4638                    write!(f, " {}", display_separated(legacy_options, " "))?;
4639                }
4640                if !values.is_empty() {
4641                    writeln!(f, ";")?;
4642                    let mut delim = "";
4643                    for v in values {
4644                        write!(f, "{delim}")?;
4645                        delim = "\t";
4646                        if let Some(v) = v {
4647                            write!(f, "{v}")?;
4648                        } else {
4649                            write!(f, "\\N")?;
4650                        }
4651                    }
4652                    write!(f, "\n\\.")?;
4653                }
4654                Ok(())
4655            }
4656            Statement::Update(update) => update.fmt(f),
4657            Statement::Delete(delete) => delete.fmt(f),
4658            Statement::Open(open) => open.fmt(f),
4659            Statement::Close { cursor } => {
4660                write!(f, "CLOSE {cursor}")?;
4661
4662                Ok(())
4663            }
4664            Statement::CreateDatabase {
4665                db_name,
4666                if_not_exists,
4667                location,
4668                managed_location,
4669                or_replace,
4670                transient,
4671                clone,
4672                data_retention_time_in_days,
4673                max_data_extension_time_in_days,
4674                external_volume,
4675                catalog,
4676                replace_invalid_characters,
4677                default_ddl_collation,
4678                storage_serialization_policy,
4679                comment,
4680                catalog_sync,
4681                catalog_sync_namespace_mode,
4682                catalog_sync_namespace_flatten_delimiter,
4683                with_tags,
4684                with_contacts,
4685            } => {
4686                write!(
4687                    f,
4688                    "CREATE {or_replace}{transient}DATABASE {if_not_exists}{name}",
4689                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
4690                    transient = if *transient { "TRANSIENT " } else { "" },
4691                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
4692                    name = db_name,
4693                )?;
4694
4695                if let Some(l) = location {
4696                    write!(f, " LOCATION '{l}'")?;
4697                }
4698                if let Some(ml) = managed_location {
4699                    write!(f, " MANAGEDLOCATION '{ml}'")?;
4700                }
4701                if let Some(clone) = clone {
4702                    write!(f, " CLONE {clone}")?;
4703                }
4704
4705                if let Some(value) = data_retention_time_in_days {
4706                    write!(f, " DATA_RETENTION_TIME_IN_DAYS = {value}")?;
4707                }
4708
4709                if let Some(value) = max_data_extension_time_in_days {
4710                    write!(f, " MAX_DATA_EXTENSION_TIME_IN_DAYS = {value}")?;
4711                }
4712
4713                if let Some(vol) = external_volume {
4714                    write!(f, " EXTERNAL_VOLUME = '{vol}'")?;
4715                }
4716
4717                if let Some(cat) = catalog {
4718                    write!(f, " CATALOG = '{cat}'")?;
4719                }
4720
4721                if let Some(true) = replace_invalid_characters {
4722                    write!(f, " REPLACE_INVALID_CHARACTERS = TRUE")?;
4723                } else if let Some(false) = replace_invalid_characters {
4724                    write!(f, " REPLACE_INVALID_CHARACTERS = FALSE")?;
4725                }
4726
4727                if let Some(collation) = default_ddl_collation {
4728                    write!(f, " DEFAULT_DDL_COLLATION = '{collation}'")?;
4729                }
4730
4731                if let Some(policy) = storage_serialization_policy {
4732                    write!(f, " STORAGE_SERIALIZATION_POLICY = {policy}")?;
4733                }
4734
4735                if let Some(comment) = comment {
4736                    write!(f, " COMMENT = '{comment}'")?;
4737                }
4738
4739                if let Some(sync) = catalog_sync {
4740                    write!(f, " CATALOG_SYNC = '{sync}'")?;
4741                }
4742
4743                if let Some(mode) = catalog_sync_namespace_mode {
4744                    write!(f, " CATALOG_SYNC_NAMESPACE_MODE = {mode}")?;
4745                }
4746
4747                if let Some(delim) = catalog_sync_namespace_flatten_delimiter {
4748                    write!(f, " CATALOG_SYNC_NAMESPACE_FLATTEN_DELIMITER = '{delim}'")?;
4749                }
4750
4751                if let Some(tags) = with_tags {
4752                    write!(f, " WITH TAG ({})", display_comma_separated(tags))?;
4753                }
4754
4755                if let Some(contacts) = with_contacts {
4756                    write!(f, " WITH CONTACT ({})", display_comma_separated(contacts))?;
4757                }
4758                Ok(())
4759            }
4760            Statement::CreateFunction(create_function) => create_function.fmt(f),
4761            Statement::CreateDomain(create_domain) => create_domain.fmt(f),
4762            Statement::CreateTrigger(create_trigger) => create_trigger.fmt(f),
4763            Statement::DropTrigger(drop_trigger) => drop_trigger.fmt(f),
4764            Statement::CreateProcedure {
4765                name,
4766                or_alter,
4767                params,
4768                language,
4769                body,
4770            } => {
4771                write!(
4772                    f,
4773                    "CREATE {or_alter}PROCEDURE {name}",
4774                    or_alter = if *or_alter { "OR ALTER " } else { "" },
4775                    name = name
4776                )?;
4777
4778                if let Some(p) = params {
4779                    if !p.is_empty() {
4780                        write!(f, " ({})", display_comma_separated(p))?;
4781                    }
4782                }
4783
4784                if let Some(language) = language {
4785                    write!(f, " LANGUAGE {language}")?;
4786                }
4787
4788                write!(f, " AS {body}")
4789            }
4790            Statement::CreateMacro {
4791                or_replace,
4792                temporary,
4793                name,
4794                args,
4795                definition,
4796            } => {
4797                write!(
4798                    f,
4799                    "CREATE {or_replace}{temp}MACRO {name}",
4800                    temp = if *temporary { "TEMPORARY " } else { "" },
4801                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
4802                )?;
4803                if let Some(args) = args {
4804                    write!(f, "({})", display_comma_separated(args))?;
4805                }
4806                match definition {
4807                    MacroDefinition::Expr(expr) => write!(f, " AS {expr}")?,
4808                    MacroDefinition::Table(query) => write!(f, " AS TABLE {query}")?,
4809                }
4810                Ok(())
4811            }
4812            Statement::CreateView(create_view) => create_view.fmt(f),
4813            Statement::CreateTable(create_table) => create_table.fmt(f),
4814            Statement::LoadData {
4815                local,
4816                inpath,
4817                overwrite,
4818                table_name,
4819                partitioned,
4820                table_format,
4821            } => {
4822                write!(
4823                    f,
4824                    "LOAD DATA {local}INPATH '{inpath}' {overwrite}INTO TABLE {table_name}",
4825                    local = if *local { "LOCAL " } else { "" },
4826                    inpath = inpath,
4827                    overwrite = if *overwrite { "OVERWRITE " } else { "" },
4828                    table_name = table_name,
4829                )?;
4830                if let Some(ref parts) = &partitioned {
4831                    if !parts.is_empty() {
4832                        write!(f, " PARTITION ({})", display_comma_separated(parts))?;
4833                    }
4834                }
4835                if let Some(HiveLoadDataFormat {
4836                    serde,
4837                    input_format,
4838                }) = &table_format
4839                {
4840                    write!(f, " INPUTFORMAT {input_format} SERDE {serde}")?;
4841                }
4842                Ok(())
4843            }
4844            Statement::CreateVirtualTable {
4845                name,
4846                if_not_exists,
4847                module_name,
4848                module_args,
4849            } => {
4850                write!(
4851                    f,
4852                    "CREATE VIRTUAL TABLE {if_not_exists}{name} USING {module_name}",
4853                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
4854                    name = name,
4855                    module_name = module_name
4856                )?;
4857                if !module_args.is_empty() {
4858                    write!(f, " ({})", display_comma_separated(module_args))?;
4859                }
4860                Ok(())
4861            }
4862            Statement::CreateIndex(create_index) => create_index.fmt(f),
4863            Statement::CreateExtension(create_extension) => write!(f, "{create_extension}"),
4864            Statement::DropExtension(drop_extension) => write!(f, "{drop_extension}"),
4865            Statement::DropOperator(drop_operator) => write!(f, "{drop_operator}"),
4866            Statement::DropOperatorFamily(drop_operator_family) => {
4867                write!(f, "{drop_operator_family}")
4868            }
4869            Statement::DropOperatorClass(drop_operator_class) => {
4870                write!(f, "{drop_operator_class}")
4871            }
4872            Statement::CreateRole(create_role) => write!(f, "{create_role}"),
4873            Statement::CreateSecret {
4874                or_replace,
4875                temporary,
4876                if_not_exists,
4877                name,
4878                storage_specifier,
4879                secret_type,
4880                options,
4881            } => {
4882                write!(
4883                    f,
4884                    "CREATE {or_replace}",
4885                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
4886                )?;
4887                if let Some(t) = temporary {
4888                    write!(f, "{}", if *t { "TEMPORARY " } else { "PERSISTENT " })?;
4889                }
4890                write!(
4891                    f,
4892                    "SECRET {if_not_exists}",
4893                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
4894                )?;
4895                if let Some(n) = name {
4896                    write!(f, "{n} ")?;
4897                };
4898                if let Some(s) = storage_specifier {
4899                    write!(f, "IN {s} ")?;
4900                }
4901                write!(f, "( TYPE {secret_type}",)?;
4902                if !options.is_empty() {
4903                    write!(f, ", {o}", o = display_comma_separated(options))?;
4904                }
4905                write!(f, " )")?;
4906                Ok(())
4907            }
4908            Statement::CreateServer(stmt) => {
4909                write!(f, "{stmt}")
4910            }
4911            Statement::CreatePolicy {
4912                name,
4913                table_name,
4914                policy_type,
4915                command,
4916                to,
4917                using,
4918                with_check,
4919            } => {
4920                write!(f, "CREATE POLICY {name} ON {table_name}")?;
4921
4922                if let Some(policy_type) = policy_type {
4923                    match policy_type {
4924                        CreatePolicyType::Permissive => write!(f, " AS PERMISSIVE")?,
4925                        CreatePolicyType::Restrictive => write!(f, " AS RESTRICTIVE")?,
4926                    }
4927                }
4928
4929                if let Some(command) = command {
4930                    match command {
4931                        CreatePolicyCommand::All => write!(f, " FOR ALL")?,
4932                        CreatePolicyCommand::Select => write!(f, " FOR SELECT")?,
4933                        CreatePolicyCommand::Insert => write!(f, " FOR INSERT")?,
4934                        CreatePolicyCommand::Update => write!(f, " FOR UPDATE")?,
4935                        CreatePolicyCommand::Delete => write!(f, " FOR DELETE")?,
4936                    }
4937                }
4938
4939                if let Some(to) = to {
4940                    write!(f, " TO {}", display_comma_separated(to))?;
4941                }
4942
4943                if let Some(using) = using {
4944                    write!(f, " USING ({using})")?;
4945                }
4946
4947                if let Some(with_check) = with_check {
4948                    write!(f, " WITH CHECK ({with_check})")?;
4949                }
4950
4951                Ok(())
4952            }
4953            Statement::CreateConnector(create_connector) => create_connector.fmt(f),
4954            Statement::CreateOperator(create_operator) => create_operator.fmt(f),
4955            Statement::CreateOperatorFamily(create_operator_family) => {
4956                create_operator_family.fmt(f)
4957            }
4958            Statement::CreateOperatorClass(create_operator_class) => create_operator_class.fmt(f),
4959            Statement::AlterTable(alter_table) => write!(f, "{alter_table}"),
4960            Statement::AlterIndex { name, operation } => {
4961                write!(f, "ALTER INDEX {name} {operation}")
4962            }
4963            Statement::AlterView {
4964                name,
4965                columns,
4966                query,
4967                with_options,
4968            } => {
4969                write!(f, "ALTER VIEW {name}")?;
4970                if !with_options.is_empty() {
4971                    write!(f, " WITH ({})", display_comma_separated(with_options))?;
4972                }
4973                if !columns.is_empty() {
4974                    write!(f, " ({})", display_comma_separated(columns))?;
4975                }
4976                write!(f, " AS {query}")
4977            }
4978            Statement::AlterType(AlterType { name, operation }) => {
4979                write!(f, "ALTER TYPE {name} {operation}")
4980            }
4981            Statement::AlterOperator(alter_operator) => write!(f, "{alter_operator}"),
4982            Statement::AlterOperatorFamily(alter_operator_family) => {
4983                write!(f, "{alter_operator_family}")
4984            }
4985            Statement::AlterRole { name, operation } => {
4986                write!(f, "ALTER ROLE {name} {operation}")
4987            }
4988            Statement::AlterPolicy {
4989                name,
4990                table_name,
4991                operation,
4992            } => {
4993                write!(f, "ALTER POLICY {name} ON {table_name}{operation}")
4994            }
4995            Statement::AlterConnector {
4996                name,
4997                properties,
4998                url,
4999                owner,
5000            } => {
5001                write!(f, "ALTER CONNECTOR {name}")?;
5002                if let Some(properties) = properties {
5003                    write!(
5004                        f,
5005                        " SET DCPROPERTIES({})",
5006                        display_comma_separated(properties)
5007                    )?;
5008                }
5009                if let Some(url) = url {
5010                    write!(f, " SET URL '{url}'")?;
5011                }
5012                if let Some(owner) = owner {
5013                    write!(f, " SET OWNER {owner}")?;
5014                }
5015                Ok(())
5016            }
5017            Statement::AlterSession {
5018                set,
5019                session_params,
5020            } => {
5021                write!(
5022                    f,
5023                    "ALTER SESSION {set}",
5024                    set = if *set { "SET" } else { "UNSET" }
5025                )?;
5026                if !session_params.options.is_empty() {
5027                    if *set {
5028                        write!(f, " {session_params}")?;
5029                    } else {
5030                        let options = session_params
5031                            .options
5032                            .iter()
5033                            .map(|p| p.option_name.clone())
5034                            .collect::<Vec<_>>();
5035                        write!(f, " {}", display_separated(&options, ", "))?;
5036                    }
5037                }
5038                Ok(())
5039            }
5040            Statement::Drop {
5041                object_type,
5042                if_exists,
5043                names,
5044                cascade,
5045                restrict,
5046                purge,
5047                temporary,
5048                table,
5049            } => {
5050                write!(
5051                    f,
5052                    "DROP {}{}{} {}{}{}{}",
5053                    if *temporary { "TEMPORARY " } else { "" },
5054                    object_type,
5055                    if *if_exists { " IF EXISTS" } else { "" },
5056                    display_comma_separated(names),
5057                    if *cascade { " CASCADE" } else { "" },
5058                    if *restrict { " RESTRICT" } else { "" },
5059                    if *purge { " PURGE" } else { "" },
5060                )?;
5061                if let Some(table_name) = table.as_ref() {
5062                    write!(f, " ON {table_name}")?;
5063                };
5064                Ok(())
5065            }
5066            Statement::DropFunction(drop_function) => write!(f, "{drop_function}"),
5067            Statement::DropDomain(DropDomain {
5068                if_exists,
5069                name,
5070                drop_behavior,
5071            }) => {
5072                write!(
5073                    f,
5074                    "DROP DOMAIN{} {name}",
5075                    if *if_exists { " IF EXISTS" } else { "" },
5076                )?;
5077                if let Some(op) = drop_behavior {
5078                    write!(f, " {op}")?;
5079                }
5080                Ok(())
5081            }
5082            Statement::DropProcedure {
5083                if_exists,
5084                proc_desc,
5085                drop_behavior,
5086            } => {
5087                write!(
5088                    f,
5089                    "DROP PROCEDURE{} {}",
5090                    if *if_exists { " IF EXISTS" } else { "" },
5091                    display_comma_separated(proc_desc),
5092                )?;
5093                if let Some(op) = drop_behavior {
5094                    write!(f, " {op}")?;
5095                }
5096                Ok(())
5097            }
5098            Statement::DropSecret {
5099                if_exists,
5100                temporary,
5101                name,
5102                storage_specifier,
5103            } => {
5104                write!(f, "DROP ")?;
5105                if let Some(t) = temporary {
5106                    write!(f, "{}", if *t { "TEMPORARY " } else { "PERSISTENT " })?;
5107                }
5108                write!(
5109                    f,
5110                    "SECRET {if_exists}{name}",
5111                    if_exists = if *if_exists { "IF EXISTS " } else { "" },
5112                )?;
5113                if let Some(s) = storage_specifier {
5114                    write!(f, " FROM {s}")?;
5115                }
5116                Ok(())
5117            }
5118            Statement::DropPolicy {
5119                if_exists,
5120                name,
5121                table_name,
5122                drop_behavior,
5123            } => {
5124                write!(f, "DROP POLICY")?;
5125                if *if_exists {
5126                    write!(f, " IF EXISTS")?;
5127                }
5128                write!(f, " {name} ON {table_name}")?;
5129                if let Some(drop_behavior) = drop_behavior {
5130                    write!(f, " {drop_behavior}")?;
5131                }
5132                Ok(())
5133            }
5134            Statement::DropConnector { if_exists, name } => {
5135                write!(
5136                    f,
5137                    "DROP CONNECTOR {if_exists}{name}",
5138                    if_exists = if *if_exists { "IF EXISTS " } else { "" }
5139                )?;
5140                Ok(())
5141            }
5142            Statement::Discard { object_type } => {
5143                write!(f, "DISCARD {object_type}")?;
5144                Ok(())
5145            }
5146            Self::Set(set) => write!(f, "{set}"),
5147            Statement::ShowVariable { variable } => {
5148                write!(f, "SHOW")?;
5149                if !variable.is_empty() {
5150                    write!(f, " {}", display_separated(variable, " "))?;
5151                }
5152                Ok(())
5153            }
5154            Statement::ShowStatus {
5155                filter,
5156                global,
5157                session,
5158            } => {
5159                write!(f, "SHOW")?;
5160                if *global {
5161                    write!(f, " GLOBAL")?;
5162                }
5163                if *session {
5164                    write!(f, " SESSION")?;
5165                }
5166                write!(f, " STATUS")?;
5167                if filter.is_some() {
5168                    write!(f, " {}", filter.as_ref().unwrap())?;
5169                }
5170                Ok(())
5171            }
5172            Statement::ShowVariables {
5173                filter,
5174                global,
5175                session,
5176            } => {
5177                write!(f, "SHOW")?;
5178                if *global {
5179                    write!(f, " GLOBAL")?;
5180                }
5181                if *session {
5182                    write!(f, " SESSION")?;
5183                }
5184                write!(f, " VARIABLES")?;
5185                if filter.is_some() {
5186                    write!(f, " {}", filter.as_ref().unwrap())?;
5187                }
5188                Ok(())
5189            }
5190            Statement::ShowCreate { obj_type, obj_name } => {
5191                write!(f, "SHOW CREATE {obj_type} {obj_name}",)?;
5192                Ok(())
5193            }
5194            Statement::ShowColumns {
5195                extended,
5196                full,
5197                show_options,
5198            } => {
5199                write!(
5200                    f,
5201                    "SHOW {extended}{full}COLUMNS{show_options}",
5202                    extended = if *extended { "EXTENDED " } else { "" },
5203                    full = if *full { "FULL " } else { "" },
5204                )?;
5205                Ok(())
5206            }
5207            Statement::ShowDatabases {
5208                terse,
5209                history,
5210                show_options,
5211            } => {
5212                write!(
5213                    f,
5214                    "SHOW {terse}DATABASES{history}{show_options}",
5215                    terse = if *terse { "TERSE " } else { "" },
5216                    history = if *history { " HISTORY" } else { "" },
5217                )?;
5218                Ok(())
5219            }
5220            Statement::ShowSchemas {
5221                terse,
5222                history,
5223                show_options,
5224            } => {
5225                write!(
5226                    f,
5227                    "SHOW {terse}SCHEMAS{history}{show_options}",
5228                    terse = if *terse { "TERSE " } else { "" },
5229                    history = if *history { " HISTORY" } else { "" },
5230                )?;
5231                Ok(())
5232            }
5233            Statement::ShowObjects(ShowObjects {
5234                terse,
5235                show_options,
5236            }) => {
5237                write!(
5238                    f,
5239                    "SHOW {terse}OBJECTS{show_options}",
5240                    terse = if *terse { "TERSE " } else { "" },
5241                )?;
5242                Ok(())
5243            }
5244            Statement::ShowTables {
5245                terse,
5246                history,
5247                extended,
5248                full,
5249                external,
5250                show_options,
5251            } => {
5252                write!(
5253                    f,
5254                    "SHOW {terse}{extended}{full}{external}TABLES{history}{show_options}",
5255                    terse = if *terse { "TERSE " } else { "" },
5256                    extended = if *extended { "EXTENDED " } else { "" },
5257                    full = if *full { "FULL " } else { "" },
5258                    external = if *external { "EXTERNAL " } else { "" },
5259                    history = if *history { " HISTORY" } else { "" },
5260                )?;
5261                Ok(())
5262            }
5263            Statement::ShowViews {
5264                terse,
5265                materialized,
5266                show_options,
5267            } => {
5268                write!(
5269                    f,
5270                    "SHOW {terse}{materialized}VIEWS{show_options}",
5271                    terse = if *terse { "TERSE " } else { "" },
5272                    materialized = if *materialized { "MATERIALIZED " } else { "" }
5273                )?;
5274                Ok(())
5275            }
5276            Statement::ShowFunctions { filter } => {
5277                write!(f, "SHOW FUNCTIONS")?;
5278                if let Some(filter) = filter {
5279                    write!(f, " {filter}")?;
5280                }
5281                Ok(())
5282            }
5283            Statement::Use(use_expr) => use_expr.fmt(f),
5284            Statement::ShowCollation { filter } => {
5285                write!(f, "SHOW COLLATION")?;
5286                if let Some(filter) = filter {
5287                    write!(f, " {filter}")?;
5288                }
5289                Ok(())
5290            }
5291            Statement::ShowCharset(show_stm) => show_stm.fmt(f),
5292            Statement::StartTransaction {
5293                modes,
5294                begin: syntax_begin,
5295                transaction,
5296                modifier,
5297                statements,
5298                exception,
5299                has_end_keyword,
5300            } => {
5301                if *syntax_begin {
5302                    if let Some(modifier) = *modifier {
5303                        write!(f, "BEGIN {modifier}")?;
5304                    } else {
5305                        write!(f, "BEGIN")?;
5306                    }
5307                } else {
5308                    write!(f, "START")?;
5309                }
5310                if let Some(transaction) = transaction {
5311                    write!(f, " {transaction}")?;
5312                }
5313                if !modes.is_empty() {
5314                    write!(f, " {}", display_comma_separated(modes))?;
5315                }
5316                if !statements.is_empty() {
5317                    write!(f, " ")?;
5318                    format_statement_list(f, statements)?;
5319                }
5320                if let Some(exception_when) = exception {
5321                    write!(f, " EXCEPTION")?;
5322                    for when in exception_when {
5323                        write!(f, " {when}")?;
5324                    }
5325                }
5326                if *has_end_keyword {
5327                    write!(f, " END")?;
5328                }
5329                Ok(())
5330            }
5331            Statement::Commit {
5332                chain,
5333                end: end_syntax,
5334                modifier,
5335            } => {
5336                if *end_syntax {
5337                    write!(f, "END")?;
5338                    if let Some(modifier) = *modifier {
5339                        write!(f, " {modifier}")?;
5340                    }
5341                    if *chain {
5342                        write!(f, " AND CHAIN")?;
5343                    }
5344                } else {
5345                    write!(f, "COMMIT{}", if *chain { " AND CHAIN" } else { "" })?;
5346                }
5347                Ok(())
5348            }
5349            Statement::Rollback { chain, savepoint } => {
5350                write!(f, "ROLLBACK")?;
5351
5352                if *chain {
5353                    write!(f, " AND CHAIN")?;
5354                }
5355
5356                if let Some(savepoint) = savepoint {
5357                    write!(f, " TO SAVEPOINT {savepoint}")?;
5358                }
5359
5360                Ok(())
5361            }
5362            Statement::CreateSchema {
5363                schema_name,
5364                if_not_exists,
5365                with,
5366                options,
5367                default_collate_spec,
5368                clone,
5369            } => {
5370                write!(
5371                    f,
5372                    "CREATE SCHEMA {if_not_exists}{name}",
5373                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5374                    name = schema_name
5375                )?;
5376
5377                if let Some(collate) = default_collate_spec {
5378                    write!(f, " DEFAULT COLLATE {collate}")?;
5379                }
5380
5381                if let Some(with) = with {
5382                    write!(f, " WITH ({})", display_comma_separated(with))?;
5383                }
5384
5385                if let Some(options) = options {
5386                    write!(f, " OPTIONS({})", display_comma_separated(options))?;
5387                }
5388
5389                if let Some(clone) = clone {
5390                    write!(f, " CLONE {clone}")?;
5391                }
5392                Ok(())
5393            }
5394            Statement::Assert { condition, message } => {
5395                write!(f, "ASSERT {condition}")?;
5396                if let Some(m) = message {
5397                    write!(f, " AS {m}")?;
5398                }
5399                Ok(())
5400            }
5401            Statement::Grant {
5402                privileges,
5403                objects,
5404                grantees,
5405                with_grant_option,
5406                as_grantor,
5407                granted_by,
5408                current_grants,
5409            } => {
5410                write!(f, "GRANT {privileges} ")?;
5411                if let Some(objects) = objects {
5412                    write!(f, "ON {objects} ")?;
5413                }
5414                write!(f, "TO {}", display_comma_separated(grantees))?;
5415                if *with_grant_option {
5416                    write!(f, " WITH GRANT OPTION")?;
5417                }
5418                if let Some(current_grants) = current_grants {
5419                    write!(f, " {current_grants}")?;
5420                }
5421                if let Some(grantor) = as_grantor {
5422                    write!(f, " AS {grantor}")?;
5423                }
5424                if let Some(grantor) = granted_by {
5425                    write!(f, " GRANTED BY {grantor}")?;
5426                }
5427                Ok(())
5428            }
5429            Statement::Deny(s) => write!(f, "{s}"),
5430            Statement::Revoke {
5431                privileges,
5432                objects,
5433                grantees,
5434                granted_by,
5435                cascade,
5436            } => {
5437                write!(f, "REVOKE {privileges} ")?;
5438                if let Some(objects) = objects {
5439                    write!(f, "ON {objects} ")?;
5440                }
5441                write!(f, "FROM {}", display_comma_separated(grantees))?;
5442                if let Some(grantor) = granted_by {
5443                    write!(f, " GRANTED BY {grantor}")?;
5444                }
5445                if let Some(cascade) = cascade {
5446                    write!(f, " {cascade}")?;
5447                }
5448                Ok(())
5449            }
5450            Statement::Deallocate { name, prepare } => write!(
5451                f,
5452                "DEALLOCATE {prepare}{name}",
5453                prepare = if *prepare { "PREPARE " } else { "" },
5454                name = name,
5455            ),
5456            Statement::Execute {
5457                name,
5458                parameters,
5459                has_parentheses,
5460                immediate,
5461                into,
5462                using,
5463                output,
5464                default,
5465            } => {
5466                let (open, close) = if *has_parentheses {
5467                    ("(", ")")
5468                } else {
5469                    (if parameters.is_empty() { "" } else { " " }, "")
5470                };
5471                write!(f, "EXECUTE")?;
5472                if *immediate {
5473                    write!(f, " IMMEDIATE")?;
5474                }
5475                if let Some(name) = name {
5476                    write!(f, " {name}")?;
5477                }
5478                write!(f, "{open}{}{close}", display_comma_separated(parameters),)?;
5479                if !into.is_empty() {
5480                    write!(f, " INTO {}", display_comma_separated(into))?;
5481                }
5482                if !using.is_empty() {
5483                    write!(f, " USING {}", display_comma_separated(using))?;
5484                };
5485                if *output {
5486                    write!(f, " OUTPUT")?;
5487                }
5488                if *default {
5489                    write!(f, " DEFAULT")?;
5490                }
5491                Ok(())
5492            }
5493            Statement::Prepare {
5494                name,
5495                data_types,
5496                statement,
5497            } => {
5498                write!(f, "PREPARE {name} ")?;
5499                if !data_types.is_empty() {
5500                    write!(f, "({}) ", display_comma_separated(data_types))?;
5501                }
5502                write!(f, "AS {statement}")
5503            }
5504            Statement::Comment {
5505                object_type,
5506                object_name,
5507                comment,
5508                if_exists,
5509            } => {
5510                write!(f, "COMMENT ")?;
5511                if *if_exists {
5512                    write!(f, "IF EXISTS ")?
5513                };
5514                write!(f, "ON {object_type} {object_name} IS ")?;
5515                if let Some(c) = comment {
5516                    write!(f, "'{c}'")
5517                } else {
5518                    write!(f, "NULL")
5519                }
5520            }
5521            Statement::Savepoint { name } => {
5522                write!(f, "SAVEPOINT ")?;
5523                write!(f, "{name}")
5524            }
5525            Statement::ReleaseSavepoint { name } => {
5526                write!(f, "RELEASE SAVEPOINT {name}")
5527            }
5528            Statement::Merge(merge) => merge.fmt(f),
5529            Statement::Cache {
5530                table_name,
5531                table_flag,
5532                has_as,
5533                options,
5534                query,
5535            } => {
5536                if let Some(table_flag) = table_flag {
5537                    write!(f, "CACHE {table_flag} TABLE {table_name}")?;
5538                } else {
5539                    write!(f, "CACHE TABLE {table_name}")?;
5540                }
5541
5542                if !options.is_empty() {
5543                    write!(f, " OPTIONS({})", display_comma_separated(options))?;
5544                }
5545
5546                match (*has_as, query) {
5547                    (true, Some(query)) => write!(f, " AS {query}"),
5548                    (true, None) => f.write_str(" AS"),
5549                    (false, Some(query)) => write!(f, " {query}"),
5550                    (false, None) => Ok(()),
5551                }
5552            }
5553            Statement::UNCache {
5554                table_name,
5555                if_exists,
5556            } => {
5557                if *if_exists {
5558                    write!(f, "UNCACHE TABLE IF EXISTS {table_name}")
5559                } else {
5560                    write!(f, "UNCACHE TABLE {table_name}")
5561                }
5562            }
5563            Statement::CreateSequence {
5564                temporary,
5565                if_not_exists,
5566                name,
5567                data_type,
5568                sequence_options,
5569                owned_by,
5570            } => {
5571                let as_type: String = if let Some(dt) = data_type.as_ref() {
5572                    //Cannot use format!(" AS {}", dt), due to format! is not available in --target thumbv6m-none-eabi
5573                    // " AS ".to_owned() + &dt.to_string()
5574                    [" AS ", &dt.to_string()].concat()
5575                } else {
5576                    "".to_string()
5577                };
5578                write!(
5579                    f,
5580                    "CREATE {temporary}SEQUENCE {if_not_exists}{name}{as_type}",
5581                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5582                    temporary = if *temporary { "TEMPORARY " } else { "" },
5583                    name = name,
5584                    as_type = as_type
5585                )?;
5586                for sequence_option in sequence_options {
5587                    write!(f, "{sequence_option}")?;
5588                }
5589                if let Some(ob) = owned_by.as_ref() {
5590                    write!(f, " OWNED BY {ob}")?;
5591                }
5592                write!(f, "")
5593            }
5594            Statement::CreateStage {
5595                or_replace,
5596                temporary,
5597                if_not_exists,
5598                name,
5599                stage_params,
5600                directory_table_params,
5601                file_format,
5602                copy_options,
5603                comment,
5604                ..
5605            } => {
5606                write!(
5607                    f,
5608                    "CREATE {or_replace}{temp}STAGE {if_not_exists}{name}{stage_params}",
5609                    temp = if *temporary { "TEMPORARY " } else { "" },
5610                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
5611                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5612                )?;
5613                if !directory_table_params.options.is_empty() {
5614                    write!(f, " DIRECTORY=({directory_table_params})")?;
5615                }
5616                if !file_format.options.is_empty() {
5617                    write!(f, " FILE_FORMAT=({file_format})")?;
5618                }
5619                if !copy_options.options.is_empty() {
5620                    write!(f, " COPY_OPTIONS=({copy_options})")?;
5621                }
5622                if comment.is_some() {
5623                    write!(f, " COMMENT='{}'", comment.as_ref().unwrap())?;
5624                }
5625                Ok(())
5626            }
5627            Statement::CopyIntoSnowflake {
5628                kind,
5629                into,
5630                into_columns,
5631                from_obj,
5632                from_obj_alias,
5633                stage_params,
5634                from_transformations,
5635                from_query,
5636                files,
5637                pattern,
5638                file_format,
5639                copy_options,
5640                validation_mode,
5641                partition,
5642            } => {
5643                write!(f, "COPY INTO {into}")?;
5644                if let Some(into_columns) = into_columns {
5645                    write!(f, " ({})", display_comma_separated(into_columns))?;
5646                }
5647                if let Some(from_transformations) = from_transformations {
5648                    // Data load with transformation
5649                    if let Some(from_stage) = from_obj {
5650                        write!(
5651                            f,
5652                            " FROM (SELECT {} FROM {}{}",
5653                            display_separated(from_transformations, ", "),
5654                            from_stage,
5655                            stage_params
5656                        )?;
5657                    }
5658                    if let Some(from_obj_alias) = from_obj_alias {
5659                        write!(f, " AS {from_obj_alias}")?;
5660                    }
5661                    write!(f, ")")?;
5662                } else if let Some(from_obj) = from_obj {
5663                    // Standard data load
5664                    write!(f, " FROM {from_obj}{stage_params}")?;
5665                    if let Some(from_obj_alias) = from_obj_alias {
5666                        write!(f, " AS {from_obj_alias}")?;
5667                    }
5668                } else if let Some(from_query) = from_query {
5669                    // Data unload from query
5670                    write!(f, " FROM ({from_query})")?;
5671                }
5672
5673                if let Some(files) = files {
5674                    write!(f, " FILES = ('{}')", display_separated(files, "', '"))?;
5675                }
5676                if let Some(pattern) = pattern {
5677                    write!(f, " PATTERN = '{pattern}'")?;
5678                }
5679                if let Some(partition) = partition {
5680                    write!(f, " PARTITION BY {partition}")?;
5681                }
5682                if !file_format.options.is_empty() {
5683                    write!(f, " FILE_FORMAT=({file_format})")?;
5684                }
5685                if !copy_options.options.is_empty() {
5686                    match kind {
5687                        CopyIntoSnowflakeKind::Table => {
5688                            write!(f, " COPY_OPTIONS=({copy_options})")?
5689                        }
5690                        CopyIntoSnowflakeKind::Location => write!(f, " {copy_options}")?,
5691                    }
5692                }
5693                if let Some(validation_mode) = validation_mode {
5694                    write!(f, " VALIDATION_MODE = {validation_mode}")?;
5695                }
5696                Ok(())
5697            }
5698            Statement::CreateType {
5699                name,
5700                representation,
5701            } => {
5702                write!(f, "CREATE TYPE {name}")?;
5703                if let Some(repr) = representation {
5704                    write!(f, " {repr}")?;
5705                }
5706                Ok(())
5707            }
5708            Statement::Pragma { name, value, is_eq } => {
5709                write!(f, "PRAGMA {name}")?;
5710                if value.is_some() {
5711                    let val = value.as_ref().unwrap();
5712                    if *is_eq {
5713                        write!(f, " = {val}")?;
5714                    } else {
5715                        write!(f, "({val})")?;
5716                    }
5717                }
5718                Ok(())
5719            }
5720            Statement::LockTables { tables } => {
5721                write!(f, "LOCK TABLES {}", display_comma_separated(tables))
5722            }
5723            Statement::UnlockTables => {
5724                write!(f, "UNLOCK TABLES")
5725            }
5726            Statement::Unload {
5727                query,
5728                query_text,
5729                to,
5730                auth,
5731                with,
5732                options,
5733            } => {
5734                write!(f, "UNLOAD(")?;
5735                if let Some(query) = query {
5736                    write!(f, "{query}")?;
5737                }
5738                if let Some(query_text) = query_text {
5739                    write!(f, "'{query_text}'")?;
5740                }
5741                write!(f, ") TO {to}")?;
5742                if let Some(auth) = auth {
5743                    write!(f, " IAM_ROLE {auth}")?;
5744                }
5745                if !with.is_empty() {
5746                    write!(f, " WITH ({})", display_comma_separated(with))?;
5747                }
5748                if !options.is_empty() {
5749                    write!(f, " {}", display_separated(options, " "))?;
5750                }
5751                Ok(())
5752            }
5753            Statement::OptimizeTable {
5754                name,
5755                on_cluster,
5756                partition,
5757                include_final,
5758                deduplicate,
5759            } => {
5760                write!(f, "OPTIMIZE TABLE {name}")?;
5761                if let Some(on_cluster) = on_cluster {
5762                    write!(f, " ON CLUSTER {on_cluster}")?;
5763                }
5764                if let Some(partition) = partition {
5765                    write!(f, " {partition}")?;
5766                }
5767                if *include_final {
5768                    write!(f, " FINAL")?;
5769                }
5770                if let Some(deduplicate) = deduplicate {
5771                    write!(f, " {deduplicate}")?;
5772                }
5773                Ok(())
5774            }
5775            Statement::LISTEN { channel } => {
5776                write!(f, "LISTEN {channel}")?;
5777                Ok(())
5778            }
5779            Statement::UNLISTEN { channel } => {
5780                write!(f, "UNLISTEN {channel}")?;
5781                Ok(())
5782            }
5783            Statement::NOTIFY { channel, payload } => {
5784                write!(f, "NOTIFY {channel}")?;
5785                if let Some(payload) = payload {
5786                    write!(f, ", '{payload}'")?;
5787                }
5788                Ok(())
5789            }
5790            Statement::RenameTable(rename_tables) => {
5791                write!(f, "RENAME TABLE {}", display_comma_separated(rename_tables))
5792            }
5793            Statement::RaisError {
5794                message,
5795                severity,
5796                state,
5797                arguments,
5798                options,
5799            } => {
5800                write!(f, "RAISERROR({message}, {severity}, {state}")?;
5801                if !arguments.is_empty() {
5802                    write!(f, ", {}", display_comma_separated(arguments))?;
5803                }
5804                write!(f, ")")?;
5805                if !options.is_empty() {
5806                    write!(f, " WITH {}", display_comma_separated(options))?;
5807                }
5808                Ok(())
5809            }
5810            Statement::Print(s) => write!(f, "{s}"),
5811            Statement::Return(r) => write!(f, "{r}"),
5812            Statement::List(command) => write!(f, "LIST {command}"),
5813            Statement::Remove(command) => write!(f, "REMOVE {command}"),
5814            Statement::ExportData(e) => write!(f, "{e}"),
5815            Statement::CreateUser(s) => write!(f, "{s}"),
5816            Statement::AlterSchema(s) => write!(f, "{s}"),
5817            Statement::Vacuum(s) => write!(f, "{s}"),
5818            Statement::AlterUser(s) => write!(f, "{s}"),
5819            Statement::Reset(s) => write!(f, "{s}"),
5820        }
5821    }
5822}
5823
5824/// Can use to describe options in create sequence or table column type identity
5825/// ```sql
5826/// [ INCREMENT [ BY ] increment ]
5827///     [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
5828///     [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
5829/// ```
5830#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5831#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5832#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5833pub enum SequenceOptions {
5834    IncrementBy(Expr, bool),
5835    MinValue(Option<Expr>),
5836    MaxValue(Option<Expr>),
5837    StartWith(Expr, bool),
5838    Cache(Expr),
5839    Cycle(bool),
5840}
5841
5842impl fmt::Display for SequenceOptions {
5843    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5844        match self {
5845            SequenceOptions::IncrementBy(increment, by) => {
5846                write!(
5847                    f,
5848                    " INCREMENT{by} {increment}",
5849                    by = if *by { " BY" } else { "" },
5850                    increment = increment
5851                )
5852            }
5853            SequenceOptions::MinValue(Some(expr)) => {
5854                write!(f, " MINVALUE {expr}")
5855            }
5856            SequenceOptions::MinValue(None) => {
5857                write!(f, " NO MINVALUE")
5858            }
5859            SequenceOptions::MaxValue(Some(expr)) => {
5860                write!(f, " MAXVALUE {expr}")
5861            }
5862            SequenceOptions::MaxValue(None) => {
5863                write!(f, " NO MAXVALUE")
5864            }
5865            SequenceOptions::StartWith(start, with) => {
5866                write!(
5867                    f,
5868                    " START{with} {start}",
5869                    with = if *with { " WITH" } else { "" },
5870                    start = start
5871                )
5872            }
5873            SequenceOptions::Cache(cache) => {
5874                write!(f, " CACHE {}", *cache)
5875            }
5876            SequenceOptions::Cycle(no) => {
5877                write!(f, " {}CYCLE", if *no { "NO " } else { "" })
5878            }
5879        }
5880    }
5881}
5882
5883/// Assignment for a `SET` statement (name [=|TO] value)
5884#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5885#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5886#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5887pub struct SetAssignment {
5888    pub scope: Option<ContextModifier>,
5889    pub name: ObjectName,
5890    pub value: Expr,
5891}
5892
5893impl fmt::Display for SetAssignment {
5894    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5895        write!(
5896            f,
5897            "{}{} = {}",
5898            self.scope.map(|s| format!("{s}")).unwrap_or_default(),
5899            self.name,
5900            self.value
5901        )
5902    }
5903}
5904
5905/// Target of a `TRUNCATE TABLE` command
5906///
5907/// Note this is its own struct because `visit_relation` requires an `ObjectName` (not a `Vec<ObjectName>`)
5908#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5909#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5910#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5911pub struct TruncateTableTarget {
5912    /// name of the table being truncated
5913    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
5914    pub name: ObjectName,
5915    /// Postgres-specific option
5916    /// [ TRUNCATE TABLE ONLY ]
5917    /// <https://www.postgresql.org/docs/current/sql-truncate.html>
5918    pub only: bool,
5919}
5920
5921impl fmt::Display for TruncateTableTarget {
5922    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5923        if self.only {
5924            write!(f, "ONLY ")?;
5925        };
5926        write!(f, "{}", self.name)
5927    }
5928}
5929
5930/// PostgreSQL identity option for TRUNCATE table
5931/// [ RESTART IDENTITY | CONTINUE IDENTITY ]
5932#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5933#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5934#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5935pub enum TruncateIdentityOption {
5936    Restart,
5937    Continue,
5938}
5939
5940/// Cascade/restrict option for Postgres TRUNCATE table, MySQL GRANT/REVOKE, etc.
5941/// [ CASCADE | RESTRICT ]
5942#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5943#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5944#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5945pub enum CascadeOption {
5946    Cascade,
5947    Restrict,
5948}
5949
5950impl Display for CascadeOption {
5951    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5952        match self {
5953            CascadeOption::Cascade => write!(f, "CASCADE"),
5954            CascadeOption::Restrict => write!(f, "RESTRICT"),
5955        }
5956    }
5957}
5958
5959/// Transaction started with [ TRANSACTION | WORK ]
5960#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5961#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5962#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5963pub enum BeginTransactionKind {
5964    Transaction,
5965    Work,
5966}
5967
5968impl Display for BeginTransactionKind {
5969    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5970        match self {
5971            BeginTransactionKind::Transaction => write!(f, "TRANSACTION"),
5972            BeginTransactionKind::Work => write!(f, "WORK"),
5973        }
5974    }
5975}
5976
5977/// Can use to describe options in  create sequence or table column type identity
5978/// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
5979#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5980#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5981#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5982pub enum MinMaxValue {
5983    // clause is not specified
5984    Empty,
5985    // NO MINVALUE/NO MAXVALUE
5986    None,
5987    // MINVALUE <expr> / MAXVALUE <expr>
5988    Some(Expr),
5989}
5990
5991#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
5992#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
5993#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
5994#[non_exhaustive]
5995pub enum OnInsert {
5996    /// ON DUPLICATE KEY UPDATE (MySQL when the key already exists, then execute an update instead)
5997    DuplicateKeyUpdate(Vec<Assignment>),
5998    /// ON CONFLICT is a PostgreSQL and Sqlite extension
5999    OnConflict(OnConflict),
6000}
6001
6002#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6003#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6004#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6005pub struct InsertAliases {
6006    pub row_alias: ObjectName,
6007    pub col_aliases: Option<Vec<Ident>>,
6008}
6009
6010#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6011#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6012#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6013pub struct OnConflict {
6014    pub conflict_target: Option<ConflictTarget>,
6015    pub action: OnConflictAction,
6016}
6017#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6018#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6019#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6020pub enum ConflictTarget {
6021    Columns(Vec<Ident>),
6022    OnConstraint(ObjectName),
6023}
6024#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6025#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6026#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6027pub enum OnConflictAction {
6028    DoNothing,
6029    DoUpdate(DoUpdate),
6030}
6031
6032#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6033#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6034#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6035pub struct DoUpdate {
6036    /// Column assignments
6037    pub assignments: Vec<Assignment>,
6038    /// WHERE
6039    pub selection: Option<Expr>,
6040}
6041
6042impl fmt::Display for OnInsert {
6043    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6044        match self {
6045            Self::DuplicateKeyUpdate(expr) => write!(
6046                f,
6047                " ON DUPLICATE KEY UPDATE {}",
6048                display_comma_separated(expr)
6049            ),
6050            Self::OnConflict(o) => write!(f, "{o}"),
6051        }
6052    }
6053}
6054impl fmt::Display for OnConflict {
6055    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6056        write!(f, " ON CONFLICT")?;
6057        if let Some(target) = &self.conflict_target {
6058            write!(f, "{target}")?;
6059        }
6060        write!(f, " {}", self.action)
6061    }
6062}
6063impl fmt::Display for ConflictTarget {
6064    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6065        match self {
6066            ConflictTarget::Columns(cols) => write!(f, "({})", display_comma_separated(cols)),
6067            ConflictTarget::OnConstraint(name) => write!(f, " ON CONSTRAINT {name}"),
6068        }
6069    }
6070}
6071impl fmt::Display for OnConflictAction {
6072    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6073        match self {
6074            Self::DoNothing => write!(f, "DO NOTHING"),
6075            Self::DoUpdate(do_update) => {
6076                write!(f, "DO UPDATE")?;
6077                if !do_update.assignments.is_empty() {
6078                    write!(
6079                        f,
6080                        " SET {}",
6081                        display_comma_separated(&do_update.assignments)
6082                    )?;
6083                }
6084                if let Some(selection) = &do_update.selection {
6085                    write!(f, " WHERE {selection}")?;
6086                }
6087                Ok(())
6088            }
6089        }
6090    }
6091}
6092
6093/// Privileges granted in a GRANT statement or revoked in a REVOKE statement.
6094#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6095#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6096#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6097pub enum Privileges {
6098    /// All privileges applicable to the object type
6099    All {
6100        /// Optional keyword from the spec, ignored in practice
6101        with_privileges_keyword: bool,
6102    },
6103    /// Specific privileges (e.g. `SELECT`, `INSERT`)
6104    Actions(Vec<Action>),
6105}
6106
6107impl fmt::Display for Privileges {
6108    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6109        match self {
6110            Privileges::All {
6111                with_privileges_keyword,
6112            } => {
6113                write!(
6114                    f,
6115                    "ALL{}",
6116                    if *with_privileges_keyword {
6117                        " PRIVILEGES"
6118                    } else {
6119                        ""
6120                    }
6121                )
6122            }
6123            Privileges::Actions(actions) => {
6124                write!(f, "{}", display_comma_separated(actions))
6125            }
6126        }
6127    }
6128}
6129
6130/// Specific direction for FETCH statement
6131#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6132#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6133#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6134pub enum FetchDirection {
6135    Count { limit: Value },
6136    Next,
6137    Prior,
6138    First,
6139    Last,
6140    Absolute { limit: Value },
6141    Relative { limit: Value },
6142    All,
6143    // FORWARD
6144    // FORWARD count
6145    Forward { limit: Option<Value> },
6146    ForwardAll,
6147    // BACKWARD
6148    // BACKWARD count
6149    Backward { limit: Option<Value> },
6150    BackwardAll,
6151}
6152
6153impl fmt::Display for FetchDirection {
6154    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6155        match self {
6156            FetchDirection::Count { limit } => f.write_str(&limit.to_string())?,
6157            FetchDirection::Next => f.write_str("NEXT")?,
6158            FetchDirection::Prior => f.write_str("PRIOR")?,
6159            FetchDirection::First => f.write_str("FIRST")?,
6160            FetchDirection::Last => f.write_str("LAST")?,
6161            FetchDirection::Absolute { limit } => {
6162                f.write_str("ABSOLUTE ")?;
6163                f.write_str(&limit.to_string())?;
6164            }
6165            FetchDirection::Relative { limit } => {
6166                f.write_str("RELATIVE ")?;
6167                f.write_str(&limit.to_string())?;
6168            }
6169            FetchDirection::All => f.write_str("ALL")?,
6170            FetchDirection::Forward { limit } => {
6171                f.write_str("FORWARD")?;
6172
6173                if let Some(l) = limit {
6174                    f.write_str(" ")?;
6175                    f.write_str(&l.to_string())?;
6176                }
6177            }
6178            FetchDirection::ForwardAll => f.write_str("FORWARD ALL")?,
6179            FetchDirection::Backward { limit } => {
6180                f.write_str("BACKWARD")?;
6181
6182                if let Some(l) = limit {
6183                    f.write_str(" ")?;
6184                    f.write_str(&l.to_string())?;
6185                }
6186            }
6187            FetchDirection::BackwardAll => f.write_str("BACKWARD ALL")?,
6188        };
6189
6190        Ok(())
6191    }
6192}
6193
6194/// The "position" for a FETCH statement.
6195///
6196/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/fetch-transact-sql)
6197#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6198#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6199#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6200pub enum FetchPosition {
6201    From,
6202    In,
6203}
6204
6205impl fmt::Display for FetchPosition {
6206    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6207        match self {
6208            FetchPosition::From => f.write_str("FROM")?,
6209            FetchPosition::In => f.write_str("IN")?,
6210        };
6211
6212        Ok(())
6213    }
6214}
6215
6216/// A privilege on a database object (table, sequence, etc.).
6217#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6218#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6219#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6220pub enum Action {
6221    AddSearchOptimization,
6222    Apply {
6223        apply_type: ActionApplyType,
6224    },
6225    ApplyBudget,
6226    AttachListing,
6227    AttachPolicy,
6228    Audit,
6229    BindServiceEndpoint,
6230    Connect,
6231    Create {
6232        obj_type: Option<ActionCreateObjectType>,
6233    },
6234    DatabaseRole {
6235        role: ObjectName,
6236    },
6237    Delete,
6238    Drop,
6239    EvolveSchema,
6240    Exec {
6241        obj_type: Option<ActionExecuteObjectType>,
6242    },
6243    Execute {
6244        obj_type: Option<ActionExecuteObjectType>,
6245    },
6246    Failover,
6247    ImportedPrivileges,
6248    ImportShare,
6249    Insert {
6250        columns: Option<Vec<Ident>>,
6251    },
6252    Manage {
6253        manage_type: ActionManageType,
6254    },
6255    ManageReleases,
6256    ManageVersions,
6257    Modify {
6258        modify_type: Option<ActionModifyType>,
6259    },
6260    Monitor {
6261        monitor_type: Option<ActionMonitorType>,
6262    },
6263    Operate,
6264    OverrideShareRestrictions,
6265    Ownership,
6266    PurchaseDataExchangeListing,
6267    Read,
6268    ReadSession,
6269    References {
6270        columns: Option<Vec<Ident>>,
6271    },
6272    Replicate,
6273    ResolveAll,
6274    Role {
6275        role: ObjectName,
6276    },
6277    Select {
6278        columns: Option<Vec<Ident>>,
6279    },
6280    Temporary,
6281    Trigger,
6282    Truncate,
6283    Update {
6284        columns: Option<Vec<Ident>>,
6285    },
6286    Usage,
6287}
6288
6289impl fmt::Display for Action {
6290    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6291        match self {
6292            Action::AddSearchOptimization => f.write_str("ADD SEARCH OPTIMIZATION")?,
6293            Action::Apply { apply_type } => write!(f, "APPLY {apply_type}")?,
6294            Action::ApplyBudget => f.write_str("APPLYBUDGET")?,
6295            Action::AttachListing => f.write_str("ATTACH LISTING")?,
6296            Action::AttachPolicy => f.write_str("ATTACH POLICY")?,
6297            Action::Audit => f.write_str("AUDIT")?,
6298            Action::BindServiceEndpoint => f.write_str("BIND SERVICE ENDPOINT")?,
6299            Action::Connect => f.write_str("CONNECT")?,
6300            Action::Create { obj_type } => {
6301                f.write_str("CREATE")?;
6302                if let Some(obj_type) = obj_type {
6303                    write!(f, " {obj_type}")?
6304                }
6305            }
6306            Action::DatabaseRole { role } => write!(f, "DATABASE ROLE {role}")?,
6307            Action::Delete => f.write_str("DELETE")?,
6308            Action::Drop => f.write_str("DROP")?,
6309            Action::EvolveSchema => f.write_str("EVOLVE SCHEMA")?,
6310            Action::Exec { obj_type } => {
6311                f.write_str("EXEC")?;
6312                if let Some(obj_type) = obj_type {
6313                    write!(f, " {obj_type}")?
6314                }
6315            }
6316            Action::Execute { obj_type } => {
6317                f.write_str("EXECUTE")?;
6318                if let Some(obj_type) = obj_type {
6319                    write!(f, " {obj_type}")?
6320                }
6321            }
6322            Action::Failover => f.write_str("FAILOVER")?,
6323            Action::ImportedPrivileges => f.write_str("IMPORTED PRIVILEGES")?,
6324            Action::ImportShare => f.write_str("IMPORT SHARE")?,
6325            Action::Insert { .. } => f.write_str("INSERT")?,
6326            Action::Manage { manage_type } => write!(f, "MANAGE {manage_type}")?,
6327            Action::ManageReleases => f.write_str("MANAGE RELEASES")?,
6328            Action::ManageVersions => f.write_str("MANAGE VERSIONS")?,
6329            Action::Modify { modify_type } => {
6330                write!(f, "MODIFY")?;
6331                if let Some(modify_type) = modify_type {
6332                    write!(f, " {modify_type}")?;
6333                }
6334            }
6335            Action::Monitor { monitor_type } => {
6336                write!(f, "MONITOR")?;
6337                if let Some(monitor_type) = monitor_type {
6338                    write!(f, " {monitor_type}")?
6339                }
6340            }
6341            Action::Operate => f.write_str("OPERATE")?,
6342            Action::OverrideShareRestrictions => f.write_str("OVERRIDE SHARE RESTRICTIONS")?,
6343            Action::Ownership => f.write_str("OWNERSHIP")?,
6344            Action::PurchaseDataExchangeListing => f.write_str("PURCHASE DATA EXCHANGE LISTING")?,
6345            Action::Read => f.write_str("READ")?,
6346            Action::ReadSession => f.write_str("READ SESSION")?,
6347            Action::References { .. } => f.write_str("REFERENCES")?,
6348            Action::Replicate => f.write_str("REPLICATE")?,
6349            Action::ResolveAll => f.write_str("RESOLVE ALL")?,
6350            Action::Role { role } => write!(f, "ROLE {role}")?,
6351            Action::Select { .. } => f.write_str("SELECT")?,
6352            Action::Temporary => f.write_str("TEMPORARY")?,
6353            Action::Trigger => f.write_str("TRIGGER")?,
6354            Action::Truncate => f.write_str("TRUNCATE")?,
6355            Action::Update { .. } => f.write_str("UPDATE")?,
6356            Action::Usage => f.write_str("USAGE")?,
6357        };
6358        match self {
6359            Action::Insert { columns }
6360            | Action::References { columns }
6361            | Action::Select { columns }
6362            | Action::Update { columns } => {
6363                if let Some(columns) = columns {
6364                    write!(f, " ({})", display_comma_separated(columns))?;
6365                }
6366            }
6367            _ => (),
6368        };
6369        Ok(())
6370    }
6371}
6372
6373#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6374#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6375#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6376/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6377/// under `globalPrivileges` in the `CREATE` privilege.
6378pub enum ActionCreateObjectType {
6379    Account,
6380    Application,
6381    ApplicationPackage,
6382    ComputePool,
6383    DataExchangeListing,
6384    Database,
6385    ExternalVolume,
6386    FailoverGroup,
6387    Integration,
6388    NetworkPolicy,
6389    OrganiationListing,
6390    ReplicationGroup,
6391    Role,
6392    Schema,
6393    Share,
6394    User,
6395    Warehouse,
6396}
6397
6398impl fmt::Display for ActionCreateObjectType {
6399    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6400        match self {
6401            ActionCreateObjectType::Account => write!(f, "ACCOUNT"),
6402            ActionCreateObjectType::Application => write!(f, "APPLICATION"),
6403            ActionCreateObjectType::ApplicationPackage => write!(f, "APPLICATION PACKAGE"),
6404            ActionCreateObjectType::ComputePool => write!(f, "COMPUTE POOL"),
6405            ActionCreateObjectType::DataExchangeListing => write!(f, "DATA EXCHANGE LISTING"),
6406            ActionCreateObjectType::Database => write!(f, "DATABASE"),
6407            ActionCreateObjectType::ExternalVolume => write!(f, "EXTERNAL VOLUME"),
6408            ActionCreateObjectType::FailoverGroup => write!(f, "FAILOVER GROUP"),
6409            ActionCreateObjectType::Integration => write!(f, "INTEGRATION"),
6410            ActionCreateObjectType::NetworkPolicy => write!(f, "NETWORK POLICY"),
6411            ActionCreateObjectType::OrganiationListing => write!(f, "ORGANIZATION LISTING"),
6412            ActionCreateObjectType::ReplicationGroup => write!(f, "REPLICATION GROUP"),
6413            ActionCreateObjectType::Role => write!(f, "ROLE"),
6414            ActionCreateObjectType::Schema => write!(f, "SCHEMA"),
6415            ActionCreateObjectType::Share => write!(f, "SHARE"),
6416            ActionCreateObjectType::User => write!(f, "USER"),
6417            ActionCreateObjectType::Warehouse => write!(f, "WAREHOUSE"),
6418        }
6419    }
6420}
6421
6422#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6423#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6424#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6425/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6426/// under `globalPrivileges` in the `APPLY` privilege.
6427pub enum ActionApplyType {
6428    AggregationPolicy,
6429    AuthenticationPolicy,
6430    JoinPolicy,
6431    MaskingPolicy,
6432    PackagesPolicy,
6433    PasswordPolicy,
6434    ProjectionPolicy,
6435    RowAccessPolicy,
6436    SessionPolicy,
6437    Tag,
6438}
6439
6440impl fmt::Display for ActionApplyType {
6441    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6442        match self {
6443            ActionApplyType::AggregationPolicy => write!(f, "AGGREGATION POLICY"),
6444            ActionApplyType::AuthenticationPolicy => write!(f, "AUTHENTICATION POLICY"),
6445            ActionApplyType::JoinPolicy => write!(f, "JOIN POLICY"),
6446            ActionApplyType::MaskingPolicy => write!(f, "MASKING POLICY"),
6447            ActionApplyType::PackagesPolicy => write!(f, "PACKAGES POLICY"),
6448            ActionApplyType::PasswordPolicy => write!(f, "PASSWORD POLICY"),
6449            ActionApplyType::ProjectionPolicy => write!(f, "PROJECTION POLICY"),
6450            ActionApplyType::RowAccessPolicy => write!(f, "ROW ACCESS POLICY"),
6451            ActionApplyType::SessionPolicy => write!(f, "SESSION POLICY"),
6452            ActionApplyType::Tag => write!(f, "TAG"),
6453        }
6454    }
6455}
6456
6457#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6458#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6459#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6460/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6461/// under `globalPrivileges` in the `EXECUTE` privilege.
6462pub enum ActionExecuteObjectType {
6463    Alert,
6464    DataMetricFunction,
6465    ManagedAlert,
6466    ManagedTask,
6467    Task,
6468}
6469
6470impl fmt::Display for ActionExecuteObjectType {
6471    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6472        match self {
6473            ActionExecuteObjectType::Alert => write!(f, "ALERT"),
6474            ActionExecuteObjectType::DataMetricFunction => write!(f, "DATA METRIC FUNCTION"),
6475            ActionExecuteObjectType::ManagedAlert => write!(f, "MANAGED ALERT"),
6476            ActionExecuteObjectType::ManagedTask => write!(f, "MANAGED TASK"),
6477            ActionExecuteObjectType::Task => write!(f, "TASK"),
6478        }
6479    }
6480}
6481
6482#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6483#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6484#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6485/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6486/// under `globalPrivileges` in the `MANAGE` privilege.
6487pub enum ActionManageType {
6488    AccountSupportCases,
6489    EventSharing,
6490    Grants,
6491    ListingAutoFulfillment,
6492    OrganizationSupportCases,
6493    UserSupportCases,
6494    Warehouses,
6495}
6496
6497impl fmt::Display for ActionManageType {
6498    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6499        match self {
6500            ActionManageType::AccountSupportCases => write!(f, "ACCOUNT SUPPORT CASES"),
6501            ActionManageType::EventSharing => write!(f, "EVENT SHARING"),
6502            ActionManageType::Grants => write!(f, "GRANTS"),
6503            ActionManageType::ListingAutoFulfillment => write!(f, "LISTING AUTO FULFILLMENT"),
6504            ActionManageType::OrganizationSupportCases => write!(f, "ORGANIZATION SUPPORT CASES"),
6505            ActionManageType::UserSupportCases => write!(f, "USER SUPPORT CASES"),
6506            ActionManageType::Warehouses => write!(f, "WAREHOUSES"),
6507        }
6508    }
6509}
6510
6511#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6512#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6513#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6514/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6515/// under `globalPrivileges` in the `MODIFY` privilege.
6516pub enum ActionModifyType {
6517    LogLevel,
6518    TraceLevel,
6519    SessionLogLevel,
6520    SessionTraceLevel,
6521}
6522
6523impl fmt::Display for ActionModifyType {
6524    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6525        match self {
6526            ActionModifyType::LogLevel => write!(f, "LOG LEVEL"),
6527            ActionModifyType::TraceLevel => write!(f, "TRACE LEVEL"),
6528            ActionModifyType::SessionLogLevel => write!(f, "SESSION LOG LEVEL"),
6529            ActionModifyType::SessionTraceLevel => write!(f, "SESSION TRACE LEVEL"),
6530        }
6531    }
6532}
6533
6534#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6535#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6536#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6537/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
6538/// under `globalPrivileges` in the `MONITOR` privilege.
6539pub enum ActionMonitorType {
6540    Execution,
6541    Security,
6542    Usage,
6543}
6544
6545impl fmt::Display for ActionMonitorType {
6546    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6547        match self {
6548            ActionMonitorType::Execution => write!(f, "EXECUTION"),
6549            ActionMonitorType::Security => write!(f, "SECURITY"),
6550            ActionMonitorType::Usage => write!(f, "USAGE"),
6551        }
6552    }
6553}
6554
6555/// The principal that receives the privileges
6556#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6557#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6558#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6559pub struct Grantee {
6560    pub grantee_type: GranteesType,
6561    pub name: Option<GranteeName>,
6562}
6563
6564impl fmt::Display for Grantee {
6565    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6566        match self.grantee_type {
6567            GranteesType::Role => {
6568                write!(f, "ROLE ")?;
6569            }
6570            GranteesType::Share => {
6571                write!(f, "SHARE ")?;
6572            }
6573            GranteesType::User => {
6574                write!(f, "USER ")?;
6575            }
6576            GranteesType::Group => {
6577                write!(f, "GROUP ")?;
6578            }
6579            GranteesType::Public => {
6580                write!(f, "PUBLIC ")?;
6581            }
6582            GranteesType::DatabaseRole => {
6583                write!(f, "DATABASE ROLE ")?;
6584            }
6585            GranteesType::Application => {
6586                write!(f, "APPLICATION ")?;
6587            }
6588            GranteesType::ApplicationRole => {
6589                write!(f, "APPLICATION ROLE ")?;
6590            }
6591            GranteesType::None => (),
6592        }
6593        if let Some(ref name) = self.name {
6594            name.fmt(f)?;
6595        }
6596        Ok(())
6597    }
6598}
6599
6600#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6601#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6602#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6603pub enum GranteesType {
6604    Role,
6605    Share,
6606    User,
6607    Group,
6608    Public,
6609    DatabaseRole,
6610    Application,
6611    ApplicationRole,
6612    None,
6613}
6614
6615/// Users/roles designated in a GRANT/REVOKE
6616#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6617#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6618#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6619pub enum GranteeName {
6620    /// A bare identifier
6621    ObjectName(ObjectName),
6622    /// A MySQL user/host pair such as 'root'@'%'
6623    UserHost { user: Ident, host: Ident },
6624}
6625
6626impl fmt::Display for GranteeName {
6627    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6628        match self {
6629            GranteeName::ObjectName(name) => name.fmt(f),
6630            GranteeName::UserHost { user, host } => {
6631                write!(f, "{user}@{host}")
6632            }
6633        }
6634    }
6635}
6636
6637/// Objects on which privileges are granted in a GRANT statement.
6638#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6639#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6640#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6641pub enum GrantObjects {
6642    /// Grant privileges on `ALL SEQUENCES IN SCHEMA <schema_name> [, ...]`
6643    AllSequencesInSchema { schemas: Vec<ObjectName> },
6644    /// Grant privileges on `ALL TABLES IN SCHEMA <schema_name> [, ...]`
6645    AllTablesInSchema { schemas: Vec<ObjectName> },
6646    /// Grant privileges on `ALL VIEWS IN SCHEMA <schema_name> [, ...]`
6647    AllViewsInSchema { schemas: Vec<ObjectName> },
6648    /// Grant privileges on `ALL MATERIALIZED VIEWS IN SCHEMA <schema_name> [, ...]`
6649    AllMaterializedViewsInSchema { schemas: Vec<ObjectName> },
6650    /// Grant privileges on `ALL EXTERNAL TABLES IN SCHEMA <schema_name> [, ...]`
6651    AllExternalTablesInSchema { schemas: Vec<ObjectName> },
6652    /// Grant privileges on `ALL FUNCTIONS IN SCHEMA <schema_name> [, ...]`
6653    AllFunctionsInSchema { schemas: Vec<ObjectName> },
6654    /// Grant privileges on `FUTURE SCHEMAS IN DATABASE <database_name> [, ...]`
6655    FutureSchemasInDatabase { databases: Vec<ObjectName> },
6656    /// Grant privileges on `FUTURE TABLES IN SCHEMA <schema_name> [, ...]`
6657    FutureTablesInSchema { schemas: Vec<ObjectName> },
6658    /// Grant privileges on `FUTURE VIEWS IN SCHEMA <schema_name> [, ...]`
6659    FutureViewsInSchema { schemas: Vec<ObjectName> },
6660    /// Grant privileges on `FUTURE EXTERNAL TABLES IN SCHEMA <schema_name> [, ...]`
6661    FutureExternalTablesInSchema { schemas: Vec<ObjectName> },
6662    /// Grant privileges on `FUTURE MATERIALIZED VIEWS IN SCHEMA <schema_name> [, ...]`
6663    FutureMaterializedViewsInSchema { schemas: Vec<ObjectName> },
6664    /// Grant privileges on `FUTURE SEQUENCES IN SCHEMA <schema_name> [, ...]`
6665    FutureSequencesInSchema { schemas: Vec<ObjectName> },
6666    /// Grant privileges on specific databases
6667    Databases(Vec<ObjectName>),
6668    /// Grant privileges on specific schemas
6669    Schemas(Vec<ObjectName>),
6670    /// Grant privileges on specific sequences
6671    Sequences(Vec<ObjectName>),
6672    /// Grant privileges on specific tables
6673    Tables(Vec<ObjectName>),
6674    /// Grant privileges on specific views
6675    Views(Vec<ObjectName>),
6676    /// Grant privileges on specific warehouses
6677    Warehouses(Vec<ObjectName>),
6678    /// Grant privileges on specific integrations
6679    Integrations(Vec<ObjectName>),
6680    /// Grant privileges on resource monitors
6681    ResourceMonitors(Vec<ObjectName>),
6682    /// Grant privileges on users
6683    Users(Vec<ObjectName>),
6684    /// Grant privileges on compute pools
6685    ComputePools(Vec<ObjectName>),
6686    /// Grant privileges on connections
6687    Connections(Vec<ObjectName>),
6688    /// Grant privileges on failover groups
6689    FailoverGroup(Vec<ObjectName>),
6690    /// Grant privileges on replication group
6691    ReplicationGroup(Vec<ObjectName>),
6692    /// Grant privileges on external volumes
6693    ExternalVolumes(Vec<ObjectName>),
6694    /// Grant privileges on a procedure. In dialects that
6695    /// support overloading, the argument types must be specified.
6696    ///
6697    /// For example:
6698    /// `GRANT USAGE ON PROCEDURE foo(varchar) TO ROLE role1`
6699    Procedure {
6700        name: ObjectName,
6701        arg_types: Vec<DataType>,
6702    },
6703
6704    /// Grant privileges on a function. In dialects that
6705    /// support overloading, the argument types must be specified.
6706    ///
6707    /// For example:
6708    /// `GRANT USAGE ON FUNCTION foo(varchar) TO ROLE role1`
6709    Function {
6710        name: ObjectName,
6711        arg_types: Vec<DataType>,
6712    },
6713}
6714
6715impl fmt::Display for GrantObjects {
6716    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6717        match self {
6718            GrantObjects::Sequences(sequences) => {
6719                write!(f, "SEQUENCE {}", display_comma_separated(sequences))
6720            }
6721            GrantObjects::Databases(databases) => {
6722                write!(f, "DATABASE {}", display_comma_separated(databases))
6723            }
6724            GrantObjects::Schemas(schemas) => {
6725                write!(f, "SCHEMA {}", display_comma_separated(schemas))
6726            }
6727            GrantObjects::Tables(tables) => {
6728                write!(f, "{}", display_comma_separated(tables))
6729            }
6730            GrantObjects::Views(views) => {
6731                write!(f, "VIEW {}", display_comma_separated(views))
6732            }
6733            GrantObjects::Warehouses(warehouses) => {
6734                write!(f, "WAREHOUSE {}", display_comma_separated(warehouses))
6735            }
6736            GrantObjects::Integrations(integrations) => {
6737                write!(f, "INTEGRATION {}", display_comma_separated(integrations))
6738            }
6739            GrantObjects::AllSequencesInSchema { schemas } => {
6740                write!(
6741                    f,
6742                    "ALL SEQUENCES IN SCHEMA {}",
6743                    display_comma_separated(schemas)
6744                )
6745            }
6746            GrantObjects::AllTablesInSchema { schemas } => {
6747                write!(
6748                    f,
6749                    "ALL TABLES IN SCHEMA {}",
6750                    display_comma_separated(schemas)
6751                )
6752            }
6753            GrantObjects::AllExternalTablesInSchema { schemas } => {
6754                write!(
6755                    f,
6756                    "ALL EXTERNAL TABLES IN SCHEMA {}",
6757                    display_comma_separated(schemas)
6758                )
6759            }
6760            GrantObjects::AllViewsInSchema { schemas } => {
6761                write!(
6762                    f,
6763                    "ALL VIEWS IN SCHEMA {}",
6764                    display_comma_separated(schemas)
6765                )
6766            }
6767            GrantObjects::AllMaterializedViewsInSchema { schemas } => {
6768                write!(
6769                    f,
6770                    "ALL MATERIALIZED VIEWS IN SCHEMA {}",
6771                    display_comma_separated(schemas)
6772                )
6773            }
6774            GrantObjects::AllFunctionsInSchema { schemas } => {
6775                write!(
6776                    f,
6777                    "ALL FUNCTIONS IN SCHEMA {}",
6778                    display_comma_separated(schemas)
6779                )
6780            }
6781            GrantObjects::FutureSchemasInDatabase { databases } => {
6782                write!(
6783                    f,
6784                    "FUTURE SCHEMAS IN DATABASE {}",
6785                    display_comma_separated(databases)
6786                )
6787            }
6788            GrantObjects::FutureTablesInSchema { schemas } => {
6789                write!(
6790                    f,
6791                    "FUTURE TABLES IN SCHEMA {}",
6792                    display_comma_separated(schemas)
6793                )
6794            }
6795            GrantObjects::FutureExternalTablesInSchema { schemas } => {
6796                write!(
6797                    f,
6798                    "FUTURE EXTERNAL TABLES IN SCHEMA {}",
6799                    display_comma_separated(schemas)
6800                )
6801            }
6802            GrantObjects::FutureViewsInSchema { schemas } => {
6803                write!(
6804                    f,
6805                    "FUTURE VIEWS IN SCHEMA {}",
6806                    display_comma_separated(schemas)
6807                )
6808            }
6809            GrantObjects::FutureMaterializedViewsInSchema { schemas } => {
6810                write!(
6811                    f,
6812                    "FUTURE MATERIALIZED VIEWS IN SCHEMA {}",
6813                    display_comma_separated(schemas)
6814                )
6815            }
6816            GrantObjects::FutureSequencesInSchema { schemas } => {
6817                write!(
6818                    f,
6819                    "FUTURE SEQUENCES IN SCHEMA {}",
6820                    display_comma_separated(schemas)
6821                )
6822            }
6823            GrantObjects::ResourceMonitors(objects) => {
6824                write!(f, "RESOURCE MONITOR {}", display_comma_separated(objects))
6825            }
6826            GrantObjects::Users(objects) => {
6827                write!(f, "USER {}", display_comma_separated(objects))
6828            }
6829            GrantObjects::ComputePools(objects) => {
6830                write!(f, "COMPUTE POOL {}", display_comma_separated(objects))
6831            }
6832            GrantObjects::Connections(objects) => {
6833                write!(f, "CONNECTION {}", display_comma_separated(objects))
6834            }
6835            GrantObjects::FailoverGroup(objects) => {
6836                write!(f, "FAILOVER GROUP {}", display_comma_separated(objects))
6837            }
6838            GrantObjects::ReplicationGroup(objects) => {
6839                write!(f, "REPLICATION GROUP {}", display_comma_separated(objects))
6840            }
6841            GrantObjects::ExternalVolumes(objects) => {
6842                write!(f, "EXTERNAL VOLUME {}", display_comma_separated(objects))
6843            }
6844            GrantObjects::Procedure { name, arg_types } => {
6845                write!(f, "PROCEDURE {name}")?;
6846                if !arg_types.is_empty() {
6847                    write!(f, "({})", display_comma_separated(arg_types))?;
6848                }
6849                Ok(())
6850            }
6851            GrantObjects::Function { name, arg_types } => {
6852                write!(f, "FUNCTION {name}")?;
6853                if !arg_types.is_empty() {
6854                    write!(f, "({})", display_comma_separated(arg_types))?;
6855                }
6856                Ok(())
6857            }
6858        }
6859    }
6860}
6861
6862/// A `DENY` statement
6863///
6864/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/deny-transact-sql)
6865#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6866#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6867#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6868pub struct DenyStatement {
6869    pub privileges: Privileges,
6870    pub objects: GrantObjects,
6871    pub grantees: Vec<Grantee>,
6872    pub granted_by: Option<Ident>,
6873    pub cascade: Option<CascadeOption>,
6874}
6875
6876impl fmt::Display for DenyStatement {
6877    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6878        write!(f, "DENY {}", self.privileges)?;
6879        write!(f, " ON {}", self.objects)?;
6880        if !self.grantees.is_empty() {
6881            write!(f, " TO {}", display_comma_separated(&self.grantees))?;
6882        }
6883        if let Some(cascade) = &self.cascade {
6884            write!(f, " {cascade}")?;
6885        }
6886        if let Some(granted_by) = &self.granted_by {
6887            write!(f, " AS {granted_by}")?;
6888        }
6889        Ok(())
6890    }
6891}
6892
6893/// SQL assignment `foo = expr` as used in SQLUpdate
6894#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6895#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6896#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6897pub struct Assignment {
6898    pub target: AssignmentTarget,
6899    pub value: Expr,
6900}
6901
6902impl fmt::Display for Assignment {
6903    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6904        write!(f, "{} = {}", self.target, self.value)
6905    }
6906}
6907
6908/// Left-hand side of an assignment in an UPDATE statement,
6909/// e.g. `foo` in `foo = 5` (ColumnName assignment) or
6910/// `(a, b)` in `(a, b) = (1, 2)` (Tuple assignment).
6911#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6912#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6913#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6914pub enum AssignmentTarget {
6915    /// A single column
6916    ColumnName(ObjectName),
6917    /// A tuple of columns
6918    Tuple(Vec<ObjectName>),
6919}
6920
6921impl fmt::Display for AssignmentTarget {
6922    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6923        match self {
6924            AssignmentTarget::ColumnName(column) => write!(f, "{column}"),
6925            AssignmentTarget::Tuple(columns) => write!(f, "({})", display_comma_separated(columns)),
6926        }
6927    }
6928}
6929
6930#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6931#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6932#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6933pub enum FunctionArgExpr {
6934    Expr(Expr),
6935    /// Qualified wildcard, e.g. `alias.*` or `schema.table.*`.
6936    QualifiedWildcard(ObjectName),
6937    /// An unqualified `*`
6938    Wildcard,
6939}
6940
6941impl From<Expr> for FunctionArgExpr {
6942    fn from(wildcard_expr: Expr) -> Self {
6943        match wildcard_expr {
6944            Expr::QualifiedWildcard(prefix, _) => Self::QualifiedWildcard(prefix),
6945            Expr::Wildcard(_) => Self::Wildcard,
6946            expr => Self::Expr(expr),
6947        }
6948    }
6949}
6950
6951impl fmt::Display for FunctionArgExpr {
6952    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6953        match self {
6954            FunctionArgExpr::Expr(expr) => write!(f, "{expr}"),
6955            FunctionArgExpr::QualifiedWildcard(prefix) => write!(f, "{prefix}.*"),
6956            FunctionArgExpr::Wildcard => f.write_str("*"),
6957        }
6958    }
6959}
6960
6961#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6962#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6963#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6964/// Operator used to separate function arguments
6965pub enum FunctionArgOperator {
6966    /// function(arg1 = value1)
6967    Equals,
6968    /// function(arg1 => value1)
6969    RightArrow,
6970    /// function(arg1 := value1)
6971    Assignment,
6972    /// function(arg1 : value1)
6973    Colon,
6974    /// function(arg1 VALUE value1)
6975    Value,
6976}
6977
6978impl fmt::Display for FunctionArgOperator {
6979    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6980        match self {
6981            FunctionArgOperator::Equals => f.write_str("="),
6982            FunctionArgOperator::RightArrow => f.write_str("=>"),
6983            FunctionArgOperator::Assignment => f.write_str(":="),
6984            FunctionArgOperator::Colon => f.write_str(":"),
6985            FunctionArgOperator::Value => f.write_str("VALUE"),
6986        }
6987    }
6988}
6989
6990#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6991#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6992#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6993pub enum FunctionArg {
6994    /// `name` is identifier
6995    ///
6996    /// Enabled when `Dialect::supports_named_fn_args_with_expr_name` returns 'false'
6997    Named {
6998        name: Ident,
6999        arg: FunctionArgExpr,
7000        operator: FunctionArgOperator,
7001    },
7002    /// `name` is arbitrary expression
7003    ///
7004    /// Enabled when `Dialect::supports_named_fn_args_with_expr_name` returns 'true'
7005    ExprNamed {
7006        name: Expr,
7007        arg: FunctionArgExpr,
7008        operator: FunctionArgOperator,
7009    },
7010    Unnamed(FunctionArgExpr),
7011}
7012
7013impl fmt::Display for FunctionArg {
7014    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7015        match self {
7016            FunctionArg::Named {
7017                name,
7018                arg,
7019                operator,
7020            } => write!(f, "{name} {operator} {arg}"),
7021            FunctionArg::ExprNamed {
7022                name,
7023                arg,
7024                operator,
7025            } => write!(f, "{name} {operator} {arg}"),
7026            FunctionArg::Unnamed(unnamed_arg) => write!(f, "{unnamed_arg}"),
7027        }
7028    }
7029}
7030
7031#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7032#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7033#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7034pub enum CloseCursor {
7035    All,
7036    Specific { name: Ident },
7037}
7038
7039impl fmt::Display for CloseCursor {
7040    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7041        match self {
7042            CloseCursor::All => write!(f, "ALL"),
7043            CloseCursor::Specific { name } => write!(f, "{name}"),
7044        }
7045    }
7046}
7047
7048/// A Drop Domain statement
7049#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7050#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7051#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7052pub struct DropDomain {
7053    /// Whether to drop the domain if it exists
7054    pub if_exists: bool,
7055    /// The name of the domain to drop
7056    pub name: ObjectName,
7057    /// The behavior to apply when dropping the domain
7058    pub drop_behavior: Option<DropBehavior>,
7059}
7060
7061/// A constant of form `<data_type> 'value'`.
7062/// This can represent ANSI SQL `DATE`, `TIME`, and `TIMESTAMP` literals (such as `DATE '2020-01-01'`),
7063/// as well as constants of other types (a non-standard PostgreSQL extension).
7064#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7065#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7066#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7067pub struct TypedString {
7068    pub data_type: DataType,
7069    /// The value of the constant.
7070    /// Hint: you can unwrap the string value using `value.into_string()`.
7071    pub value: ValueWithSpan,
7072    /// Flags whether this TypedString uses the [ODBC syntax].
7073    ///
7074    /// Example:
7075    /// ```sql
7076    /// -- An ODBC date literal:
7077    /// SELECT {d '2025-07-16'}
7078    /// -- This is equivalent to the standard ANSI SQL literal:
7079    /// SELECT DATE '2025-07-16'
7080    ///
7081    /// [ODBC syntax]: https://learn.microsoft.com/en-us/sql/odbc/reference/develop-app/date-time-and-timestamp-literals?view=sql-server-2017
7082    pub uses_odbc_syntax: bool,
7083}
7084
7085impl fmt::Display for TypedString {
7086    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7087        let data_type = &self.data_type;
7088        let value = &self.value;
7089        match self.uses_odbc_syntax {
7090            false => {
7091                write!(f, "{data_type}")?;
7092                write!(f, " {value}")
7093            }
7094            true => {
7095                let prefix = match data_type {
7096                    DataType::Date => "d",
7097                    DataType::Time(..) => "t",
7098                    DataType::Timestamp(..) => "ts",
7099                    _ => "?",
7100                };
7101                write!(f, "{{{prefix} {value}}}")
7102            }
7103        }
7104    }
7105}
7106
7107/// A function call
7108#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7109#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7110#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7111pub struct Function {
7112    pub name: ObjectName,
7113    /// Flags whether this function call uses the [ODBC syntax].
7114    ///
7115    /// Example:
7116    /// ```sql
7117    /// SELECT {fn CONCAT('foo', 'bar')}
7118    /// ```
7119    ///
7120    /// [ODBC syntax]: https://learn.microsoft.com/en-us/sql/odbc/reference/develop-app/scalar-function-calls?view=sql-server-2017
7121    pub uses_odbc_syntax: bool,
7122    /// The parameters to the function, including any options specified within the
7123    /// delimiting parentheses.
7124    ///
7125    /// Example:
7126    /// ```plaintext
7127    /// HISTOGRAM(0.5, 0.6)(x, y)
7128    /// ```
7129    ///
7130    /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/aggregate-functions/parametric-functions)
7131    pub parameters: FunctionArguments,
7132    /// The arguments to the function, including any options specified within the
7133    /// delimiting parentheses.
7134    pub args: FunctionArguments,
7135    /// e.g. `x > 5` in `COUNT(x) FILTER (WHERE x > 5)`
7136    pub filter: Option<Box<Expr>>,
7137    /// Indicates how `NULL`s should be handled in the calculation.
7138    ///
7139    /// Example:
7140    /// ```plaintext
7141    /// FIRST_VALUE( <expr> ) [ { IGNORE | RESPECT } NULLS ] OVER ...
7142    /// ```
7143    ///
7144    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/functions/first_value)
7145    pub null_treatment: Option<NullTreatment>,
7146    /// The `OVER` clause, indicating a window function call.
7147    pub over: Option<WindowType>,
7148    /// A clause used with certain aggregate functions to control the ordering
7149    /// within grouped sets before the function is applied.
7150    ///
7151    /// Syntax:
7152    /// ```plaintext
7153    /// <aggregate_function>(expression) WITHIN GROUP (ORDER BY key [ASC | DESC], ...)
7154    /// ```
7155    pub within_group: Vec<OrderByExpr>,
7156}
7157
7158impl fmt::Display for Function {
7159    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7160        if self.uses_odbc_syntax {
7161            write!(f, "{{fn ")?;
7162        }
7163
7164        write!(f, "{}{}{}", self.name, self.parameters, self.args)?;
7165
7166        if !self.within_group.is_empty() {
7167            write!(
7168                f,
7169                " WITHIN GROUP (ORDER BY {})",
7170                display_comma_separated(&self.within_group)
7171            )?;
7172        }
7173
7174        if let Some(filter_cond) = &self.filter {
7175            write!(f, " FILTER (WHERE {filter_cond})")?;
7176        }
7177
7178        if let Some(null_treatment) = &self.null_treatment {
7179            write!(f, " {null_treatment}")?;
7180        }
7181
7182        if let Some(o) = &self.over {
7183            f.write_str(" OVER ")?;
7184            o.fmt(f)?;
7185        }
7186
7187        if self.uses_odbc_syntax {
7188            write!(f, "}}")?;
7189        }
7190
7191        Ok(())
7192    }
7193}
7194
7195/// The arguments passed to a function call.
7196#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7197#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7198#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7199pub enum FunctionArguments {
7200    /// Used for special functions like `CURRENT_TIMESTAMP` that are invoked
7201    /// without parentheses.
7202    None,
7203    /// On some dialects, a subquery can be passed without surrounding
7204    /// parentheses if it's the sole argument to the function.
7205    Subquery(Box<Query>),
7206    /// A normal function argument list, including any clauses within it such as
7207    /// `DISTINCT` or `ORDER BY`.
7208    List(FunctionArgumentList),
7209}
7210
7211impl fmt::Display for FunctionArguments {
7212    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7213        match self {
7214            FunctionArguments::None => Ok(()),
7215            FunctionArguments::Subquery(query) => write!(f, "({query})"),
7216            FunctionArguments::List(args) => write!(f, "({args})"),
7217        }
7218    }
7219}
7220
7221/// This represents everything inside the parentheses when calling a function.
7222#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7223#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7224#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7225pub struct FunctionArgumentList {
7226    /// `[ ALL | DISTINCT ]`
7227    pub duplicate_treatment: Option<DuplicateTreatment>,
7228    /// The function arguments.
7229    pub args: Vec<FunctionArg>,
7230    /// Additional clauses specified within the argument list.
7231    pub clauses: Vec<FunctionArgumentClause>,
7232}
7233
7234impl fmt::Display for FunctionArgumentList {
7235    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7236        if let Some(duplicate_treatment) = self.duplicate_treatment {
7237            write!(f, "{duplicate_treatment} ")?;
7238        }
7239        write!(f, "{}", display_comma_separated(&self.args))?;
7240        if !self.clauses.is_empty() {
7241            if !self.args.is_empty() {
7242                write!(f, " ")?;
7243            }
7244            write!(f, "{}", display_separated(&self.clauses, " "))?;
7245        }
7246        Ok(())
7247    }
7248}
7249
7250#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7251#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7252#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7253pub enum FunctionArgumentClause {
7254    /// Indicates how `NULL`s should be handled in the calculation, e.g. in `FIRST_VALUE` on [BigQuery].
7255    ///
7256    /// Syntax:
7257    /// ```plaintext
7258    /// { IGNORE | RESPECT } NULLS ]
7259    /// ```
7260    ///
7261    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#first_value
7262    IgnoreOrRespectNulls(NullTreatment),
7263    /// Specifies the the ordering for some ordered set aggregates, e.g. `ARRAY_AGG` on [BigQuery].
7264    ///
7265    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#array_agg
7266    OrderBy(Vec<OrderByExpr>),
7267    /// Specifies a limit for the `ARRAY_AGG` and `ARRAY_CONCAT_AGG` functions on BigQuery.
7268    Limit(Expr),
7269    /// Specifies the behavior on overflow of the `LISTAGG` function.
7270    ///
7271    /// See <https://trino.io/docs/current/functions/aggregate.html>.
7272    OnOverflow(ListAggOnOverflow),
7273    /// Specifies a minimum or maximum bound on the input to [`ANY_VALUE`] on BigQuery.
7274    ///
7275    /// Syntax:
7276    /// ```plaintext
7277    /// HAVING { MAX | MIN } expression
7278    /// ```
7279    ///
7280    /// [`ANY_VALUE`]: https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#any_value
7281    Having(HavingBound),
7282    /// The `SEPARATOR` clause to the [`GROUP_CONCAT`] function in MySQL.
7283    ///
7284    /// [`GROUP_CONCAT`]: https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat
7285    Separator(Value),
7286    /// The `ON NULL` clause for some JSON functions.
7287    ///
7288    /// [MSSQL `JSON_ARRAY`](https://learn.microsoft.com/en-us/sql/t-sql/functions/json-array-transact-sql?view=sql-server-ver16)
7289    /// [MSSQL `JSON_OBJECT`](https://learn.microsoft.com/en-us/sql/t-sql/functions/json-object-transact-sql?view=sql-server-ver16>)
7290    /// [PostgreSQL JSON functions](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSON-PROCESSING)
7291    JsonNullClause(JsonNullClause),
7292    /// The `RETURNING` clause for some JSON functions in PostgreSQL
7293    ///
7294    /// [`JSON_OBJECT`](https://www.postgresql.org/docs/current/functions-json.html#:~:text=json_object)
7295    JsonReturningClause(JsonReturningClause),
7296}
7297
7298impl fmt::Display for FunctionArgumentClause {
7299    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7300        match self {
7301            FunctionArgumentClause::IgnoreOrRespectNulls(null_treatment) => {
7302                write!(f, "{null_treatment}")
7303            }
7304            FunctionArgumentClause::OrderBy(order_by) => {
7305                write!(f, "ORDER BY {}", display_comma_separated(order_by))
7306            }
7307            FunctionArgumentClause::Limit(limit) => write!(f, "LIMIT {limit}"),
7308            FunctionArgumentClause::OnOverflow(on_overflow) => write!(f, "{on_overflow}"),
7309            FunctionArgumentClause::Having(bound) => write!(f, "{bound}"),
7310            FunctionArgumentClause::Separator(sep) => write!(f, "SEPARATOR {sep}"),
7311            FunctionArgumentClause::JsonNullClause(null_clause) => write!(f, "{null_clause}"),
7312            FunctionArgumentClause::JsonReturningClause(returning_clause) => {
7313                write!(f, "{returning_clause}")
7314            }
7315        }
7316    }
7317}
7318
7319/// A method call
7320#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7321#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7322#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7323pub struct Method {
7324    pub expr: Box<Expr>,
7325    // always non-empty
7326    pub method_chain: Vec<Function>,
7327}
7328
7329impl fmt::Display for Method {
7330    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7331        write!(
7332            f,
7333            "{}.{}",
7334            self.expr,
7335            display_separated(&self.method_chain, ".")
7336        )
7337    }
7338}
7339
7340#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7341#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7342#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7343pub enum DuplicateTreatment {
7344    /// Perform the calculation only unique values.
7345    Distinct,
7346    /// Retain all duplicate values (the default).
7347    All,
7348}
7349
7350impl fmt::Display for DuplicateTreatment {
7351    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7352        match self {
7353            DuplicateTreatment::Distinct => write!(f, "DISTINCT"),
7354            DuplicateTreatment::All => write!(f, "ALL"),
7355        }
7356    }
7357}
7358
7359#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7360#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7361#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7362pub enum AnalyzeFormatKind {
7363    /// e.g. `EXPLAIN ANALYZE FORMAT JSON SELECT * FROM tbl`
7364    Keyword(AnalyzeFormat),
7365    /// e.g. `EXPLAIN ANALYZE FORMAT=JSON SELECT * FROM tbl`
7366    Assignment(AnalyzeFormat),
7367}
7368
7369impl fmt::Display for AnalyzeFormatKind {
7370    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7371        match self {
7372            AnalyzeFormatKind::Keyword(format) => write!(f, "FORMAT {format}"),
7373            AnalyzeFormatKind::Assignment(format) => write!(f, "FORMAT={format}"),
7374        }
7375    }
7376}
7377
7378#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7379#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7380#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7381pub enum AnalyzeFormat {
7382    TEXT,
7383    GRAPHVIZ,
7384    JSON,
7385    TRADITIONAL,
7386    TREE,
7387}
7388
7389impl fmt::Display for AnalyzeFormat {
7390    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
7391        f.write_str(match self {
7392            AnalyzeFormat::TEXT => "TEXT",
7393            AnalyzeFormat::GRAPHVIZ => "GRAPHVIZ",
7394            AnalyzeFormat::JSON => "JSON",
7395            AnalyzeFormat::TRADITIONAL => "TRADITIONAL",
7396            AnalyzeFormat::TREE => "TREE",
7397        })
7398    }
7399}
7400
7401/// External table's available file format
7402#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7403#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7404#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7405pub enum FileFormat {
7406    TEXTFILE,
7407    SEQUENCEFILE,
7408    ORC,
7409    PARQUET,
7410    AVRO,
7411    RCFILE,
7412    JSONFILE,
7413}
7414
7415impl fmt::Display for FileFormat {
7416    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7417        use self::FileFormat::*;
7418        f.write_str(match self {
7419            TEXTFILE => "TEXTFILE",
7420            SEQUENCEFILE => "SEQUENCEFILE",
7421            ORC => "ORC",
7422            PARQUET => "PARQUET",
7423            AVRO => "AVRO",
7424            RCFILE => "RCFILE",
7425            JSONFILE => "JSONFILE",
7426        })
7427    }
7428}
7429
7430/// The `ON OVERFLOW` clause of a LISTAGG invocation
7431#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7432#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7433#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7434pub enum ListAggOnOverflow {
7435    /// `ON OVERFLOW ERROR`
7436    Error,
7437
7438    /// `ON OVERFLOW TRUNCATE [ <filler> ] WITH[OUT] COUNT`
7439    Truncate {
7440        filler: Option<Box<Expr>>,
7441        with_count: bool,
7442    },
7443}
7444
7445impl fmt::Display for ListAggOnOverflow {
7446    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7447        write!(f, "ON OVERFLOW")?;
7448        match self {
7449            ListAggOnOverflow::Error => write!(f, " ERROR"),
7450            ListAggOnOverflow::Truncate { filler, with_count } => {
7451                write!(f, " TRUNCATE")?;
7452                if let Some(filler) = filler {
7453                    write!(f, " {filler}")?;
7454                }
7455                if *with_count {
7456                    write!(f, " WITH")?;
7457                } else {
7458                    write!(f, " WITHOUT")?;
7459                }
7460                write!(f, " COUNT")
7461            }
7462        }
7463    }
7464}
7465
7466/// The `HAVING` clause in a call to `ANY_VALUE` on BigQuery.
7467#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7468#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7469#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7470pub struct HavingBound(pub HavingBoundKind, pub Expr);
7471
7472impl fmt::Display for HavingBound {
7473    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7474        write!(f, "HAVING {} {}", self.0, self.1)
7475    }
7476}
7477
7478#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7479#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7480#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7481pub enum HavingBoundKind {
7482    Min,
7483    Max,
7484}
7485
7486impl fmt::Display for HavingBoundKind {
7487    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7488        match self {
7489            HavingBoundKind::Min => write!(f, "MIN"),
7490            HavingBoundKind::Max => write!(f, "MAX"),
7491        }
7492    }
7493}
7494
7495#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7496#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7497#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7498pub enum ObjectType {
7499    Table,
7500    View,
7501    MaterializedView,
7502    Index,
7503    Schema,
7504    Database,
7505    Role,
7506    Sequence,
7507    Stage,
7508    Type,
7509    User,
7510    Stream,
7511}
7512
7513impl fmt::Display for ObjectType {
7514    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7515        f.write_str(match self {
7516            ObjectType::Table => "TABLE",
7517            ObjectType::View => "VIEW",
7518            ObjectType::MaterializedView => "MATERIALIZED VIEW",
7519            ObjectType::Index => "INDEX",
7520            ObjectType::Schema => "SCHEMA",
7521            ObjectType::Database => "DATABASE",
7522            ObjectType::Role => "ROLE",
7523            ObjectType::Sequence => "SEQUENCE",
7524            ObjectType::Stage => "STAGE",
7525            ObjectType::Type => "TYPE",
7526            ObjectType::User => "USER",
7527            ObjectType::Stream => "STREAM",
7528        })
7529    }
7530}
7531
7532#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7533#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7534#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7535pub enum KillType {
7536    Connection,
7537    Query,
7538    Mutation,
7539}
7540
7541impl fmt::Display for KillType {
7542    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7543        f.write_str(match self {
7544            // MySQL
7545            KillType::Connection => "CONNECTION",
7546            KillType::Query => "QUERY",
7547            // Clickhouse supports Mutation
7548            KillType::Mutation => "MUTATION",
7549        })
7550    }
7551}
7552
7553#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7554#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7555#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7556pub enum HiveDistributionStyle {
7557    PARTITIONED {
7558        columns: Vec<ColumnDef>,
7559    },
7560    SKEWED {
7561        columns: Vec<ColumnDef>,
7562        on: Vec<ColumnDef>,
7563        stored_as_directories: bool,
7564    },
7565    NONE,
7566}
7567
7568#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7569#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7570#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7571pub enum HiveRowFormat {
7572    SERDE { class: String },
7573    DELIMITED { delimiters: Vec<HiveRowDelimiter> },
7574}
7575
7576#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7577#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7578#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7579pub struct HiveLoadDataFormat {
7580    pub serde: Expr,
7581    pub input_format: Expr,
7582}
7583
7584#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7585#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7586#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7587pub struct HiveRowDelimiter {
7588    pub delimiter: HiveDelimiter,
7589    pub char: Ident,
7590}
7591
7592impl fmt::Display for HiveRowDelimiter {
7593    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7594        write!(f, "{} ", self.delimiter)?;
7595        write!(f, "{}", self.char)
7596    }
7597}
7598
7599#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7600#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7601#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7602pub enum HiveDelimiter {
7603    FieldsTerminatedBy,
7604    FieldsEscapedBy,
7605    CollectionItemsTerminatedBy,
7606    MapKeysTerminatedBy,
7607    LinesTerminatedBy,
7608    NullDefinedAs,
7609}
7610
7611impl fmt::Display for HiveDelimiter {
7612    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7613        use HiveDelimiter::*;
7614        f.write_str(match self {
7615            FieldsTerminatedBy => "FIELDS TERMINATED BY",
7616            FieldsEscapedBy => "ESCAPED BY",
7617            CollectionItemsTerminatedBy => "COLLECTION ITEMS TERMINATED BY",
7618            MapKeysTerminatedBy => "MAP KEYS TERMINATED BY",
7619            LinesTerminatedBy => "LINES TERMINATED BY",
7620            NullDefinedAs => "NULL DEFINED AS",
7621        })
7622    }
7623}
7624
7625#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7626#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7627#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7628pub enum HiveDescribeFormat {
7629    Extended,
7630    Formatted,
7631}
7632
7633impl fmt::Display for HiveDescribeFormat {
7634    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7635        use HiveDescribeFormat::*;
7636        f.write_str(match self {
7637            Extended => "EXTENDED",
7638            Formatted => "FORMATTED",
7639        })
7640    }
7641}
7642
7643#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7644#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7645#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7646pub enum DescribeAlias {
7647    Describe,
7648    Explain,
7649    Desc,
7650}
7651
7652impl fmt::Display for DescribeAlias {
7653    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7654        use DescribeAlias::*;
7655        f.write_str(match self {
7656            Describe => "DESCRIBE",
7657            Explain => "EXPLAIN",
7658            Desc => "DESC",
7659        })
7660    }
7661}
7662
7663#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7664#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7665#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7666#[allow(clippy::large_enum_variant)]
7667pub enum HiveIOFormat {
7668    IOF {
7669        input_format: Expr,
7670        output_format: Expr,
7671    },
7672    FileFormat {
7673        format: FileFormat,
7674    },
7675}
7676
7677#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
7678#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7679#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7680pub struct HiveFormat {
7681    pub row_format: Option<HiveRowFormat>,
7682    pub serde_properties: Option<Vec<SqlOption>>,
7683    pub storage: Option<HiveIOFormat>,
7684    pub location: Option<String>,
7685}
7686
7687#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7688#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7689#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7690pub struct ClusteredIndex {
7691    pub name: Ident,
7692    pub asc: Option<bool>,
7693}
7694
7695impl fmt::Display for ClusteredIndex {
7696    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7697        write!(f, "{}", self.name)?;
7698        match self.asc {
7699            Some(true) => write!(f, " ASC"),
7700            Some(false) => write!(f, " DESC"),
7701            _ => Ok(()),
7702        }
7703    }
7704}
7705
7706#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7707#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7708#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7709pub enum TableOptionsClustered {
7710    ColumnstoreIndex,
7711    ColumnstoreIndexOrder(Vec<Ident>),
7712    Index(Vec<ClusteredIndex>),
7713}
7714
7715impl fmt::Display for TableOptionsClustered {
7716    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7717        match self {
7718            TableOptionsClustered::ColumnstoreIndex => {
7719                write!(f, "CLUSTERED COLUMNSTORE INDEX")
7720            }
7721            TableOptionsClustered::ColumnstoreIndexOrder(values) => {
7722                write!(
7723                    f,
7724                    "CLUSTERED COLUMNSTORE INDEX ORDER ({})",
7725                    display_comma_separated(values)
7726                )
7727            }
7728            TableOptionsClustered::Index(values) => {
7729                write!(f, "CLUSTERED INDEX ({})", display_comma_separated(values))
7730            }
7731        }
7732    }
7733}
7734
7735/// Specifies which partition the boundary values on table partitioning belongs to.
7736#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7737#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7738#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7739pub enum PartitionRangeDirection {
7740    Left,
7741    Right,
7742}
7743
7744#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7745#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7746#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7747pub enum SqlOption {
7748    /// Clustered represents the clustered version of table storage for MSSQL.
7749    ///
7750    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#TableOptions>
7751    Clustered(TableOptionsClustered),
7752    /// Single identifier options, e.g. `HEAP` for MSSQL.
7753    ///
7754    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#TableOptions>
7755    Ident(Ident),
7756    /// Any option that consists of a key value pair where the value is an expression. e.g.
7757    ///
7758    ///   WITH(DISTRIBUTION = ROUND_ROBIN)
7759    KeyValue { key: Ident, value: Expr },
7760    /// One or more table partitions and represents which partition the boundary values belong to,
7761    /// e.g.
7762    ///
7763    ///   PARTITION (id RANGE LEFT FOR VALUES (10, 20, 30, 40))
7764    ///
7765    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#TablePartitionOptions>
7766    Partition {
7767        column_name: Ident,
7768        range_direction: Option<PartitionRangeDirection>,
7769        for_values: Vec<Expr>,
7770    },
7771    /// Comment parameter (supports `=` and no `=` syntax)
7772    Comment(CommentDef),
7773    /// MySQL TableSpace option
7774    /// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
7775    TableSpace(TablespaceOption),
7776    /// An option representing a key value pair, where the value is a parenthesized list and with an optional name
7777    /// e.g.
7778    ///
7779    ///   UNION  = (tbl_name\[,tbl_name\]...) <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
7780    ///   ENGINE = ReplicatedMergeTree('/table_name','{replica}', ver) <https://clickhouse.com/docs/engines/table-engines/mergetree-family/replication>
7781    ///   ENGINE = SummingMergeTree(\[columns\]) <https://clickhouse.com/docs/engines/table-engines/mergetree-family/summingmergetree>
7782    NamedParenthesizedList(NamedParenthesizedList),
7783}
7784
7785impl fmt::Display for SqlOption {
7786    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7787        match self {
7788            SqlOption::Clustered(c) => write!(f, "{c}"),
7789            SqlOption::Ident(ident) => {
7790                write!(f, "{ident}")
7791            }
7792            SqlOption::KeyValue { key: name, value } => {
7793                write!(f, "{name} = {value}")
7794            }
7795            SqlOption::Partition {
7796                column_name,
7797                range_direction,
7798                for_values,
7799            } => {
7800                let direction = match range_direction {
7801                    Some(PartitionRangeDirection::Left) => " LEFT",
7802                    Some(PartitionRangeDirection::Right) => " RIGHT",
7803                    None => "",
7804                };
7805
7806                write!(
7807                    f,
7808                    "PARTITION ({} RANGE{} FOR VALUES ({}))",
7809                    column_name,
7810                    direction,
7811                    display_comma_separated(for_values)
7812                )
7813            }
7814            SqlOption::TableSpace(tablespace_option) => {
7815                write!(f, "TABLESPACE {}", tablespace_option.name)?;
7816                match tablespace_option.storage {
7817                    Some(StorageType::Disk) => write!(f, " STORAGE DISK"),
7818                    Some(StorageType::Memory) => write!(f, " STORAGE MEMORY"),
7819                    None => Ok(()),
7820                }
7821            }
7822            SqlOption::Comment(comment) => match comment {
7823                CommentDef::WithEq(comment) => {
7824                    write!(f, "COMMENT = '{comment}'")
7825                }
7826                CommentDef::WithoutEq(comment) => {
7827                    write!(f, "COMMENT '{comment}'")
7828                }
7829            },
7830            SqlOption::NamedParenthesizedList(value) => {
7831                write!(f, "{} = ", value.key)?;
7832                if let Some(key) = &value.name {
7833                    write!(f, "{key}")?;
7834                }
7835                if !value.values.is_empty() {
7836                    write!(f, "({})", display_comma_separated(&value.values))?
7837                }
7838                Ok(())
7839            }
7840        }
7841    }
7842}
7843
7844#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
7845#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7846#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7847pub enum StorageType {
7848    Disk,
7849    Memory,
7850}
7851
7852#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
7853#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7854#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7855/// MySql TableSpace option
7856/// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
7857pub struct TablespaceOption {
7858    pub name: String,
7859    pub storage: Option<StorageType>,
7860}
7861
7862#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7863#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7864#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7865pub struct SecretOption {
7866    pub key: Ident,
7867    pub value: Ident,
7868}
7869
7870impl fmt::Display for SecretOption {
7871    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7872        write!(f, "{} {}", self.key, self.value)
7873    }
7874}
7875
7876/// A `CREATE SERVER` statement.
7877///
7878/// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-createserver.html)
7879#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7880#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7881#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7882pub struct CreateServerStatement {
7883    pub name: ObjectName,
7884    pub if_not_exists: bool,
7885    pub server_type: Option<Ident>,
7886    pub version: Option<Ident>,
7887    pub foreign_data_wrapper: ObjectName,
7888    pub options: Option<Vec<CreateServerOption>>,
7889}
7890
7891impl fmt::Display for CreateServerStatement {
7892    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7893        let CreateServerStatement {
7894            name,
7895            if_not_exists,
7896            server_type,
7897            version,
7898            foreign_data_wrapper,
7899            options,
7900        } = self;
7901
7902        write!(
7903            f,
7904            "CREATE SERVER {if_not_exists}{name} ",
7905            if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
7906        )?;
7907
7908        if let Some(st) = server_type {
7909            write!(f, "TYPE {st} ")?;
7910        }
7911
7912        if let Some(v) = version {
7913            write!(f, "VERSION {v} ")?;
7914        }
7915
7916        write!(f, "FOREIGN DATA WRAPPER {foreign_data_wrapper}")?;
7917
7918        if let Some(o) = options {
7919            write!(f, " OPTIONS ({o})", o = display_comma_separated(o))?;
7920        }
7921
7922        Ok(())
7923    }
7924}
7925
7926#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7927#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7928#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7929pub struct CreateServerOption {
7930    pub key: Ident,
7931    pub value: Ident,
7932}
7933
7934impl fmt::Display for CreateServerOption {
7935    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7936        write!(f, "{} {}", self.key, self.value)
7937    }
7938}
7939
7940#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7941#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7942#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7943pub enum AttachDuckDBDatabaseOption {
7944    ReadOnly(Option<bool>),
7945    Type(Ident),
7946}
7947
7948impl fmt::Display for AttachDuckDBDatabaseOption {
7949    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7950        match self {
7951            AttachDuckDBDatabaseOption::ReadOnly(Some(true)) => write!(f, "READ_ONLY true"),
7952            AttachDuckDBDatabaseOption::ReadOnly(Some(false)) => write!(f, "READ_ONLY false"),
7953            AttachDuckDBDatabaseOption::ReadOnly(None) => write!(f, "READ_ONLY"),
7954            AttachDuckDBDatabaseOption::Type(t) => write!(f, "TYPE {t}"),
7955        }
7956    }
7957}
7958
7959#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7960#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7961#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7962pub enum TransactionMode {
7963    AccessMode(TransactionAccessMode),
7964    IsolationLevel(TransactionIsolationLevel),
7965}
7966
7967impl fmt::Display for TransactionMode {
7968    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7969        use TransactionMode::*;
7970        match self {
7971            AccessMode(access_mode) => write!(f, "{access_mode}"),
7972            IsolationLevel(iso_level) => write!(f, "ISOLATION LEVEL {iso_level}"),
7973        }
7974    }
7975}
7976
7977#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7978#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7979#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7980pub enum TransactionAccessMode {
7981    ReadOnly,
7982    ReadWrite,
7983}
7984
7985impl fmt::Display for TransactionAccessMode {
7986    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7987        use TransactionAccessMode::*;
7988        f.write_str(match self {
7989            ReadOnly => "READ ONLY",
7990            ReadWrite => "READ WRITE",
7991        })
7992    }
7993}
7994
7995#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7996#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7997#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7998pub enum TransactionIsolationLevel {
7999    ReadUncommitted,
8000    ReadCommitted,
8001    RepeatableRead,
8002    Serializable,
8003    Snapshot,
8004}
8005
8006impl fmt::Display for TransactionIsolationLevel {
8007    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8008        use TransactionIsolationLevel::*;
8009        f.write_str(match self {
8010            ReadUncommitted => "READ UNCOMMITTED",
8011            ReadCommitted => "READ COMMITTED",
8012            RepeatableRead => "REPEATABLE READ",
8013            Serializable => "SERIALIZABLE",
8014            Snapshot => "SNAPSHOT",
8015        })
8016    }
8017}
8018
8019/// Modifier for the transaction in the `BEGIN` syntax
8020///
8021/// SQLite: <https://sqlite.org/lang_transaction.html>
8022/// MS-SQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql>
8023#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8024#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8025#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8026pub enum TransactionModifier {
8027    Deferred,
8028    Immediate,
8029    Exclusive,
8030    Try,
8031    Catch,
8032}
8033
8034impl fmt::Display for TransactionModifier {
8035    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8036        use TransactionModifier::*;
8037        f.write_str(match self {
8038            Deferred => "DEFERRED",
8039            Immediate => "IMMEDIATE",
8040            Exclusive => "EXCLUSIVE",
8041            Try => "TRY",
8042            Catch => "CATCH",
8043        })
8044    }
8045}
8046
8047#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8048#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8049#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8050pub enum ShowStatementFilter {
8051    Like(String),
8052    ILike(String),
8053    Where(Expr),
8054    NoKeyword(String),
8055}
8056
8057impl fmt::Display for ShowStatementFilter {
8058    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8059        use ShowStatementFilter::*;
8060        match self {
8061            Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
8062            ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
8063            Where(expr) => write!(f, "WHERE {expr}"),
8064            NoKeyword(pattern) => write!(f, "'{}'", value::escape_single_quote_string(pattern)),
8065        }
8066    }
8067}
8068
8069#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8070#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8071#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8072pub enum ShowStatementInClause {
8073    IN,
8074    FROM,
8075}
8076
8077impl fmt::Display for ShowStatementInClause {
8078    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8079        use ShowStatementInClause::*;
8080        match self {
8081            FROM => write!(f, "FROM"),
8082            IN => write!(f, "IN"),
8083        }
8084    }
8085}
8086
8087/// Sqlite specific syntax
8088///
8089/// See [Sqlite documentation](https://sqlite.org/lang_conflict.html)
8090/// for more details.
8091#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8092#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8093#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8094pub enum SqliteOnConflict {
8095    Rollback,
8096    Abort,
8097    Fail,
8098    Ignore,
8099    Replace,
8100}
8101
8102impl fmt::Display for SqliteOnConflict {
8103    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8104        use SqliteOnConflict::*;
8105        match self {
8106            Rollback => write!(f, "OR ROLLBACK"),
8107            Abort => write!(f, "OR ABORT"),
8108            Fail => write!(f, "OR FAIL"),
8109            Ignore => write!(f, "OR IGNORE"),
8110            Replace => write!(f, "OR REPLACE"),
8111        }
8112    }
8113}
8114
8115/// Mysql specific syntax
8116///
8117/// See [Mysql documentation](https://dev.mysql.com/doc/refman/8.0/en/replace.html)
8118/// See [Mysql documentation](https://dev.mysql.com/doc/refman/8.0/en/insert.html)
8119/// for more details.
8120#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8121#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8122#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8123pub enum MysqlInsertPriority {
8124    LowPriority,
8125    Delayed,
8126    HighPriority,
8127}
8128
8129impl fmt::Display for crate::ast::MysqlInsertPriority {
8130    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8131        use MysqlInsertPriority::*;
8132        match self {
8133            LowPriority => write!(f, "LOW_PRIORITY"),
8134            Delayed => write!(f, "DELAYED"),
8135            HighPriority => write!(f, "HIGH_PRIORITY"),
8136        }
8137    }
8138}
8139
8140#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8141#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8142#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8143pub enum CopySource {
8144    Table {
8145        /// The name of the table to copy from.
8146        table_name: ObjectName,
8147        /// A list of column names to copy. Empty list means that all columns
8148        /// are copied.
8149        columns: Vec<Ident>,
8150    },
8151    Query(Box<Query>),
8152}
8153
8154#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8155#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8156#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8157pub enum CopyTarget {
8158    Stdin,
8159    Stdout,
8160    File {
8161        /// The path name of the input or output file.
8162        filename: String,
8163    },
8164    Program {
8165        /// A command to execute
8166        command: String,
8167    },
8168}
8169
8170impl fmt::Display for CopyTarget {
8171    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8172        use CopyTarget::*;
8173        match self {
8174            Stdin => write!(f, "STDIN"),
8175            Stdout => write!(f, "STDOUT"),
8176            File { filename } => write!(f, "'{}'", value::escape_single_quote_string(filename)),
8177            Program { command } => write!(
8178                f,
8179                "PROGRAM '{}'",
8180                value::escape_single_quote_string(command)
8181            ),
8182        }
8183    }
8184}
8185
8186#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8187#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8188#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8189pub enum OnCommit {
8190    DeleteRows,
8191    PreserveRows,
8192    Drop,
8193}
8194
8195/// An option in `COPY` statement.
8196///
8197/// <https://www.postgresql.org/docs/14/sql-copy.html>
8198#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8199#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8200#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8201pub enum CopyOption {
8202    /// FORMAT format_name
8203    Format(Ident),
8204    /// FREEZE \[ boolean \]
8205    Freeze(bool),
8206    /// DELIMITER 'delimiter_character'
8207    Delimiter(char),
8208    /// NULL 'null_string'
8209    Null(String),
8210    /// HEADER \[ boolean \]
8211    Header(bool),
8212    /// QUOTE 'quote_character'
8213    Quote(char),
8214    /// ESCAPE 'escape_character'
8215    Escape(char),
8216    /// FORCE_QUOTE { ( column_name [, ...] ) | * }
8217    ForceQuote(Vec<Ident>),
8218    /// FORCE_NOT_NULL ( column_name [, ...] )
8219    ForceNotNull(Vec<Ident>),
8220    /// FORCE_NULL ( column_name [, ...] )
8221    ForceNull(Vec<Ident>),
8222    /// ENCODING 'encoding_name'
8223    Encoding(String),
8224}
8225
8226impl fmt::Display for CopyOption {
8227    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8228        use CopyOption::*;
8229        match self {
8230            Format(name) => write!(f, "FORMAT {name}"),
8231            Freeze(true) => write!(f, "FREEZE"),
8232            Freeze(false) => write!(f, "FREEZE FALSE"),
8233            Delimiter(char) => write!(f, "DELIMITER '{char}'"),
8234            Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
8235            Header(true) => write!(f, "HEADER"),
8236            Header(false) => write!(f, "HEADER FALSE"),
8237            Quote(char) => write!(f, "QUOTE '{char}'"),
8238            Escape(char) => write!(f, "ESCAPE '{char}'"),
8239            ForceQuote(columns) => write!(f, "FORCE_QUOTE ({})", display_comma_separated(columns)),
8240            ForceNotNull(columns) => {
8241                write!(f, "FORCE_NOT_NULL ({})", display_comma_separated(columns))
8242            }
8243            ForceNull(columns) => write!(f, "FORCE_NULL ({})", display_comma_separated(columns)),
8244            Encoding(name) => write!(f, "ENCODING '{}'", value::escape_single_quote_string(name)),
8245        }
8246    }
8247}
8248
8249/// An option in `COPY` statement before PostgreSQL version 9.0.
8250///
8251/// [PostgreSQL](https://www.postgresql.org/docs/8.4/sql-copy.html)
8252/// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_COPY-alphabetical-parm-list.html)
8253#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8254#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8255#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8256pub enum CopyLegacyOption {
8257    /// ACCEPTANYDATE
8258    AcceptAnyDate,
8259    /// ACCEPTINVCHARS
8260    AcceptInvChars(Option<String>),
8261    /// ADDQUOTES
8262    AddQuotes,
8263    /// ALLOWOVERWRITE
8264    AllowOverwrite,
8265    /// BINARY
8266    Binary,
8267    /// BLANKSASNULL
8268    BlankAsNull,
8269    /// BZIP2
8270    Bzip2,
8271    /// CLEANPATH
8272    CleanPath,
8273    /// COMPUPDATE [ PRESET | { ON | TRUE } | { OFF | FALSE } ]
8274    CompUpdate { preset: bool, enabled: Option<bool> },
8275    /// CSV ...
8276    Csv(Vec<CopyLegacyCsvOption>),
8277    /// DATEFORMAT \[ AS \] {'dateformat_string' | 'auto' }
8278    DateFormat(Option<String>),
8279    /// DELIMITER \[ AS \] 'delimiter_character'
8280    Delimiter(char),
8281    /// EMPTYASNULL
8282    EmptyAsNull,
8283    /// ENCRYPTED \[ AUTO \]
8284    Encrypted { auto: bool },
8285    /// ESCAPE
8286    Escape,
8287    /// EXTENSION 'extension-name'
8288    Extension(String),
8289    /// FIXEDWIDTH \[ AS \] 'fixedwidth-spec'
8290    FixedWidth(String),
8291    /// GZIP
8292    Gzip,
8293    /// HEADER
8294    Header,
8295    /// IAM_ROLE { DEFAULT | 'arn:aws:iam::123456789:role/role1' }
8296    IamRole(IamRoleKind),
8297    /// IGNOREHEADER \[ AS \] number_rows
8298    IgnoreHeader(u64),
8299    /// JSON
8300    Json,
8301    /// MANIFEST \[ VERBOSE \]
8302    Manifest { verbose: bool },
8303    /// MAXFILESIZE \[ AS \] max-size \[ MB | GB \]
8304    MaxFileSize(FileSize),
8305    /// NULL \[ AS \] 'null_string'
8306    Null(String),
8307    /// PARALLEL [ { ON | TRUE } | { OFF | FALSE } ]
8308    Parallel(Option<bool>),
8309    /// PARQUET
8310    Parquet,
8311    /// PARTITION BY ( column_name [, ... ] ) \[ INCLUDE \]
8312    PartitionBy(UnloadPartitionBy),
8313    /// REGION \[ AS \] 'aws-region' }
8314    Region(String),
8315    /// REMOVEQUOTES
8316    RemoveQuotes,
8317    /// ROWGROUPSIZE \[ AS \] size \[ MB | GB \]
8318    RowGroupSize(FileSize),
8319    /// STATUPDATE [ { ON | TRUE } | { OFF | FALSE } ]
8320    StatUpdate(Option<bool>),
8321    /// TIMEFORMAT \[ AS \] {'timeformat_string' | 'auto' | 'epochsecs' | 'epochmillisecs' }
8322    TimeFormat(Option<String>),
8323    /// TRUNCATECOLUMNS
8324    TruncateColumns,
8325    /// ZSTD
8326    Zstd,
8327}
8328
8329impl fmt::Display for CopyLegacyOption {
8330    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8331        use CopyLegacyOption::*;
8332        match self {
8333            AcceptAnyDate => write!(f, "ACCEPTANYDATE"),
8334            AcceptInvChars(ch) => {
8335                write!(f, "ACCEPTINVCHARS")?;
8336                if let Some(ch) = ch {
8337                    write!(f, " '{}'", value::escape_single_quote_string(ch))?;
8338                }
8339                Ok(())
8340            }
8341            AddQuotes => write!(f, "ADDQUOTES"),
8342            AllowOverwrite => write!(f, "ALLOWOVERWRITE"),
8343            Binary => write!(f, "BINARY"),
8344            BlankAsNull => write!(f, "BLANKSASNULL"),
8345            Bzip2 => write!(f, "BZIP2"),
8346            CleanPath => write!(f, "CLEANPATH"),
8347            CompUpdate { preset, enabled } => {
8348                write!(f, "COMPUPDATE")?;
8349                if *preset {
8350                    write!(f, " PRESET")?;
8351                } else if let Some(enabled) = enabled {
8352                    write!(
8353                        f,
8354                        "{}",
8355                        match enabled {
8356                            true => " TRUE",
8357                            false => " FALSE",
8358                        }
8359                    )?;
8360                }
8361                Ok(())
8362            }
8363            Csv(opts) => {
8364                write!(f, "CSV")?;
8365                if !opts.is_empty() {
8366                    write!(f, " {}", display_separated(opts, " "))?;
8367                }
8368                Ok(())
8369            }
8370            DateFormat(fmt) => {
8371                write!(f, "DATEFORMAT")?;
8372                if let Some(fmt) = fmt {
8373                    write!(f, " '{}'", value::escape_single_quote_string(fmt))?;
8374                }
8375                Ok(())
8376            }
8377            Delimiter(char) => write!(f, "DELIMITER '{char}'"),
8378            EmptyAsNull => write!(f, "EMPTYASNULL"),
8379            Encrypted { auto } => write!(f, "ENCRYPTED{}", if *auto { " AUTO" } else { "" }),
8380            Escape => write!(f, "ESCAPE"),
8381            Extension(ext) => write!(f, "EXTENSION '{}'", value::escape_single_quote_string(ext)),
8382            FixedWidth(spec) => write!(
8383                f,
8384                "FIXEDWIDTH '{}'",
8385                value::escape_single_quote_string(spec)
8386            ),
8387            Gzip => write!(f, "GZIP"),
8388            Header => write!(f, "HEADER"),
8389            IamRole(role) => write!(f, "IAM_ROLE {role}"),
8390            IgnoreHeader(num_rows) => write!(f, "IGNOREHEADER {num_rows}"),
8391            Json => write!(f, "JSON"),
8392            Manifest { verbose } => write!(f, "MANIFEST{}", if *verbose { " VERBOSE" } else { "" }),
8393            MaxFileSize(file_size) => write!(f, "MAXFILESIZE {file_size}"),
8394            Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
8395            Parallel(enabled) => {
8396                write!(
8397                    f,
8398                    "PARALLEL{}",
8399                    match enabled {
8400                        Some(true) => " TRUE",
8401                        Some(false) => " FALSE",
8402                        _ => "",
8403                    }
8404                )
8405            }
8406            Parquet => write!(f, "PARQUET"),
8407            PartitionBy(p) => write!(f, "{p}"),
8408            Region(region) => write!(f, "REGION '{}'", value::escape_single_quote_string(region)),
8409            RemoveQuotes => write!(f, "REMOVEQUOTES"),
8410            RowGroupSize(file_size) => write!(f, "ROWGROUPSIZE {file_size}"),
8411            StatUpdate(enabled) => {
8412                write!(
8413                    f,
8414                    "STATUPDATE{}",
8415                    match enabled {
8416                        Some(true) => " TRUE",
8417                        Some(false) => " FALSE",
8418                        _ => "",
8419                    }
8420                )
8421            }
8422            TimeFormat(fmt) => {
8423                write!(f, "TIMEFORMAT")?;
8424                if let Some(fmt) = fmt {
8425                    write!(f, " '{}'", value::escape_single_quote_string(fmt))?;
8426                }
8427                Ok(())
8428            }
8429            TruncateColumns => write!(f, "TRUNCATECOLUMNS"),
8430            Zstd => write!(f, "ZSTD"),
8431        }
8432    }
8433}
8434
8435/// ```sql
8436/// SIZE \[ MB | GB \]
8437/// ```
8438#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8439#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8440#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8441pub struct FileSize {
8442    pub size: Value,
8443    pub unit: Option<FileSizeUnit>,
8444}
8445
8446impl fmt::Display for FileSize {
8447    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8448        write!(f, "{}", self.size)?;
8449        if let Some(unit) = &self.unit {
8450            write!(f, " {unit}")?;
8451        }
8452        Ok(())
8453    }
8454}
8455
8456#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8457#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8458#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8459pub enum FileSizeUnit {
8460    MB,
8461    GB,
8462}
8463
8464impl fmt::Display for FileSizeUnit {
8465    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8466        match self {
8467            FileSizeUnit::MB => write!(f, "MB"),
8468            FileSizeUnit::GB => write!(f, "GB"),
8469        }
8470    }
8471}
8472
8473/// Specifies the partition keys for the unload operation
8474///
8475/// ```sql
8476/// PARTITION BY ( column_name [, ... ] ) [ INCLUDE ]
8477/// ```
8478#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8479#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8480#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8481pub struct UnloadPartitionBy {
8482    pub columns: Vec<Ident>,
8483    pub include: bool,
8484}
8485
8486impl fmt::Display for UnloadPartitionBy {
8487    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8488        write!(
8489            f,
8490            "PARTITION BY ({}){}",
8491            display_comma_separated(&self.columns),
8492            if self.include { " INCLUDE" } else { "" }
8493        )
8494    }
8495}
8496
8497/// An `IAM_ROLE` option in the AWS ecosystem
8498///
8499/// [Redshift COPY](https://docs.aws.amazon.com/redshift/latest/dg/copy-parameters-authorization.html#copy-iam-role)
8500#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8501#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8502#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8503pub enum IamRoleKind {
8504    /// Default role
8505    Default,
8506    /// Specific role ARN, for example: `arn:aws:iam::123456789:role/role1`
8507    Arn(String),
8508}
8509
8510impl fmt::Display for IamRoleKind {
8511    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8512        match self {
8513            IamRoleKind::Default => write!(f, "DEFAULT"),
8514            IamRoleKind::Arn(arn) => write!(f, "'{arn}'"),
8515        }
8516    }
8517}
8518
8519/// A `CSV` option in `COPY` statement before PostgreSQL version 9.0.
8520///
8521/// <https://www.postgresql.org/docs/8.4/sql-copy.html>
8522#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8523#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8524#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8525pub enum CopyLegacyCsvOption {
8526    /// HEADER
8527    Header,
8528    /// QUOTE \[ AS \] 'quote_character'
8529    Quote(char),
8530    /// ESCAPE \[ AS \] 'escape_character'
8531    Escape(char),
8532    /// FORCE QUOTE { column_name [, ...] | * }
8533    ForceQuote(Vec<Ident>),
8534    /// FORCE NOT NULL column_name [, ...]
8535    ForceNotNull(Vec<Ident>),
8536}
8537
8538impl fmt::Display for CopyLegacyCsvOption {
8539    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8540        use CopyLegacyCsvOption::*;
8541        match self {
8542            Header => write!(f, "HEADER"),
8543            Quote(char) => write!(f, "QUOTE '{char}'"),
8544            Escape(char) => write!(f, "ESCAPE '{char}'"),
8545            ForceQuote(columns) => write!(f, "FORCE QUOTE {}", display_comma_separated(columns)),
8546            ForceNotNull(columns) => {
8547                write!(f, "FORCE NOT NULL {}", display_comma_separated(columns))
8548            }
8549        }
8550    }
8551}
8552
8553#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8554#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8555#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8556pub enum DiscardObject {
8557    ALL,
8558    PLANS,
8559    SEQUENCES,
8560    TEMP,
8561}
8562
8563impl fmt::Display for DiscardObject {
8564    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8565        match self {
8566            DiscardObject::ALL => f.write_str("ALL"),
8567            DiscardObject::PLANS => f.write_str("PLANS"),
8568            DiscardObject::SEQUENCES => f.write_str("SEQUENCES"),
8569            DiscardObject::TEMP => f.write_str("TEMP"),
8570        }
8571    }
8572}
8573
8574#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8575#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8576#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8577pub enum FlushType {
8578    BinaryLogs,
8579    EngineLogs,
8580    ErrorLogs,
8581    GeneralLogs,
8582    Hosts,
8583    Logs,
8584    Privileges,
8585    OptimizerCosts,
8586    RelayLogs,
8587    SlowLogs,
8588    Status,
8589    UserResources,
8590    Tables,
8591}
8592
8593impl fmt::Display for FlushType {
8594    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8595        match self {
8596            FlushType::BinaryLogs => f.write_str("BINARY LOGS"),
8597            FlushType::EngineLogs => f.write_str("ENGINE LOGS"),
8598            FlushType::ErrorLogs => f.write_str("ERROR LOGS"),
8599            FlushType::GeneralLogs => f.write_str("GENERAL LOGS"),
8600            FlushType::Hosts => f.write_str("HOSTS"),
8601            FlushType::Logs => f.write_str("LOGS"),
8602            FlushType::Privileges => f.write_str("PRIVILEGES"),
8603            FlushType::OptimizerCosts => f.write_str("OPTIMIZER_COSTS"),
8604            FlushType::RelayLogs => f.write_str("RELAY LOGS"),
8605            FlushType::SlowLogs => f.write_str("SLOW LOGS"),
8606            FlushType::Status => f.write_str("STATUS"),
8607            FlushType::UserResources => f.write_str("USER_RESOURCES"),
8608            FlushType::Tables => f.write_str("TABLES"),
8609        }
8610    }
8611}
8612
8613#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8614#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8615#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8616pub enum FlushLocation {
8617    NoWriteToBinlog,
8618    Local,
8619}
8620
8621impl fmt::Display for FlushLocation {
8622    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8623        match self {
8624            FlushLocation::NoWriteToBinlog => f.write_str("NO_WRITE_TO_BINLOG"),
8625            FlushLocation::Local => f.write_str("LOCAL"),
8626        }
8627    }
8628}
8629
8630/// Optional context modifier for statements that can be or `LOCAL`, `GLOBAL`, or `SESSION`.
8631#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8632#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8633#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8634pub enum ContextModifier {
8635    /// `LOCAL` identifier, usually related to transactional states.
8636    Local,
8637    /// `SESSION` identifier
8638    Session,
8639    /// `GLOBAL` identifier
8640    Global,
8641}
8642
8643impl fmt::Display for ContextModifier {
8644    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8645        match self {
8646            Self::Local => {
8647                write!(f, "LOCAL ")
8648            }
8649            Self::Session => {
8650                write!(f, "SESSION ")
8651            }
8652            Self::Global => {
8653                write!(f, "GLOBAL ")
8654            }
8655        }
8656    }
8657}
8658
8659/// Function describe in DROP FUNCTION.
8660#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8661#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8662pub enum DropFunctionOption {
8663    Restrict,
8664    Cascade,
8665}
8666
8667impl fmt::Display for DropFunctionOption {
8668    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8669        match self {
8670            DropFunctionOption::Restrict => write!(f, "RESTRICT "),
8671            DropFunctionOption::Cascade => write!(f, "CASCADE  "),
8672        }
8673    }
8674}
8675
8676/// Generic function description for DROP FUNCTION and CREATE TRIGGER.
8677#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8678#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8679#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8680pub struct FunctionDesc {
8681    pub name: ObjectName,
8682    pub args: Option<Vec<OperateFunctionArg>>,
8683}
8684
8685impl fmt::Display for FunctionDesc {
8686    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8687        write!(f, "{}", self.name)?;
8688        if let Some(args) = &self.args {
8689            write!(f, "({})", display_comma_separated(args))?;
8690        }
8691        Ok(())
8692    }
8693}
8694
8695/// Function argument in CREATE OR DROP FUNCTION.
8696#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8697#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8698#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8699pub struct OperateFunctionArg {
8700    pub mode: Option<ArgMode>,
8701    pub name: Option<Ident>,
8702    pub data_type: DataType,
8703    pub default_expr: Option<Expr>,
8704}
8705
8706impl OperateFunctionArg {
8707    /// Returns an unnamed argument.
8708    pub fn unnamed(data_type: DataType) -> Self {
8709        Self {
8710            mode: None,
8711            name: None,
8712            data_type,
8713            default_expr: None,
8714        }
8715    }
8716
8717    /// Returns an argument with name.
8718    pub fn with_name(name: &str, data_type: DataType) -> Self {
8719        Self {
8720            mode: None,
8721            name: Some(name.into()),
8722            data_type,
8723            default_expr: None,
8724        }
8725    }
8726}
8727
8728impl fmt::Display for OperateFunctionArg {
8729    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8730        if let Some(mode) = &self.mode {
8731            write!(f, "{mode} ")?;
8732        }
8733        if let Some(name) = &self.name {
8734            write!(f, "{name} ")?;
8735        }
8736        write!(f, "{}", self.data_type)?;
8737        if let Some(default_expr) = &self.default_expr {
8738            write!(f, " = {default_expr}")?;
8739        }
8740        Ok(())
8741    }
8742}
8743
8744/// The mode of an argument in CREATE FUNCTION.
8745#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8746#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8747#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8748pub enum ArgMode {
8749    In,
8750    Out,
8751    InOut,
8752}
8753
8754impl fmt::Display for ArgMode {
8755    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8756        match self {
8757            ArgMode::In => write!(f, "IN"),
8758            ArgMode::Out => write!(f, "OUT"),
8759            ArgMode::InOut => write!(f, "INOUT"),
8760        }
8761    }
8762}
8763
8764/// These attributes inform the query optimizer about the behavior of the function.
8765#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8766#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8767#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8768pub enum FunctionBehavior {
8769    Immutable,
8770    Stable,
8771    Volatile,
8772}
8773
8774impl fmt::Display for FunctionBehavior {
8775    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8776        match self {
8777            FunctionBehavior::Immutable => write!(f, "IMMUTABLE"),
8778            FunctionBehavior::Stable => write!(f, "STABLE"),
8779            FunctionBehavior::Volatile => write!(f, "VOLATILE"),
8780        }
8781    }
8782}
8783
8784/// Security attribute for functions: SECURITY DEFINER or SECURITY INVOKER.
8785///
8786/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
8787#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8788#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8789#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8790pub enum FunctionSecurity {
8791    Definer,
8792    Invoker,
8793}
8794
8795impl fmt::Display for FunctionSecurity {
8796    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8797        match self {
8798            FunctionSecurity::Definer => write!(f, "SECURITY DEFINER"),
8799            FunctionSecurity::Invoker => write!(f, "SECURITY INVOKER"),
8800        }
8801    }
8802}
8803
8804/// Value for a SET configuration parameter in a CREATE FUNCTION statement.
8805///
8806/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
8807#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8808#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8809#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8810pub enum FunctionSetValue {
8811    /// SET param = value1, value2, ...
8812    Values(Vec<Expr>),
8813    /// SET param FROM CURRENT
8814    FromCurrent,
8815}
8816
8817/// A SET configuration_parameter clause in a CREATE FUNCTION statement.
8818///
8819/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
8820#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8821#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8822#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8823pub struct FunctionDefinitionSetParam {
8824    pub name: Ident,
8825    pub value: FunctionSetValue,
8826}
8827
8828impl fmt::Display for FunctionDefinitionSetParam {
8829    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8830        write!(f, "SET {} ", self.name)?;
8831        match &self.value {
8832            FunctionSetValue::Values(values) => {
8833                write!(f, "= {}", display_comma_separated(values))
8834            }
8835            FunctionSetValue::FromCurrent => write!(f, "FROM CURRENT"),
8836        }
8837    }
8838}
8839
8840/// These attributes describe the behavior of the function when called with a null argument.
8841#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8842#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8843#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8844pub enum FunctionCalledOnNull {
8845    CalledOnNullInput,
8846    ReturnsNullOnNullInput,
8847    Strict,
8848}
8849
8850impl fmt::Display for FunctionCalledOnNull {
8851    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8852        match self {
8853            FunctionCalledOnNull::CalledOnNullInput => write!(f, "CALLED ON NULL INPUT"),
8854            FunctionCalledOnNull::ReturnsNullOnNullInput => write!(f, "RETURNS NULL ON NULL INPUT"),
8855            FunctionCalledOnNull::Strict => write!(f, "STRICT"),
8856        }
8857    }
8858}
8859
8860/// If it is safe for PostgreSQL to call the function from multiple threads at once
8861#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8862#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8863#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8864pub enum FunctionParallel {
8865    Unsafe,
8866    Restricted,
8867    Safe,
8868}
8869
8870impl fmt::Display for FunctionParallel {
8871    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8872        match self {
8873            FunctionParallel::Unsafe => write!(f, "PARALLEL UNSAFE"),
8874            FunctionParallel::Restricted => write!(f, "PARALLEL RESTRICTED"),
8875            FunctionParallel::Safe => write!(f, "PARALLEL SAFE"),
8876        }
8877    }
8878}
8879
8880/// [BigQuery] Determinism specifier used in a UDF definition.
8881///
8882/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
8883#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8884#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8885#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8886pub enum FunctionDeterminismSpecifier {
8887    Deterministic,
8888    NotDeterministic,
8889}
8890
8891impl fmt::Display for FunctionDeterminismSpecifier {
8892    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8893        match self {
8894            FunctionDeterminismSpecifier::Deterministic => {
8895                write!(f, "DETERMINISTIC")
8896            }
8897            FunctionDeterminismSpecifier::NotDeterministic => {
8898                write!(f, "NOT DETERMINISTIC")
8899            }
8900        }
8901    }
8902}
8903
8904/// Represent the expression body of a `CREATE FUNCTION` statement as well as
8905/// where within the statement, the body shows up.
8906///
8907/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
8908/// [PostgreSQL]: https://www.postgresql.org/docs/15/sql-createfunction.html
8909/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
8910#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8911#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8912#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8913pub enum CreateFunctionBody {
8914    /// A function body expression using the 'AS' keyword and shows up
8915    /// before any `OPTIONS` clause.
8916    ///
8917    /// Example:
8918    /// ```sql
8919    /// CREATE FUNCTION myfunc(x FLOAT64, y FLOAT64) RETURNS FLOAT64
8920    /// AS (x * y)
8921    /// OPTIONS(description="desc");
8922    /// ```
8923    ///
8924    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
8925    /// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
8926    AsBeforeOptions {
8927        /// The primary expression.
8928        body: Expr,
8929        /// Link symbol if the primary expression contains the name of shared library file.
8930        ///
8931        /// Example:
8932        /// ```sql
8933        /// CREATE FUNCTION cas_in(input cstring) RETURNS cas
8934        /// AS 'MODULE_PATHNAME', 'cas_in_wrapper'
8935        /// ```
8936        /// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
8937        link_symbol: Option<Expr>,
8938    },
8939    /// A function body expression using the 'AS' keyword and shows up
8940    /// after any `OPTIONS` clause.
8941    ///
8942    /// Example:
8943    /// ```sql
8944    /// CREATE FUNCTION myfunc(x FLOAT64, y FLOAT64) RETURNS FLOAT64
8945    /// OPTIONS(description="desc")
8946    /// AS (x * y);
8947    /// ```
8948    ///
8949    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
8950    AsAfterOptions(Expr),
8951    /// Function body with statements before the `RETURN` keyword.
8952    ///
8953    /// Example:
8954    /// ```sql
8955    /// CREATE FUNCTION my_scalar_udf(a INT, b INT)
8956    /// RETURNS INT
8957    /// AS
8958    /// BEGIN
8959    ///     DECLARE c INT;
8960    ///     SET c = a + b;
8961    ///     RETURN c;
8962    /// END
8963    /// ```
8964    ///
8965    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
8966    AsBeginEnd(BeginEndStatements),
8967    /// Function body expression using the 'RETURN' keyword.
8968    ///
8969    /// Example:
8970    /// ```sql
8971    /// CREATE FUNCTION myfunc(a INTEGER, IN b INTEGER = 1) RETURNS INTEGER
8972    /// LANGUAGE SQL
8973    /// RETURN a + b;
8974    /// ```
8975    ///
8976    /// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
8977    Return(Expr),
8978
8979    /// Function body expression using the 'AS RETURN' keywords
8980    ///
8981    /// Example:
8982    /// ```sql
8983    /// CREATE FUNCTION myfunc(a INT, b INT)
8984    /// RETURNS TABLE
8985    /// AS RETURN (SELECT a + b AS sum);
8986    /// ```
8987    ///
8988    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
8989    AsReturnExpr(Expr),
8990
8991    /// Function body expression using the 'AS RETURN' keywords, with an un-parenthesized SELECT query
8992    ///
8993    /// Example:
8994    /// ```sql
8995    /// CREATE FUNCTION myfunc(a INT, b INT)
8996    /// RETURNS TABLE
8997    /// AS RETURN SELECT a + b AS sum;
8998    /// ```
8999    ///
9000    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql?view=sql-server-ver16#select_stmt
9001    AsReturnSelect(Select),
9002}
9003
9004#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9005#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9006#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9007pub enum CreateFunctionUsing {
9008    Jar(String),
9009    File(String),
9010    Archive(String),
9011}
9012
9013impl fmt::Display for CreateFunctionUsing {
9014    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9015        write!(f, "USING ")?;
9016        match self {
9017            CreateFunctionUsing::Jar(uri) => write!(f, "JAR '{uri}'"),
9018            CreateFunctionUsing::File(uri) => write!(f, "FILE '{uri}'"),
9019            CreateFunctionUsing::Archive(uri) => write!(f, "ARCHIVE '{uri}'"),
9020        }
9021    }
9022}
9023
9024/// `NAME = <EXPR>` arguments for DuckDB macros
9025///
9026/// See [Create Macro - DuckDB](https://duckdb.org/docs/sql/statements/create_macro)
9027/// for more details
9028#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9029#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9030#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9031pub struct MacroArg {
9032    pub name: Ident,
9033    pub default_expr: Option<Expr>,
9034}
9035
9036impl MacroArg {
9037    /// Returns an argument with name.
9038    pub fn new(name: &str) -> Self {
9039        Self {
9040            name: name.into(),
9041            default_expr: None,
9042        }
9043    }
9044}
9045
9046impl fmt::Display for MacroArg {
9047    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9048        write!(f, "{}", self.name)?;
9049        if let Some(default_expr) = &self.default_expr {
9050            write!(f, " := {default_expr}")?;
9051        }
9052        Ok(())
9053    }
9054}
9055
9056#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9057#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9058#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9059pub enum MacroDefinition {
9060    Expr(Expr),
9061    Table(Box<Query>),
9062}
9063
9064impl fmt::Display for MacroDefinition {
9065    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9066        match self {
9067            MacroDefinition::Expr(expr) => write!(f, "{expr}")?,
9068            MacroDefinition::Table(query) => write!(f, "{query}")?,
9069        }
9070        Ok(())
9071    }
9072}
9073
9074/// Schema possible naming variants ([1]).
9075///
9076/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#schema-definition
9077#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9078#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9079#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9080pub enum SchemaName {
9081    /// Only schema name specified: `<schema name>`.
9082    Simple(ObjectName),
9083    /// Only authorization identifier specified: `AUTHORIZATION <schema authorization identifier>`.
9084    UnnamedAuthorization(Ident),
9085    /// Both schema name and authorization identifier specified: `<schema name>  AUTHORIZATION <schema authorization identifier>`.
9086    NamedAuthorization(ObjectName, Ident),
9087}
9088
9089impl fmt::Display for SchemaName {
9090    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9091        match self {
9092            SchemaName::Simple(name) => {
9093                write!(f, "{name}")
9094            }
9095            SchemaName::UnnamedAuthorization(authorization) => {
9096                write!(f, "AUTHORIZATION {authorization}")
9097            }
9098            SchemaName::NamedAuthorization(name, authorization) => {
9099                write!(f, "{name} AUTHORIZATION {authorization}")
9100            }
9101        }
9102    }
9103}
9104
9105/// Fulltext search modifiers ([1]).
9106///
9107/// [1]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html#function_match
9108#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9109#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9110#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9111pub enum SearchModifier {
9112    /// `IN NATURAL LANGUAGE MODE`.
9113    InNaturalLanguageMode,
9114    /// `IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION`.
9115    InNaturalLanguageModeWithQueryExpansion,
9116    ///`IN BOOLEAN MODE`.
9117    InBooleanMode,
9118    ///`WITH QUERY EXPANSION`.
9119    WithQueryExpansion,
9120}
9121
9122impl fmt::Display for SearchModifier {
9123    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9124        match self {
9125            Self::InNaturalLanguageMode => {
9126                write!(f, "IN NATURAL LANGUAGE MODE")?;
9127            }
9128            Self::InNaturalLanguageModeWithQueryExpansion => {
9129                write!(f, "IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION")?;
9130            }
9131            Self::InBooleanMode => {
9132                write!(f, "IN BOOLEAN MODE")?;
9133            }
9134            Self::WithQueryExpansion => {
9135                write!(f, "WITH QUERY EXPANSION")?;
9136            }
9137        }
9138
9139        Ok(())
9140    }
9141}
9142
9143#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9144#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9145#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9146pub struct LockTable {
9147    pub table: Ident,
9148    pub alias: Option<Ident>,
9149    pub lock_type: LockTableType,
9150}
9151
9152impl fmt::Display for LockTable {
9153    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9154        let Self {
9155            table: tbl_name,
9156            alias,
9157            lock_type,
9158        } = self;
9159
9160        write!(f, "{tbl_name} ")?;
9161        if let Some(alias) = alias {
9162            write!(f, "AS {alias} ")?;
9163        }
9164        write!(f, "{lock_type}")?;
9165        Ok(())
9166    }
9167}
9168
9169#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9170#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9171#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9172pub enum LockTableType {
9173    Read { local: bool },
9174    Write { low_priority: bool },
9175}
9176
9177impl fmt::Display for LockTableType {
9178    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9179        match self {
9180            Self::Read { local } => {
9181                write!(f, "READ")?;
9182                if *local {
9183                    write!(f, " LOCAL")?;
9184                }
9185            }
9186            Self::Write { low_priority } => {
9187                if *low_priority {
9188                    write!(f, "LOW_PRIORITY ")?;
9189                }
9190                write!(f, "WRITE")?;
9191            }
9192        }
9193
9194        Ok(())
9195    }
9196}
9197
9198#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9199#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9200#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9201pub struct HiveSetLocation {
9202    pub has_set: bool,
9203    pub location: Ident,
9204}
9205
9206impl fmt::Display for HiveSetLocation {
9207    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9208        if self.has_set {
9209            write!(f, "SET ")?;
9210        }
9211        write!(f, "LOCATION {}", self.location)
9212    }
9213}
9214
9215/// MySQL `ALTER TABLE` only  [FIRST | AFTER column_name]
9216#[allow(clippy::large_enum_variant)]
9217#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9218#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9219#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9220pub enum MySQLColumnPosition {
9221    First,
9222    After(Ident),
9223}
9224
9225impl Display for MySQLColumnPosition {
9226    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9227        match self {
9228            MySQLColumnPosition::First => write!(f, "FIRST"),
9229            MySQLColumnPosition::After(ident) => {
9230                let column_name = &ident.value;
9231                write!(f, "AFTER {column_name}")
9232            }
9233        }
9234    }
9235}
9236
9237/// MySQL `CREATE VIEW` algorithm parameter: [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
9238#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9239#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9240#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9241pub enum CreateViewAlgorithm {
9242    Undefined,
9243    Merge,
9244    TempTable,
9245}
9246
9247impl Display for CreateViewAlgorithm {
9248    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9249        match self {
9250            CreateViewAlgorithm::Undefined => write!(f, "UNDEFINED"),
9251            CreateViewAlgorithm::Merge => write!(f, "MERGE"),
9252            CreateViewAlgorithm::TempTable => write!(f, "TEMPTABLE"),
9253        }
9254    }
9255}
9256/// MySQL `CREATE VIEW` security parameter: [SQL SECURITY { DEFINER | INVOKER }]
9257#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9258#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9259#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9260pub enum CreateViewSecurity {
9261    Definer,
9262    Invoker,
9263}
9264
9265impl Display for CreateViewSecurity {
9266    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9267        match self {
9268            CreateViewSecurity::Definer => write!(f, "DEFINER"),
9269            CreateViewSecurity::Invoker => write!(f, "INVOKER"),
9270        }
9271    }
9272}
9273
9274/// [MySQL] `CREATE VIEW` additional parameters
9275///
9276/// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/create-view.html
9277#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9278#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9279#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9280pub struct CreateViewParams {
9281    pub algorithm: Option<CreateViewAlgorithm>,
9282    pub definer: Option<GranteeName>,
9283    pub security: Option<CreateViewSecurity>,
9284}
9285
9286impl Display for CreateViewParams {
9287    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9288        let CreateViewParams {
9289            algorithm,
9290            definer,
9291            security,
9292        } = self;
9293        if let Some(algorithm) = algorithm {
9294            write!(f, "ALGORITHM = {algorithm} ")?;
9295        }
9296        if let Some(definers) = definer {
9297            write!(f, "DEFINER = {definers} ")?;
9298        }
9299        if let Some(security) = security {
9300            write!(f, "SQL SECURITY {security} ")?;
9301        }
9302        Ok(())
9303    }
9304}
9305
9306#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9307#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9308#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9309/// Key/Value, where the value is a (optionally named) list of identifiers
9310///
9311/// ```sql
9312/// UNION = (tbl_name[,tbl_name]...)
9313/// ENGINE = ReplicatedMergeTree('/table_name','{replica}', ver)
9314/// ENGINE = SummingMergeTree([columns])
9315/// ```
9316pub struct NamedParenthesizedList {
9317    pub key: Ident,
9318    pub name: Option<Ident>,
9319    pub values: Vec<Ident>,
9320}
9321
9322/// Snowflake `WITH ROW ACCESS POLICY policy_name ON (identifier, ...)`
9323///
9324/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
9325/// <https://docs.snowflake.com/en/user-guide/security-row-intro>
9326#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9327#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9328#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9329pub struct RowAccessPolicy {
9330    pub policy: ObjectName,
9331    pub on: Vec<Ident>,
9332}
9333
9334impl RowAccessPolicy {
9335    pub fn new(policy: ObjectName, on: Vec<Ident>) -> Self {
9336        Self { policy, on }
9337    }
9338}
9339
9340impl Display for RowAccessPolicy {
9341    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9342        write!(
9343            f,
9344            "WITH ROW ACCESS POLICY {} ON ({})",
9345            self.policy,
9346            display_comma_separated(self.on.as_slice())
9347        )
9348    }
9349}
9350
9351/// Snowflake `WITH TAG ( tag_name = '<tag_value>', ...)`
9352///
9353/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
9354#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9355#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9356#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9357pub struct Tag {
9358    pub key: ObjectName,
9359    pub value: String,
9360}
9361
9362impl Tag {
9363    pub fn new(key: ObjectName, value: String) -> Self {
9364        Self { key, value }
9365    }
9366}
9367
9368impl Display for Tag {
9369    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9370        write!(f, "{}='{}'", self.key, self.value)
9371    }
9372}
9373
9374/// Snowflake `WITH CONTACT ( purpose = contact [ , purpose = contact ...] )`
9375///
9376/// <https://docs.snowflake.com/en/sql-reference/sql/create-database>
9377#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9378#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9379#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9380pub struct ContactEntry {
9381    pub purpose: String,
9382    pub contact: String,
9383}
9384
9385impl Display for ContactEntry {
9386    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9387        write!(f, "{} = {}", self.purpose, self.contact)
9388    }
9389}
9390
9391/// Helper to indicate if a comment includes the `=` in the display form
9392#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9393#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9394#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9395pub enum CommentDef {
9396    /// Includes `=` when printing the comment, as `COMMENT = 'comment'`
9397    /// Does not include `=` when printing the comment, as `COMMENT 'comment'`
9398    WithEq(String),
9399    WithoutEq(String),
9400}
9401
9402impl Display for CommentDef {
9403    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9404        match self {
9405            CommentDef::WithEq(comment) | CommentDef::WithoutEq(comment) => write!(f, "{comment}"),
9406        }
9407    }
9408}
9409
9410/// Helper to indicate if a collection should be wrapped by a symbol in the display form
9411///
9412/// [`Display`] is implemented for every [`Vec<T>`] where `T: Display`.
9413/// The string output is a comma separated list for the vec items
9414///
9415/// # Examples
9416/// ```
9417/// # use sqlparser::ast::WrappedCollection;
9418/// let items = WrappedCollection::Parentheses(vec!["one", "two", "three"]);
9419/// assert_eq!("(one, two, three)", items.to_string());
9420///
9421/// let items = WrappedCollection::NoWrapping(vec!["one", "two", "three"]);
9422/// assert_eq!("one, two, three", items.to_string());
9423/// ```
9424#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9425#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9426#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9427pub enum WrappedCollection<T> {
9428    /// Print the collection without wrapping symbols, as `item, item, item`
9429    NoWrapping(T),
9430    /// Wraps the collection in Parentheses, as `(item, item, item)`
9431    Parentheses(T),
9432}
9433
9434impl<T> Display for WrappedCollection<Vec<T>>
9435where
9436    T: Display,
9437{
9438    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9439        match self {
9440            WrappedCollection::NoWrapping(inner) => {
9441                write!(f, "{}", display_comma_separated(inner.as_slice()))
9442            }
9443            WrappedCollection::Parentheses(inner) => {
9444                write!(f, "({})", display_comma_separated(inner.as_slice()))
9445            }
9446        }
9447    }
9448}
9449
9450/// Represents a single PostgreSQL utility option.
9451///
9452/// A utility option is a key-value pair where the key is an identifier (IDENT) and the value
9453/// can be one of the following:
9454/// - A number with an optional sign (`+` or `-`). Example: `+10`, `-10.2`, `3`
9455/// - A non-keyword string. Example: `option1`, `'option2'`, `"option3"`
9456/// - keyword: `TRUE`, `FALSE`, `ON` (`off` is also accept).
9457/// - Empty. Example: `ANALYZE` (identifier only)
9458///
9459/// Utility options are used in various PostgreSQL DDL statements, including statements such as
9460/// `CLUSTER`, `EXPLAIN`, `VACUUM`, and `REINDEX`. These statements format options as `( option [, ...] )`.
9461///
9462/// [CLUSTER](https://www.postgresql.org/docs/current/sql-cluster.html)
9463/// [EXPLAIN](https://www.postgresql.org/docs/current/sql-explain.html)
9464/// [VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html)
9465/// [REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html)
9466///
9467/// For example, the `EXPLAIN` AND `VACUUM` statements with options might look like this:
9468/// ```sql
9469/// EXPLAIN (ANALYZE, VERBOSE TRUE, FORMAT TEXT) SELECT * FROM my_table;
9470///
9471/// VACUUM (VERBOSE, ANALYZE ON, PARALLEL 10) my_table;
9472/// ```
9473#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9474#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9475#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9476pub struct UtilityOption {
9477    pub name: Ident,
9478    pub arg: Option<Expr>,
9479}
9480
9481impl Display for UtilityOption {
9482    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9483        if let Some(ref arg) = self.arg {
9484            write!(f, "{} {}", self.name, arg)
9485        } else {
9486            write!(f, "{}", self.name)
9487        }
9488    }
9489}
9490
9491/// Represents the different options available for `SHOW`
9492/// statements to filter the results. Example from Snowflake:
9493/// <https://docs.snowflake.com/en/sql-reference/sql/show-tables>
9494#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9495#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9496#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9497pub struct ShowStatementOptions {
9498    pub show_in: Option<ShowStatementIn>,
9499    pub starts_with: Option<Value>,
9500    pub limit: Option<Expr>,
9501    pub limit_from: Option<Value>,
9502    pub filter_position: Option<ShowStatementFilterPosition>,
9503}
9504
9505impl Display for ShowStatementOptions {
9506    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9507        let (like_in_infix, like_in_suffix) = match &self.filter_position {
9508            Some(ShowStatementFilterPosition::Infix(filter)) => {
9509                (format!(" {filter}"), "".to_string())
9510            }
9511            Some(ShowStatementFilterPosition::Suffix(filter)) => {
9512                ("".to_string(), format!(" {filter}"))
9513            }
9514            None => ("".to_string(), "".to_string()),
9515        };
9516        write!(
9517            f,
9518            "{like_in_infix}{show_in}{starts_with}{limit}{from}{like_in_suffix}",
9519            show_in = match &self.show_in {
9520                Some(i) => format!(" {i}"),
9521                None => String::new(),
9522            },
9523            starts_with = match &self.starts_with {
9524                Some(s) => format!(" STARTS WITH {s}"),
9525                None => String::new(),
9526            },
9527            limit = match &self.limit {
9528                Some(l) => format!(" LIMIT {l}"),
9529                None => String::new(),
9530            },
9531            from = match &self.limit_from {
9532                Some(f) => format!(" FROM {f}"),
9533                None => String::new(),
9534            }
9535        )?;
9536        Ok(())
9537    }
9538}
9539
9540#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9541#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9542#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9543pub enum ShowStatementFilterPosition {
9544    Infix(ShowStatementFilter), // For example: SHOW COLUMNS LIKE '%name%' IN TABLE tbl
9545    Suffix(ShowStatementFilter), // For example: SHOW COLUMNS IN tbl LIKE '%name%'
9546}
9547
9548#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9549#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9550#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9551pub enum ShowStatementInParentType {
9552    Account,
9553    Database,
9554    Schema,
9555    Table,
9556    View,
9557}
9558
9559impl fmt::Display for ShowStatementInParentType {
9560    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9561        match self {
9562            ShowStatementInParentType::Account => write!(f, "ACCOUNT"),
9563            ShowStatementInParentType::Database => write!(f, "DATABASE"),
9564            ShowStatementInParentType::Schema => write!(f, "SCHEMA"),
9565            ShowStatementInParentType::Table => write!(f, "TABLE"),
9566            ShowStatementInParentType::View => write!(f, "VIEW"),
9567        }
9568    }
9569}
9570
9571#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9572#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9573#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9574pub struct ShowStatementIn {
9575    pub clause: ShowStatementInClause,
9576    pub parent_type: Option<ShowStatementInParentType>,
9577    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
9578    pub parent_name: Option<ObjectName>,
9579}
9580
9581impl fmt::Display for ShowStatementIn {
9582    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9583        write!(f, "{}", self.clause)?;
9584        if let Some(parent_type) = &self.parent_type {
9585            write!(f, " {parent_type}")?;
9586        }
9587        if let Some(parent_name) = &self.parent_name {
9588            write!(f, " {parent_name}")?;
9589        }
9590        Ok(())
9591    }
9592}
9593
9594/// A Show Charset statement
9595#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9596#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9597#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9598pub struct ShowCharset {
9599    /// The statement can be written as `SHOW CHARSET` or `SHOW CHARACTER SET`
9600    /// true means CHARSET was used and false means CHARACTER SET was used
9601    pub is_shorthand: bool,
9602    pub filter: Option<ShowStatementFilter>,
9603}
9604
9605impl fmt::Display for ShowCharset {
9606    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9607        write!(f, "SHOW")?;
9608        if self.is_shorthand {
9609            write!(f, " CHARSET")?;
9610        } else {
9611            write!(f, " CHARACTER SET")?;
9612        }
9613        if let Some(filter) = &self.filter {
9614            write!(f, " {filter}")?;
9615        }
9616        Ok(())
9617    }
9618}
9619
9620#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9621#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9622#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9623pub struct ShowObjects {
9624    pub terse: bool,
9625    pub show_options: ShowStatementOptions,
9626}
9627
9628/// MSSQL's json null clause
9629///
9630/// ```plaintext
9631/// <json_null_clause> ::=
9632///       NULL ON NULL
9633///     | ABSENT ON NULL
9634/// ```
9635///
9636/// <https://learn.microsoft.com/en-us/sql/t-sql/functions/json-object-transact-sql?view=sql-server-ver16#json_null_clause>
9637#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9638#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9639#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9640pub enum JsonNullClause {
9641    NullOnNull,
9642    AbsentOnNull,
9643}
9644
9645impl Display for JsonNullClause {
9646    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9647        match self {
9648            JsonNullClause::NullOnNull => write!(f, "NULL ON NULL"),
9649            JsonNullClause::AbsentOnNull => write!(f, "ABSENT ON NULL"),
9650        }
9651    }
9652}
9653
9654/// PostgreSQL JSON function RETURNING clause
9655///
9656/// Example:
9657/// ```sql
9658/// JSON_OBJECT('a': 1 RETURNING jsonb)
9659/// ```
9660#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9661#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9662#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9663pub struct JsonReturningClause {
9664    pub data_type: DataType,
9665}
9666
9667impl Display for JsonReturningClause {
9668    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9669        write!(f, "RETURNING {}", self.data_type)
9670    }
9671}
9672
9673/// rename object definition
9674#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9675#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9676#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9677pub struct RenameTable {
9678    pub old_name: ObjectName,
9679    pub new_name: ObjectName,
9680}
9681
9682impl fmt::Display for RenameTable {
9683    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9684        write!(f, "{} TO {}", self.old_name, self.new_name)?;
9685        Ok(())
9686    }
9687}
9688
9689/// Represents the referenced table in an `INSERT INTO` statement
9690#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9691#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9692#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9693pub enum TableObject {
9694    /// Table specified by name.
9695    /// Example:
9696    /// ```sql
9697    /// INSERT INTO my_table
9698    /// ```
9699    TableName(#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] ObjectName),
9700
9701    /// Table specified as a function.
9702    /// Example:
9703    /// ```sql
9704    /// INSERT INTO TABLE FUNCTION remote('localhost', default.simple_table)
9705    /// ```
9706    /// [Clickhouse](https://clickhouse.com/docs/en/sql-reference/table-functions)
9707    TableFunction(Function),
9708}
9709
9710impl fmt::Display for TableObject {
9711    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9712        match self {
9713            Self::TableName(table_name) => write!(f, "{table_name}"),
9714            Self::TableFunction(func) => write!(f, "FUNCTION {func}"),
9715        }
9716    }
9717}
9718
9719/// Represents a SET SESSION AUTHORIZATION statement
9720#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9721#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9722#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9723pub struct SetSessionAuthorizationParam {
9724    pub scope: ContextModifier,
9725    pub kind: SetSessionAuthorizationParamKind,
9726}
9727
9728impl fmt::Display for SetSessionAuthorizationParam {
9729    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9730        write!(f, "{}", self.kind)
9731    }
9732}
9733
9734/// Represents the parameter kind for SET SESSION AUTHORIZATION
9735#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9736#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9737#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9738pub enum SetSessionAuthorizationParamKind {
9739    /// Default authorization
9740    Default,
9741
9742    /// User name
9743    User(Ident),
9744}
9745
9746impl fmt::Display for SetSessionAuthorizationParamKind {
9747    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9748        match self {
9749            SetSessionAuthorizationParamKind::Default => write!(f, "DEFAULT"),
9750            SetSessionAuthorizationParamKind::User(name) => write!(f, "{}", name),
9751        }
9752    }
9753}
9754
9755#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9756#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9757#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9758pub enum SetSessionParamKind {
9759    Generic(SetSessionParamGeneric),
9760    IdentityInsert(SetSessionParamIdentityInsert),
9761    Offsets(SetSessionParamOffsets),
9762    Statistics(SetSessionParamStatistics),
9763}
9764
9765impl fmt::Display for SetSessionParamKind {
9766    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9767        match self {
9768            SetSessionParamKind::Generic(x) => write!(f, "{x}"),
9769            SetSessionParamKind::IdentityInsert(x) => write!(f, "{x}"),
9770            SetSessionParamKind::Offsets(x) => write!(f, "{x}"),
9771            SetSessionParamKind::Statistics(x) => write!(f, "{x}"),
9772        }
9773    }
9774}
9775
9776#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9777#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9778#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9779pub struct SetSessionParamGeneric {
9780    pub names: Vec<String>,
9781    pub value: String,
9782}
9783
9784impl fmt::Display for SetSessionParamGeneric {
9785    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9786        write!(f, "{} {}", display_comma_separated(&self.names), self.value)
9787    }
9788}
9789
9790#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9791#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9792#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9793pub struct SetSessionParamIdentityInsert {
9794    pub obj: ObjectName,
9795    pub value: SessionParamValue,
9796}
9797
9798impl fmt::Display for SetSessionParamIdentityInsert {
9799    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9800        write!(f, "IDENTITY_INSERT {} {}", self.obj, self.value)
9801    }
9802}
9803
9804#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9805#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9806#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9807pub struct SetSessionParamOffsets {
9808    pub keywords: Vec<String>,
9809    pub value: SessionParamValue,
9810}
9811
9812impl fmt::Display for SetSessionParamOffsets {
9813    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9814        write!(
9815            f,
9816            "OFFSETS {} {}",
9817            display_comma_separated(&self.keywords),
9818            self.value
9819        )
9820    }
9821}
9822
9823#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9824#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9825#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9826pub struct SetSessionParamStatistics {
9827    pub topic: SessionParamStatsTopic,
9828    pub value: SessionParamValue,
9829}
9830
9831impl fmt::Display for SetSessionParamStatistics {
9832    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9833        write!(f, "STATISTICS {} {}", self.topic, self.value)
9834    }
9835}
9836
9837#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9838#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9839#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9840pub enum SessionParamStatsTopic {
9841    IO,
9842    Profile,
9843    Time,
9844    Xml,
9845}
9846
9847impl fmt::Display for SessionParamStatsTopic {
9848    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9849        match self {
9850            SessionParamStatsTopic::IO => write!(f, "IO"),
9851            SessionParamStatsTopic::Profile => write!(f, "PROFILE"),
9852            SessionParamStatsTopic::Time => write!(f, "TIME"),
9853            SessionParamStatsTopic::Xml => write!(f, "XML"),
9854        }
9855    }
9856}
9857
9858#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9859#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9860#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9861pub enum SessionParamValue {
9862    On,
9863    Off,
9864}
9865
9866impl fmt::Display for SessionParamValue {
9867    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9868        match self {
9869            SessionParamValue::On => write!(f, "ON"),
9870            SessionParamValue::Off => write!(f, "OFF"),
9871        }
9872    }
9873}
9874
9875/// Snowflake StorageSerializationPolicy for Iceberg Tables
9876/// ```sql
9877/// [ STORAGE_SERIALIZATION_POLICY = { COMPATIBLE | OPTIMIZED } ]
9878/// ```
9879///
9880/// <https://docs.snowflake.com/en/sql-reference/sql/create-iceberg-table>
9881#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9882#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9883#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9884pub enum StorageSerializationPolicy {
9885    Compatible,
9886    Optimized,
9887}
9888
9889impl Display for StorageSerializationPolicy {
9890    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9891        match self {
9892            StorageSerializationPolicy::Compatible => write!(f, "COMPATIBLE"),
9893            StorageSerializationPolicy::Optimized => write!(f, "OPTIMIZED"),
9894        }
9895    }
9896}
9897
9898/// Snowflake CatalogSyncNamespaceMode
9899/// ```sql
9900/// [ CATALOG_SYNC_NAMESPACE_MODE = { NEST | FLATTEN } ]
9901/// ```
9902///
9903/// <https://docs.snowflake.com/en/sql-reference/sql/create-database>
9904#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9905#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9906#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9907pub enum CatalogSyncNamespaceMode {
9908    Nest,
9909    Flatten,
9910}
9911
9912impl Display for CatalogSyncNamespaceMode {
9913    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9914        match self {
9915            CatalogSyncNamespaceMode::Nest => write!(f, "NEST"),
9916            CatalogSyncNamespaceMode::Flatten => write!(f, "FLATTEN"),
9917        }
9918    }
9919}
9920
9921/// Variants of the Snowflake `COPY INTO` statement
9922#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9923#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9924#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9925pub enum CopyIntoSnowflakeKind {
9926    /// Loads data from files to a table
9927    /// See: <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table>
9928    Table,
9929    /// Unloads data from a table or query to external files
9930    /// See: <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location>
9931    Location,
9932}
9933
9934#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9935#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9936#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9937pub struct PrintStatement {
9938    pub message: Box<Expr>,
9939}
9940
9941impl fmt::Display for PrintStatement {
9942    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9943        write!(f, "PRINT {}", self.message)
9944    }
9945}
9946
9947/// Represents a `Return` statement.
9948///
9949/// [MsSql triggers](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql)
9950/// [MsSql functions](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql)
9951#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9952#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9953#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9954pub struct ReturnStatement {
9955    pub value: Option<ReturnStatementValue>,
9956}
9957
9958impl fmt::Display for ReturnStatement {
9959    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9960        match &self.value {
9961            Some(ReturnStatementValue::Expr(expr)) => write!(f, "RETURN {expr}"),
9962            None => write!(f, "RETURN"),
9963        }
9964    }
9965}
9966
9967/// Variants of a `RETURN` statement
9968#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9969#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9970#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9971pub enum ReturnStatementValue {
9972    Expr(Expr),
9973}
9974
9975/// Represents an `OPEN` statement.
9976#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9977#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9978#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9979pub struct OpenStatement {
9980    /// Cursor name
9981    pub cursor_name: Ident,
9982}
9983
9984impl fmt::Display for OpenStatement {
9985    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9986        write!(f, "OPEN {}", self.cursor_name)
9987    }
9988}
9989
9990/// Specifies Include / Exclude NULL within UNPIVOT command.
9991/// For example
9992/// `UNPIVOT (column1 FOR new_column IN (col3, col4, col5, col6))`
9993#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9994#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9995#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9996pub enum NullInclusion {
9997    IncludeNulls,
9998    ExcludeNulls,
9999}
10000
10001impl fmt::Display for NullInclusion {
10002    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10003        match self {
10004            NullInclusion::IncludeNulls => write!(f, "INCLUDE NULLS"),
10005            NullInclusion::ExcludeNulls => write!(f, "EXCLUDE NULLS"),
10006        }
10007    }
10008}
10009
10010/// Checks membership of a value in a JSON array
10011///
10012/// Syntax:
10013/// ```sql
10014/// <value> MEMBER OF(<array>)
10015/// ```
10016/// [MySQL](https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#operator_member-of)
10017#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10018#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10019#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10020pub struct MemberOf {
10021    pub value: Box<Expr>,
10022    pub array: Box<Expr>,
10023}
10024
10025impl fmt::Display for MemberOf {
10026    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10027        write!(f, "{} MEMBER OF({})", self.value, self.array)
10028    }
10029}
10030
10031#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10032#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10033#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10034pub struct ExportData {
10035    pub options: Vec<SqlOption>,
10036    pub query: Box<Query>,
10037    pub connection: Option<ObjectName>,
10038}
10039
10040impl fmt::Display for ExportData {
10041    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10042        if let Some(connection) = &self.connection {
10043            write!(
10044                f,
10045                "EXPORT DATA WITH CONNECTION {connection} OPTIONS({}) AS {}",
10046                display_comma_separated(&self.options),
10047                self.query
10048            )
10049        } else {
10050            write!(
10051                f,
10052                "EXPORT DATA OPTIONS({}) AS {}",
10053                display_comma_separated(&self.options),
10054                self.query
10055            )
10056        }
10057    }
10058}
10059/// Creates a user
10060///
10061/// Syntax:
10062/// ```sql
10063/// CREATE [OR REPLACE] USER [IF NOT EXISTS] <name> [OPTIONS]
10064/// ```
10065///
10066/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-user)
10067#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10068#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10069#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10070pub struct CreateUser {
10071    pub or_replace: bool,
10072    pub if_not_exists: bool,
10073    pub name: Ident,
10074    pub options: KeyValueOptions,
10075    pub with_tags: bool,
10076    pub tags: KeyValueOptions,
10077}
10078
10079impl fmt::Display for CreateUser {
10080    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10081        write!(f, "CREATE")?;
10082        if self.or_replace {
10083            write!(f, " OR REPLACE")?;
10084        }
10085        write!(f, " USER")?;
10086        if self.if_not_exists {
10087            write!(f, " IF NOT EXISTS")?;
10088        }
10089        write!(f, " {}", self.name)?;
10090        if !self.options.options.is_empty() {
10091            write!(f, " {}", self.options)?;
10092        }
10093        if !self.tags.options.is_empty() {
10094            if self.with_tags {
10095                write!(f, " WITH")?;
10096            }
10097            write!(f, " TAG ({})", self.tags)?;
10098        }
10099        Ok(())
10100    }
10101}
10102
10103/// Modifies the properties of a user
10104///
10105/// Syntax:
10106/// ```sql
10107/// ALTER USER [ IF EXISTS ] [ <name> ] [ OPTIONS ]
10108/// ```
10109///
10110/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/alter-user)
10111#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10112#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10113#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10114pub struct AlterUser {
10115    pub if_exists: bool,
10116    pub name: Ident,
10117    /// The following fields are Snowflake-specific: <https://docs.snowflake.com/en/sql-reference/sql/alter-user#syntax>
10118    pub rename_to: Option<Ident>,
10119    pub reset_password: bool,
10120    pub abort_all_queries: bool,
10121    pub add_role_delegation: Option<AlterUserAddRoleDelegation>,
10122    pub remove_role_delegation: Option<AlterUserRemoveRoleDelegation>,
10123    pub enroll_mfa: bool,
10124    pub set_default_mfa_method: Option<MfaMethodKind>,
10125    pub remove_mfa_method: Option<MfaMethodKind>,
10126    pub modify_mfa_method: Option<AlterUserModifyMfaMethod>,
10127    pub add_mfa_method_otp: Option<AlterUserAddMfaMethodOtp>,
10128    pub set_policy: Option<AlterUserSetPolicy>,
10129    pub unset_policy: Option<UserPolicyKind>,
10130    pub set_tag: KeyValueOptions,
10131    pub unset_tag: Vec<String>,
10132    pub set_props: KeyValueOptions,
10133    pub unset_props: Vec<String>,
10134}
10135
10136/// ```sql
10137/// ALTER USER [ IF EXISTS ] [ <name> ] ADD DELEGATED AUTHORIZATION OF ROLE <role_name> TO 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 AlterUserAddRoleDelegation {
10143    pub role: Ident,
10144    pub integration: Ident,
10145}
10146
10147/// ```sql
10148/// ALTER USER [ IF EXISTS ] [ <name> ] REMOVE DELEGATED { AUTHORIZATION OF ROLE <role_name> | AUTHORIZATIONS } FROM SECURITY INTEGRATION <integration_name>
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 AlterUserRemoveRoleDelegation {
10154    pub role: Option<Ident>,
10155    pub integration: Ident,
10156}
10157
10158/// ```sql
10159/// ADD MFA METHOD OTP [ COUNT = number ]
10160/// ```
10161#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10162#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10163#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10164pub struct AlterUserAddMfaMethodOtp {
10165    pub count: Option<Value>,
10166}
10167
10168/// ```sql
10169/// ALTER USER [ IF EXISTS ] [ <name> ] MODIFY MFA METHOD <mfa_method> SET COMMENT = '<string>'
10170/// ```
10171#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10172#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10173#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10174pub struct AlterUserModifyMfaMethod {
10175    pub method: MfaMethodKind,
10176    pub comment: String,
10177}
10178
10179/// Types of MFA methods
10180#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10181#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10182#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10183pub enum MfaMethodKind {
10184    PassKey,
10185    Totp,
10186    Duo,
10187}
10188
10189impl fmt::Display for MfaMethodKind {
10190    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10191        match self {
10192            MfaMethodKind::PassKey => write!(f, "PASSKEY"),
10193            MfaMethodKind::Totp => write!(f, "TOTP"),
10194            MfaMethodKind::Duo => write!(f, "DUO"),
10195        }
10196    }
10197}
10198
10199/// ```sql
10200/// ALTER USER [ IF EXISTS ] [ <name> ] SET { AUTHENTICATION | PASSWORD | SESSION } POLICY <policy_name>
10201/// ```
10202#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10203#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10204#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10205pub struct AlterUserSetPolicy {
10206    pub policy_kind: UserPolicyKind,
10207    pub policy: Ident,
10208}
10209
10210/// Types of user-based policies
10211#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10212#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10213#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10214pub enum UserPolicyKind {
10215    Authentication,
10216    Password,
10217    Session,
10218}
10219
10220impl fmt::Display for UserPolicyKind {
10221    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10222        match self {
10223            UserPolicyKind::Authentication => write!(f, "AUTHENTICATION"),
10224            UserPolicyKind::Password => write!(f, "PASSWORD"),
10225            UserPolicyKind::Session => write!(f, "SESSION"),
10226        }
10227    }
10228}
10229
10230impl fmt::Display for AlterUser {
10231    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10232        write!(f, "ALTER")?;
10233        write!(f, " USER")?;
10234        if self.if_exists {
10235            write!(f, " IF EXISTS")?;
10236        }
10237        write!(f, " {}", self.name)?;
10238        if let Some(new_name) = &self.rename_to {
10239            write!(f, " RENAME TO {new_name}")?;
10240        }
10241        if self.reset_password {
10242            write!(f, " RESET PASSWORD")?;
10243        }
10244        if self.abort_all_queries {
10245            write!(f, " ABORT ALL QUERIES")?;
10246        }
10247        if let Some(role_delegation) = &self.add_role_delegation {
10248            let role = &role_delegation.role;
10249            let integration = &role_delegation.integration;
10250            write!(
10251                f,
10252                " ADD DELEGATED AUTHORIZATION OF ROLE {role} TO SECURITY INTEGRATION {integration}"
10253            )?;
10254        }
10255        if let Some(role_delegation) = &self.remove_role_delegation {
10256            write!(f, " REMOVE DELEGATED")?;
10257            match &role_delegation.role {
10258                Some(role) => write!(f, " AUTHORIZATION OF ROLE {role}")?,
10259                None => write!(f, " AUTHORIZATIONS")?,
10260            }
10261            let integration = &role_delegation.integration;
10262            write!(f, " FROM SECURITY INTEGRATION {integration}")?;
10263        }
10264        if self.enroll_mfa {
10265            write!(f, " ENROLL MFA")?;
10266        }
10267        if let Some(method) = &self.set_default_mfa_method {
10268            write!(f, " SET DEFAULT_MFA_METHOD {method}")?
10269        }
10270        if let Some(method) = &self.remove_mfa_method {
10271            write!(f, " REMOVE MFA METHOD {method}")?;
10272        }
10273        if let Some(modify) = &self.modify_mfa_method {
10274            let method = &modify.method;
10275            let comment = &modify.comment;
10276            write!(
10277                f,
10278                " MODIFY MFA METHOD {method} SET COMMENT '{}'",
10279                value::escape_single_quote_string(comment)
10280            )?;
10281        }
10282        if let Some(add_mfa_method_otp) = &self.add_mfa_method_otp {
10283            write!(f, " ADD MFA METHOD OTP")?;
10284            if let Some(count) = &add_mfa_method_otp.count {
10285                write!(f, " COUNT = {count}")?;
10286            }
10287        }
10288        if let Some(policy) = &self.set_policy {
10289            let policy_kind = &policy.policy_kind;
10290            let name = &policy.policy;
10291            write!(f, " SET {policy_kind} POLICY {name}")?;
10292        }
10293        if let Some(policy_kind) = &self.unset_policy {
10294            write!(f, " UNSET {policy_kind} POLICY")?;
10295        }
10296        if !self.set_tag.options.is_empty() {
10297            write!(f, " SET TAG {}", self.set_tag)?;
10298        }
10299        if !self.unset_tag.is_empty() {
10300            write!(f, " UNSET TAG {}", display_comma_separated(&self.unset_tag))?;
10301        }
10302        let has_props = !self.set_props.options.is_empty();
10303        if has_props {
10304            write!(f, " SET")?;
10305            write!(f, " {}", &self.set_props)?;
10306        }
10307        if !self.unset_props.is_empty() {
10308            write!(f, " UNSET {}", display_comma_separated(&self.unset_props))?;
10309        }
10310        Ok(())
10311    }
10312}
10313
10314/// Specifies how to create a new table based on an existing table's schema.
10315/// '''sql
10316/// CREATE TABLE new LIKE old ...
10317/// '''
10318#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10319#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10320#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10321pub enum CreateTableLikeKind {
10322    /// '''sql
10323    /// CREATE TABLE new (LIKE old ...)
10324    /// '''
10325    /// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html)
10326    Parenthesized(CreateTableLike),
10327    /// '''sql
10328    /// CREATE TABLE new LIKE old ...
10329    /// '''
10330    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-table#label-create-table-like)
10331    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_like)
10332    Plain(CreateTableLike),
10333}
10334
10335#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10336#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10337#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10338pub enum CreateTableLikeDefaults {
10339    Including,
10340    Excluding,
10341}
10342
10343impl fmt::Display for CreateTableLikeDefaults {
10344    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10345        match self {
10346            CreateTableLikeDefaults::Including => write!(f, "INCLUDING DEFAULTS"),
10347            CreateTableLikeDefaults::Excluding => write!(f, "EXCLUDING DEFAULTS"),
10348        }
10349    }
10350}
10351
10352#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10353#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10354#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10355pub struct CreateTableLike {
10356    pub name: ObjectName,
10357    pub defaults: Option<CreateTableLikeDefaults>,
10358}
10359
10360impl fmt::Display for CreateTableLike {
10361    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10362        write!(f, "LIKE {}", self.name)?;
10363        if let Some(defaults) = &self.defaults {
10364            write!(f, " {defaults}")?;
10365        }
10366        Ok(())
10367    }
10368}
10369
10370/// Specifies the refresh mode for the dynamic table.
10371///
10372/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table)
10373#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10374#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10375#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10376pub enum RefreshModeKind {
10377    Auto,
10378    Full,
10379    Incremental,
10380}
10381
10382impl fmt::Display for RefreshModeKind {
10383    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10384        match self {
10385            RefreshModeKind::Auto => write!(f, "AUTO"),
10386            RefreshModeKind::Full => write!(f, "FULL"),
10387            RefreshModeKind::Incremental => write!(f, "INCREMENTAL"),
10388        }
10389    }
10390}
10391
10392/// Specifies the behavior of the initial refresh of the dynamic table.
10393///
10394/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table)
10395#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10396#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10397#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10398pub enum InitializeKind {
10399    OnCreate,
10400    OnSchedule,
10401}
10402
10403impl fmt::Display for InitializeKind {
10404    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10405        match self {
10406            InitializeKind::OnCreate => write!(f, "ON_CREATE"),
10407            InitializeKind::OnSchedule => write!(f, "ON_SCHEDULE"),
10408        }
10409    }
10410}
10411
10412/// Re-sorts rows and reclaims space in either a specified table or all tables in the current database
10413///
10414/// '''sql
10415/// VACUUM [ FULL | SORT ONLY | DELETE ONLY | REINDEX | RECLUSTER ] [ \[ table_name \] [ TO threshold PERCENT ] \[ BOOST \] ]
10416/// '''
10417/// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)
10418#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10419#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10420#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10421pub struct VacuumStatement {
10422    pub full: bool,
10423    pub sort_only: bool,
10424    pub delete_only: bool,
10425    pub reindex: bool,
10426    pub recluster: bool,
10427    pub table_name: Option<ObjectName>,
10428    pub threshold: Option<Value>,
10429    pub boost: bool,
10430}
10431
10432impl fmt::Display for VacuumStatement {
10433    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10434        write!(
10435            f,
10436            "VACUUM{}{}{}{}{}",
10437            if self.full { " FULL" } else { "" },
10438            if self.sort_only { " SORT ONLY" } else { "" },
10439            if self.delete_only { " DELETE ONLY" } else { "" },
10440            if self.reindex { " REINDEX" } else { "" },
10441            if self.recluster { " RECLUSTER" } else { "" },
10442        )?;
10443        if let Some(table_name) = &self.table_name {
10444            write!(f, " {table_name}")?;
10445        }
10446        if let Some(threshold) = &self.threshold {
10447            write!(f, " TO {threshold} PERCENT")?;
10448        }
10449        if self.boost {
10450            write!(f, " BOOST")?;
10451        }
10452        Ok(())
10453    }
10454}
10455
10456/// Variants of the RESET statement
10457#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10458#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10459#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10460pub enum Reset {
10461    /// Resets all session parameters to their default values.
10462    ALL,
10463
10464    /// Resets a specific session parameter to its default value.
10465    ConfigurationParameter(ObjectName),
10466}
10467
10468/// Resets a session parameter to its default value.
10469/// ```sql
10470/// RESET { ALL | <configuration_parameter> }
10471/// ```
10472#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10473#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10474#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10475pub struct ResetStatement {
10476    pub reset: Reset,
10477}
10478
10479impl fmt::Display for ResetStatement {
10480    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10481        match &self.reset {
10482            Reset::ALL => write!(f, "RESET ALL"),
10483            Reset::ConfigurationParameter(param) => write!(f, "RESET {}", param),
10484        }
10485    }
10486}
10487
10488impl From<Set> for Statement {
10489    fn from(s: Set) -> Self {
10490        Self::Set(s)
10491    }
10492}
10493
10494impl From<Query> for Statement {
10495    fn from(q: Query) -> Self {
10496        Box::new(q).into()
10497    }
10498}
10499
10500impl From<Box<Query>> for Statement {
10501    fn from(q: Box<Query>) -> Self {
10502        Self::Query(q)
10503    }
10504}
10505
10506impl From<Insert> for Statement {
10507    fn from(i: Insert) -> Self {
10508        Self::Insert(i)
10509    }
10510}
10511
10512impl From<Update> for Statement {
10513    fn from(u: Update) -> Self {
10514        Self::Update(u)
10515    }
10516}
10517
10518impl From<CreateView> for Statement {
10519    fn from(cv: CreateView) -> Self {
10520        Self::CreateView(cv)
10521    }
10522}
10523
10524impl From<CreateRole> for Statement {
10525    fn from(cr: CreateRole) -> Self {
10526        Self::CreateRole(cr)
10527    }
10528}
10529
10530impl From<AlterTable> for Statement {
10531    fn from(at: AlterTable) -> Self {
10532        Self::AlterTable(at)
10533    }
10534}
10535
10536impl From<DropFunction> for Statement {
10537    fn from(df: DropFunction) -> Self {
10538        Self::DropFunction(df)
10539    }
10540}
10541
10542impl From<CreateExtension> for Statement {
10543    fn from(ce: CreateExtension) -> Self {
10544        Self::CreateExtension(ce)
10545    }
10546}
10547
10548impl From<DropExtension> for Statement {
10549    fn from(de: DropExtension) -> Self {
10550        Self::DropExtension(de)
10551    }
10552}
10553
10554impl From<CaseStatement> for Statement {
10555    fn from(c: CaseStatement) -> Self {
10556        Self::Case(c)
10557    }
10558}
10559
10560impl From<IfStatement> for Statement {
10561    fn from(i: IfStatement) -> Self {
10562        Self::If(i)
10563    }
10564}
10565
10566impl From<WhileStatement> for Statement {
10567    fn from(w: WhileStatement) -> Self {
10568        Self::While(w)
10569    }
10570}
10571
10572impl From<RaiseStatement> for Statement {
10573    fn from(r: RaiseStatement) -> Self {
10574        Self::Raise(r)
10575    }
10576}
10577
10578impl From<Function> for Statement {
10579    fn from(f: Function) -> Self {
10580        Self::Call(f)
10581    }
10582}
10583
10584impl From<OpenStatement> for Statement {
10585    fn from(o: OpenStatement) -> Self {
10586        Self::Open(o)
10587    }
10588}
10589
10590impl From<Delete> for Statement {
10591    fn from(d: Delete) -> Self {
10592        Self::Delete(d)
10593    }
10594}
10595
10596impl From<CreateTable> for Statement {
10597    fn from(c: CreateTable) -> Self {
10598        Self::CreateTable(c)
10599    }
10600}
10601
10602impl From<CreateIndex> for Statement {
10603    fn from(c: CreateIndex) -> Self {
10604        Self::CreateIndex(c)
10605    }
10606}
10607
10608impl From<CreateServerStatement> for Statement {
10609    fn from(c: CreateServerStatement) -> Self {
10610        Self::CreateServer(c)
10611    }
10612}
10613
10614impl From<CreateConnector> for Statement {
10615    fn from(c: CreateConnector) -> Self {
10616        Self::CreateConnector(c)
10617    }
10618}
10619
10620impl From<AlterSchema> for Statement {
10621    fn from(a: AlterSchema) -> Self {
10622        Self::AlterSchema(a)
10623    }
10624}
10625
10626impl From<AlterType> for Statement {
10627    fn from(a: AlterType) -> Self {
10628        Self::AlterType(a)
10629    }
10630}
10631
10632impl From<DropDomain> for Statement {
10633    fn from(d: DropDomain) -> Self {
10634        Self::DropDomain(d)
10635    }
10636}
10637
10638impl From<ShowCharset> for Statement {
10639    fn from(s: ShowCharset) -> Self {
10640        Self::ShowCharset(s)
10641    }
10642}
10643
10644impl From<ShowObjects> for Statement {
10645    fn from(s: ShowObjects) -> Self {
10646        Self::ShowObjects(s)
10647    }
10648}
10649
10650impl From<Use> for Statement {
10651    fn from(u: Use) -> Self {
10652        Self::Use(u)
10653    }
10654}
10655
10656impl From<CreateFunction> for Statement {
10657    fn from(c: CreateFunction) -> Self {
10658        Self::CreateFunction(c)
10659    }
10660}
10661
10662impl From<CreateTrigger> for Statement {
10663    fn from(c: CreateTrigger) -> Self {
10664        Self::CreateTrigger(c)
10665    }
10666}
10667
10668impl From<DropTrigger> for Statement {
10669    fn from(d: DropTrigger) -> Self {
10670        Self::DropTrigger(d)
10671    }
10672}
10673
10674impl From<DenyStatement> for Statement {
10675    fn from(d: DenyStatement) -> Self {
10676        Self::Deny(d)
10677    }
10678}
10679
10680impl From<CreateDomain> for Statement {
10681    fn from(c: CreateDomain) -> Self {
10682        Self::CreateDomain(c)
10683    }
10684}
10685
10686impl From<RenameTable> for Statement {
10687    fn from(r: RenameTable) -> Self {
10688        vec![r].into()
10689    }
10690}
10691
10692impl From<Vec<RenameTable>> for Statement {
10693    fn from(r: Vec<RenameTable>) -> Self {
10694        Self::RenameTable(r)
10695    }
10696}
10697
10698impl From<PrintStatement> for Statement {
10699    fn from(p: PrintStatement) -> Self {
10700        Self::Print(p)
10701    }
10702}
10703
10704impl From<ReturnStatement> for Statement {
10705    fn from(r: ReturnStatement) -> Self {
10706        Self::Return(r)
10707    }
10708}
10709
10710impl From<ExportData> for Statement {
10711    fn from(e: ExportData) -> Self {
10712        Self::ExportData(e)
10713    }
10714}
10715
10716impl From<CreateUser> for Statement {
10717    fn from(c: CreateUser) -> Self {
10718        Self::CreateUser(c)
10719    }
10720}
10721
10722impl From<VacuumStatement> for Statement {
10723    fn from(v: VacuumStatement) -> Self {
10724        Self::Vacuum(v)
10725    }
10726}
10727
10728impl From<ResetStatement> for Statement {
10729    fn from(r: ResetStatement) -> Self {
10730        Self::Reset(r)
10731    }
10732}
10733
10734#[cfg(test)]
10735mod tests {
10736    use crate::tokenizer::Location;
10737
10738    use super::*;
10739
10740    #[test]
10741    fn test_window_frame_default() {
10742        let window_frame = WindowFrame::default();
10743        assert_eq!(WindowFrameBound::Preceding(None), window_frame.start_bound);
10744    }
10745
10746    #[test]
10747    fn test_grouping_sets_display() {
10748        // a and b in different group
10749        let grouping_sets = Expr::GroupingSets(vec![
10750            vec![Expr::Identifier(Ident::new("a"))],
10751            vec![Expr::Identifier(Ident::new("b"))],
10752        ]);
10753        assert_eq!("GROUPING SETS ((a), (b))", format!("{grouping_sets}"));
10754
10755        // a and b in the same group
10756        let grouping_sets = Expr::GroupingSets(vec![vec![
10757            Expr::Identifier(Ident::new("a")),
10758            Expr::Identifier(Ident::new("b")),
10759        ]]);
10760        assert_eq!("GROUPING SETS ((a, b))", format!("{grouping_sets}"));
10761
10762        // (a, b) and (c, d) in different group
10763        let grouping_sets = Expr::GroupingSets(vec![
10764            vec![
10765                Expr::Identifier(Ident::new("a")),
10766                Expr::Identifier(Ident::new("b")),
10767            ],
10768            vec![
10769                Expr::Identifier(Ident::new("c")),
10770                Expr::Identifier(Ident::new("d")),
10771            ],
10772        ]);
10773        assert_eq!("GROUPING SETS ((a, b), (c, d))", format!("{grouping_sets}"));
10774    }
10775
10776    #[test]
10777    fn test_rollup_display() {
10778        let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new("a"))]]);
10779        assert_eq!("ROLLUP (a)", format!("{rollup}"));
10780
10781        let rollup = Expr::Rollup(vec![vec![
10782            Expr::Identifier(Ident::new("a")),
10783            Expr::Identifier(Ident::new("b")),
10784        ]]);
10785        assert_eq!("ROLLUP ((a, b))", format!("{rollup}"));
10786
10787        let rollup = Expr::Rollup(vec![
10788            vec![Expr::Identifier(Ident::new("a"))],
10789            vec![Expr::Identifier(Ident::new("b"))],
10790        ]);
10791        assert_eq!("ROLLUP (a, b)", format!("{rollup}"));
10792
10793        let rollup = Expr::Rollup(vec![
10794            vec![Expr::Identifier(Ident::new("a"))],
10795            vec![
10796                Expr::Identifier(Ident::new("b")),
10797                Expr::Identifier(Ident::new("c")),
10798            ],
10799            vec![Expr::Identifier(Ident::new("d"))],
10800        ]);
10801        assert_eq!("ROLLUP (a, (b, c), d)", format!("{rollup}"));
10802    }
10803
10804    #[test]
10805    fn test_cube_display() {
10806        let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new("a"))]]);
10807        assert_eq!("CUBE (a)", format!("{cube}"));
10808
10809        let cube = Expr::Cube(vec![vec![
10810            Expr::Identifier(Ident::new("a")),
10811            Expr::Identifier(Ident::new("b")),
10812        ]]);
10813        assert_eq!("CUBE ((a, b))", format!("{cube}"));
10814
10815        let cube = Expr::Cube(vec![
10816            vec![Expr::Identifier(Ident::new("a"))],
10817            vec![Expr::Identifier(Ident::new("b"))],
10818        ]);
10819        assert_eq!("CUBE (a, b)", format!("{cube}"));
10820
10821        let cube = Expr::Cube(vec![
10822            vec![Expr::Identifier(Ident::new("a"))],
10823            vec![
10824                Expr::Identifier(Ident::new("b")),
10825                Expr::Identifier(Ident::new("c")),
10826            ],
10827            vec![Expr::Identifier(Ident::new("d"))],
10828        ]);
10829        assert_eq!("CUBE (a, (b, c), d)", format!("{cube}"));
10830    }
10831
10832    #[test]
10833    fn test_interval_display() {
10834        let interval = Expr::Interval(Interval {
10835            value: Box::new(Expr::Value(
10836                Value::SingleQuotedString(String::from("123:45.67")).with_empty_span(),
10837            )),
10838            leading_field: Some(DateTimeField::Minute),
10839            leading_precision: Some(10),
10840            last_field: Some(DateTimeField::Second),
10841            fractional_seconds_precision: Some(9),
10842        });
10843        assert_eq!(
10844            "INTERVAL '123:45.67' MINUTE (10) TO SECOND (9)",
10845            format!("{interval}"),
10846        );
10847
10848        let interval = Expr::Interval(Interval {
10849            value: Box::new(Expr::Value(
10850                Value::SingleQuotedString(String::from("5")).with_empty_span(),
10851            )),
10852            leading_field: Some(DateTimeField::Second),
10853            leading_precision: Some(1),
10854            last_field: None,
10855            fractional_seconds_precision: Some(3),
10856        });
10857        assert_eq!("INTERVAL '5' SECOND (1, 3)", format!("{interval}"));
10858    }
10859
10860    #[test]
10861    fn test_one_or_many_with_parens_deref() {
10862        use core::ops::Index;
10863
10864        let one = OneOrManyWithParens::One("a");
10865
10866        assert_eq!(one.deref(), &["a"]);
10867        assert_eq!(<OneOrManyWithParens<_> as Deref>::deref(&one), &["a"]);
10868
10869        assert_eq!(one[0], "a");
10870        assert_eq!(one.index(0), &"a");
10871        assert_eq!(
10872            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&one, 0),
10873            &"a"
10874        );
10875
10876        assert_eq!(one.len(), 1);
10877        assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&one), 1);
10878
10879        let many1 = OneOrManyWithParens::Many(vec!["b"]);
10880
10881        assert_eq!(many1.deref(), &["b"]);
10882        assert_eq!(<OneOrManyWithParens<_> as Deref>::deref(&many1), &["b"]);
10883
10884        assert_eq!(many1[0], "b");
10885        assert_eq!(many1.index(0), &"b");
10886        assert_eq!(
10887            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many1, 0),
10888            &"b"
10889        );
10890
10891        assert_eq!(many1.len(), 1);
10892        assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&many1), 1);
10893
10894        let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
10895
10896        assert_eq!(many2.deref(), &["c", "d"]);
10897        assert_eq!(
10898            <OneOrManyWithParens<_> as Deref>::deref(&many2),
10899            &["c", "d"]
10900        );
10901
10902        assert_eq!(many2[0], "c");
10903        assert_eq!(many2.index(0), &"c");
10904        assert_eq!(
10905            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many2, 0),
10906            &"c"
10907        );
10908
10909        assert_eq!(many2[1], "d");
10910        assert_eq!(many2.index(1), &"d");
10911        assert_eq!(
10912            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many2, 1),
10913            &"d"
10914        );
10915
10916        assert_eq!(many2.len(), 2);
10917        assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&many2), 2);
10918    }
10919
10920    #[test]
10921    fn test_one_or_many_with_parens_as_ref() {
10922        let one = OneOrManyWithParens::One("a");
10923
10924        assert_eq!(one.as_ref(), &["a"]);
10925        assert_eq!(<OneOrManyWithParens<_> as AsRef<_>>::as_ref(&one), &["a"]);
10926
10927        let many1 = OneOrManyWithParens::Many(vec!["b"]);
10928
10929        assert_eq!(many1.as_ref(), &["b"]);
10930        assert_eq!(<OneOrManyWithParens<_> as AsRef<_>>::as_ref(&many1), &["b"]);
10931
10932        let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
10933
10934        assert_eq!(many2.as_ref(), &["c", "d"]);
10935        assert_eq!(
10936            <OneOrManyWithParens<_> as AsRef<_>>::as_ref(&many2),
10937            &["c", "d"]
10938        );
10939    }
10940
10941    #[test]
10942    fn test_one_or_many_with_parens_ref_into_iter() {
10943        let one = OneOrManyWithParens::One("a");
10944
10945        assert_eq!(Vec::from_iter(&one), vec![&"a"]);
10946
10947        let many1 = OneOrManyWithParens::Many(vec!["b"]);
10948
10949        assert_eq!(Vec::from_iter(&many1), vec![&"b"]);
10950
10951        let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
10952
10953        assert_eq!(Vec::from_iter(&many2), vec![&"c", &"d"]);
10954    }
10955
10956    #[test]
10957    fn test_one_or_many_with_parens_value_into_iter() {
10958        use core::iter::once;
10959
10960        //tests that our iterator implemented methods behaves exactly as it's inner iterator, at every step up to n calls to next/next_back
10961        fn test_steps<I>(ours: OneOrManyWithParens<usize>, inner: I, n: usize)
10962        where
10963            I: IntoIterator<Item = usize, IntoIter: DoubleEndedIterator + Clone> + Clone,
10964        {
10965            fn checks<I>(ours: OneOrManyWithParensIntoIter<usize>, inner: I)
10966            where
10967                I: Iterator<Item = usize> + Clone + DoubleEndedIterator,
10968            {
10969                assert_eq!(ours.size_hint(), inner.size_hint());
10970                assert_eq!(ours.clone().count(), inner.clone().count());
10971
10972                assert_eq!(
10973                    ours.clone().fold(1, |a, v| a + v),
10974                    inner.clone().fold(1, |a, v| a + v)
10975                );
10976
10977                assert_eq!(Vec::from_iter(ours.clone()), Vec::from_iter(inner.clone()));
10978                assert_eq!(
10979                    Vec::from_iter(ours.clone().rev()),
10980                    Vec::from_iter(inner.clone().rev())
10981                );
10982            }
10983
10984            let mut ours_next = ours.clone().into_iter();
10985            let mut inner_next = inner.clone().into_iter();
10986
10987            for _ in 0..n {
10988                checks(ours_next.clone(), inner_next.clone());
10989
10990                assert_eq!(ours_next.next(), inner_next.next());
10991            }
10992
10993            let mut ours_next_back = ours.clone().into_iter();
10994            let mut inner_next_back = inner.clone().into_iter();
10995
10996            for _ in 0..n {
10997                checks(ours_next_back.clone(), inner_next_back.clone());
10998
10999                assert_eq!(ours_next_back.next_back(), inner_next_back.next_back());
11000            }
11001
11002            let mut ours_mixed = ours.clone().into_iter();
11003            let mut inner_mixed = inner.clone().into_iter();
11004
11005            for i in 0..n {
11006                checks(ours_mixed.clone(), inner_mixed.clone());
11007
11008                if i % 2 == 0 {
11009                    assert_eq!(ours_mixed.next_back(), inner_mixed.next_back());
11010                } else {
11011                    assert_eq!(ours_mixed.next(), inner_mixed.next());
11012                }
11013            }
11014
11015            let mut ours_mixed2 = ours.into_iter();
11016            let mut inner_mixed2 = inner.into_iter();
11017
11018            for i in 0..n {
11019                checks(ours_mixed2.clone(), inner_mixed2.clone());
11020
11021                if i % 2 == 0 {
11022                    assert_eq!(ours_mixed2.next(), inner_mixed2.next());
11023                } else {
11024                    assert_eq!(ours_mixed2.next_back(), inner_mixed2.next_back());
11025                }
11026            }
11027        }
11028
11029        test_steps(OneOrManyWithParens::One(1), once(1), 3);
11030        test_steps(OneOrManyWithParens::Many(vec![2]), vec![2], 3);
11031        test_steps(OneOrManyWithParens::Many(vec![3, 4]), vec![3, 4], 4);
11032    }
11033
11034    // Tests that the position in the code of an `Ident` does not affect its
11035    // ordering.
11036    #[test]
11037    fn test_ident_ord() {
11038        let mut a = Ident::with_span(Span::new(Location::new(1, 1), Location::new(1, 1)), "a");
11039        let mut b = Ident::with_span(Span::new(Location::new(2, 2), Location::new(2, 2)), "b");
11040
11041        assert!(a < b);
11042        std::mem::swap(&mut a.span, &mut b.span);
11043        assert!(a < b);
11044    }
11045}