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, Grant, ResetConfig, Revoke, RoleOption, SecondaryRoles,
60    SetConfigValue, Use,
61};
62pub use self::ddl::{
63    Alignment, AlterCollation, AlterCollationOperation, AlterColumnOperation, AlterConnectorOwner,
64    AlterFunction, AlterFunctionAction, AlterFunctionKind, AlterFunctionOperation,
65    AlterIndexOperation, AlterOperator, AlterOperatorClass, AlterOperatorClassOperation,
66    AlterOperatorFamily, AlterOperatorFamilyOperation, AlterOperatorOperation, AlterPolicy,
67    AlterPolicyOperation, AlterSchema, AlterSchemaOperation, AlterTable, AlterTableAlgorithm,
68    AlterTableLock, AlterTableOperation, AlterTableType, AlterType, AlterTypeAddValue,
69    AlterTypeAddValuePosition, AlterTypeOperation, AlterTypeRename, AlterTypeRenameValue,
70    ClusteredBy, ColumnDef, ColumnOption, ColumnOptionDef, ColumnOptions, ColumnPolicy,
71    ColumnPolicyProperty, ConstraintCharacteristics, CreateCollation, CreateCollationDefinition,
72    CreateConnector, CreateDomain, CreateExtension, CreateFunction, CreateIndex, CreateOperator,
73    CreateOperatorClass, CreateOperatorFamily, CreatePolicy, CreatePolicyCommand, CreatePolicyType,
74    CreateTable, CreateTrigger, CreateView, Deduplicate, DeferrableInitial, DistStyle,
75    DropBehavior, DropExtension, DropFunction, DropOperator, DropOperatorClass, DropOperatorFamily,
76    DropOperatorSignature, DropPolicy, DropTrigger, ForValues, FunctionReturnType, GeneratedAs,
77    GeneratedExpressionMode, IdentityParameters, IdentityProperty, IdentityPropertyFormatKind,
78    IdentityPropertyKind, IdentityPropertyOrder, IndexColumn, IndexOption, IndexType,
79    KeyOrIndexDisplay, Msck, NullsDistinctOption, OperatorArgTypes, OperatorClassItem,
80    OperatorFamilyDropItem, OperatorFamilyItem, OperatorOption, OperatorPurpose, Owner, Partition,
81    PartitionBoundValue, ProcedureParam, ReferentialAction, RenameTableNameKind, ReplicaIdentity,
82    TagsColumnOption, TriggerObjectKind, Truncate, UserDefinedTypeCompositeAttributeDef,
83    UserDefinedTypeInternalLength, UserDefinedTypeRangeOption, UserDefinedTypeRepresentation,
84    UserDefinedTypeSqlDefinitionOption, UserDefinedTypeStorage, ViewColumnDef,
85};
86pub use self::dml::{
87    Delete, Insert, Merge, MergeAction, MergeClause, MergeClauseKind, MergeInsertExpr,
88    MergeInsertKind, MergeUpdateExpr, MultiTableInsertIntoClause, MultiTableInsertType,
89    MultiTableInsertValue, MultiTableInsertValues, MultiTableInsertWhenClause, OutputClause,
90    Update,
91};
92pub use self::operator::{BinaryOperator, UnaryOperator};
93pub use self::query::{
94    AfterMatchSkip, ConnectByKind, Cte, CteAsMaterialized, Distinct, EmptyMatchesMode,
95    ExceptSelectItem, ExcludeSelectItem, ExprWithAlias, ExprWithAliasAndOrderBy, Fetch, ForClause,
96    ForJson, ForXml, FormatClause, GroupByExpr, GroupByWithModifier, IdentWithAlias,
97    IlikeSelectItem, InputFormatClause, Interpolate, InterpolateExpr, Join, JoinConstraint,
98    JoinOperator, JsonTableColumn, JsonTableColumnErrorHandling, JsonTableNamedColumn,
99    JsonTableNestedColumn, LateralView, LimitClause, LockClause, LockType, MatchRecognizePattern,
100    MatchRecognizeSymbol, Measure, NamedWindowDefinition, NamedWindowExpr, NonBlock, Offset,
101    OffsetRows, OpenJsonTableColumn, OrderBy, OrderByExpr, OrderByKind, OrderByOptions,
102    PipeOperator, PivotValueSource, ProjectionSelect, Query, RenameSelectItem,
103    RepetitionQuantifier, ReplaceSelectElement, ReplaceSelectItem, RowsPerMatch, Select,
104    SelectFlavor, SelectInto, SelectItem, SelectItemQualifiedWildcardKind, SelectModifiers,
105    SetExpr, SetOperator, SetQuantifier, Setting, SymbolDefinition, Table, TableAlias,
106    TableAliasColumnDef, TableFactor, TableFunctionArgs, TableIndexHintForClause,
107    TableIndexHintType, TableIndexHints, TableIndexType, TableSample, TableSampleBucket,
108    TableSampleKind, TableSampleMethod, TableSampleModifier, TableSampleQuantity, TableSampleSeed,
109    TableSampleSeedModifier, TableSampleUnit, TableVersion, TableWithJoins, Top, TopQuantity,
110    UpdateTableFromKind, ValueTableMode, Values, WildcardAdditionalOptions, With, WithFill,
111    XmlNamespaceDefinition, XmlPassingArgument, XmlPassingClause, XmlTableColumn,
112    XmlTableColumnOption,
113};
114
115pub use self::trigger::{
116    TriggerEvent, TriggerExecBody, TriggerExecBodyType, TriggerObject, TriggerPeriod,
117    TriggerReferencing, TriggerReferencingType,
118};
119
120pub use self::value::{
121    escape_double_quote_string, escape_quoted_string, DateTimeField, DollarQuotedString,
122    NormalizationForm, QuoteDelimitedString, TrimWhereField, Value, ValueWithSpan,
123};
124
125use crate::ast::helpers::key_value_options::KeyValueOptions;
126use crate::ast::helpers::stmt_data_loading::StageParamsObject;
127
128#[cfg(feature = "visitor")]
129pub use visitor::*;
130
131pub use self::data_type::GeometricTypeKind;
132
133mod data_type;
134mod dcl;
135mod ddl;
136mod dml;
137/// Helper modules for building and manipulating AST nodes.
138pub mod helpers;
139pub mod table_constraints;
140pub use table_constraints::{
141    CheckConstraint, ConstraintUsingIndex, ForeignKeyConstraint, FullTextOrSpatialConstraint,
142    IndexConstraint, PrimaryKeyConstraint, TableConstraint, UniqueConstraint,
143};
144mod operator;
145mod query;
146mod spans;
147pub use spans::Spanned;
148
149pub mod comments;
150mod trigger;
151mod value;
152
153#[cfg(feature = "visitor")]
154mod visitor;
155
156/// Helper used to format a slice using a separator string (e.g., `", "`).
157pub struct DisplaySeparated<'a, T>
158where
159    T: fmt::Display,
160{
161    slice: &'a [T],
162    sep: &'static str,
163}
164
165impl<T> fmt::Display for DisplaySeparated<'_, T>
166where
167    T: fmt::Display,
168{
169    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
170        let mut delim = "";
171        for t in self.slice {
172            f.write_str(delim)?;
173            delim = self.sep;
174            t.fmt(f)?;
175        }
176        Ok(())
177    }
178}
179
180pub(crate) fn display_separated<'a, T>(slice: &'a [T], sep: &'static str) -> DisplaySeparated<'a, T>
181where
182    T: fmt::Display,
183{
184    DisplaySeparated { slice, sep }
185}
186
187pub(crate) fn display_comma_separated<T>(slice: &[T]) -> DisplaySeparated<'_, T>
188where
189    T: fmt::Display,
190{
191    DisplaySeparated { slice, sep: ", " }
192}
193
194/// Writes the given statements to the formatter, each ending with
195/// a semicolon and space separated.
196fn format_statement_list(f: &mut fmt::Formatter, statements: &[Statement]) -> fmt::Result {
197    write!(f, "{}", display_separated(statements, "; "))?;
198    // We manually insert semicolon for the last statement,
199    // since display_separated doesn't handle that case.
200    write!(f, ";")
201}
202
203/// An identifier, decomposed into its value or character data and the quote style.
204#[derive(Debug, Clone)]
205#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
206#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
207pub struct Ident {
208    /// The value of the identifier without quotes.
209    pub value: String,
210    /// The starting quote if any. Valid quote characters are the single quote,
211    /// double quote, backtick, and opening square bracket.
212    pub quote_style: Option<char>,
213    /// The span of the identifier in the original SQL string.
214    pub span: Span,
215}
216
217impl PartialEq for Ident {
218    fn eq(&self, other: &Self) -> bool {
219        let Ident {
220            value,
221            quote_style,
222            // exhaustiveness check; we ignore spans in comparisons
223            span: _,
224        } = self;
225
226        value == &other.value && quote_style == &other.quote_style
227    }
228}
229
230impl core::hash::Hash for Ident {
231    fn hash<H: hash::Hasher>(&self, state: &mut H) {
232        let Ident {
233            value,
234            quote_style,
235            // exhaustiveness check; we ignore spans in hashes
236            span: _,
237        } = self;
238
239        value.hash(state);
240        quote_style.hash(state);
241    }
242}
243
244impl Eq for Ident {}
245
246impl PartialOrd for Ident {
247    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
248        Some(self.cmp(other))
249    }
250}
251
252impl Ord for Ident {
253    fn cmp(&self, other: &Self) -> Ordering {
254        let Ident {
255            value,
256            quote_style,
257            // exhaustiveness check; we ignore spans in ordering
258            span: _,
259        } = self;
260
261        let Ident {
262            value: other_value,
263            quote_style: other_quote_style,
264            // exhaustiveness check; we ignore spans in ordering
265            span: _,
266        } = other;
267
268        // First compare by value, then by quote_style
269        value
270            .cmp(other_value)
271            .then_with(|| quote_style.cmp(other_quote_style))
272    }
273}
274
275impl Ident {
276    /// Create a new identifier with the given value and no quotes and an empty span.
277    pub fn new<S>(value: S) -> Self
278    where
279        S: Into<String>,
280    {
281        Ident {
282            value: value.into(),
283            quote_style: None,
284            span: Span::empty(),
285        }
286    }
287
288    /// Create a new quoted identifier with the given quote and value. This function
289    /// panics if the given quote is not a valid quote character.
290    pub fn with_quote<S>(quote: char, value: S) -> Self
291    where
292        S: Into<String>,
293    {
294        assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
295        Ident {
296            value: value.into(),
297            quote_style: Some(quote),
298            span: Span::empty(),
299        }
300    }
301
302    /// Create an `Ident` with the given `span` and `value` (unquoted).
303    pub fn with_span<S>(span: Span, value: S) -> Self
304    where
305        S: Into<String>,
306    {
307        Ident {
308            value: value.into(),
309            quote_style: None,
310            span,
311        }
312    }
313
314    /// Create a quoted `Ident` with the given `quote` and `span`.
315    pub fn with_quote_and_span<S>(quote: char, span: Span, value: S) -> Self
316    where
317        S: Into<String>,
318    {
319        assert!(quote == '\'' || quote == '"' || quote == '`' || quote == '[');
320        Ident {
321            value: value.into(),
322            quote_style: Some(quote),
323            span,
324        }
325    }
326}
327
328impl From<&str> for Ident {
329    fn from(value: &str) -> Self {
330        Ident {
331            value: value.to_string(),
332            quote_style: None,
333            span: Span::empty(),
334        }
335    }
336}
337
338impl fmt::Display for Ident {
339    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
340        match self.quote_style {
341            Some(q) if q == '"' || q == '\'' || q == '`' => {
342                let escaped = value::escape_quoted_string(&self.value, q);
343                write!(f, "{q}{escaped}{q}")
344            }
345            Some('[') => write!(f, "[{}]", self.value),
346            None => f.write_str(&self.value),
347            _ => panic!("unexpected quote style"),
348        }
349    }
350}
351
352/// A name of a table, view, custom type, etc., possibly multi-part, i.e. db.schema.obj
353#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
354#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
355#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
356pub struct ObjectName(pub Vec<ObjectNamePart>);
357
358impl From<Vec<Ident>> for ObjectName {
359    fn from(idents: Vec<Ident>) -> Self {
360        ObjectName(idents.into_iter().map(ObjectNamePart::Identifier).collect())
361    }
362}
363
364impl From<Ident> for ObjectName {
365    fn from(ident: Ident) -> Self {
366        ObjectName(vec![ObjectNamePart::Identifier(ident)])
367    }
368}
369
370impl fmt::Display for ObjectName {
371    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
372        write!(f, "{}", display_separated(&self.0, "."))
373    }
374}
375
376/// A single part of an ObjectName
377#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
378#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
379#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
380pub enum ObjectNamePart {
381    /// A single identifier part, e.g. `schema` or `table`.
382    Identifier(Ident),
383    /// A function that returns an identifier (dialect-specific).
384    Function(ObjectNamePartFunction),
385}
386
387impl ObjectNamePart {
388    /// Return the identifier if this is an `Identifier` variant.
389    pub fn as_ident(&self) -> Option<&Ident> {
390        match self {
391            ObjectNamePart::Identifier(ident) => Some(ident),
392            ObjectNamePart::Function(_) => None,
393        }
394    }
395}
396
397impl fmt::Display for ObjectNamePart {
398    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
399        match self {
400            ObjectNamePart::Identifier(ident) => write!(f, "{ident}"),
401            ObjectNamePart::Function(func) => write!(f, "{func}"),
402        }
403    }
404}
405
406/// An object name part that consists of a function that dynamically
407/// constructs identifiers.
408///
409/// - [Snowflake](https://docs.snowflake.com/en/sql-reference/identifier-literal)
410#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
411#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
412#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
413pub struct ObjectNamePartFunction {
414    /// The function name that produces the object name part.
415    pub name: Ident,
416    /// Function arguments used to compute the identifier.
417    pub args: Vec<FunctionArg>,
418}
419
420impl fmt::Display for ObjectNamePartFunction {
421    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
422        write!(f, "{}(", self.name)?;
423        write!(f, "{})", display_comma_separated(&self.args))
424    }
425}
426
427/// Represents an Array Expression, either
428/// `ARRAY[..]`, or `[..]`
429#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
430#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
431#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
432pub struct Array {
433    /// The list of expressions between brackets
434    pub elem: Vec<Expr>,
435
436    /// `true` for  `ARRAY[..]`, `false` for `[..]`
437    pub named: bool,
438}
439
440impl fmt::Display for Array {
441    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
442        write!(
443            f,
444            "{}[{}]",
445            if self.named { "ARRAY" } else { "" },
446            display_comma_separated(&self.elem)
447        )
448    }
449}
450
451/// Represents an INTERVAL expression, roughly in the following format:
452/// `INTERVAL '<value>' [ <leading_field> [ (<leading_precision>) ] ]
453/// [ TO <last_field> [ (<fractional_seconds_precision>) ] ]`,
454/// e.g. `INTERVAL '123:45.67' MINUTE(3) TO SECOND(2)`.
455///
456/// The parser does not validate the `<value>`, nor does it ensure
457/// that the `<leading_field>` units >= the units in `<last_field>`,
458/// so the user will have to reject intervals like `HOUR TO YEAR`.
459#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
460#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
461#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
462pub struct Interval {
463    /// The interval value expression (commonly a string literal).
464    pub value: Box<Expr>,
465    /// Optional leading time unit (e.g., `HOUR`, `MINUTE`).
466    pub leading_field: Option<DateTimeField>,
467    /// Optional leading precision for the leading field.
468    pub leading_precision: Option<u64>,
469    /// Optional trailing time unit for a range (e.g., `SECOND`).
470    pub last_field: Option<DateTimeField>,
471    /// The fractional seconds precision, when specified.
472    ///
473    /// See SQL `SECOND(n)` or `SECOND(m, n)` forms.
474    pub fractional_seconds_precision: Option<u64>,
475}
476
477impl fmt::Display for Interval {
478    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
479        let value = self.value.as_ref();
480        match (
481            &self.leading_field,
482            self.leading_precision,
483            self.fractional_seconds_precision,
484        ) {
485            (
486                Some(DateTimeField::Second),
487                Some(leading_precision),
488                Some(fractional_seconds_precision),
489            ) => {
490                // When the leading field is SECOND, the parser guarantees that
491                // the last field is None.
492                assert!(self.last_field.is_none());
493                write!(
494                    f,
495                    "INTERVAL {value} SECOND ({leading_precision}, {fractional_seconds_precision})"
496                )
497            }
498            _ => {
499                write!(f, "INTERVAL {value}")?;
500                if let Some(leading_field) = &self.leading_field {
501                    write!(f, " {leading_field}")?;
502                }
503                if let Some(leading_precision) = self.leading_precision {
504                    write!(f, " ({leading_precision})")?;
505                }
506                if let Some(last_field) = &self.last_field {
507                    write!(f, " TO {last_field}")?;
508                }
509                if let Some(fractional_seconds_precision) = self.fractional_seconds_precision {
510                    write!(f, " ({fractional_seconds_precision})")?;
511                }
512                Ok(())
513            }
514        }
515    }
516}
517
518/// A field definition within a struct
519///
520/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
521#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
522#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
523#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
524pub struct StructField {
525    /// Optional name of the struct field.
526    pub field_name: Option<Ident>,
527    /// The field data type.
528    pub field_type: DataType,
529    /// Struct field options (e.g., `OPTIONS(...)` on BigQuery).
530    /// See [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#column_name_and_column_schema)
531    pub options: Option<Vec<SqlOption>>,
532}
533
534impl fmt::Display for StructField {
535    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
536        if let Some(name) = &self.field_name {
537            write!(f, "{name} {}", self.field_type)?;
538        } else {
539            write!(f, "{}", self.field_type)?;
540        }
541        if let Some(options) = &self.options {
542            write!(f, " OPTIONS({})", display_separated(options, ", "))
543        } else {
544            Ok(())
545        }
546    }
547}
548
549/// A field definition within a union
550///
551/// [DuckDB]: https://duckdb.org/docs/sql/data_types/union.html
552#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
553#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
554#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
555pub struct UnionField {
556    /// Name of the union field.
557    pub field_name: Ident,
558    /// Type of the union field.
559    pub field_type: DataType,
560}
561
562impl fmt::Display for UnionField {
563    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
564        write!(f, "{} {}", self.field_name, self.field_type)
565    }
566}
567
568/// A dictionary field within a dictionary.
569///
570/// [DuckDB]: https://duckdb.org/docs/sql/data_types/struct#creating-structs
571#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
572#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
573#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
574pub struct DictionaryField {
575    /// Dictionary key identifier.
576    pub key: Ident,
577    /// Value expression for the dictionary entry.
578    pub value: Box<Expr>,
579}
580
581impl fmt::Display for DictionaryField {
582    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
583        write!(f, "{}: {}", self.key, self.value)
584    }
585}
586
587/// Represents a Map expression.
588#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
589#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
590#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
591pub struct Map {
592    /// Entries of the map as key/value pairs.
593    pub entries: Vec<MapEntry>,
594}
595
596impl Display for Map {
597    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
598        write!(f, "MAP {{{}}}", display_comma_separated(&self.entries))
599    }
600}
601
602/// A map field within a map.
603///
604/// [DuckDB]: https://duckdb.org/docs/sql/data_types/map.html#creating-maps
605#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
606#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
607#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
608pub struct MapEntry {
609    /// Key expression of the map entry.
610    pub key: Box<Expr>,
611    /// Value expression of the map entry.
612    pub value: Box<Expr>,
613}
614
615impl fmt::Display for MapEntry {
616    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
617        write!(f, "{}: {}", self.key, self.value)
618    }
619}
620
621/// Options for `CAST` / `TRY_CAST`
622/// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax>
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 enum CastFormat {
627    /// A simple cast format specified by a `Value`.
628    Value(ValueWithSpan),
629    /// A cast format with an explicit time zone: `(format, timezone)`.
630    ValueAtTimeZone(ValueWithSpan, ValueWithSpan),
631}
632
633/// An element of a JSON path.
634#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
635#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
636#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
637pub enum JsonPathElem {
638    /// Accesses an object field using dot notation, e.g. `obj:foo.bar.baz`.
639    ///
640    /// See <https://docs.snowflake.com/en/user-guide/querying-semistructured#dot-notation>.
641    Dot {
642        /// The object key text (without quotes).
643        key: String,
644        /// `true` when the key was quoted in the source.
645        quoted: bool,
646    },
647    /// Accesses an object field or array element using bracket notation,
648    /// e.g. `obj['foo']`.
649    ///
650    /// See <https://docs.snowflake.com/en/user-guide/querying-semistructured#bracket-notation>.
651    Bracket {
652        /// The expression used as the bracket key (string or numeric expression).
653        key: Expr,
654    },
655    /// Access an object field using colon bracket notation
656    /// e.g. `obj:['foo']`
657    ///
658    /// See <https://docs.databricks.com/en/sql/language-manual/functions/colonsign.html>
659    ColonBracket {
660        /// The expression used as the bracket key (string or numeric expression).
661        key: Expr,
662    },
663}
664
665/// A JSON path.
666///
667/// See <https://docs.snowflake.com/en/user-guide/querying-semistructured>.
668/// See <https://docs.databricks.com/en/sql/language-manual/sql-ref-json-path-expression.html>.
669#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
670#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
671#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
672pub struct JsonPath {
673    /// Sequence of path elements that form the JSON path.
674    pub path: Vec<JsonPathElem>,
675}
676
677impl fmt::Display for JsonPath {
678    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
679        for (i, elem) in self.path.iter().enumerate() {
680            match elem {
681                JsonPathElem::Dot { key, quoted } => {
682                    if i == 0 {
683                        write!(f, ":")?;
684                    } else {
685                        write!(f, ".")?;
686                    }
687
688                    if *quoted {
689                        write!(f, "\"{}\"", escape_double_quote_string(key))?;
690                    } else {
691                        write!(f, "{key}")?;
692                    }
693                }
694                JsonPathElem::Bracket { key } => {
695                    write!(f, "[{key}]")?;
696                }
697                JsonPathElem::ColonBracket { key } => {
698                    write!(f, ":[{key}]")?;
699                }
700            }
701        }
702        Ok(())
703    }
704}
705
706/// The syntax used for in a cast expression.
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 CastKind {
711    /// The standard SQL cast syntax, e.g. `CAST(<expr> as <datatype>)`
712    Cast,
713    /// A cast that returns `NULL` on failure, e.g. `TRY_CAST(<expr> as <datatype>)`.
714    ///
715    /// See <https://docs.snowflake.com/en/sql-reference/functions/try_cast>.
716    /// See <https://learn.microsoft.com/en-us/sql/t-sql/functions/try-cast-transact-sql>.
717    TryCast,
718    /// A cast that returns `NULL` on failure, bigQuery-specific ,  e.g. `SAFE_CAST(<expr> as <datatype>)`.
719    ///
720    /// See <https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#safe_casting>.
721    SafeCast,
722    /// `<expr> :: <datatype>`
723    DoubleColon,
724}
725
726/// `MATCH` type for constraint references
727///
728/// See: <https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-PARMS-REFERENCES>
729#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
730#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
731#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
732pub enum ConstraintReferenceMatchKind {
733    /// `MATCH FULL`
734    Full,
735    /// `MATCH PARTIAL`
736    Partial,
737    /// `MATCH SIMPLE`
738    Simple,
739}
740
741impl fmt::Display for ConstraintReferenceMatchKind {
742    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
743        match self {
744            Self::Full => write!(f, "MATCH FULL"),
745            Self::Partial => write!(f, "MATCH PARTIAL"),
746            Self::Simple => write!(f, "MATCH SIMPLE"),
747        }
748    }
749}
750
751/// `EXTRACT` syntax variants.
752///
753/// In Snowflake dialect, the `EXTRACT` expression can support either the `from` syntax
754/// or the comma syntax.
755///
756/// See <https://docs.snowflake.com/en/sql-reference/functions/extract>
757#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
758#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
759#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
760pub enum ExtractSyntax {
761    /// `EXTRACT( <date_or_time_part> FROM <date_or_time_expr> )`
762    From,
763    /// `EXTRACT( <date_or_time_part> , <date_or_timestamp_expr> )`
764    Comma,
765}
766
767/// The syntax used in a CEIL or FLOOR expression.
768///
769/// The `CEIL/FLOOR(<datetime value expression> TO <time unit>)` is an Amazon Kinesis Data Analytics extension.
770/// See <https://docs.aws.amazon.com/kinesisanalytics/latest/sqlref/sql-reference-ceil.html> for
771/// details.
772///
773/// Other dialects either support `CEIL/FLOOR( <expr> [, <scale>])` format or just
774/// `CEIL/FLOOR(<expr>)`.
775#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
776#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
777#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
778pub enum CeilFloorKind {
779    /// `CEIL( <expr> TO <DateTimeField>)`
780    DateTimeField(DateTimeField),
781    /// `CEIL( <expr> [, <scale>])`
782    Scale(ValueWithSpan),
783}
784
785/// A WHEN clause in a CASE expression containing both
786/// the condition and its corresponding result
787#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
788#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
789#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
790pub struct CaseWhen {
791    /// The `WHEN` condition expression.
792    pub condition: Expr,
793    /// The expression returned when `condition` matches.
794    pub result: Expr,
795}
796
797impl fmt::Display for CaseWhen {
798    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
799        f.write_str("WHEN ")?;
800        self.condition.fmt(f)?;
801        f.write_str(" THEN")?;
802        SpaceOrNewline.fmt(f)?;
803        Indent(&self.result).fmt(f)?;
804        Ok(())
805    }
806}
807
808/// An SQL expression of any type.
809///
810/// # Semantics / Type Checking
811///
812/// The parser does not distinguish between expressions of different types
813/// (e.g. boolean vs string). The caller is responsible for detecting and
814/// validating types as necessary (for example  `WHERE 1` vs `SELECT 1=1`)
815/// See the [README.md] for more details.
816///
817/// [README.md]: https://github.com/apache/datafusion-sqlparser-rs/blob/main/README.md#syntax-vs-semantics
818///
819/// # Equality and Hashing Does not Include Source Locations
820///
821/// The `Expr` type implements `PartialEq` and `Eq` based on the semantic value
822/// of the expression (not bitwise comparison). This means that `Expr` instances
823/// that are semantically equivalent but have different spans (locations in the
824/// source tree) will compare as equal.
825#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
826#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
827#[cfg_attr(
828    feature = "visitor",
829    derive(Visit, VisitMut),
830    visit(with = "visit_expr")
831)]
832pub enum Expr {
833    /// Identifier e.g. table name or column name
834    Identifier(Ident),
835    /// Multi-part identifier, e.g. `table_alias.column` or `schema.table.col`
836    CompoundIdentifier(Vec<Ident>),
837    /// Multi-part expression access.
838    ///
839    /// This structure represents an access chain in structured / nested types
840    /// such as maps, arrays, and lists:
841    /// - Array
842    ///     - A 1-dim array `a[1]` will be represented like:
843    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript(1)]`
844    ///     - A 2-dim array `a[1][2]` will be represented like:
845    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript(1), Subscript(2)]`
846    /// - Map or Struct (Bracket-style)
847    ///     - A map `a['field1']` will be represented like:
848    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript('field')]`
849    ///     - A 2-dim map `a['field1']['field2']` will be represented like:
850    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript('field1'), Subscript('field2')]`
851    /// - Struct (Dot-style) (only effect when the chain contains both subscript and expr)
852    ///     - A struct access `a[field1].field2` will be represented like:
853    ///       `CompoundFieldAccess(Ident('a'), vec![Subscript('field1'), Ident('field2')]`
854    /// - If a struct access likes `a.field1.field2`, it will be represented by CompoundIdentifier([a, field1, field2])
855    CompoundFieldAccess {
856        /// The base expression being accessed.
857        root: Box<Expr>,
858        /// Sequence of access operations (subscript or identifier accesses).
859        access_chain: Vec<AccessExpr>,
860    },
861    /// Access data nested in a value containing semi-structured data, such as
862    /// the `VARIANT` type on Snowflake. for example `src:customer[0].name`.
863    ///
864    /// See <https://docs.snowflake.com/en/user-guide/querying-semistructured>.
865    /// See <https://docs.databricks.com/en/sql/language-manual/functions/colonsign.html>.
866    JsonAccess {
867        /// The value being queried.
868        value: Box<Expr>,
869        /// The path to the data to extract.
870        path: JsonPath,
871    },
872    /// `IS FALSE` operator
873    IsFalse(Box<Expr>),
874    /// `IS NOT FALSE` operator
875    IsNotFalse(Box<Expr>),
876    /// `IS TRUE` operator
877    IsTrue(Box<Expr>),
878    /// `IS NOT TRUE` operator
879    IsNotTrue(Box<Expr>),
880    /// `IS NULL` operator
881    IsNull(Box<Expr>),
882    /// `IS NOT NULL` operator
883    IsNotNull(Box<Expr>),
884    /// `IS UNKNOWN` operator
885    IsUnknown(Box<Expr>),
886    /// `IS NOT UNKNOWN` operator
887    IsNotUnknown(Box<Expr>),
888    /// `IS DISTINCT FROM` operator
889    IsDistinctFrom(Box<Expr>, Box<Expr>),
890    /// `IS NOT DISTINCT FROM` operator
891    IsNotDistinctFrom(Box<Expr>, Box<Expr>),
892    /// `<expr> IS [ NOT ] [ form ] NORMALIZED`
893    IsNormalized {
894        /// Expression being tested.
895        expr: Box<Expr>,
896        /// Optional normalization `form` (e.g., NFC, NFD).
897        form: Option<NormalizationForm>,
898        /// `true` when `NOT` is present.
899        negated: bool,
900    },
901    /// `[ NOT ] IN (val1, val2, ...)`
902    InList {
903        /// Left-hand expression to test for membership.
904        expr: Box<Expr>,
905        /// Literal list of expressions to check against.
906        list: Vec<Expr>,
907        /// `true` when the `NOT` modifier is present.
908        negated: bool,
909    },
910    /// `[ NOT ] IN (SELECT ...)`
911    InSubquery {
912        /// Left-hand expression to test for membership.
913        expr: Box<Expr>,
914        /// The subquery providing the candidate values.
915        subquery: Box<Query>,
916        /// `true` when the `NOT` modifier is present.
917        negated: bool,
918    },
919    /// `[ NOT ] IN UNNEST(array_expression)`
920    InUnnest {
921        /// Left-hand expression to test for membership.
922        expr: Box<Expr>,
923        /// Array expression being unnested.
924        array_expr: Box<Expr>,
925        /// `true` when the `NOT` modifier is present.
926        negated: bool,
927    },
928    /// `<expr> [ NOT ] BETWEEN <low> AND <high>`
929    Between {
930        /// Expression being compared.
931        expr: Box<Expr>,
932        /// `true` when the `NOT` modifier is present.
933        negated: bool,
934        /// Lower bound.
935        low: Box<Expr>,
936        /// Upper bound.
937        high: Box<Expr>,
938    },
939    /// Binary operation e.g. `1 + 1` or `foo > bar`
940    BinaryOp {
941        /// Left operand.
942        left: Box<Expr>,
943        /// Operator between operands.
944        op: BinaryOperator,
945        /// Right operand.
946        right: Box<Expr>,
947    },
948    /// `[NOT] LIKE <pattern> [ESCAPE <escape_character>]`
949    Like {
950        /// `true` when `NOT` is present.
951        negated: bool,
952        /// Snowflake supports the ANY keyword to match against a list of patterns
953        /// <https://docs.snowflake.com/en/sql-reference/functions/like_any>
954        any: bool,
955        /// Expression to match.
956        expr: Box<Expr>,
957        /// Pattern expression.
958        pattern: Box<Expr>,
959        /// Optional escape character.
960        escape_char: Option<ValueWithSpan>,
961    },
962    /// `ILIKE` (case-insensitive `LIKE`)
963    ILike {
964        /// `true` when `NOT` is present.
965        negated: bool,
966        /// Snowflake supports the ANY keyword to match against a list of patterns
967        /// <https://docs.snowflake.com/en/sql-reference/functions/like_any>
968        any: bool,
969        /// Expression to match.
970        expr: Box<Expr>,
971        /// Pattern expression.
972        pattern: Box<Expr>,
973        /// Optional escape character.
974        escape_char: Option<ValueWithSpan>,
975    },
976    /// `SIMILAR TO` regex
977    SimilarTo {
978        /// `true` when `NOT` is present.
979        negated: bool,
980        /// Expression to test.
981        expr: Box<Expr>,
982        /// Pattern expression.
983        pattern: Box<Expr>,
984        /// Optional escape character.
985        escape_char: Option<ValueWithSpan>,
986    },
987    /// MySQL: `RLIKE` regex or `REGEXP` regex
988    RLike {
989        /// `true` when `NOT` is present.
990        negated: bool,
991        /// Expression to test.
992        expr: Box<Expr>,
993        /// Pattern expression.
994        pattern: Box<Expr>,
995        /// true for REGEXP, false for RLIKE (no difference in semantics)
996        regexp: bool,
997    },
998    /// `ANY` operation e.g. `foo > ANY(bar)`, comparison operator is one of `[=, >, <, =>, =<, !=]`
999    /// <https://docs.snowflake.com/en/sql-reference/operators-subquery#all-any>
1000    AnyOp {
1001        /// Left operand.
1002        left: Box<Expr>,
1003        /// Comparison operator.
1004        compare_op: BinaryOperator,
1005        /// Right-hand subquery expression.
1006        right: Box<Expr>,
1007        /// ANY and SOME are synonymous: <https://docs.cloudera.com/cdw-runtime/cloud/using-hiveql/topics/hive_comparison_predicates.html>
1008        is_some: bool,
1009    },
1010    /// `ALL` operation e.g. `foo > ALL(bar)`, comparison operator is one of `[=, >, <, =>, =<, !=]`
1011    /// <https://docs.snowflake.com/en/sql-reference/operators-subquery#all-any>
1012    AllOp {
1013        /// Left operand.
1014        left: Box<Expr>,
1015        /// Comparison operator.
1016        compare_op: BinaryOperator,
1017        /// Right-hand subquery expression.
1018        right: Box<Expr>,
1019    },
1020
1021    /// Unary operation e.g. `NOT foo`
1022    UnaryOp {
1023        /// The unary operator (e.g., `NOT`, `-`).
1024        op: UnaryOperator,
1025        /// Operand expression.
1026        expr: Box<Expr>,
1027    },
1028    /// CONVERT a value to a different data type or character encoding. e.g. `CONVERT(foo USING utf8mb4)`
1029    Convert {
1030        /// CONVERT (false) or TRY_CONVERT (true)
1031        /// <https://learn.microsoft.com/en-us/sql/t-sql/functions/try-convert-transact-sql?view=sql-server-ver16>
1032        is_try: bool,
1033        /// The expression to convert.
1034        expr: Box<Expr>,
1035        /// The target data type, if provided.
1036        data_type: Option<DataType>,
1037        /// Optional target character encoding (e.g., `utf8mb4`).
1038        charset: Option<ObjectName>,
1039        /// `true` when target precedes the value (MSSQL syntax).
1040        target_before_value: bool,
1041        /// How to translate the expression.
1042        ///
1043        /// [MSSQL]: https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#style
1044        styles: Vec<Expr>,
1045    },
1046    /// `CAST` an expression to a different data type e.g. `CAST(foo AS VARCHAR(123))`
1047    Cast {
1048        /// The cast kind (e.g., `CAST`, `TRY_CAST`).
1049        kind: CastKind,
1050        /// Expression being cast.
1051        expr: Box<Expr>,
1052        /// Target data type.
1053        data_type: DataType,
1054        /// [MySQL] allows CAST(... AS type ARRAY) in functional index definitions for InnoDB
1055        /// multi-valued indices. It's not really a datatype, and is only allowed in `CAST` in key
1056        /// specifications, so it's a flag here.
1057        ///
1058        /// [MySQL]: https://dev.mysql.com/doc/refman/8.4/en/cast-functions.html#function_cast
1059        array: bool,
1060        /// Optional CAST(string_expression AS type FORMAT format_string_expression) as used by [BigQuery]
1061        ///
1062        /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax
1063        format: Option<CastFormat>,
1064    },
1065    /// AT a timestamp to a different timezone e.g. `FROM_UNIXTIME(0) AT TIME ZONE 'UTC-06:00'`
1066    AtTimeZone {
1067        /// Timestamp expression to shift.
1068        timestamp: Box<Expr>,
1069        /// Time zone expression to apply.
1070        time_zone: Box<Expr>,
1071    },
1072    /// Extract a field from a timestamp e.g. `EXTRACT(MONTH FROM foo)`
1073    /// Or `EXTRACT(MONTH, foo)`
1074    ///
1075    /// Syntax:
1076    /// ```sql
1077    /// EXTRACT(DateTimeField FROM <expr>) | EXTRACT(DateTimeField, <expr>)
1078    /// ```
1079    Extract {
1080        /// Which datetime field is being extracted.
1081        field: DateTimeField,
1082        /// Syntax variant used (`From` or `Comma`).
1083        syntax: ExtractSyntax,
1084        /// Expression to extract from.
1085        expr: Box<Expr>,
1086    },
1087    /// ```sql
1088    /// CEIL(<expr> [TO DateTimeField])
1089    /// ```
1090    /// ```sql
1091    /// CEIL( <input_expr> [, <scale_expr> ] )
1092    /// ```
1093    Ceil {
1094        /// Expression to ceil.
1095        expr: Box<Expr>,
1096        /// The CEIL/FLOOR kind (datetime field or scale).
1097        field: CeilFloorKind,
1098    },
1099    /// ```sql
1100    /// FLOOR(<expr> [TO DateTimeField])
1101    /// ```
1102    /// ```sql
1103    /// FLOOR( <input_expr> [, <scale_expr> ] )
1104    ///
1105    Floor {
1106        /// Expression to floor.
1107        expr: Box<Expr>,
1108        /// The CEIL/FLOOR kind (datetime field or scale).
1109        field: CeilFloorKind,
1110    },
1111    /// ```sql
1112    /// POSITION(<expr> in <expr>)
1113    /// ```
1114    Position {
1115        /// Expression to search for.
1116        expr: Box<Expr>,
1117        /// Expression to search in.
1118        r#in: Box<Expr>,
1119    },
1120    /// ```sql
1121    /// SUBSTRING(<expr> [FROM <expr>] [FOR <expr>])
1122    /// ```
1123    /// or
1124    /// ```sql
1125    /// SUBSTRING(<expr>, <expr>, <expr>)
1126    /// ```
1127    Substring {
1128        /// Source expression.
1129        expr: Box<Expr>,
1130        /// Optional `FROM` expression.
1131        substring_from: Option<Box<Expr>>,
1132        /// Optional `FOR` expression.
1133        substring_for: Option<Box<Expr>>,
1134
1135        /// false if the expression is represented using the `SUBSTRING(expr [FROM start] [FOR len])` syntax
1136        /// true if the expression is represented using the `SUBSTRING(expr, start, len)` syntax
1137        /// This flag is used for formatting.
1138        special: bool,
1139
1140        /// true if the expression is represented using the `SUBSTR` shorthand
1141        /// This flag is used for formatting.
1142        shorthand: bool,
1143    },
1144    /// ```sql
1145    /// TRIM([BOTH | LEADING | TRAILING] [<expr> FROM] <expr>)
1146    /// TRIM(<expr>)
1147    /// TRIM(<expr>, [, characters]) -- PostgreSQL, DuckDB, Snowflake, BigQuery, Generic
1148    /// ```
1149    Trim {
1150        /// Which side to trim: `BOTH`, `LEADING`, or `TRAILING`.
1151        trim_where: Option<TrimWhereField>,
1152        /// Optional expression specifying what to trim from the value `expr`.
1153        trim_what: Option<Box<Expr>>,
1154        /// The expression to trim from.
1155        expr: Box<Expr>,
1156        /// Optional list of characters to trim (dialect-specific).
1157        trim_characters: Option<Vec<Expr>>,
1158    },
1159    /// ```sql
1160    /// OVERLAY(<expr> PLACING <expr> FROM <expr>[ FOR <expr> ]
1161    /// ```
1162    Overlay {
1163        /// The target expression being overlayed.
1164        expr: Box<Expr>,
1165        /// The expression to place into the target.
1166        overlay_what: Box<Expr>,
1167        /// The `FROM` position expression indicating where to start overlay.
1168        overlay_from: Box<Expr>,
1169        /// Optional `FOR` length expression limiting the overlay span.
1170        overlay_for: Option<Box<Expr>>,
1171    },
1172    /// `expr COLLATE collation`
1173    Collate {
1174        /// The expression being collated.
1175        expr: Box<Expr>,
1176        /// The collation name to apply to the expression.
1177        collation: ObjectName,
1178    },
1179    /// Nested expression e.g. `(foo > bar)` or `(1)`
1180    Nested(Box<Expr>),
1181    /// A literal value, such as string, number, date or NULL
1182    Value(ValueWithSpan),
1183    /// Prefixed expression, e.g. introducer strings, projection prefix
1184    /// <https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html>
1185    /// <https://docs.snowflake.com/en/sql-reference/constructs/connect-by>
1186    Prefixed {
1187        /// The prefix identifier (introducer or projection prefix).
1188        prefix: Ident,
1189        /// The value expression being prefixed.
1190        /// Hint: you can unwrap the string value using `value.into_string()`.
1191        value: Box<Expr>,
1192    },
1193    /// A constant of form `<data_type> 'value'`.
1194    /// This can represent ANSI SQL `DATE`, `TIME`, and `TIMESTAMP` literals (such as `DATE '2020-01-01'`),
1195    /// as well as constants of other types (a non-standard PostgreSQL extension).
1196    TypedString(TypedString),
1197    /// Scalar function call e.g. `LEFT(foo, 5)`
1198    Function(Function),
1199    /// `CASE [<operand>] WHEN <condition> THEN <result> ... [ELSE <result>] END`
1200    ///
1201    /// Note we only recognize a complete single expression as `<condition>`,
1202    /// not `< 0` nor `1, 2, 3` as allowed in a `<simple when clause>` per
1203    /// <https://jakewheat.github.io/sql-overview/sql-2011-foundation-grammar.html#simple-when-clause>
1204    Case {
1205        /// The attached `CASE` token (keeps original spacing/comments).
1206        case_token: AttachedToken,
1207        /// The attached `END` token (keeps original spacing/comments).
1208        end_token: AttachedToken,
1209        /// Optional operand expression after `CASE` (for simple CASE).
1210        operand: Option<Box<Expr>>,
1211        /// The `WHEN ... THEN` conditions and results.
1212        conditions: Vec<CaseWhen>,
1213        /// Optional `ELSE` result expression.
1214        else_result: Option<Box<Expr>>,
1215    },
1216    /// An exists expression `[ NOT ] EXISTS(SELECT ...)`, used in expressions like
1217    /// `WHERE [ NOT ] EXISTS (SELECT ...)`.
1218    Exists {
1219        /// The subquery checked by `EXISTS`.
1220        subquery: Box<Query>,
1221        /// Whether the `EXISTS` is negated (`NOT EXISTS`).
1222        negated: bool,
1223    },
1224    /// A parenthesized subquery `(SELECT ...)`, used in expression like
1225    /// `SELECT (subquery) AS x` or `WHERE (subquery) = x`
1226    Subquery(Box<Query>),
1227    /// The `GROUPING SETS` expr.
1228    GroupingSets(Vec<Vec<Expr>>),
1229    /// The `CUBE` expr.
1230    Cube(Vec<Vec<Expr>>),
1231    /// The `ROLLUP` expr.
1232    Rollup(Vec<Vec<Expr>>),
1233    /// ROW / TUPLE a single value, such as `SELECT (1, 2)`
1234    Tuple(Vec<Expr>),
1235    /// `Struct` literal expression
1236    /// Syntax:
1237    /// ```sql
1238    /// STRUCT<[field_name] field_type, ...>( expr1 [, ... ])
1239    ///
1240    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type)
1241    /// [Databricks](https://docs.databricks.com/en/sql/language-manual/functions/struct.html)
1242    /// ```
1243    Struct {
1244        /// Struct values.
1245        values: Vec<Expr>,
1246        /// Struct field definitions.
1247        fields: Vec<StructField>,
1248    },
1249    /// `BigQuery` specific: An named expression in a typeless struct [1]
1250    ///
1251    /// Syntax
1252    /// ```sql
1253    /// 1 AS A
1254    /// ```
1255    /// [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types#struct_type
1256    Named {
1257        /// The expression being named.
1258        expr: Box<Expr>,
1259        /// The assigned identifier name for the expression.
1260        name: Ident,
1261    },
1262    /// `DuckDB` specific `Struct` literal expression [1]
1263    ///
1264    /// Syntax:
1265    /// ```sql
1266    /// syntax: {'field_name': expr1[, ... ]}
1267    /// ```
1268    /// [1]: https://duckdb.org/docs/sql/data_types/struct#creating-structs
1269    Dictionary(Vec<DictionaryField>),
1270    /// `DuckDB` specific `Map` literal expression [1]
1271    ///
1272    /// Syntax:
1273    /// ```sql
1274    /// syntax: Map {key1: value1[, ... ]}
1275    /// ```
1276    /// [1]: https://duckdb.org/docs/sql/data_types/map#creating-maps
1277    Map(Map),
1278    /// An array expression e.g. `ARRAY[1, 2]`
1279    Array(Array),
1280    /// An interval expression e.g. `INTERVAL '1' YEAR`
1281    Interval(Interval),
1282    /// `MySQL` specific text search function [(1)].
1283    ///
1284    /// Syntax:
1285    /// ```sql
1286    /// MATCH (<col>, <col>, ...) AGAINST (<expr> [<search modifier>])
1287    ///
1288    /// <col> = CompoundIdentifier
1289    /// <expr> = String literal
1290    /// ```
1291    /// [(1)]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html#function_match
1292    MatchAgainst {
1293        /// `(<col>, <col>, ...)`.
1294        columns: Vec<ObjectName>,
1295        /// `<expr>`.
1296        match_value: ValueWithSpan,
1297        /// `<search modifier>`
1298        opt_search_modifier: Option<SearchModifier>,
1299    },
1300    /// An unqualified `*` wildcard token (e.g. `*`).
1301    Wildcard(AttachedToken),
1302    /// Qualified wildcard, e.g. `alias.*` or `schema.table.*`.
1303    /// (Same caveats apply to `QualifiedWildcard` as to `Wildcard`.)
1304    QualifiedWildcard(ObjectName, AttachedToken),
1305    /// Some dialects support an older syntax for outer joins where columns are
1306    /// marked with the `(+)` operator in the WHERE clause, for example:
1307    ///
1308    /// ```sql
1309    /// SELECT t1.c1, t2.c2 FROM t1, t2 WHERE t1.c1 = t2.c2 (+)
1310    /// ```
1311    ///
1312    /// which is equivalent to
1313    ///
1314    /// ```sql
1315    /// SELECT t1.c1, t2.c2 FROM t1 LEFT OUTER JOIN t2 ON t1.c1 = t2.c2
1316    /// ```
1317    ///
1318    /// See <https://docs.snowflake.com/en/sql-reference/constructs/where#joins-in-the-where-clause>.
1319    OuterJoin(Box<Expr>),
1320    /// A reference to the prior level in a CONNECT BY clause.
1321    Prior(Box<Expr>),
1322    /// A lambda function.
1323    ///
1324    /// Syntax:
1325    /// ```plaintext
1326    /// param -> expr | (param1, ...) -> expr
1327    /// ```
1328    ///
1329    /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/functions#higher-order-functions---operator-and-lambdaparams-expr-function)
1330    /// [Databricks](https://docs.databricks.com/en/sql/language-manual/sql-ref-lambda-functions.html)
1331    /// [DuckDB](https://duckdb.org/docs/stable/sql/functions/lambda)
1332    Lambda(LambdaFunction),
1333    /// Checks membership of a value in a JSON array
1334    MemberOf(MemberOf),
1335}
1336
1337impl Expr {
1338    /// Creates a new [`Expr::Value`]
1339    pub fn value(value: impl Into<ValueWithSpan>) -> Self {
1340        Expr::Value(value.into())
1341    }
1342}
1343
1344/// The contents inside the `[` and `]` in a subscript expression.
1345#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1346#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1347#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1348pub enum Subscript {
1349    /// Accesses the element of the array at the given index.
1350    Index {
1351        /// The index expression used to access the array element.
1352        index: Expr,
1353    },
1354
1355    /// Accesses a slice of an array on PostgreSQL, e.g.
1356    ///
1357    /// ```plaintext
1358    /// => select (array[1,2,3,4,5,6])[2:5];
1359    /// -----------
1360    /// {2,3,4,5}
1361    /// ```
1362    ///
1363    /// The lower and/or upper bound can be omitted to slice from the start or
1364    /// end of the array respectively.
1365    ///
1366    /// See <https://www.postgresql.org/docs/current/arrays.html#ARRAYS-ACCESSING>.
1367    ///
1368    /// Also supports an optional "stride" as the last element (this is not
1369    /// supported by postgres), e.g.
1370    ///
1371    /// ```plaintext
1372    /// => select (array[1,2,3,4,5,6])[1:6:2];
1373    /// -----------
1374    /// {1,3,5}
1375    /// ```
1376    Slice {
1377        /// Optional lower bound for the slice (inclusive).
1378        lower_bound: Option<Expr>,
1379        /// Optional upper bound for the slice (inclusive).
1380        upper_bound: Option<Expr>,
1381        /// Optional stride for the slice (step size).
1382        stride: Option<Expr>,
1383    },
1384}
1385
1386impl fmt::Display for Subscript {
1387    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1388        match self {
1389            Subscript::Index { index } => write!(f, "{index}"),
1390            Subscript::Slice {
1391                lower_bound,
1392                upper_bound,
1393                stride,
1394            } => {
1395                if let Some(lower) = lower_bound {
1396                    write!(f, "{lower}")?;
1397                }
1398                write!(f, ":")?;
1399                if let Some(upper) = upper_bound {
1400                    write!(f, "{upper}")?;
1401                }
1402                if let Some(stride) = stride {
1403                    write!(f, ":")?;
1404                    write!(f, "{stride}")?;
1405                }
1406                Ok(())
1407            }
1408        }
1409    }
1410}
1411
1412/// An element of a [`Expr::CompoundFieldAccess`].
1413/// It can be an expression or a subscript.
1414#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1415#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1416#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1417pub enum AccessExpr {
1418    /// Accesses a field using dot notation, e.g. `foo.bar.baz`.
1419    Dot(Expr),
1420    /// Accesses a field or array element using bracket notation, e.g. `foo['bar']`.
1421    Subscript(Subscript),
1422}
1423
1424impl fmt::Display for AccessExpr {
1425    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1426        match self {
1427            AccessExpr::Dot(expr) => write!(f, ".{expr}"),
1428            AccessExpr::Subscript(subscript) => write!(f, "[{subscript}]"),
1429        }
1430    }
1431}
1432
1433/// A lambda function.
1434#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1435#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1436#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1437pub struct LambdaFunction {
1438    /// The parameters to the lambda function.
1439    pub params: OneOrManyWithParens<LambdaFunctionParameter>,
1440    /// The body of the lambda function.
1441    pub body: Box<Expr>,
1442    /// The syntax style used to write the lambda function.
1443    pub syntax: LambdaSyntax,
1444}
1445
1446impl fmt::Display for LambdaFunction {
1447    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1448        match self.syntax {
1449            LambdaSyntax::Arrow => write!(f, "{} -> {}", self.params, self.body),
1450            LambdaSyntax::LambdaKeyword => {
1451                // For lambda keyword syntax, display params without parentheses
1452                // e.g., `lambda x, y : expr` not `lambda (x, y) : expr`
1453                write!(f, "lambda ")?;
1454                match &self.params {
1455                    OneOrManyWithParens::One(p) => write!(f, "{p}")?,
1456                    OneOrManyWithParens::Many(ps) => write!(f, "{}", display_comma_separated(ps))?,
1457                };
1458                write!(f, " : {}", self.body)
1459            }
1460        }
1461    }
1462}
1463
1464/// A parameter to a lambda function, optionally with a data type.
1465#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1466#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1467#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1468pub struct LambdaFunctionParameter {
1469    /// The name of the parameter
1470    pub name: Ident,
1471    /// The optional data type of the parameter
1472    /// [Snowflake Syntax](https://docs.snowflake.com/en/sql-reference/functions/filter#arguments)
1473    pub data_type: Option<DataType>,
1474}
1475
1476impl fmt::Display for LambdaFunctionParameter {
1477    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1478        match &self.data_type {
1479            Some(dt) => write!(f, "{} {}", self.name, dt),
1480            None => write!(f, "{}", self.name),
1481        }
1482    }
1483}
1484
1485/// The syntax style for a lambda function.
1486#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Copy)]
1487#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1488#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1489pub enum LambdaSyntax {
1490    /// Arrow syntax: `param -> expr` or `(param1, param2) -> expr`
1491    ///
1492    /// <https://docs.databricks.com/aws/en/sql/language-manual/sql-ref-lambda-functions>
1493    ///
1494    /// Supported, but deprecated in DuckDB:
1495    /// <https://duckdb.org/docs/stable/sql/functions/lambda>
1496    Arrow,
1497    /// Lambda keyword syntax: `lambda param : expr` or `lambda param1, param2 : expr`
1498    ///
1499    /// Recommended in DuckDB:
1500    /// <https://duckdb.org/docs/stable/sql/functions/lambda>
1501    LambdaKeyword,
1502}
1503
1504/// Encapsulates the common pattern in SQL where either one unparenthesized item
1505/// such as an identifier or expression is permitted, or multiple of the same
1506/// item in a parenthesized list. For accessing items regardless of the form,
1507/// `OneOrManyWithParens` implements `Deref<Target = [T]>` and `IntoIterator`,
1508/// so you can call slice methods on it and iterate over items
1509/// # Examples
1510/// Accessing as a slice:
1511/// ```
1512/// # use sqlparser::ast::OneOrManyWithParens;
1513/// let one = OneOrManyWithParens::One("a");
1514///
1515/// assert_eq!(one[0], "a");
1516/// assert_eq!(one.len(), 1);
1517/// ```
1518/// Iterating:
1519/// ```
1520/// # use sqlparser::ast::OneOrManyWithParens;
1521/// let one = OneOrManyWithParens::One("a");
1522/// let many = OneOrManyWithParens::Many(vec!["a", "b"]);
1523///
1524/// assert_eq!(one.into_iter().chain(many).collect::<Vec<_>>(), vec!["a", "a", "b"] );
1525/// ```
1526#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1527#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1528#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1529pub enum OneOrManyWithParens<T> {
1530    /// A single `T`, unparenthesized.
1531    One(T),
1532    /// One or more `T`s, parenthesized.
1533    Many(Vec<T>),
1534}
1535
1536impl<T> Deref for OneOrManyWithParens<T> {
1537    type Target = [T];
1538
1539    fn deref(&self) -> &[T] {
1540        match self {
1541            OneOrManyWithParens::One(one) => core::slice::from_ref(one),
1542            OneOrManyWithParens::Many(many) => many,
1543        }
1544    }
1545}
1546
1547impl<T> AsRef<[T]> for OneOrManyWithParens<T> {
1548    fn as_ref(&self) -> &[T] {
1549        self
1550    }
1551}
1552
1553impl<'a, T> IntoIterator for &'a OneOrManyWithParens<T> {
1554    type Item = &'a T;
1555    type IntoIter = core::slice::Iter<'a, T>;
1556
1557    fn into_iter(self) -> Self::IntoIter {
1558        self.iter()
1559    }
1560}
1561
1562/// Owned iterator implementation of `OneOrManyWithParens`
1563#[derive(Debug, Clone)]
1564pub struct OneOrManyWithParensIntoIter<T> {
1565    inner: OneOrManyWithParensIntoIterInner<T>,
1566}
1567
1568#[derive(Debug, Clone)]
1569enum OneOrManyWithParensIntoIterInner<T> {
1570    One(core::iter::Once<T>),
1571    Many(<Vec<T> as IntoIterator>::IntoIter),
1572}
1573
1574impl<T> core::iter::FusedIterator for OneOrManyWithParensIntoIter<T>
1575where
1576    core::iter::Once<T>: core::iter::FusedIterator,
1577    <Vec<T> as IntoIterator>::IntoIter: core::iter::FusedIterator,
1578{
1579}
1580
1581impl<T> core::iter::ExactSizeIterator for OneOrManyWithParensIntoIter<T>
1582where
1583    core::iter::Once<T>: core::iter::ExactSizeIterator,
1584    <Vec<T> as IntoIterator>::IntoIter: core::iter::ExactSizeIterator,
1585{
1586}
1587
1588impl<T> core::iter::Iterator for OneOrManyWithParensIntoIter<T> {
1589    type Item = T;
1590
1591    fn next(&mut self) -> Option<Self::Item> {
1592        match &mut self.inner {
1593            OneOrManyWithParensIntoIterInner::One(one) => one.next(),
1594            OneOrManyWithParensIntoIterInner::Many(many) => many.next(),
1595        }
1596    }
1597
1598    fn size_hint(&self) -> (usize, Option<usize>) {
1599        match &self.inner {
1600            OneOrManyWithParensIntoIterInner::One(one) => one.size_hint(),
1601            OneOrManyWithParensIntoIterInner::Many(many) => many.size_hint(),
1602        }
1603    }
1604
1605    fn count(self) -> usize
1606    where
1607        Self: Sized,
1608    {
1609        match self.inner {
1610            OneOrManyWithParensIntoIterInner::One(one) => one.count(),
1611            OneOrManyWithParensIntoIterInner::Many(many) => many.count(),
1612        }
1613    }
1614
1615    fn fold<B, F>(mut self, init: B, f: F) -> B
1616    where
1617        Self: Sized,
1618        F: FnMut(B, Self::Item) -> B,
1619    {
1620        match &mut self.inner {
1621            OneOrManyWithParensIntoIterInner::One(one) => one.fold(init, f),
1622            OneOrManyWithParensIntoIterInner::Many(many) => many.fold(init, f),
1623        }
1624    }
1625}
1626
1627impl<T> core::iter::DoubleEndedIterator for OneOrManyWithParensIntoIter<T> {
1628    fn next_back(&mut self) -> Option<Self::Item> {
1629        match &mut self.inner {
1630            OneOrManyWithParensIntoIterInner::One(one) => one.next_back(),
1631            OneOrManyWithParensIntoIterInner::Many(many) => many.next_back(),
1632        }
1633    }
1634}
1635
1636impl<T> IntoIterator for OneOrManyWithParens<T> {
1637    type Item = T;
1638
1639    type IntoIter = OneOrManyWithParensIntoIter<T>;
1640
1641    fn into_iter(self) -> Self::IntoIter {
1642        let inner = match self {
1643            OneOrManyWithParens::One(one) => {
1644                OneOrManyWithParensIntoIterInner::One(core::iter::once(one))
1645            }
1646            OneOrManyWithParens::Many(many) => {
1647                OneOrManyWithParensIntoIterInner::Many(many.into_iter())
1648            }
1649        };
1650
1651        OneOrManyWithParensIntoIter { inner }
1652    }
1653}
1654
1655impl<T> fmt::Display for OneOrManyWithParens<T>
1656where
1657    T: fmt::Display,
1658{
1659    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1660        match self {
1661            OneOrManyWithParens::One(value) => write!(f, "{value}"),
1662            OneOrManyWithParens::Many(values) => {
1663                write!(f, "({})", display_comma_separated(values))
1664            }
1665        }
1666    }
1667}
1668
1669impl fmt::Display for CastFormat {
1670    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1671        match self {
1672            CastFormat::Value(v) => write!(f, "{v}"),
1673            CastFormat::ValueAtTimeZone(v, tz) => write!(f, "{v} AT TIME ZONE {tz}"),
1674        }
1675    }
1676}
1677
1678impl fmt::Display for Expr {
1679    #[cfg_attr(feature = "recursive-protection", recursive::recursive)]
1680    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1681        match self {
1682            Expr::Identifier(s) => write!(f, "{s}"),
1683            Expr::Wildcard(_) => f.write_str("*"),
1684            Expr::QualifiedWildcard(prefix, _) => write!(f, "{prefix}.*"),
1685            Expr::CompoundIdentifier(s) => write!(f, "{}", display_separated(s, ".")),
1686            Expr::CompoundFieldAccess { root, access_chain } => {
1687                write!(f, "{root}")?;
1688                for field in access_chain {
1689                    write!(f, "{field}")?;
1690                }
1691                Ok(())
1692            }
1693            Expr::IsTrue(ast) => write!(f, "{ast} IS TRUE"),
1694            Expr::IsNotTrue(ast) => write!(f, "{ast} IS NOT TRUE"),
1695            Expr::IsFalse(ast) => write!(f, "{ast} IS FALSE"),
1696            Expr::IsNotFalse(ast) => write!(f, "{ast} IS NOT FALSE"),
1697            Expr::IsNull(ast) => write!(f, "{ast} IS NULL"),
1698            Expr::IsNotNull(ast) => write!(f, "{ast} IS NOT NULL"),
1699            Expr::IsUnknown(ast) => write!(f, "{ast} IS UNKNOWN"),
1700            Expr::IsNotUnknown(ast) => write!(f, "{ast} IS NOT UNKNOWN"),
1701            Expr::InList {
1702                expr,
1703                list,
1704                negated,
1705            } => write!(
1706                f,
1707                "{} {}IN ({})",
1708                expr,
1709                if *negated { "NOT " } else { "" },
1710                display_comma_separated(list)
1711            ),
1712            Expr::InSubquery {
1713                expr,
1714                subquery,
1715                negated,
1716            } => write!(
1717                f,
1718                "{} {}IN ({})",
1719                expr,
1720                if *negated { "NOT " } else { "" },
1721                subquery
1722            ),
1723            Expr::InUnnest {
1724                expr,
1725                array_expr,
1726                negated,
1727            } => write!(
1728                f,
1729                "{} {}IN UNNEST({})",
1730                expr,
1731                if *negated { "NOT " } else { "" },
1732                array_expr
1733            ),
1734            Expr::Between {
1735                expr,
1736                negated,
1737                low,
1738                high,
1739            } => write!(
1740                f,
1741                "{} {}BETWEEN {} AND {}",
1742                expr,
1743                if *negated { "NOT " } else { "" },
1744                low,
1745                high
1746            ),
1747            Expr::BinaryOp { left, op, right } => write!(f, "{left} {op} {right}"),
1748            Expr::Like {
1749                negated,
1750                expr,
1751                pattern,
1752                escape_char,
1753                any,
1754            } => match escape_char {
1755                Some(ch) => write!(
1756                    f,
1757                    "{} {}LIKE {}{} ESCAPE {}",
1758                    expr,
1759                    if *negated { "NOT " } else { "" },
1760                    if *any { "ANY " } else { "" },
1761                    pattern,
1762                    ch
1763                ),
1764                _ => write!(
1765                    f,
1766                    "{} {}LIKE {}{}",
1767                    expr,
1768                    if *negated { "NOT " } else { "" },
1769                    if *any { "ANY " } else { "" },
1770                    pattern
1771                ),
1772            },
1773            Expr::ILike {
1774                negated,
1775                expr,
1776                pattern,
1777                escape_char,
1778                any,
1779            } => match escape_char {
1780                Some(ch) => write!(
1781                    f,
1782                    "{} {}ILIKE {}{} ESCAPE {}",
1783                    expr,
1784                    if *negated { "NOT " } else { "" },
1785                    if *any { "ANY" } else { "" },
1786                    pattern,
1787                    ch
1788                ),
1789                _ => write!(
1790                    f,
1791                    "{} {}ILIKE {}{}",
1792                    expr,
1793                    if *negated { "NOT " } else { "" },
1794                    if *any { "ANY " } else { "" },
1795                    pattern
1796                ),
1797            },
1798            Expr::RLike {
1799                negated,
1800                expr,
1801                pattern,
1802                regexp,
1803            } => write!(
1804                f,
1805                "{} {}{} {}",
1806                expr,
1807                if *negated { "NOT " } else { "" },
1808                if *regexp { "REGEXP" } else { "RLIKE" },
1809                pattern
1810            ),
1811            Expr::IsNormalized {
1812                expr,
1813                form,
1814                negated,
1815            } => {
1816                let not_ = if *negated { "NOT " } else { "" };
1817                if form.is_none() {
1818                    write!(f, "{expr} IS {not_}NORMALIZED")
1819                } else {
1820                    write!(
1821                        f,
1822                        "{} IS {}{} NORMALIZED",
1823                        expr,
1824                        not_,
1825                        form.as_ref().unwrap()
1826                    )
1827                }
1828            }
1829            Expr::SimilarTo {
1830                negated,
1831                expr,
1832                pattern,
1833                escape_char,
1834            } => match escape_char {
1835                Some(ch) => write!(
1836                    f,
1837                    "{} {}SIMILAR TO {} ESCAPE {}",
1838                    expr,
1839                    if *negated { "NOT " } else { "" },
1840                    pattern,
1841                    ch
1842                ),
1843                _ => write!(
1844                    f,
1845                    "{} {}SIMILAR TO {}",
1846                    expr,
1847                    if *negated { "NOT " } else { "" },
1848                    pattern
1849                ),
1850            },
1851            Expr::AnyOp {
1852                left,
1853                compare_op,
1854                right,
1855                is_some,
1856            } => {
1857                let add_parens = !matches!(right.as_ref(), Expr::Subquery(_));
1858                write!(
1859                    f,
1860                    "{left} {compare_op} {}{}{right}{}",
1861                    if *is_some { "SOME" } else { "ANY" },
1862                    if add_parens { "(" } else { "" },
1863                    if add_parens { ")" } else { "" },
1864                )
1865            }
1866            Expr::AllOp {
1867                left,
1868                compare_op,
1869                right,
1870            } => {
1871                let add_parens = !matches!(right.as_ref(), Expr::Subquery(_));
1872                write!(
1873                    f,
1874                    "{left} {compare_op} ALL{}{right}{}",
1875                    if add_parens { "(" } else { "" },
1876                    if add_parens { ")" } else { "" },
1877                )
1878            }
1879            Expr::UnaryOp { op, expr } => {
1880                if op == &UnaryOperator::PGPostfixFactorial {
1881                    write!(f, "{expr}{op}")
1882                } else if matches!(
1883                    op,
1884                    UnaryOperator::Not
1885                        | UnaryOperator::Hash
1886                        | UnaryOperator::AtDashAt
1887                        | UnaryOperator::DoubleAt
1888                        | UnaryOperator::QuestionDash
1889                        | UnaryOperator::QuestionPipe
1890                ) {
1891                    write!(f, "{op} {expr}")
1892                } else {
1893                    write!(f, "{op}{expr}")
1894                }
1895            }
1896            Expr::Convert {
1897                is_try,
1898                expr,
1899                target_before_value,
1900                data_type,
1901                charset,
1902                styles,
1903            } => {
1904                write!(f, "{}CONVERT(", if *is_try { "TRY_" } else { "" })?;
1905                if let Some(data_type) = data_type {
1906                    if let Some(charset) = charset {
1907                        write!(f, "{expr}, {data_type} CHARACTER SET {charset}")
1908                    } else if *target_before_value {
1909                        write!(f, "{data_type}, {expr}")
1910                    } else {
1911                        write!(f, "{expr}, {data_type}")
1912                    }
1913                } else if let Some(charset) = charset {
1914                    write!(f, "{expr} USING {charset}")
1915                } else {
1916                    write!(f, "{expr}") // This should never happen
1917                }?;
1918                if !styles.is_empty() {
1919                    write!(f, ", {}", display_comma_separated(styles))?;
1920                }
1921                write!(f, ")")
1922            }
1923            Expr::Cast {
1924                kind,
1925                expr,
1926                data_type,
1927                array,
1928                format,
1929            } => match kind {
1930                CastKind::Cast => {
1931                    write!(f, "CAST({expr} AS {data_type}")?;
1932                    if *array {
1933                        write!(f, " ARRAY")?;
1934                    }
1935                    if let Some(format) = format {
1936                        write!(f, " FORMAT {format}")?;
1937                    }
1938                    write!(f, ")")
1939                }
1940                CastKind::TryCast => {
1941                    if let Some(format) = format {
1942                        write!(f, "TRY_CAST({expr} AS {data_type} FORMAT {format})")
1943                    } else {
1944                        write!(f, "TRY_CAST({expr} AS {data_type})")
1945                    }
1946                }
1947                CastKind::SafeCast => {
1948                    if let Some(format) = format {
1949                        write!(f, "SAFE_CAST({expr} AS {data_type} FORMAT {format})")
1950                    } else {
1951                        write!(f, "SAFE_CAST({expr} AS {data_type})")
1952                    }
1953                }
1954                CastKind::DoubleColon => {
1955                    write!(f, "{expr}::{data_type}")
1956                }
1957            },
1958            Expr::Extract {
1959                field,
1960                syntax,
1961                expr,
1962            } => match syntax {
1963                ExtractSyntax::From => write!(f, "EXTRACT({field} FROM {expr})"),
1964                ExtractSyntax::Comma => write!(f, "EXTRACT({field}, {expr})"),
1965            },
1966            Expr::Ceil { expr, field } => match field {
1967                CeilFloorKind::DateTimeField(DateTimeField::NoDateTime) => {
1968                    write!(f, "CEIL({expr})")
1969                }
1970                CeilFloorKind::DateTimeField(dt_field) => write!(f, "CEIL({expr} TO {dt_field})"),
1971                CeilFloorKind::Scale(s) => write!(f, "CEIL({expr}, {s})"),
1972            },
1973            Expr::Floor { expr, field } => match field {
1974                CeilFloorKind::DateTimeField(DateTimeField::NoDateTime) => {
1975                    write!(f, "FLOOR({expr})")
1976                }
1977                CeilFloorKind::DateTimeField(dt_field) => write!(f, "FLOOR({expr} TO {dt_field})"),
1978                CeilFloorKind::Scale(s) => write!(f, "FLOOR({expr}, {s})"),
1979            },
1980            Expr::Position { expr, r#in } => write!(f, "POSITION({expr} IN {in})"),
1981            Expr::Collate { expr, collation } => write!(f, "{expr} COLLATE {collation}"),
1982            Expr::Nested(ast) => write!(f, "({ast})"),
1983            Expr::Value(v) => write!(f, "{v}"),
1984            Expr::Prefixed { prefix, value } => write!(f, "{prefix} {value}"),
1985            Expr::TypedString(ts) => ts.fmt(f),
1986            Expr::Function(fun) => fun.fmt(f),
1987            Expr::Case {
1988                case_token: _,
1989                end_token: _,
1990                operand,
1991                conditions,
1992                else_result,
1993            } => {
1994                f.write_str("CASE")?;
1995                if let Some(operand) = operand {
1996                    f.write_str(" ")?;
1997                    operand.fmt(f)?;
1998                }
1999                for when in conditions {
2000                    SpaceOrNewline.fmt(f)?;
2001                    Indent(when).fmt(f)?;
2002                }
2003                if let Some(else_result) = else_result {
2004                    SpaceOrNewline.fmt(f)?;
2005                    Indent("ELSE").fmt(f)?;
2006                    SpaceOrNewline.fmt(f)?;
2007                    Indent(Indent(else_result)).fmt(f)?;
2008                }
2009                SpaceOrNewline.fmt(f)?;
2010                f.write_str("END")
2011            }
2012            Expr::Exists { subquery, negated } => write!(
2013                f,
2014                "{}EXISTS ({})",
2015                if *negated { "NOT " } else { "" },
2016                subquery
2017            ),
2018            Expr::Subquery(s) => write!(f, "({s})"),
2019            Expr::GroupingSets(sets) => {
2020                write!(f, "GROUPING SETS (")?;
2021                let mut sep = "";
2022                for set in sets {
2023                    write!(f, "{sep}")?;
2024                    sep = ", ";
2025                    write!(f, "({})", display_comma_separated(set))?;
2026                }
2027                write!(f, ")")
2028            }
2029            Expr::Cube(sets) => {
2030                write!(f, "CUBE (")?;
2031                let mut sep = "";
2032                for set in sets {
2033                    write!(f, "{sep}")?;
2034                    sep = ", ";
2035                    if set.len() == 1 {
2036                        write!(f, "{}", set[0])?;
2037                    } else {
2038                        write!(f, "({})", display_comma_separated(set))?;
2039                    }
2040                }
2041                write!(f, ")")
2042            }
2043            Expr::Rollup(sets) => {
2044                write!(f, "ROLLUP (")?;
2045                let mut sep = "";
2046                for set in sets {
2047                    write!(f, "{sep}")?;
2048                    sep = ", ";
2049                    if set.len() == 1 {
2050                        write!(f, "{}", set[0])?;
2051                    } else {
2052                        write!(f, "({})", display_comma_separated(set))?;
2053                    }
2054                }
2055                write!(f, ")")
2056            }
2057            Expr::Substring {
2058                expr,
2059                substring_from,
2060                substring_for,
2061                special,
2062                shorthand,
2063            } => {
2064                f.write_str("SUBSTR")?;
2065                if !*shorthand {
2066                    f.write_str("ING")?;
2067                }
2068                write!(f, "({expr}")?;
2069                if let Some(from_part) = substring_from {
2070                    if *special {
2071                        write!(f, ", {from_part}")?;
2072                    } else {
2073                        write!(f, " FROM {from_part}")?;
2074                    }
2075                }
2076                if let Some(for_part) = substring_for {
2077                    if *special {
2078                        write!(f, ", {for_part}")?;
2079                    } else {
2080                        write!(f, " FOR {for_part}")?;
2081                    }
2082                }
2083
2084                write!(f, ")")
2085            }
2086            Expr::Overlay {
2087                expr,
2088                overlay_what,
2089                overlay_from,
2090                overlay_for,
2091            } => {
2092                write!(
2093                    f,
2094                    "OVERLAY({expr} PLACING {overlay_what} FROM {overlay_from}"
2095                )?;
2096                if let Some(for_part) = overlay_for {
2097                    write!(f, " FOR {for_part}")?;
2098                }
2099
2100                write!(f, ")")
2101            }
2102            Expr::IsDistinctFrom(a, b) => write!(f, "{a} IS DISTINCT FROM {b}"),
2103            Expr::IsNotDistinctFrom(a, b) => write!(f, "{a} IS NOT DISTINCT FROM {b}"),
2104            Expr::Trim {
2105                expr,
2106                trim_where,
2107                trim_what,
2108                trim_characters,
2109            } => {
2110                write!(f, "TRIM(")?;
2111                if let Some(ident) = trim_where {
2112                    write!(f, "{ident} ")?;
2113                }
2114                if let Some(trim_char) = trim_what {
2115                    write!(f, "{trim_char} FROM {expr}")?;
2116                } else {
2117                    write!(f, "{expr}")?;
2118                }
2119                if let Some(characters) = trim_characters {
2120                    write!(f, ", {}", display_comma_separated(characters))?;
2121                }
2122
2123                write!(f, ")")
2124            }
2125            Expr::Tuple(exprs) => {
2126                write!(f, "({})", display_comma_separated(exprs))
2127            }
2128            Expr::Struct { values, fields } => {
2129                if !fields.is_empty() {
2130                    write!(
2131                        f,
2132                        "STRUCT<{}>({})",
2133                        display_comma_separated(fields),
2134                        display_comma_separated(values)
2135                    )
2136                } else {
2137                    write!(f, "STRUCT({})", display_comma_separated(values))
2138                }
2139            }
2140            Expr::Named { expr, name } => {
2141                write!(f, "{expr} AS {name}")
2142            }
2143            Expr::Dictionary(fields) => {
2144                write!(f, "{{{}}}", display_comma_separated(fields))
2145            }
2146            Expr::Map(map) => {
2147                write!(f, "{map}")
2148            }
2149            Expr::Array(set) => {
2150                write!(f, "{set}")
2151            }
2152            Expr::JsonAccess { value, path } => {
2153                write!(f, "{value}{path}")
2154            }
2155            Expr::AtTimeZone {
2156                timestamp,
2157                time_zone,
2158            } => {
2159                write!(f, "{timestamp} AT TIME ZONE {time_zone}")
2160            }
2161            Expr::Interval(interval) => {
2162                write!(f, "{interval}")
2163            }
2164            Expr::MatchAgainst {
2165                columns,
2166                match_value: match_expr,
2167                opt_search_modifier,
2168            } => {
2169                write!(f, "MATCH ({}) AGAINST ", display_comma_separated(columns),)?;
2170
2171                if let Some(search_modifier) = opt_search_modifier {
2172                    write!(f, "({match_expr} {search_modifier})")?;
2173                } else {
2174                    write!(f, "({match_expr})")?;
2175                }
2176
2177                Ok(())
2178            }
2179            Expr::OuterJoin(expr) => {
2180                write!(f, "{expr} (+)")
2181            }
2182            Expr::Prior(expr) => write!(f, "PRIOR {expr}"),
2183            Expr::Lambda(lambda) => write!(f, "{lambda}"),
2184            Expr::MemberOf(member_of) => write!(f, "{member_of}"),
2185        }
2186    }
2187}
2188
2189/// The type of a window used in `OVER` clauses.
2190///
2191/// A window can be either an inline specification (`WindowSpec`) or a
2192/// reference to a previously defined named window.
2193///
2194/// - `WindowSpec(WindowSpec)`: An inline window specification, e.g.
2195///   `OVER (PARTITION BY ... ORDER BY ...)`.
2196/// - `NamedWindow(Ident)`: A reference to a named window declared elsewhere.
2197#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2198#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2199#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2200pub enum WindowType {
2201    /// An inline window specification.
2202    WindowSpec(WindowSpec),
2203    /// A reference to a previously defined named window.
2204    NamedWindow(Ident),
2205}
2206
2207impl Display for WindowType {
2208    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2209        match self {
2210            WindowType::WindowSpec(spec) => {
2211                f.write_str("(")?;
2212                NewLine.fmt(f)?;
2213                Indent(spec).fmt(f)?;
2214                NewLine.fmt(f)?;
2215                f.write_str(")")
2216            }
2217            WindowType::NamedWindow(name) => name.fmt(f),
2218        }
2219    }
2220}
2221
2222/// A window specification (i.e. `OVER ([window_name] PARTITION BY .. ORDER BY .. etc.)`)
2223#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2224#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2225#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2226pub struct WindowSpec {
2227    /// Optional window name.
2228    ///
2229    /// You can find it at least in [MySQL][1], [BigQuery][2], [PostgreSQL][3]
2230    ///
2231    /// [1]: https://dev.mysql.com/doc/refman/8.0/en/window-functions-named-windows.html
2232    /// [2]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
2233    /// [3]: https://www.postgresql.org/docs/current/sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS
2234    pub window_name: Option<Ident>,
2235    /// `OVER (PARTITION BY ...)`
2236    pub partition_by: Vec<Expr>,
2237    /// `OVER (ORDER BY ...)`
2238    pub order_by: Vec<OrderByExpr>,
2239    /// `OVER (window frame)`
2240    pub window_frame: Option<WindowFrame>,
2241}
2242
2243impl fmt::Display for WindowSpec {
2244    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2245        let mut is_first = true;
2246        if let Some(window_name) = &self.window_name {
2247            if !is_first {
2248                SpaceOrNewline.fmt(f)?;
2249            }
2250            is_first = false;
2251            write!(f, "{window_name}")?;
2252        }
2253        if !self.partition_by.is_empty() {
2254            if !is_first {
2255                SpaceOrNewline.fmt(f)?;
2256            }
2257            is_first = false;
2258            write!(
2259                f,
2260                "PARTITION BY {}",
2261                display_comma_separated(&self.partition_by)
2262            )?;
2263        }
2264        if !self.order_by.is_empty() {
2265            if !is_first {
2266                SpaceOrNewline.fmt(f)?;
2267            }
2268            is_first = false;
2269            write!(f, "ORDER BY {}", display_comma_separated(&self.order_by))?;
2270        }
2271        if let Some(window_frame) = &self.window_frame {
2272            if !is_first {
2273                SpaceOrNewline.fmt(f)?;
2274            }
2275            if let Some(end_bound) = &window_frame.end_bound {
2276                write!(
2277                    f,
2278                    "{} BETWEEN {} AND {}",
2279                    window_frame.units, window_frame.start_bound, end_bound
2280                )?;
2281            } else {
2282                write!(f, "{} {}", window_frame.units, window_frame.start_bound)?;
2283            }
2284        }
2285        Ok(())
2286    }
2287}
2288
2289/// Specifies the data processed by a window function, e.g.
2290/// `RANGE UNBOUNDED PRECEDING` or `ROWS BETWEEN 5 PRECEDING AND CURRENT ROW`.
2291///
2292/// Note: The parser does not validate the specified bounds; the caller should
2293/// reject invalid bounds like `ROWS UNBOUNDED FOLLOWING` before execution.
2294#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2295#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2296#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2297pub struct WindowFrame {
2298    /// Units for the frame (e.g. `ROWS`, `RANGE`, `GROUPS`).
2299    pub units: WindowFrameUnits,
2300    /// The start bound of the window frame.
2301    pub start_bound: WindowFrameBound,
2302    /// The right bound of the `BETWEEN .. AND` clause. The end bound of `None`
2303    /// indicates the shorthand form (e.g. `ROWS 1 PRECEDING`), which must
2304    /// behave the same as `end_bound = WindowFrameBound::CurrentRow`.
2305    pub end_bound: Option<WindowFrameBound>,
2306    // TBD: EXCLUDE
2307}
2308
2309impl Default for WindowFrame {
2310    /// Returns default value for window frame
2311    ///
2312    /// See [this page](https://www.sqlite.org/windowfunctions.html#frame_specifications) for more details.
2313    fn default() -> Self {
2314        Self {
2315            units: WindowFrameUnits::Range,
2316            start_bound: WindowFrameBound::Preceding(None),
2317            end_bound: None,
2318        }
2319    }
2320}
2321
2322#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2323#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2324#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2325/// Units used to describe the window frame scope.
2326pub enum WindowFrameUnits {
2327    /// `ROWS` unit.
2328    Rows,
2329    /// `RANGE` unit.
2330    Range,
2331    /// `GROUPS` unit.
2332    Groups,
2333}
2334
2335impl fmt::Display for WindowFrameUnits {
2336    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2337        f.write_str(match self {
2338            WindowFrameUnits::Rows => "ROWS",
2339            WindowFrameUnits::Range => "RANGE",
2340            WindowFrameUnits::Groups => "GROUPS",
2341        })
2342    }
2343}
2344
2345/// Specifies Ignore / Respect NULL within window functions.
2346/// For example
2347/// `FIRST_VALUE(column2) IGNORE NULLS OVER (PARTITION BY column1)`
2348#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2349#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2350#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2351/// How NULL values are treated in certain window functions.
2352pub enum NullTreatment {
2353    /// Ignore NULL values (e.g. `IGNORE NULLS`).
2354    IgnoreNulls,
2355    /// Respect NULL values (e.g. `RESPECT NULLS`).
2356    RespectNulls,
2357}
2358
2359impl fmt::Display for NullTreatment {
2360    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2361        f.write_str(match self {
2362            NullTreatment::IgnoreNulls => "IGNORE NULLS",
2363            NullTreatment::RespectNulls => "RESPECT NULLS",
2364        })
2365    }
2366}
2367
2368/// Specifies [WindowFrame]'s `start_bound` and `end_bound`
2369#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2370#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2371#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2372pub enum WindowFrameBound {
2373    /// `CURRENT ROW`
2374    CurrentRow,
2375    /// `<N> PRECEDING` or `UNBOUNDED PRECEDING`
2376    Preceding(Option<Box<Expr>>),
2377    /// `<N> FOLLOWING` or `UNBOUNDED FOLLOWING`.
2378    Following(Option<Box<Expr>>),
2379}
2380
2381impl fmt::Display for WindowFrameBound {
2382    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2383        match self {
2384            WindowFrameBound::CurrentRow => f.write_str("CURRENT ROW"),
2385            WindowFrameBound::Preceding(None) => f.write_str("UNBOUNDED PRECEDING"),
2386            WindowFrameBound::Following(None) => f.write_str("UNBOUNDED FOLLOWING"),
2387            WindowFrameBound::Preceding(Some(n)) => write!(f, "{n} PRECEDING"),
2388            WindowFrameBound::Following(Some(n)) => write!(f, "{n} FOLLOWING"),
2389        }
2390    }
2391}
2392
2393#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2394#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2395#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2396/// Indicates partition operation type for partition management statements.
2397pub enum AddDropSync {
2398    /// Add partitions.
2399    ADD,
2400    /// Drop partitions.
2401    DROP,
2402    /// Sync partitions.
2403    SYNC,
2404}
2405
2406impl fmt::Display for AddDropSync {
2407    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2408        match self {
2409            AddDropSync::SYNC => f.write_str("SYNC PARTITIONS"),
2410            AddDropSync::DROP => f.write_str("DROP PARTITIONS"),
2411            AddDropSync::ADD => f.write_str("ADD PARTITIONS"),
2412        }
2413    }
2414}
2415
2416#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2417#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2418#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2419/// Object kinds supported by `SHOW CREATE` statements.
2420pub enum ShowCreateObject {
2421    /// An event object for `SHOW CREATE EVENT`.
2422    Event,
2423    /// A function object for `SHOW CREATE FUNCTION`.
2424    Function,
2425    /// A procedure object for `SHOW CREATE PROCEDURE`.
2426    Procedure,
2427    /// A table object for `SHOW CREATE TABLE`.
2428    Table,
2429    /// A trigger object for `SHOW CREATE TRIGGER`.
2430    Trigger,
2431    /// A view object for `SHOW CREATE VIEW`.
2432    View,
2433}
2434
2435impl fmt::Display for ShowCreateObject {
2436    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2437        match self {
2438            ShowCreateObject::Event => f.write_str("EVENT"),
2439            ShowCreateObject::Function => f.write_str("FUNCTION"),
2440            ShowCreateObject::Procedure => f.write_str("PROCEDURE"),
2441            ShowCreateObject::Table => f.write_str("TABLE"),
2442            ShowCreateObject::Trigger => f.write_str("TRIGGER"),
2443            ShowCreateObject::View => f.write_str("VIEW"),
2444        }
2445    }
2446}
2447
2448#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2449#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2450#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2451/// Objects that can be targeted by a `COMMENT` statement.
2452pub enum CommentObject {
2453    /// A collation.
2454    Collation,
2455    /// A table column.
2456    Column,
2457    /// A database.
2458    Database,
2459    /// A domain.
2460    Domain,
2461    /// An extension.
2462    Extension,
2463    /// A function.
2464    Function,
2465    /// An index.
2466    Index,
2467    /// A materialized view.
2468    MaterializedView,
2469    /// A procedure.
2470    Procedure,
2471    /// A role.
2472    Role,
2473    /// A schema.
2474    Schema,
2475    /// A sequence.
2476    Sequence,
2477    /// A table.
2478    Table,
2479    /// A type.
2480    Type,
2481    /// A user.
2482    User,
2483    /// A view.
2484    View,
2485}
2486
2487impl fmt::Display for CommentObject {
2488    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2489        match self {
2490            CommentObject::Collation => f.write_str("COLLATION"),
2491            CommentObject::Column => f.write_str("COLUMN"),
2492            CommentObject::Database => f.write_str("DATABASE"),
2493            CommentObject::Domain => f.write_str("DOMAIN"),
2494            CommentObject::Extension => f.write_str("EXTENSION"),
2495            CommentObject::Function => f.write_str("FUNCTION"),
2496            CommentObject::Index => f.write_str("INDEX"),
2497            CommentObject::MaterializedView => f.write_str("MATERIALIZED VIEW"),
2498            CommentObject::Procedure => f.write_str("PROCEDURE"),
2499            CommentObject::Role => f.write_str("ROLE"),
2500            CommentObject::Schema => f.write_str("SCHEMA"),
2501            CommentObject::Sequence => f.write_str("SEQUENCE"),
2502            CommentObject::Table => f.write_str("TABLE"),
2503            CommentObject::Type => f.write_str("TYPE"),
2504            CommentObject::User => f.write_str("USER"),
2505            CommentObject::View => f.write_str("VIEW"),
2506        }
2507    }
2508}
2509
2510#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2511#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2512#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2513/// Password specification variants used in user-related statements.
2514pub enum Password {
2515    /// A concrete password expression.
2516    Password(Expr),
2517    /// Represents a `NULL` password.
2518    NullPassword,
2519}
2520
2521/// A `CASE` statement.
2522///
2523/// Examples:
2524/// ```sql
2525/// CASE
2526///     WHEN EXISTS(SELECT 1)
2527///         THEN SELECT 1 FROM T;
2528///     WHEN EXISTS(SELECT 2)
2529///         THEN SELECT 1 FROM U;
2530///     ELSE
2531///         SELECT 1 FROM V;
2532/// END CASE;
2533/// ```
2534///
2535/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#case_search_expression)
2536/// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/case)
2537#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2538#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2539#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2540pub struct CaseStatement {
2541    /// The `CASE` token that starts the statement.
2542    pub case_token: AttachedToken,
2543    /// Optional expression to match against in `CASE ... WHEN`.
2544    pub match_expr: Option<Expr>,
2545    /// The `WHEN ... THEN` blocks of the `CASE` statement.
2546    pub when_blocks: Vec<ConditionalStatementBlock>,
2547    /// Optional `ELSE` block for the `CASE` statement.
2548    pub else_block: Option<ConditionalStatementBlock>,
2549    /// The last token of the statement (`END` or `CASE`).
2550    pub end_case_token: AttachedToken,
2551}
2552
2553impl fmt::Display for CaseStatement {
2554    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2555        let CaseStatement {
2556            case_token: _,
2557            match_expr,
2558            when_blocks,
2559            else_block,
2560            end_case_token: AttachedToken(end),
2561        } = self;
2562
2563        write!(f, "CASE")?;
2564
2565        if let Some(expr) = match_expr {
2566            write!(f, " {expr}")?;
2567        }
2568
2569        if !when_blocks.is_empty() {
2570            write!(f, " {}", display_separated(when_blocks, " "))?;
2571        }
2572
2573        if let Some(else_block) = else_block {
2574            write!(f, " {else_block}")?;
2575        }
2576
2577        write!(f, " END")?;
2578
2579        if let Token::Word(w) = &end.token {
2580            if w.keyword == Keyword::CASE {
2581                write!(f, " CASE")?;
2582            }
2583        }
2584
2585        Ok(())
2586    }
2587}
2588
2589/// An `IF` statement.
2590///
2591/// Example (BigQuery or Snowflake):
2592/// ```sql
2593/// IF TRUE THEN
2594///     SELECT 1;
2595///     SELECT 2;
2596/// ELSEIF TRUE THEN
2597///     SELECT 3;
2598/// ELSE
2599///     SELECT 4;
2600/// END IF
2601/// ```
2602/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#if)
2603/// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/if)
2604///
2605/// Example (MSSQL):
2606/// ```sql
2607/// IF 1=1 SELECT 1 ELSE SELECT 2
2608/// ```
2609/// [MSSQL](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/if-else-transact-sql?view=sql-server-ver16)
2610#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2611#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2612#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2613pub struct IfStatement {
2614    /// The initial `IF` block containing the condition and statements.
2615    pub if_block: ConditionalStatementBlock,
2616    /// Additional `ELSEIF` blocks.
2617    pub elseif_blocks: Vec<ConditionalStatementBlock>,
2618    /// Optional `ELSE` block.
2619    pub else_block: Option<ConditionalStatementBlock>,
2620    /// Optional trailing `END` token for the `IF` statement.
2621    pub end_token: Option<AttachedToken>,
2622}
2623
2624impl fmt::Display for IfStatement {
2625    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2626        let IfStatement {
2627            if_block,
2628            elseif_blocks,
2629            else_block,
2630            end_token,
2631        } = self;
2632
2633        write!(f, "{if_block}")?;
2634
2635        for elseif_block in elseif_blocks {
2636            write!(f, " {elseif_block}")?;
2637        }
2638
2639        if let Some(else_block) = else_block {
2640            write!(f, " {else_block}")?;
2641        }
2642
2643        if let Some(AttachedToken(end_token)) = end_token {
2644            write!(f, " END {end_token}")?;
2645        }
2646
2647        Ok(())
2648    }
2649}
2650
2651/// A `WHILE` statement.
2652///
2653/// Example:
2654/// ```sql
2655/// WHILE @@FETCH_STATUS = 0
2656/// BEGIN
2657///    FETCH NEXT FROM c1 INTO @var1, @var2;
2658/// END
2659/// ```
2660///
2661/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/while-transact-sql)
2662#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2663#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2664#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2665pub struct WhileStatement {
2666    /// Block executed while the condition holds.
2667    pub while_block: ConditionalStatementBlock,
2668}
2669
2670impl fmt::Display for WhileStatement {
2671    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2672        let WhileStatement { while_block } = self;
2673        write!(f, "{while_block}")?;
2674        Ok(())
2675    }
2676}
2677
2678/// A block within a [Statement::Case] or [Statement::If] or [Statement::While]-like statement
2679///
2680/// Example 1:
2681/// ```sql
2682/// WHEN EXISTS(SELECT 1) THEN SELECT 1;
2683/// ```
2684///
2685/// Example 2:
2686/// ```sql
2687/// IF TRUE THEN SELECT 1; SELECT 2;
2688/// ```
2689///
2690/// Example 3:
2691/// ```sql
2692/// ELSE SELECT 1; SELECT 2;
2693/// ```
2694///
2695/// Example 4:
2696/// ```sql
2697/// WHILE @@FETCH_STATUS = 0
2698/// BEGIN
2699///    FETCH NEXT FROM c1 INTO @var1, @var2;
2700/// END
2701/// ```
2702#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2703#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2704#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2705pub struct ConditionalStatementBlock {
2706    /// Token representing the start of the block (e.g., WHEN/IF/WHILE).
2707    pub start_token: AttachedToken,
2708    /// Optional condition expression for the block.
2709    pub condition: Option<Expr>,
2710    /// Optional token for the `THEN` keyword.
2711    pub then_token: Option<AttachedToken>,
2712    /// The statements contained in this conditional block.
2713    pub conditional_statements: ConditionalStatements,
2714}
2715
2716impl ConditionalStatementBlock {
2717    /// Get the statements in this conditional block.
2718    pub fn statements(&self) -> &Vec<Statement> {
2719        self.conditional_statements.statements()
2720    }
2721}
2722
2723impl fmt::Display for ConditionalStatementBlock {
2724    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2725        let ConditionalStatementBlock {
2726            start_token: AttachedToken(start_token),
2727            condition,
2728            then_token,
2729            conditional_statements,
2730        } = self;
2731
2732        write!(f, "{start_token}")?;
2733
2734        if let Some(condition) = condition {
2735            write!(f, " {condition}")?;
2736        }
2737
2738        if then_token.is_some() {
2739            write!(f, " THEN")?;
2740        }
2741
2742        if !conditional_statements.statements().is_empty() {
2743            write!(f, " {conditional_statements}")?;
2744        }
2745
2746        Ok(())
2747    }
2748}
2749
2750/// A list of statements in a [ConditionalStatementBlock].
2751#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2752#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2753#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2754/// Statements used inside conditional blocks (`IF`, `WHEN`, `WHILE`).
2755pub enum ConditionalStatements {
2756    /// Simple sequence of statements (no `BEGIN`/`END`).
2757    Sequence {
2758        /// The statements in the sequence.
2759        statements: Vec<Statement>,
2760    },
2761    /// Block enclosed by `BEGIN` and `END`.
2762    BeginEnd(BeginEndStatements),
2763}
2764
2765impl ConditionalStatements {
2766    /// Get the statements in this conditional statements block.
2767    pub fn statements(&self) -> &Vec<Statement> {
2768        match self {
2769            ConditionalStatements::Sequence { statements } => statements,
2770            ConditionalStatements::BeginEnd(bes) => &bes.statements,
2771        }
2772    }
2773}
2774
2775impl fmt::Display for ConditionalStatements {
2776    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2777        match self {
2778            ConditionalStatements::Sequence { statements } => {
2779                if !statements.is_empty() {
2780                    format_statement_list(f, statements)?;
2781                }
2782                Ok(())
2783            }
2784            ConditionalStatements::BeginEnd(bes) => write!(f, "{bes}"),
2785        }
2786    }
2787}
2788
2789/// Represents a list of statements enclosed within `BEGIN` and `END` keywords.
2790/// Example:
2791/// ```sql
2792/// BEGIN
2793///     SELECT 1;
2794///     SELECT 2;
2795/// END
2796/// ```
2797#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2798#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2799#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2800pub struct BeginEndStatements {
2801    /// Token representing the `BEGIN` keyword (may include span info).
2802    pub begin_token: AttachedToken,
2803    /// Statements contained within the block.
2804    pub statements: Vec<Statement>,
2805    /// Token representing the `END` keyword (may include span info).
2806    pub end_token: AttachedToken,
2807}
2808
2809impl fmt::Display for BeginEndStatements {
2810    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2811        let BeginEndStatements {
2812            begin_token: AttachedToken(begin_token),
2813            statements,
2814            end_token: AttachedToken(end_token),
2815        } = self;
2816
2817        if begin_token.token != Token::EOF {
2818            write!(f, "{begin_token} ")?;
2819        }
2820        if !statements.is_empty() {
2821            format_statement_list(f, statements)?;
2822        }
2823        if end_token.token != Token::EOF {
2824            write!(f, " {end_token}")?;
2825        }
2826        Ok(())
2827    }
2828}
2829
2830/// A `RAISE` statement.
2831///
2832/// Examples:
2833/// ```sql
2834/// RAISE USING MESSAGE = 'error';
2835///
2836/// RAISE myerror;
2837/// ```
2838///
2839/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#raise)
2840/// [Snowflake](https://docs.snowflake.com/en/sql-reference/snowflake-scripting/raise)
2841#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2842#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2843#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2844pub struct RaiseStatement {
2845    /// Optional value provided to the RAISE statement.
2846    pub value: Option<RaiseStatementValue>,
2847}
2848
2849impl fmt::Display for RaiseStatement {
2850    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2851        let RaiseStatement { value } = self;
2852
2853        write!(f, "RAISE")?;
2854        if let Some(value) = value {
2855            write!(f, " {value}")?;
2856        }
2857
2858        Ok(())
2859    }
2860}
2861
2862/// Represents the error value of a [RaiseStatement].
2863#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2864#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2865#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2866pub enum RaiseStatementValue {
2867    /// `RAISE USING MESSAGE = 'error'`
2868    UsingMessage(Expr),
2869    /// `RAISE myerror`
2870    Expr(Expr),
2871}
2872
2873impl fmt::Display for RaiseStatementValue {
2874    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2875        match self {
2876            RaiseStatementValue::Expr(expr) => write!(f, "{expr}"),
2877            RaiseStatementValue::UsingMessage(expr) => write!(f, "USING MESSAGE = {expr}"),
2878        }
2879    }
2880}
2881
2882/// A MSSQL `THROW` statement.
2883///
2884/// ```sql
2885/// THROW [ error_number, message, state ]
2886/// ```
2887///
2888/// [MSSQL](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/throw-transact-sql)
2889#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2890#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2891#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2892pub struct ThrowStatement {
2893    /// Error number expression.
2894    pub error_number: Option<Box<Expr>>,
2895    /// Error message expression.
2896    pub message: Option<Box<Expr>>,
2897    /// State expression.
2898    pub state: Option<Box<Expr>>,
2899}
2900
2901impl fmt::Display for ThrowStatement {
2902    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2903        let ThrowStatement {
2904            error_number,
2905            message,
2906            state,
2907        } = self;
2908
2909        write!(f, "THROW")?;
2910        if let (Some(error_number), Some(message), Some(state)) = (error_number, message, state) {
2911            write!(f, " {error_number}, {message}, {state}")?;
2912        }
2913        Ok(())
2914    }
2915}
2916
2917/// Represents an expression assignment within a variable `DECLARE` statement.
2918///
2919/// Examples:
2920/// ```sql
2921/// DECLARE variable_name := 42
2922/// DECLARE variable_name DEFAULT 42
2923/// ```
2924#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2925#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2926#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2927pub enum DeclareAssignment {
2928    /// Plain expression specified.
2929    Expr(Box<Expr>),
2930
2931    /// Expression assigned via the `DEFAULT` keyword
2932    Default(Box<Expr>),
2933
2934    /// Expression assigned via the `:=` syntax
2935    ///
2936    /// Example:
2937    /// ```sql
2938    /// DECLARE variable_name := 42;
2939    /// ```
2940    DuckAssignment(Box<Expr>),
2941
2942    /// Expression via the `FOR` keyword
2943    ///
2944    /// Example:
2945    /// ```sql
2946    /// DECLARE c1 CURSOR FOR res
2947    /// ```
2948    For(Box<Expr>),
2949
2950    /// Expression via the `=` syntax.
2951    ///
2952    /// Example:
2953    /// ```sql
2954    /// DECLARE @variable AS INT = 100
2955    /// ```
2956    MsSqlAssignment(Box<Expr>),
2957}
2958
2959impl fmt::Display for DeclareAssignment {
2960    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2961        match self {
2962            DeclareAssignment::Expr(expr) => {
2963                write!(f, "{expr}")
2964            }
2965            DeclareAssignment::Default(expr) => {
2966                write!(f, "DEFAULT {expr}")
2967            }
2968            DeclareAssignment::DuckAssignment(expr) => {
2969                write!(f, ":= {expr}")
2970            }
2971            DeclareAssignment::MsSqlAssignment(expr) => {
2972                write!(f, "= {expr}")
2973            }
2974            DeclareAssignment::For(expr) => {
2975                write!(f, "FOR {expr}")
2976            }
2977        }
2978    }
2979}
2980
2981/// Represents the type of a `DECLARE` statement.
2982#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
2983#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
2984#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
2985pub enum DeclareType {
2986    /// Cursor variable type. e.g. [Snowflake] [PostgreSQL] [MsSql]
2987    ///
2988    /// [Snowflake]: https://docs.snowflake.com/en/developer-guide/snowflake-scripting/cursors#declaring-a-cursor
2989    /// [PostgreSQL]: https://www.postgresql.org/docs/current/plpgsql-cursors.html
2990    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/declare-cursor-transact-sql
2991    Cursor,
2992
2993    /// Result set variable type. [Snowflake]
2994    ///
2995    /// Syntax:
2996    /// ```text
2997    /// <resultset_name> RESULTSET [ { DEFAULT | := } ( <query> ) ] ;
2998    /// ```
2999    /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare#resultset-declaration-syntax
3000    ResultSet,
3001
3002    /// Exception declaration syntax. [Snowflake]
3003    ///
3004    /// Syntax:
3005    /// ```text
3006    /// <exception_name> EXCEPTION [ ( <exception_number> , '<exception_message>' ) ] ;
3007    /// ```
3008    /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare#exception-declaration-syntax
3009    Exception,
3010}
3011
3012impl fmt::Display for DeclareType {
3013    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3014        match self {
3015            DeclareType::Cursor => {
3016                write!(f, "CURSOR")
3017            }
3018            DeclareType::ResultSet => {
3019                write!(f, "RESULTSET")
3020            }
3021            DeclareType::Exception => {
3022                write!(f, "EXCEPTION")
3023            }
3024        }
3025    }
3026}
3027
3028/// A `DECLARE` statement.
3029/// [PostgreSQL] [Snowflake] [BigQuery]
3030///
3031/// Examples:
3032/// ```sql
3033/// DECLARE variable_name := 42
3034/// DECLARE liahona CURSOR FOR SELECT * FROM films;
3035/// ```
3036///
3037/// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-declare.html
3038/// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare
3039/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#declare
3040#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3041#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3042#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3043pub struct Declare {
3044    /// The name(s) being declared.
3045    /// Example: `DECLARE a, b, c DEFAULT 42;
3046    pub names: Vec<Ident>,
3047    /// Data-type assigned to the declared variable.
3048    /// Example: `DECLARE x INT64 DEFAULT 42;
3049    pub data_type: Option<DataType>,
3050    /// Expression being assigned to the declared variable.
3051    pub assignment: Option<DeclareAssignment>,
3052    /// Represents the type of the declared variable.
3053    pub declare_type: Option<DeclareType>,
3054    /// Causes the cursor to return data in binary rather than in text format.
3055    pub binary: Option<bool>,
3056    /// None = Not specified
3057    /// Some(true) = INSENSITIVE
3058    /// Some(false) = ASENSITIVE
3059    pub sensitive: Option<bool>,
3060    /// None = Not specified
3061    /// Some(true) = SCROLL
3062    /// Some(false) = NO SCROLL
3063    pub scroll: Option<bool>,
3064    /// None = Not specified
3065    /// Some(true) = WITH HOLD, specifies that the cursor can continue to be used after the transaction that created it successfully commits
3066    /// Some(false) = WITHOUT HOLD, specifies that the cursor cannot be used outside of the transaction that created it
3067    pub hold: Option<bool>,
3068    /// `FOR <query>` clause in a CURSOR declaration.
3069    pub for_query: Option<Box<Query>>,
3070}
3071
3072impl fmt::Display for Declare {
3073    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3074        let Declare {
3075            names,
3076            data_type,
3077            assignment,
3078            declare_type,
3079            binary,
3080            sensitive,
3081            scroll,
3082            hold,
3083            for_query,
3084        } = self;
3085        write!(f, "{}", display_comma_separated(names))?;
3086
3087        if let Some(true) = binary {
3088            write!(f, " BINARY")?;
3089        }
3090
3091        if let Some(sensitive) = sensitive {
3092            if *sensitive {
3093                write!(f, " INSENSITIVE")?;
3094            } else {
3095                write!(f, " ASENSITIVE")?;
3096            }
3097        }
3098
3099        if let Some(scroll) = scroll {
3100            if *scroll {
3101                write!(f, " SCROLL")?;
3102            } else {
3103                write!(f, " NO SCROLL")?;
3104            }
3105        }
3106
3107        if let Some(declare_type) = declare_type {
3108            write!(f, " {declare_type}")?;
3109        }
3110
3111        if let Some(hold) = hold {
3112            if *hold {
3113                write!(f, " WITH HOLD")?;
3114            } else {
3115                write!(f, " WITHOUT HOLD")?;
3116            }
3117        }
3118
3119        if let Some(query) = for_query {
3120            write!(f, " FOR {query}")?;
3121        }
3122
3123        if let Some(data_type) = data_type {
3124            write!(f, " {data_type}")?;
3125        }
3126
3127        if let Some(expr) = assignment {
3128            write!(f, " {expr}")?;
3129        }
3130        Ok(())
3131    }
3132}
3133
3134/// Sql options of a `CREATE TABLE` statement.
3135#[derive(Debug, Default, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3136#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3137#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3138/// Options allowed within a `CREATE TABLE` statement.
3139pub enum CreateTableOptions {
3140    /// No options specified.
3141    #[default]
3142    None,
3143    /// Options specified using the `WITH` keyword, e.g. `WITH (k = v)`.
3144    With(Vec<SqlOption>),
3145    /// Options specified using the `OPTIONS(...)` clause.
3146    Options(Vec<SqlOption>),
3147    /// Plain space-separated options.
3148    Plain(Vec<SqlOption>),
3149    /// Table properties (e.g., TBLPROPERTIES / storage properties).
3150    TableProperties(Vec<SqlOption>),
3151}
3152
3153impl fmt::Display for CreateTableOptions {
3154    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3155        match self {
3156            CreateTableOptions::With(with_options) => {
3157                write!(f, "WITH ({})", display_comma_separated(with_options))
3158            }
3159            CreateTableOptions::Options(options) => {
3160                write!(f, "OPTIONS({})", display_comma_separated(options))
3161            }
3162            CreateTableOptions::TableProperties(options) => {
3163                write!(f, "TBLPROPERTIES ({})", display_comma_separated(options))
3164            }
3165            CreateTableOptions::Plain(options) => {
3166                write!(f, "{}", display_separated(options, " "))
3167            }
3168            CreateTableOptions::None => Ok(()),
3169        }
3170    }
3171}
3172
3173/// A `FROM` clause within a `DELETE` statement.
3174///
3175/// Syntax
3176/// ```sql
3177/// [FROM] table
3178/// ```
3179#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3180#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3181#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3182pub enum FromTable {
3183    /// An explicit `FROM` keyword was specified.
3184    WithFromKeyword(Vec<TableWithJoins>),
3185    /// BigQuery: `FROM` keyword was omitted.
3186    /// <https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#delete_statement>
3187    WithoutKeyword(Vec<TableWithJoins>),
3188}
3189impl Display for FromTable {
3190    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3191        match self {
3192            FromTable::WithFromKeyword(tables) => {
3193                write!(f, "FROM {}", display_comma_separated(tables))
3194            }
3195            FromTable::WithoutKeyword(tables) => {
3196                write!(f, "{}", display_comma_separated(tables))
3197            }
3198        }
3199    }
3200}
3201
3202#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3203#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3204#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3205/// Variants for the `SET` family of statements.
3206pub enum Set {
3207    /// SQL Standard-style
3208    /// SET a = 1;
3209    /// `SET var = value` (standard SQL-style assignment).
3210    SingleAssignment {
3211        /// Optional scope modifier (`SESSION` / `LOCAL`).
3212        scope: Option<ContextModifier>,
3213        /// Whether this is a Hive-style `HIVEVAR:` assignment.
3214        hivevar: bool,
3215        /// Variable name to assign.
3216        variable: ObjectName,
3217        /// Values assigned to the variable.
3218        values: Vec<Expr>,
3219    },
3220    /// Snowflake-style
3221    /// SET (a, b, ..) = (1, 2, ..);
3222    /// `SET (a, b) = (1, 2)` (tuple assignment syntax).
3223    ParenthesizedAssignments {
3224        /// Variables being assigned in tuple form.
3225        variables: Vec<ObjectName>,
3226        /// Corresponding values for the variables.
3227        values: Vec<Expr>,
3228    },
3229    /// MySQL-style
3230    /// SET a = 1, b = 2, ..;
3231    /// `SET a = 1, b = 2` (MySQL-style comma-separated assignments).
3232    MultipleAssignments {
3233        /// List of `SET` assignments (MySQL-style comma-separated).
3234        assignments: Vec<SetAssignment>,
3235    },
3236    /// Session authorization for Postgres/Redshift
3237    ///
3238    /// ```sql
3239    /// SET SESSION AUTHORIZATION { user_name | DEFAULT }
3240    /// ```
3241    ///
3242    /// See <https://www.postgresql.org/docs/current/sql-set-session-authorization.html>
3243    /// See <https://docs.aws.amazon.com/redshift/latest/dg/r_SET_SESSION_AUTHORIZATION.html>
3244    SetSessionAuthorization(SetSessionAuthorizationParam),
3245    /// MS-SQL session
3246    ///
3247    /// See <https://learn.microsoft.com/en-us/sql/t-sql/statements/set-statements-transact-sql>
3248    SetSessionParam(SetSessionParamKind),
3249    /// ```sql
3250    /// SET [ SESSION | LOCAL ] ROLE role_name
3251    /// ```
3252    ///
3253    /// Sets session state. Examples: [ANSI][1], [Postgresql][2], [MySQL][3], and [Oracle][4]
3254    ///
3255    /// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#set-role-statement
3256    /// [2]: https://www.postgresql.org/docs/14/sql-set-role.html
3257    /// [3]: https://dev.mysql.com/doc/refman/8.0/en/set-role.html
3258    /// [4]: https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_10004.htm
3259    SetRole {
3260        /// Non-ANSI optional identifier to inform if the role is defined inside the current session (`SESSION`) or transaction (`LOCAL`).
3261        context_modifier: Option<ContextModifier>,
3262        /// Role name. If NONE is specified, then the current role name is removed.
3263        role_name: Option<Ident>,
3264    },
3265    /// ```sql
3266    /// SET TIME ZONE <value>
3267    /// ```
3268    ///
3269    /// Note: this is a PostgreSQL-specific statements
3270    /// `SET TIME ZONE <value>` is an alias for `SET timezone TO <value>` in PostgreSQL
3271    /// However, we allow it for all dialects.
3272    /// `SET TIME ZONE` statement. `local` indicates the `LOCAL` keyword.
3273    /// `SET TIME ZONE <value>` statement.
3274    SetTimeZone {
3275        /// Whether the `LOCAL` keyword was specified.
3276        local: bool,
3277        /// Time zone expression value.
3278        value: Expr,
3279    },
3280    /// ```sql
3281    /// SET NAMES 'charset_name' [COLLATE 'collation_name']
3282    /// ```
3283    SetNames {
3284        /// Character set name to set.
3285        charset_name: Ident,
3286        /// Optional collation name.
3287        collation_name: Option<String>,
3288    },
3289    /// ```sql
3290    /// SET NAMES DEFAULT
3291    /// ```
3292    ///
3293    /// Note: this is a MySQL-specific statement.
3294    SetNamesDefault {},
3295    /// ```sql
3296    /// SET TRANSACTION ...
3297    /// ```
3298    SetTransaction {
3299        /// Transaction modes (e.g., ISOLATION LEVEL, READ ONLY).
3300        modes: Vec<TransactionMode>,
3301        /// Optional snapshot value for transaction snapshot control.
3302        snapshot: Option<ValueWithSpan>,
3303        /// `true` when the `SESSION` keyword was used.
3304        session: bool,
3305    },
3306}
3307
3308impl Display for Set {
3309    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3310        match self {
3311            Self::ParenthesizedAssignments { variables, values } => write!(
3312                f,
3313                "SET ({}) = ({})",
3314                display_comma_separated(variables),
3315                display_comma_separated(values)
3316            ),
3317            Self::MultipleAssignments { assignments } => {
3318                write!(f, "SET {}", display_comma_separated(assignments))
3319            }
3320            Self::SetRole {
3321                context_modifier,
3322                role_name,
3323            } => {
3324                let role_name = role_name.clone().unwrap_or_else(|| Ident::new("NONE"));
3325                write!(
3326                    f,
3327                    "SET {modifier}ROLE {role_name}",
3328                    modifier = context_modifier.map(|m| format!("{m}")).unwrap_or_default()
3329                )
3330            }
3331            Self::SetSessionAuthorization(kind) => write!(f, "SET SESSION AUTHORIZATION {kind}"),
3332            Self::SetSessionParam(kind) => write!(f, "SET {kind}"),
3333            Self::SetTransaction {
3334                modes,
3335                snapshot,
3336                session,
3337            } => {
3338                if *session {
3339                    write!(f, "SET SESSION CHARACTERISTICS AS TRANSACTION")?;
3340                } else {
3341                    write!(f, "SET TRANSACTION")?;
3342                }
3343                if !modes.is_empty() {
3344                    write!(f, " {}", display_comma_separated(modes))?;
3345                }
3346                if let Some(snapshot_id) = snapshot {
3347                    write!(f, " SNAPSHOT {snapshot_id}")?;
3348                }
3349                Ok(())
3350            }
3351            Self::SetTimeZone { local, value } => {
3352                f.write_str("SET ")?;
3353                if *local {
3354                    f.write_str("LOCAL ")?;
3355                }
3356                write!(f, "TIME ZONE {value}")
3357            }
3358            Self::SetNames {
3359                charset_name,
3360                collation_name,
3361            } => {
3362                write!(f, "SET NAMES {charset_name}")?;
3363
3364                if let Some(collation) = collation_name {
3365                    f.write_str(" COLLATE ")?;
3366                    f.write_str(collation)?;
3367                };
3368
3369                Ok(())
3370            }
3371            Self::SetNamesDefault {} => {
3372                f.write_str("SET NAMES DEFAULT")?;
3373
3374                Ok(())
3375            }
3376            Set::SingleAssignment {
3377                scope,
3378                hivevar,
3379                variable,
3380                values,
3381            } => {
3382                write!(
3383                    f,
3384                    "SET {}{}{} = {}",
3385                    scope.map(|s| format!("{s}")).unwrap_or_default(),
3386                    if *hivevar { "HIVEVAR:" } else { "" },
3387                    variable,
3388                    display_comma_separated(values)
3389                )
3390            }
3391        }
3392    }
3393}
3394
3395/// A representation of a `WHEN` arm with all the identifiers catched and the statements to execute
3396/// for the arm.
3397///
3398/// Snowflake: <https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
3399/// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
3400#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3401#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3402#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3403pub struct ExceptionWhen {
3404    /// Identifiers that trigger this branch (error conditions).
3405    pub idents: Vec<Ident>,
3406    /// Statements to execute when the condition matches.
3407    pub statements: Vec<Statement>,
3408}
3409
3410impl Display for ExceptionWhen {
3411    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3412        write!(
3413            f,
3414            "WHEN {idents} THEN",
3415            idents = display_separated(&self.idents, " OR ")
3416        )?;
3417
3418        if !self.statements.is_empty() {
3419            write!(f, " ")?;
3420            format_statement_list(f, &self.statements)?;
3421        }
3422
3423        Ok(())
3424    }
3425}
3426
3427/// ANALYZE statement
3428///
3429/// Supported syntax varies by dialect:
3430/// - Hive: `ANALYZE TABLE t [PARTITION (...)] COMPUTE STATISTICS [NOSCAN] [FOR COLUMNS [col1, ...]] [CACHE METADATA]`
3431/// - PostgreSQL: `ANALYZE [VERBOSE] [t [(col1, ...)]]` See <https://www.postgresql.org/docs/current/sql-analyze.html>
3432/// - General: `ANALYZE [TABLE] t`
3433#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3434#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3435#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3436pub struct Analyze {
3437    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3438    /// Name of the table to analyze. `None` for bare `ANALYZE`.
3439    pub table_name: Option<ObjectName>,
3440    /// Optional partition expressions to restrict the analysis.
3441    pub partitions: Option<Vec<Expr>>,
3442    /// `true` when analyzing specific columns (Hive `FOR COLUMNS` syntax).
3443    pub for_columns: bool,
3444    /// Columns to analyze.
3445    pub columns: Vec<Ident>,
3446    /// Whether to cache metadata before analyzing.
3447    pub cache_metadata: bool,
3448    /// Whether to skip scanning the table.
3449    pub noscan: bool,
3450    /// Whether to compute statistics during analysis.
3451    pub compute_statistics: bool,
3452    /// Whether the `TABLE` keyword was present.
3453    pub has_table_keyword: bool,
3454}
3455
3456impl fmt::Display for Analyze {
3457    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3458        write!(f, "ANALYZE")?;
3459        if let Some(ref table_name) = self.table_name {
3460            if self.has_table_keyword {
3461                write!(f, " TABLE")?;
3462            }
3463            write!(f, " {table_name}")?;
3464        }
3465        if !self.for_columns && !self.columns.is_empty() {
3466            write!(f, " ({})", display_comma_separated(&self.columns))?;
3467        }
3468        if let Some(ref parts) = self.partitions {
3469            if !parts.is_empty() {
3470                write!(f, " PARTITION ({})", display_comma_separated(parts))?;
3471            }
3472        }
3473        if self.compute_statistics {
3474            write!(f, " COMPUTE STATISTICS")?;
3475        }
3476        if self.noscan {
3477            write!(f, " NOSCAN")?;
3478        }
3479        if self.cache_metadata {
3480            write!(f, " CACHE METADATA")?;
3481        }
3482        if self.for_columns {
3483            write!(f, " FOR COLUMNS")?;
3484            if !self.columns.is_empty() {
3485                write!(f, " {}", display_comma_separated(&self.columns))?;
3486            }
3487        }
3488        Ok(())
3489    }
3490}
3491
3492/// A top-level statement (SELECT, INSERT, CREATE, etc.)
3493#[allow(clippy::large_enum_variant)]
3494#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3495#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3496#[cfg_attr(
3497    feature = "visitor",
3498    derive(Visit, VisitMut),
3499    visit(with = "visit_statement")
3500)]
3501pub enum Statement {
3502    /// ```sql
3503    /// ANALYZE
3504    /// ```
3505    /// Analyze (Hive)
3506    Analyze(Analyze),
3507    /// `SET` statements (session, transaction, timezone, etc.).
3508    Set(Set),
3509    /// ```sql
3510    /// TRUNCATE
3511    /// ```
3512    /// Truncate (Hive)
3513    Truncate(Truncate),
3514    /// ```sql
3515    /// MSCK
3516    /// ```
3517    /// Msck (Hive)
3518    Msck(Msck),
3519    /// ```sql
3520    /// SELECT
3521    /// ```
3522    Query(Box<Query>),
3523    /// ```sql
3524    /// INSERT
3525    /// ```
3526    Insert(Insert),
3527    /// ```sql
3528    /// INSTALL
3529    /// ```
3530    Install {
3531        /// Only for DuckDB
3532        extension_name: Ident,
3533    },
3534    /// ```sql
3535    /// LOAD
3536    /// ```
3537    Load {
3538        /// Only for DuckDB
3539        extension_name: Ident,
3540    },
3541    // TODO: Support ROW FORMAT
3542    /// LOAD DATA from a directory or query source.
3543    Directory {
3544        /// Whether to overwrite existing files.
3545        overwrite: bool,
3546        /// Whether the directory is local to the server.
3547        local: bool,
3548        /// Path to the directory or files.
3549        path: String,
3550        /// Optional file format for the data.
3551        file_format: Option<FileFormat>,
3552        /// Source query providing data to load.
3553        source: Box<Query>,
3554    },
3555    /// A `CASE` statement.
3556    Case(CaseStatement),
3557    /// An `IF` statement.
3558    If(IfStatement),
3559    /// A `WHILE` statement.
3560    While(WhileStatement),
3561    /// A `RAISE` statement.
3562    Raise(RaiseStatement),
3563    /// ```sql
3564    /// CALL <function>
3565    /// ```
3566    Call(Function),
3567    /// ```sql
3568    /// COPY [TO | FROM] ...
3569    /// ```
3570    Copy {
3571        /// The source of 'COPY TO', or the target of 'COPY FROM'
3572        source: CopySource,
3573        /// If true, is a 'COPY TO' statement. If false is a 'COPY FROM'
3574        to: bool,
3575        /// The target of 'COPY TO', or the source of 'COPY FROM'
3576        target: CopyTarget,
3577        /// WITH options (from PostgreSQL version 9.0)
3578        options: Vec<CopyOption>,
3579        /// WITH options (before PostgreSQL version 9.0)
3580        legacy_options: Vec<CopyLegacyOption>,
3581        /// VALUES a vector of values to be copied
3582        values: Vec<Option<String>>,
3583    },
3584    /// ```sql
3585    /// COPY INTO <table> | <location>
3586    /// ```
3587    /// See:
3588    /// <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table>
3589    /// <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location>
3590    ///
3591    /// Copy Into syntax available for Snowflake is different than the one implemented in
3592    /// Postgres. Although they share common prefix, it is reasonable to implement them
3593    /// in different enums. This can be refactored later once custom dialects
3594    /// are allowed to have custom Statements.
3595    CopyIntoSnowflake {
3596        /// Kind of COPY INTO operation (table or location).
3597        kind: CopyIntoSnowflakeKind,
3598        /// Target object for the COPY INTO operation.
3599        into: ObjectName,
3600        /// Optional list of target columns.
3601        into_columns: Option<Vec<Ident>>,
3602        /// Optional source object name (staged data).
3603        from_obj: Option<ObjectName>,
3604        /// Optional alias for the source object.
3605        from_obj_alias: Option<Ident>,
3606        /// Stage-specific parameters (e.g., credentials, path).
3607        stage_params: StageParamsObject,
3608        /// Optional list of transformations applied when loading.
3609        from_transformations: Option<Vec<StageLoadSelectItemKind>>,
3610        /// Optional source query instead of a staged object.
3611        from_query: Option<Box<Query>>,
3612        /// Optional list of specific file names to load.
3613        files: Option<Vec<String>>,
3614        /// Optional filename matching pattern.
3615        pattern: Option<String>,
3616        /// File format options.
3617        file_format: KeyValueOptions,
3618        /// Additional copy options.
3619        copy_options: KeyValueOptions,
3620        /// Optional validation mode string.
3621        validation_mode: Option<String>,
3622        /// Optional partition expression for loading.
3623        partition: Option<Box<Expr>>,
3624    },
3625    /// ```sql
3626    /// OPEN cursor_name
3627    /// ```
3628    /// Opens a cursor.
3629    Open(OpenStatement),
3630    /// ```sql
3631    /// CLOSE
3632    /// ```
3633    /// Closes the portal underlying an open cursor.
3634    Close {
3635        /// Cursor name
3636        cursor: CloseCursor,
3637    },
3638    /// ```sql
3639    /// UPDATE
3640    /// ```
3641    Update(Update),
3642    /// ```sql
3643    /// DELETE
3644    /// ```
3645    Delete(Delete),
3646    /// ```sql
3647    /// CREATE VIEW
3648    /// ```
3649    CreateView(CreateView),
3650    /// ```sql
3651    /// CREATE TABLE
3652    /// ```
3653    CreateTable(CreateTable),
3654    /// ```sql
3655    /// CREATE VIRTUAL TABLE .. USING <module_name> (<module_args>)`
3656    /// ```
3657    /// Sqlite specific statement
3658    CreateVirtualTable {
3659        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3660        /// Name of the virtual table module instance.
3661        name: ObjectName,
3662        /// `true` when `IF NOT EXISTS` was specified.
3663        if_not_exists: bool,
3664        /// Module name used by the virtual table.
3665        module_name: Ident,
3666        /// Arguments passed to the module.
3667        module_args: Vec<Ident>,
3668    },
3669    /// ```sql
3670    /// `CREATE INDEX`
3671    /// ```
3672    CreateIndex(CreateIndex),
3673    /// ```sql
3674    /// CREATE ROLE
3675    /// ```
3676    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createrole.html)
3677    CreateRole(CreateRole),
3678    /// ```sql
3679    /// CREATE SECRET
3680    /// ```
3681    /// See [DuckDB](https://duckdb.org/docs/sql/statements/create_secret.html)
3682    CreateSecret {
3683        /// `true` when `OR REPLACE` was specified.
3684        or_replace: bool,
3685        /// Optional `TEMPORARY` flag.
3686        temporary: Option<bool>,
3687        /// `true` when `IF NOT EXISTS` was present.
3688        if_not_exists: bool,
3689        /// Optional secret name.
3690        name: Option<Ident>,
3691        /// Optional storage specifier identifier.
3692        storage_specifier: Option<Ident>,
3693        /// The secret type identifier.
3694        secret_type: Ident,
3695        /// Additional secret options.
3696        options: Vec<SecretOption>,
3697    },
3698    /// A `CREATE SERVER` statement.
3699    CreateServer(CreateServerStatement),
3700    /// ```sql
3701    /// CREATE POLICY
3702    /// ```
3703    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createpolicy.html)
3704    CreatePolicy(CreatePolicy),
3705    /// ```sql
3706    /// CREATE CONNECTOR
3707    /// ```
3708    /// See [Hive](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-CreateDataConnectorCreateConnector)
3709    CreateConnector(CreateConnector),
3710    /// ```sql
3711    /// CREATE OPERATOR
3712    /// ```
3713    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createoperator.html)
3714    CreateOperator(CreateOperator),
3715    /// ```sql
3716    /// CREATE OPERATOR FAMILY
3717    /// ```
3718    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopfamily.html)
3719    CreateOperatorFamily(CreateOperatorFamily),
3720    /// ```sql
3721    /// CREATE OPERATOR CLASS
3722    /// ```
3723    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-createopclass.html)
3724    CreateOperatorClass(CreateOperatorClass),
3725    /// ```sql
3726    /// ALTER TABLE
3727    /// ```
3728    AlterTable(AlterTable),
3729    /// ```sql
3730    /// ALTER SCHEMA
3731    /// ```
3732    /// See [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#alter_schema_collate_statement)
3733    AlterSchema(AlterSchema),
3734    /// ```sql
3735    /// ALTER INDEX
3736    /// ```
3737    AlterIndex {
3738        /// Name of the index to alter.
3739        name: ObjectName,
3740        /// The operation to perform on the index.
3741        operation: AlterIndexOperation,
3742    },
3743    /// ```sql
3744    /// ALTER VIEW
3745    /// ```
3746    AlterView {
3747        /// View name being altered.
3748        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
3749        name: ObjectName,
3750        /// Optional new column list for the view.
3751        columns: Vec<Ident>,
3752        /// Replacement query for the view definition.
3753        query: Box<Query>,
3754        /// Additional WITH options for the view.
3755        with_options: Vec<SqlOption>,
3756    },
3757    /// ```sql
3758    /// ALTER FUNCTION
3759    /// ALTER AGGREGATE
3760    /// ```
3761    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alterfunction.html)
3762    /// and [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteraggregate.html)
3763    AlterFunction(AlterFunction),
3764    /// ```sql
3765    /// ALTER TYPE
3766    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-altertype.html)
3767    /// ```
3768    AlterType(AlterType),
3769    /// ```sql
3770    /// ALTER COLLATION
3771    /// ```
3772    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-altercollation.html)
3773    AlterCollation(AlterCollation),
3774    /// ```sql
3775    /// ALTER OPERATOR
3776    /// ```
3777    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteroperator.html)
3778    AlterOperator(AlterOperator),
3779    /// ```sql
3780    /// ALTER OPERATOR FAMILY
3781    /// ```
3782    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteropfamily.html)
3783    AlterOperatorFamily(AlterOperatorFamily),
3784    /// ```sql
3785    /// ALTER OPERATOR CLASS
3786    /// ```
3787    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-alteropclass.html)
3788    AlterOperatorClass(AlterOperatorClass),
3789    /// ```sql
3790    /// ALTER ROLE
3791    /// ```
3792    AlterRole {
3793        /// Role name being altered.
3794        name: Ident,
3795        /// Operation to perform on the role.
3796        operation: AlterRoleOperation,
3797    },
3798    /// ```sql
3799    /// ALTER POLICY <NAME> ON <TABLE NAME> [<OPERATION>]
3800    /// ```
3801    /// (Postgresql-specific)
3802    AlterPolicy(AlterPolicy),
3803    /// ```sql
3804    /// ALTER CONNECTOR connector_name SET DCPROPERTIES(property_name=property_value, ...);
3805    /// or
3806    /// ALTER CONNECTOR connector_name SET URL new_url;
3807    /// or
3808    /// ALTER CONNECTOR connector_name SET OWNER [USER|ROLE] user_or_role;
3809    /// ```
3810    /// (Hive-specific)
3811    AlterConnector {
3812        /// Name of the connector to alter.
3813        name: Ident,
3814        /// Optional connector properties to set.
3815        properties: Option<Vec<SqlOption>>,
3816        /// Optional new URL for the connector.
3817        url: Option<String>,
3818        /// Optional new owner specification.
3819        owner: Option<ddl::AlterConnectorOwner>,
3820    },
3821    /// ```sql
3822    /// ALTER SESSION SET sessionParam
3823    /// ALTER SESSION UNSET <param_name> [ , <param_name> , ... ]
3824    /// ```
3825    /// See <https://docs.snowflake.com/en/sql-reference/sql/alter-session>
3826    AlterSession {
3827        /// true is to set for the session parameters, false is to unset
3828        set: bool,
3829        /// The session parameters to set or unset
3830        session_params: KeyValueOptions,
3831    },
3832    /// ```sql
3833    /// ATTACH DATABASE 'path/to/file' AS alias
3834    /// ```
3835    /// (SQLite-specific)
3836    AttachDatabase {
3837        /// The name to bind to the newly attached database
3838        schema_name: Ident,
3839        /// An expression that indicates the path to the database file
3840        database_file_name: Expr,
3841        /// true if the syntax is 'ATTACH DATABASE', false if it's just 'ATTACH'
3842        database: bool,
3843    },
3844    /// (DuckDB-specific)
3845    /// ```sql
3846    /// ATTACH 'sqlite_file.db' AS sqlite_db (READ_ONLY, TYPE SQLITE);
3847    /// ```
3848    /// See <https://duckdb.org/docs/sql/statements/attach.html>
3849    AttachDuckDBDatabase {
3850        /// `true` when `IF NOT EXISTS` was present.
3851        if_not_exists: bool,
3852        /// `true` if the syntax used `ATTACH DATABASE` rather than `ATTACH`.
3853        database: bool,
3854        /// The path identifier to the database file being attached.
3855        database_path: Ident,
3856        /// Optional alias assigned to the attached database.
3857        database_alias: Option<Ident>,
3858        /// Dialect-specific attach options (e.g., `READ_ONLY`).
3859        attach_options: Vec<AttachDuckDBDatabaseOption>,
3860    },
3861    /// (DuckDB-specific)
3862    /// ```sql
3863    /// DETACH db_alias;
3864    /// ```
3865    /// See <https://duckdb.org/docs/sql/statements/attach.html>
3866    DetachDuckDBDatabase {
3867        /// `true` when `IF EXISTS` was present.
3868        if_exists: bool,
3869        /// `true` if the syntax used `DETACH DATABASE` rather than `DETACH`.
3870        database: bool,
3871        /// Alias of the database to detach.
3872        database_alias: Ident,
3873    },
3874    /// ```sql
3875    /// DROP [TABLE, VIEW, ...]
3876    /// ```
3877    Drop {
3878        /// The type of the object to drop: TABLE, VIEW, etc.
3879        object_type: ObjectType,
3880        /// An optional `IF EXISTS` clause. (Non-standard.)
3881        if_exists: bool,
3882        /// One or more objects to drop. (ANSI SQL requires exactly one.)
3883        names: Vec<ObjectName>,
3884        /// Whether `CASCADE` was specified. This will be `false` when
3885        /// `RESTRICT` or no drop behavior at all was specified.
3886        cascade: bool,
3887        /// Whether `RESTRICT` was specified. This will be `false` when
3888        /// `CASCADE` or no drop behavior at all was specified.
3889        restrict: bool,
3890        /// Hive allows you specify whether the table's stored data will be
3891        /// deleted along with the dropped table
3892        purge: bool,
3893        /// MySQL-specific "TEMPORARY" keyword
3894        temporary: bool,
3895        /// MySQL-specific drop index syntax, which requires table specification
3896        /// See <https://dev.mysql.com/doc/refman/8.4/en/drop-index.html>
3897        table: Option<ObjectName>,
3898    },
3899    /// ```sql
3900    /// DROP FUNCTION
3901    /// ```
3902    DropFunction(DropFunction),
3903    /// ```sql
3904    /// DROP DOMAIN
3905    /// ```
3906    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-dropdomain.html)
3907    ///
3908    /// DROP DOMAIN [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
3909    ///
3910    DropDomain(DropDomain),
3911    /// ```sql
3912    /// DROP PROCEDURE
3913    /// ```
3914    DropProcedure {
3915        /// `true` when `IF EXISTS` was present.
3916        if_exists: bool,
3917        /// One or more functions/procedures to drop.
3918        proc_desc: Vec<FunctionDesc>,
3919        /// Optional drop behavior (`CASCADE` or `RESTRICT`).
3920        drop_behavior: Option<DropBehavior>,
3921    },
3922    /// ```sql
3923    /// DROP SECRET
3924    /// ```
3925    DropSecret {
3926        /// `true` when `IF EXISTS` was present.
3927        if_exists: bool,
3928        /// Optional `TEMPORARY` marker.
3929        temporary: Option<bool>,
3930        /// Name of the secret to drop.
3931        name: Ident,
3932        /// Optional storage specifier identifier.
3933        storage_specifier: Option<Ident>,
3934    },
3935    ///```sql
3936    /// DROP POLICY
3937    /// ```
3938    /// See [PostgreSQL](https://www.postgresql.org/docs/current/sql-droppolicy.html)
3939    DropPolicy(DropPolicy),
3940    /// ```sql
3941    /// DROP CONNECTOR
3942    /// ```
3943    /// See [Hive](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362034#LanguageManualDDL-DropConnector)
3944    DropConnector {
3945        /// `true` when `IF EXISTS` was present.
3946        if_exists: bool,
3947        /// Name of the connector to drop.
3948        name: Ident,
3949    },
3950    /// ```sql
3951    /// DECLARE
3952    /// ```
3953    /// Declare Cursor Variables
3954    ///
3955    /// Note: this is a PostgreSQL-specific statement,
3956    /// but may also compatible with other SQL.
3957    Declare {
3958        /// Cursor declaration statements collected by `DECLARE`.
3959        stmts: Vec<Declare>,
3960    },
3961    /// ```sql
3962    /// CREATE EXTENSION [ IF NOT EXISTS ] extension_name
3963    ///     [ WITH ] [ SCHEMA schema_name ]
3964    ///              [ VERSION version ]
3965    ///              [ CASCADE ]
3966    /// ```
3967    ///
3968    /// Note: this is a PostgreSQL-specific statement,
3969    CreateExtension(CreateExtension),
3970    /// ```sql
3971    /// CREATE COLLATION
3972    /// ```
3973    /// Note: this is a PostgreSQL-specific statement.
3974    /// <https://www.postgresql.org/docs/current/sql-createcollation.html>
3975    CreateCollation(CreateCollation),
3976    /// ```sql
3977    /// DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
3978    /// ```
3979    /// Note: this is a PostgreSQL-specific statement.
3980    /// <https://www.postgresql.org/docs/current/sql-dropextension.html>
3981    DropExtension(DropExtension),
3982    /// ```sql
3983    /// DROP OPERATOR [ IF EXISTS ] name ( { left_type | NONE } , right_type ) [, ...] [ CASCADE | RESTRICT ]
3984    /// ```
3985    /// Note: this is a PostgreSQL-specific statement.
3986    /// <https://www.postgresql.org/docs/current/sql-dropoperator.html>
3987    DropOperator(DropOperator),
3988    /// ```sql
3989    /// DROP OPERATOR FAMILY [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]
3990    /// ```
3991    /// Note: this is a PostgreSQL-specific statement.
3992    /// <https://www.postgresql.org/docs/current/sql-dropopfamily.html>
3993    DropOperatorFamily(DropOperatorFamily),
3994    /// ```sql
3995    /// DROP OPERATOR CLASS [ IF EXISTS ] name USING index_method [ CASCADE | RESTRICT ]
3996    /// ```
3997    /// Note: this is a PostgreSQL-specific statement.
3998    /// <https://www.postgresql.org/docs/current/sql-dropopclass.html>
3999    DropOperatorClass(DropOperatorClass),
4000    /// ```sql
4001    /// FETCH
4002    /// ```
4003    /// Retrieve rows from a query using a cursor
4004    ///
4005    /// Note: this is a PostgreSQL-specific statement,
4006    /// but may also compatible with other SQL.
4007    Fetch {
4008        /// Cursor name
4009        name: Ident,
4010        /// The fetch direction (e.g., `FORWARD`, `BACKWARD`).
4011        direction: FetchDirection,
4012        /// The fetch position (e.g., `ALL`, `NEXT`, `ABSOLUTE`).
4013        position: FetchPosition,
4014        /// Optional target table to fetch rows into.
4015        into: Option<ObjectName>,
4016    },
4017    /// ```sql
4018    /// FLUSH [NO_WRITE_TO_BINLOG | LOCAL] flush_option [, flush_option] ... | tables_option
4019    /// ```
4020    ///
4021    /// Note: this is a Mysql-specific statement,
4022    /// but may also compatible with other SQL.
4023    Flush {
4024        /// The specific flush option or object to flush.
4025        object_type: FlushType,
4026        /// Optional flush location (dialect-specific).
4027        location: Option<FlushLocation>,
4028        /// Optional channel name used for flush operations.
4029        channel: Option<String>,
4030        /// Whether a read lock was requested.
4031        read_lock: bool,
4032        /// Whether this is an export flush operation.
4033        export: bool,
4034        /// Optional list of tables involved in the flush.
4035        tables: Vec<ObjectName>,
4036    },
4037    /// ```sql
4038    /// DISCARD [ ALL | PLANS | SEQUENCES | TEMPORARY | TEMP ]
4039    /// ```
4040    ///
4041    /// Note: this is a PostgreSQL-specific statement,
4042    /// but may also compatible with other SQL.
4043    Discard {
4044        /// The kind of object(s) to discard (ALL, PLANS, etc.).
4045        object_type: DiscardObject,
4046    },
4047    /// `SHOW FUNCTIONS`
4048    ///
4049    /// Note: this is a Presto-specific statement.
4050    ShowFunctions {
4051        /// Optional filter for which functions to display.
4052        filter: Option<ShowStatementFilter>,
4053    },
4054    /// ```sql
4055    /// SHOW <variable>
4056    /// ```
4057    ///
4058    /// Note: this is a PostgreSQL-specific statement.
4059    ShowVariable {
4060        /// Variable name as one or more identifiers.
4061        variable: Vec<Ident>,
4062    },
4063    /// ```sql
4064    /// SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern' | WHERE expr]
4065    /// ```
4066    ///
4067    /// Note: this is a MySQL-specific statement.
4068    ShowStatus {
4069        /// Optional filter for which status entries to display.
4070        filter: Option<ShowStatementFilter>,
4071        /// `true` when `GLOBAL` scope was requested.
4072        global: bool,
4073        /// `true` when `SESSION` scope was requested.
4074        session: bool,
4075    },
4076    /// ```sql
4077    /// SHOW VARIABLES
4078    /// ```
4079    ///
4080    /// Note: this is a MySQL-specific statement.
4081    ShowVariables {
4082        /// Optional filter for which variables to display.
4083        filter: Option<ShowStatementFilter>,
4084        /// `true` when `GLOBAL` scope was requested.
4085        global: bool,
4086        /// `true` when `SESSION` scope was requested.
4087        session: bool,
4088    },
4089    /// ```sql
4090    /// SHOW CREATE TABLE
4091    /// ```
4092    ///
4093    /// Note: this is a MySQL-specific statement.
4094    ShowCreate {
4095        /// The kind of object being shown (TABLE, VIEW, etc.).
4096        obj_type: ShowCreateObject,
4097        /// The name of the object to show create statement for.
4098        obj_name: ObjectName,
4099    },
4100    /// ```sql
4101    /// SHOW COLUMNS
4102    /// ```
4103    ShowColumns {
4104        /// `true` when extended column information was requested.
4105        extended: bool,
4106        /// `true` when full column details were requested.
4107        full: bool,
4108        /// Additional options for `SHOW COLUMNS`.
4109        show_options: ShowStatementOptions,
4110    },
4111    /// ```sql
4112    /// SHOW DATABASES
4113    /// ```
4114    ShowDatabases {
4115        /// `true` when terse output format was requested.
4116        terse: bool,
4117        /// `true` when history information was requested.
4118        history: bool,
4119        /// Additional options for `SHOW DATABASES`.
4120        show_options: ShowStatementOptions,
4121    },
4122    /// ```sql
4123    /// SHOW [FULL] PROCESSLIST
4124    /// ```
4125    ///
4126    /// Note: this is a MySQL-specific statement.
4127    ShowProcessList {
4128        /// `true` when full process information was requested.
4129        full: bool,
4130    },
4131    /// ```sql
4132    /// SHOW SCHEMAS
4133    /// ```
4134    ShowSchemas {
4135        /// `true` when terse (compact) output was requested.
4136        terse: bool,
4137        /// `true` when history information was requested.
4138        history: bool,
4139        /// Additional options for `SHOW SCHEMAS`.
4140        show_options: ShowStatementOptions,
4141    },
4142    // ```sql
4143    // SHOW {CHARACTER SET | CHARSET}
4144    // ```
4145    // [MySQL]:
4146    // <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>
4147    /// Show the available character sets (alias `CHARSET`).
4148    ShowCharset(ShowCharset),
4149    /// ```sql
4150    /// SHOW OBJECTS LIKE 'line%' IN mydb.public
4151    /// ```
4152    /// Snowflake-specific statement
4153    /// <https://docs.snowflake.com/en/sql-reference/sql/show-objects>
4154    ShowObjects(ShowObjects),
4155    /// ```sql
4156    /// SHOW TABLES
4157    /// ```
4158    ShowTables {
4159        /// `true` when terse output format was requested (compact listing).
4160        terse: bool,
4161        /// `true` when history rows are requested.
4162        history: bool,
4163        /// `true` when extended information should be shown.
4164        extended: bool,
4165        /// `true` when a full listing was requested.
4166        full: bool,
4167        /// `true` when external tables should be included.
4168        external: bool,
4169        /// Additional options for `SHOW` statements.
4170        show_options: ShowStatementOptions,
4171    },
4172    /// ```sql
4173    /// SHOW VIEWS
4174    /// ```
4175    ShowViews {
4176        /// `true` when terse output format was requested.
4177        terse: bool,
4178        /// `true` when materialized views should be included.
4179        materialized: bool,
4180        /// Additional options for `SHOW` statements.
4181        show_options: ShowStatementOptions,
4182    },
4183    /// ```sql
4184    /// SHOW COLLATION
4185    /// ```
4186    ///
4187    /// Note: this is a MySQL-specific statement.
4188    ShowCollation {
4189        /// Optional filter for which collations to display.
4190        filter: Option<ShowStatementFilter>,
4191    },
4192    /// ```sql
4193    /// `USE ...`
4194    /// ```
4195    Use(Use),
4196    /// ```sql
4197    /// START  [ TRANSACTION | WORK ] | START TRANSACTION } ...
4198    /// ```
4199    /// If `begin` is false.
4200    ///
4201    /// ```sql
4202    /// `BEGIN  [ TRANSACTION | WORK ] | START TRANSACTION } ...`
4203    /// ```
4204    /// If `begin` is true
4205    StartTransaction {
4206        /// Transaction modes such as `ISOLATION LEVEL` or `READ WRITE`.
4207        modes: Vec<TransactionMode>,
4208        /// `true` when this was parsed as `BEGIN` instead of `START`.
4209        begin: bool,
4210        /// Optional specific keyword used: `TRANSACTION` or `WORK`.
4211        transaction: Option<BeginTransactionKind>,
4212        /// Optional transaction modifier (e.g., `AND NO CHAIN`).
4213        modifier: Option<TransactionModifier>,
4214        /// List of statements belonging to the `BEGIN` block.
4215        /// Example:
4216        /// ```sql
4217        /// BEGIN
4218        ///     SELECT 1;
4219        ///     SELECT 2;
4220        /// END;
4221        /// ```
4222        statements: Vec<Statement>,
4223        /// Exception handling with exception clauses.
4224        /// Example:
4225        /// ```sql
4226        /// EXCEPTION
4227        ///     WHEN EXCEPTION_1 THEN
4228        ///         SELECT 2;
4229        ///     WHEN EXCEPTION_2 OR EXCEPTION_3 THEN
4230        ///         SELECT 3;
4231        ///     WHEN OTHER THEN
4232        ///         SELECT 4;
4233        /// ```
4234        /// <https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#beginexceptionend>
4235        /// <https://docs.snowflake.com/en/sql-reference/snowflake-scripting/exception>
4236        exception: Option<Vec<ExceptionWhen>>,
4237        /// TRUE if the statement has an `END` keyword.
4238        has_end_keyword: bool,
4239    },
4240    /// ```sql
4241    /// COMMENT ON ...
4242    /// ```
4243    ///
4244    /// Note: this is a PostgreSQL-specific statement.
4245    Comment {
4246        /// Type of object being commented (table, column, etc.).
4247        object_type: CommentObject,
4248        /// Name of the object the comment applies to.
4249        object_name: ObjectName,
4250        /// Optional comment text (None to remove comment).
4251        comment: Option<String>,
4252        /// An optional `IF EXISTS` clause. (Non-standard.)
4253        /// See <https://docs.snowflake.com/en/sql-reference/sql/comment>
4254        if_exists: bool,
4255    },
4256    /// ```sql
4257    /// COMMIT [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]
4258    /// ```
4259    /// If `end` is false
4260    ///
4261    /// ```sql
4262    /// END [ TRY | CATCH ]
4263    /// ```
4264    /// If `end` is true
4265    Commit {
4266        /// `true` when `AND [ NO ] CHAIN` was present.
4267        chain: bool,
4268        /// `true` when this `COMMIT` was parsed as an `END` block terminator.
4269        end: bool,
4270        /// Optional transaction modifier for commit semantics.
4271        modifier: Option<TransactionModifier>,
4272    },
4273    /// ```sql
4274    /// ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ] [ TO [ SAVEPOINT ] savepoint_name ]
4275    /// ```
4276    Rollback {
4277        /// `true` when `AND [ NO ] CHAIN` was present.
4278        chain: bool,
4279        /// Optional savepoint name to roll back to.
4280        savepoint: Option<Ident>,
4281    },
4282    /// ```sql
4283    /// CREATE SCHEMA
4284    /// ```
4285    CreateSchema {
4286        /// `<schema name> | AUTHORIZATION <schema authorization identifier>  | <schema name>  AUTHORIZATION <schema authorization identifier>`
4287        schema_name: SchemaName,
4288        /// `true` when `IF NOT EXISTS` was present.
4289        if_not_exists: bool,
4290        /// Schema properties.
4291        ///
4292        /// ```sql
4293        /// CREATE SCHEMA myschema WITH (key1='value1');
4294        /// ```
4295        ///
4296        /// [Trino](https://trino.io/docs/current/sql/create-schema.html)
4297        with: Option<Vec<SqlOption>>,
4298        /// Schema options.
4299        ///
4300        /// ```sql
4301        /// CREATE SCHEMA myschema OPTIONS(key1='value1');
4302        /// ```
4303        ///
4304        /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_schema_statement)
4305        options: Option<Vec<SqlOption>>,
4306        /// Default collation specification for the schema.
4307        ///
4308        /// ```sql
4309        /// CREATE SCHEMA myschema DEFAULT COLLATE 'und:ci';
4310        /// ```
4311        ///
4312        /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_schema_statement)
4313        default_collate_spec: Option<Expr>,
4314        /// Clones a schema
4315        ///
4316        /// ```sql
4317        /// CREATE SCHEMA myschema CLONE otherschema
4318        /// ```
4319        ///
4320        /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-clone#databases-schemas)
4321        clone: Option<ObjectName>,
4322    },
4323    /// ```sql
4324    /// CREATE DATABASE
4325    /// ```
4326    /// See:
4327    /// <https://docs.snowflake.com/en/sql-reference/sql/create-database>
4328    CreateDatabase {
4329        /// Database name.
4330        db_name: ObjectName,
4331        /// `IF NOT EXISTS` flag.
4332        if_not_exists: bool,
4333        /// Optional location URI.
4334        location: Option<String>,
4335        /// Optional managed location.
4336        managed_location: Option<String>,
4337        /// `OR REPLACE` flag.
4338        or_replace: bool,
4339        /// `TRANSIENT` flag.
4340        transient: bool,
4341        /// Optional clone source.
4342        clone: Option<ObjectName>,
4343        /// Optional data retention time in days.
4344        data_retention_time_in_days: Option<u64>,
4345        /// Optional maximum data extension time in days.
4346        max_data_extension_time_in_days: Option<u64>,
4347        /// Optional external volume identifier.
4348        external_volume: Option<String>,
4349        /// Optional catalog name.
4350        catalog: Option<String>,
4351        /// Whether to replace invalid characters.
4352        replace_invalid_characters: Option<bool>,
4353        /// Default DDL collation string.
4354        default_ddl_collation: Option<String>,
4355        /// Storage serialization policy.
4356        storage_serialization_policy: Option<StorageSerializationPolicy>,
4357        /// Optional comment.
4358        comment: Option<String>,
4359        /// Optional default character set (MySQL).
4360        default_charset: Option<String>,
4361        /// Optional default collation (MySQL).
4362        default_collation: Option<String>,
4363        /// Optional catalog sync identifier.
4364        catalog_sync: Option<String>,
4365        /// Catalog sync namespace mode.
4366        catalog_sync_namespace_mode: Option<CatalogSyncNamespaceMode>,
4367        /// Optional flatten delimiter for namespace sync.
4368        catalog_sync_namespace_flatten_delimiter: Option<String>,
4369        /// Optional tags for the database.
4370        with_tags: Option<Vec<Tag>>,
4371        /// Optional contact entries for the database.
4372        with_contacts: Option<Vec<ContactEntry>>,
4373    },
4374    /// ```sql
4375    /// CREATE FUNCTION
4376    /// ```
4377    ///
4378    /// Supported variants:
4379    /// 1. [Hive](https://cwiki.apache.org/confluence/display/hive/languagemanual+ddl#LanguageManualDDL-Create/Drop/ReloadFunction)
4380    /// 2. [PostgreSQL](https://www.postgresql.org/docs/15/sql-createfunction.html)
4381    /// 3. [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_function_statement)
4382    /// 4. [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql)
4383    CreateFunction(CreateFunction),
4384    /// CREATE TRIGGER statement. See struct [CreateTrigger] for details.
4385    CreateTrigger(CreateTrigger),
4386    /// DROP TRIGGER statement. See struct [DropTrigger] for details.
4387    DropTrigger(DropTrigger),
4388    /// ```sql
4389    /// CREATE PROCEDURE
4390    /// ```
4391    CreateProcedure {
4392        /// `OR ALTER` flag.
4393        or_alter: bool,
4394        /// Procedure name.
4395        name: ObjectName,
4396        /// Optional procedure parameters.
4397        params: Option<Vec<ProcedureParam>>,
4398        /// Optional language identifier.
4399        language: Option<Ident>,
4400        /// Procedure body statements.
4401        body: ConditionalStatements,
4402    },
4403    /// ```sql
4404    /// CREATE MACRO
4405    /// ```
4406    ///
4407    /// Supported variants:
4408    /// 1. [DuckDB](https://duckdb.org/docs/sql/statements/create_macro)
4409    CreateMacro {
4410        /// `OR REPLACE` flag.
4411        or_replace: bool,
4412        /// Whether macro is temporary.
4413        temporary: bool,
4414        /// Macro name.
4415        name: ObjectName,
4416        /// Optional macro arguments.
4417        args: Option<Vec<MacroArg>>,
4418        /// Macro definition body.
4419        definition: MacroDefinition,
4420    },
4421    /// ```sql
4422    /// CREATE STAGE
4423    /// ```
4424    /// See <https://docs.snowflake.com/en/sql-reference/sql/create-stage>
4425    CreateStage {
4426        /// `OR REPLACE` flag for stage.
4427        or_replace: bool,
4428        /// Whether stage is temporary.
4429        temporary: bool,
4430        /// `IF NOT EXISTS` flag.
4431        if_not_exists: bool,
4432        /// Stage name.
4433        name: ObjectName,
4434        /// Stage parameters.
4435        stage_params: StageParamsObject,
4436        /// Directory table parameters.
4437        directory_table_params: KeyValueOptions,
4438        /// File format options.
4439        file_format: KeyValueOptions,
4440        /// Copy options for stage.
4441        copy_options: KeyValueOptions,
4442        /// Optional comment.
4443        comment: Option<String>,
4444    },
4445    /// ```sql
4446    /// ASSERT <condition> [AS <message>]
4447    /// ```
4448    Assert {
4449        /// Assertion condition expression.
4450        condition: Expr,
4451        /// Optional message expression.
4452        message: Option<Expr>,
4453    },
4454    /// ```sql
4455    /// GRANT privileges ON objects TO grantees
4456    /// ```
4457    Grant(Grant),
4458    /// ```sql
4459    /// DENY privileges ON object TO grantees
4460    /// ```
4461    Deny(DenyStatement),
4462    /// ```sql
4463    /// REVOKE privileges ON objects FROM grantees
4464    /// ```
4465    Revoke(Revoke),
4466    /// ```sql
4467    /// DEALLOCATE [ PREPARE ] { name | ALL }
4468    /// ```
4469    ///
4470    /// Note: this is a PostgreSQL-specific statement.
4471    Deallocate {
4472        /// Name to deallocate (or `ALL`).
4473        name: Ident,
4474        /// Whether `PREPARE` keyword was present.
4475        prepare: bool,
4476    },
4477    /// ```sql
4478    /// An `EXECUTE` statement
4479    /// ```
4480    ///
4481    /// Postgres: <https://www.postgresql.org/docs/current/sql-execute.html>
4482    /// MSSQL: <https://learn.microsoft.com/en-us/sql/relational-databases/stored-procedures/execute-a-stored-procedure>
4483    /// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#execute_immediate>
4484    /// Snowflake: <https://docs.snowflake.com/en/sql-reference/sql/execute-immediate>
4485    Execute {
4486        /// Optional function/procedure name.
4487        name: Option<ObjectName>,
4488        /// Parameter expressions passed to execute.
4489        parameters: Vec<Expr>,
4490        /// Whether parentheses were present around `parameters`.
4491        has_parentheses: bool,
4492        /// Is this an `EXECUTE IMMEDIATE`.
4493        immediate: bool,
4494        /// Identifiers to capture results into.
4495        into: Vec<Ident>,
4496        /// `USING` expressions with optional aliases.
4497        using: Vec<ExprWithAlias>,
4498        /// Whether the last parameter is the return value of the procedure
4499        /// MSSQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver17#output>
4500        output: bool,
4501        /// Whether to invoke the procedure with the default parameter values
4502        /// MSSQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/execute-transact-sql?view=sql-server-ver17#default>
4503        default: bool,
4504    },
4505    /// ```sql
4506    /// PREPARE name [ ( data_type [, ...] ) ] AS statement
4507    /// ```
4508    ///
4509    /// Note: this is a PostgreSQL-specific statement.
4510    Prepare {
4511        /// Name of the prepared statement.
4512        name: Ident,
4513        /// Optional data types for parameters.
4514        data_types: Vec<DataType>,
4515        /// Statement being prepared.
4516        statement: Box<Statement>,
4517    },
4518    /// ```sql
4519    /// KILL [CONNECTION | QUERY | MUTATION]
4520    /// ```
4521    ///
4522    /// See <https://clickhouse.com/docs/en/sql-reference/statements/kill/>
4523    /// See <https://dev.mysql.com/doc/refman/8.0/en/kill.html>
4524    Kill {
4525        /// Optional kill modifier (CONNECTION, QUERY, MUTATION).
4526        modifier: Option<KillType>,
4527        // processlist_id
4528        /// The id of the process to kill.
4529        id: u64,
4530    },
4531    /// ```sql
4532    /// [EXPLAIN | DESC | DESCRIBE] TABLE
4533    /// ```
4534    /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/explain.html>
4535    ExplainTable {
4536        /// `EXPLAIN | DESC | DESCRIBE`
4537        describe_alias: DescribeAlias,
4538        /// Hive style `FORMATTED | EXTENDED`
4539        hive_format: Option<HiveDescribeFormat>,
4540        /// Snowflake and ClickHouse support `DESC|DESCRIBE TABLE <table_name>` syntax
4541        ///
4542        /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/desc-table.html)
4543        /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/describe-table)
4544        has_table_keyword: bool,
4545        /// Table name
4546        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
4547        table_name: ObjectName,
4548    },
4549    /// ```sql
4550    /// [EXPLAIN | DESC | DESCRIBE]  <statement>
4551    /// ```
4552    Explain {
4553        /// `EXPLAIN | DESC | DESCRIBE`
4554        describe_alias: DescribeAlias,
4555        /// Carry out the command and show actual run times and other statistics.
4556        analyze: bool,
4557        /// Display additional information regarding the plan.
4558        verbose: bool,
4559        /// `EXPLAIN QUERY PLAN`
4560        /// Display the query plan without running the query.
4561        ///
4562        /// [SQLite](https://sqlite.org/lang_explain.html)
4563        query_plan: bool,
4564        /// `EXPLAIN ESTIMATE`
4565        /// [Clickhouse](https://clickhouse.com/docs/en/sql-reference/statements/explain#explain-estimate)
4566        estimate: bool,
4567        /// A SQL query that specifies what to explain
4568        statement: Box<Statement>,
4569        /// Optional output format of explain
4570        format: Option<AnalyzeFormatKind>,
4571        /// Postgres style utility options, `(analyze, verbose true)`
4572        options: Option<Vec<UtilityOption>>,
4573    },
4574    /// ```sql
4575    /// SAVEPOINT
4576    /// ```
4577    /// Define a new savepoint within the current transaction
4578    Savepoint {
4579        /// Name of the savepoint being defined.
4580        name: Ident,
4581    },
4582    /// ```sql
4583    /// RELEASE [ SAVEPOINT ] savepoint_name
4584    /// ```
4585    ReleaseSavepoint {
4586        /// Name of the savepoint to release.
4587        name: Ident,
4588    },
4589    /// A `MERGE` statement.
4590    ///
4591    /// ```sql
4592    /// MERGE INTO <target_table> USING <source> ON <join_expr> { matchedClause | notMatchedClause } [ ... ]
4593    /// ```
4594    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/merge)
4595    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
4596    /// [MSSQL](https://learn.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver16)
4597    Merge(Merge),
4598    /// ```sql
4599    /// CACHE [ FLAG ] TABLE <table_name> [ OPTIONS('K1' = 'V1', 'K2' = V2) ] [ AS ] [ <query> ]
4600    /// ```
4601    ///
4602    /// See [Spark SQL docs] for more details.
4603    ///
4604    /// [Spark SQL docs]: https://docs.databricks.com/spark/latest/spark-sql/language-manual/sql-ref-syntax-aux-cache-cache-table.html
4605    Cache {
4606        /// Table flag
4607        table_flag: Option<ObjectName>,
4608        /// Table name
4609        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
4610        table_name: ObjectName,
4611        /// `true` if `AS` keyword was present before the query.
4612        has_as: bool,
4613        /// Table confs
4614        options: Vec<SqlOption>,
4615        /// Cache table as a Query
4616        query: Option<Box<Query>>,
4617    },
4618    /// ```sql
4619    /// UNCACHE TABLE [ IF EXISTS ]  <table_name>
4620    /// ```
4621    UNCache {
4622        /// Table name
4623        #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
4624        table_name: ObjectName,
4625        /// `true` when `IF EXISTS` was present.
4626        if_exists: bool,
4627    },
4628    /// ```sql
4629    /// CREATE [ { TEMPORARY | TEMP } ] SEQUENCE [ IF NOT EXISTS ] <sequence_name>
4630    /// ```
4631    /// Define a new sequence:
4632    CreateSequence {
4633        /// Whether the sequence is temporary.
4634        temporary: bool,
4635        /// `IF NOT EXISTS` flag.
4636        if_not_exists: bool,
4637        /// Sequence name.
4638        name: ObjectName,
4639        /// Optional data type for the sequence.
4640        data_type: Option<DataType>,
4641        /// Sequence options (INCREMENT, MINVALUE, etc.).
4642        sequence_options: Vec<SequenceOptions>,
4643        /// Optional `OWNED BY` target.
4644        owned_by: Option<ObjectName>,
4645    },
4646    /// A `CREATE DOMAIN` statement.
4647    CreateDomain(CreateDomain),
4648    /// ```sql
4649    /// CREATE TYPE <name>
4650    /// ```
4651    CreateType {
4652        /// Type name to create.
4653        name: ObjectName,
4654        /// Optional type representation details.
4655        representation: Option<UserDefinedTypeRepresentation>,
4656    },
4657    /// ```sql
4658    /// PRAGMA <schema-name>.<pragma-name> = <pragma-value>
4659    /// ```
4660    Pragma {
4661        /// Pragma name (possibly qualified).
4662        name: ObjectName,
4663        /// Optional pragma value.
4664        value: Option<ValueWithSpan>,
4665        /// Whether the pragma used `=`.
4666        is_eq: bool,
4667    },
4668    /// ```sql
4669    /// LOCK [ TABLE ] [ ONLY ] name [ * ] [, ...] [ IN lockmode MODE ] [ NOWAIT ]
4670    /// ```
4671    ///
4672    /// See <https://www.postgresql.org/docs/current/sql-lock.html>
4673    Lock(Lock),
4674    /// ```sql
4675    /// LOCK TABLES <table_name> [READ [LOCAL] | [LOW_PRIORITY] WRITE]
4676    /// ```
4677    /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html>
4678    LockTables {
4679        /// List of tables to lock with modes.
4680        tables: Vec<LockTable>,
4681    },
4682    /// ```sql
4683    /// UNLOCK TABLES
4684    /// ```
4685    /// Note: this is a MySQL-specific statement. See <https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html>
4686    UnlockTables,
4687    /// Unloads the result of a query to file
4688    ///
4689    /// [Athena](https://docs.aws.amazon.com/athena/latest/ug/unload.html):
4690    /// ```sql
4691    /// UNLOAD(statement) TO <destination> [ WITH options ]
4692    /// ```
4693    ///
4694    /// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_UNLOAD.html):
4695    /// ```sql
4696    /// UNLOAD('statement') TO <destination> [ OPTIONS ]
4697    /// ```
4698    Unload {
4699        /// Optional query AST to unload.
4700        query: Option<Box<Query>>,
4701        /// Optional original query text.
4702        query_text: Option<String>,
4703        /// Destination identifier.
4704        to: Ident,
4705        /// Optional IAM role/auth information.
4706        auth: Option<IamRoleKind>,
4707        /// Additional `WITH` options.
4708        with: Vec<SqlOption>,
4709        /// Legacy copy-style options.
4710        options: Vec<CopyLegacyOption>,
4711    },
4712    /// ClickHouse:
4713    /// ```sql
4714    /// OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition | PARTITION ID 'partition_id'] [FINAL] [DEDUPLICATE [BY expression]]
4715    /// ```
4716    /// See ClickHouse <https://clickhouse.com/docs/en/sql-reference/statements/optimize>
4717    ///
4718    /// Databricks:
4719    /// ```sql
4720    /// OPTIMIZE table_name [WHERE predicate] [ZORDER BY (col_name1 [, ...])]
4721    /// ```
4722    /// See Databricks <https://docs.databricks.com/en/sql/language-manual/delta-optimize.html>
4723    OptimizeTable {
4724        /// Table name to optimize.
4725        name: ObjectName,
4726        /// Whether the `TABLE` keyword was present (ClickHouse uses `OPTIMIZE TABLE`, Databricks uses `OPTIMIZE`).
4727        has_table_keyword: bool,
4728        /// Optional cluster identifier.
4729        /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/optimize)
4730        on_cluster: Option<Ident>,
4731        /// Optional partition spec.
4732        /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/optimize)
4733        partition: Option<Partition>,
4734        /// Whether `FINAL` was specified.
4735        /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/optimize)
4736        include_final: bool,
4737        /// Optional deduplication settings.
4738        /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/statements/optimize)
4739        deduplicate: Option<Deduplicate>,
4740        /// Optional WHERE predicate.
4741        /// [Databricks](https://docs.databricks.com/en/sql/language-manual/delta-optimize.html)
4742        predicate: Option<Expr>,
4743        /// Optional ZORDER BY columns.
4744        /// [Databricks](https://docs.databricks.com/en/sql/language-manual/delta-optimize.html)
4745        zorder: Option<Vec<Expr>>,
4746    },
4747    /// ```sql
4748    /// LISTEN
4749    /// ```
4750    /// listen for a notification channel
4751    ///
4752    /// See Postgres <https://www.postgresql.org/docs/current/sql-listen.html>
4753    LISTEN {
4754        /// Notification channel identifier.
4755        channel: Ident,
4756    },
4757    /// ```sql
4758    /// UNLISTEN
4759    /// ```
4760    /// stop listening for a notification
4761    ///
4762    /// See Postgres <https://www.postgresql.org/docs/current/sql-unlisten.html>
4763    UNLISTEN {
4764        /// Notification channel identifier.
4765        channel: Ident,
4766    },
4767    /// ```sql
4768    /// NOTIFY channel [ , payload ]
4769    /// ```
4770    /// send a notification event together with an optional "payload" string to channel
4771    ///
4772    /// See Postgres <https://www.postgresql.org/docs/current/sql-notify.html>
4773    NOTIFY {
4774        /// Notification channel identifier.
4775        channel: Ident,
4776        /// Optional payload string.
4777        payload: Option<String>,
4778    },
4779    /// ```sql
4780    /// LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename
4781    /// [PARTITION (partcol1=val1, partcol2=val2 ...)]
4782    /// [INPUTFORMAT 'inputformat' SERDE 'serde']
4783    /// ```
4784    /// Loading files into tables
4785    ///
4786    /// See Hive <https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=27362036#LanguageManualDML-Loadingfilesintotables>
4787    LoadData {
4788        /// Whether `LOCAL` is present.
4789        local: bool,
4790        /// Input path for files to load.
4791        inpath: String,
4792        /// Whether `OVERWRITE` was specified.
4793        overwrite: bool,
4794        /// Target table name to load into.
4795        table_name: ObjectName,
4796        /// Optional partition specification.
4797        partitioned: Option<Vec<Expr>>,
4798        /// Optional table format information.
4799        table_format: Option<HiveLoadDataFormat>,
4800    },
4801    /// ```sql
4802    /// Rename TABLE tbl_name TO new_tbl_name[, tbl_name2 TO new_tbl_name2] ...
4803    /// ```
4804    /// Renames one or more tables
4805    ///
4806    /// See Mysql <https://dev.mysql.com/doc/refman/9.1/en/rename-table.html>
4807    RenameTable(Vec<RenameTable>),
4808    /// Snowflake `LIST`
4809    /// See: <https://docs.snowflake.com/en/sql-reference/sql/list>
4810    List(FileStagingCommand),
4811    /// Snowflake `REMOVE`
4812    /// See: <https://docs.snowflake.com/en/sql-reference/sql/remove>
4813    Remove(FileStagingCommand),
4814    /// RaiseError (MSSQL)
4815    /// RAISERROR ( { msg_id | msg_str | @local_variable }
4816    /// { , severity , state }
4817    /// [ , argument [ , ...n ] ] )
4818    /// [ WITH option [ , ...n ] ]
4819    /// See <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/raiserror-transact-sql?view=sql-server-ver16>
4820    RaisError {
4821        /// Error message expression or identifier.
4822        message: Box<Expr>,
4823        /// Severity expression.
4824        severity: Box<Expr>,
4825        /// State expression.
4826        state: Box<Expr>,
4827        /// Substitution arguments for the message.
4828        arguments: Vec<Expr>,
4829        /// Additional `WITH` options for RAISERROR.
4830        options: Vec<RaisErrorOption>,
4831    },
4832    /// A MSSQL `THROW` statement.
4833    Throw(ThrowStatement),
4834    /// ```sql
4835    /// PRINT msg_str | @local_variable | string_expr
4836    /// ```
4837    ///
4838    /// See: <https://learn.microsoft.com/en-us/sql/t-sql/statements/print-transact-sql>
4839    Print(PrintStatement),
4840    /// MSSQL `WAITFOR` statement.
4841    ///
4842    /// See: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/waitfor-transact-sql>
4843    WaitFor(WaitForStatement),
4844    /// ```sql
4845    /// RETURN [ expression ]
4846    /// ```
4847    ///
4848    /// See [ReturnStatement]
4849    Return(ReturnStatement),
4850    /// Export data statement
4851    ///
4852    /// Example:
4853    /// ```sql
4854    /// EXPORT DATA OPTIONS(uri='gs://bucket/folder/*', format='PARQUET', overwrite=true) AS
4855    /// SELECT field1, field2 FROM mydataset.table1 ORDER BY field1 LIMIT 10
4856    /// ```
4857    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/export-statements)
4858    ExportData(ExportData),
4859    /// ```sql
4860    /// CREATE [OR REPLACE] USER <user> [IF NOT EXISTS]
4861    /// ```
4862    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-user)
4863    CreateUser(CreateUser),
4864    /// ```sql
4865    /// ALTER USER \[ IF EXISTS \] \[ <name> \]
4866    /// ```
4867    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/alter-user)
4868    AlterUser(AlterUser),
4869    /// Re-sorts rows and reclaims space in either a specified table or all tables in the current database
4870    ///
4871    /// ```sql
4872    /// VACUUM tbl
4873    /// ```
4874    /// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)
4875    Vacuum(VacuumStatement),
4876    /// Restore the value of a run-time parameter to the default value.
4877    ///
4878    /// ```sql
4879    /// RESET configuration_parameter;
4880    /// RESET ALL;
4881    /// ```
4882    /// [PostgreSQL](https://www.postgresql.org/docs/current/sql-reset.html)
4883    Reset(ResetStatement),
4884}
4885
4886impl From<Analyze> for Statement {
4887    fn from(analyze: Analyze) -> Self {
4888        Statement::Analyze(analyze)
4889    }
4890}
4891
4892impl From<ddl::Truncate> for Statement {
4893    fn from(truncate: ddl::Truncate) -> Self {
4894        Statement::Truncate(truncate)
4895    }
4896}
4897
4898impl From<Lock> for Statement {
4899    fn from(lock: Lock) -> Self {
4900        Statement::Lock(lock)
4901    }
4902}
4903
4904impl From<ddl::Msck> for Statement {
4905    fn from(msck: ddl::Msck) -> Self {
4906        Statement::Msck(msck)
4907    }
4908}
4909
4910/// ```sql
4911/// {COPY | REVOKE} CURRENT GRANTS
4912/// ```
4913///
4914/// - [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/grant-ownership#optional-parameters)
4915#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4916#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4917#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4918pub enum CurrentGrantsKind {
4919    /// `COPY CURRENT GRANTS` (copy current grants to target).
4920    CopyCurrentGrants,
4921    /// `REVOKE CURRENT GRANTS` (revoke current grants from target).
4922    RevokeCurrentGrants,
4923}
4924
4925impl fmt::Display for CurrentGrantsKind {
4926    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4927        match self {
4928            CurrentGrantsKind::CopyCurrentGrants => write!(f, "COPY CURRENT GRANTS"),
4929            CurrentGrantsKind::RevokeCurrentGrants => write!(f, "REVOKE CURRENT GRANTS"),
4930        }
4931    }
4932}
4933
4934#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
4935#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
4936#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
4937/// `RAISERROR` options
4938/// See <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/raiserror-transact-sql?view=sql-server-ver16#options>
4939pub enum RaisErrorOption {
4940    /// Log the error.
4941    Log,
4942    /// Do not wait for completion.
4943    NoWait,
4944    /// Set the error state.
4945    SetError,
4946}
4947
4948impl fmt::Display for RaisErrorOption {
4949    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4950        match self {
4951            RaisErrorOption::Log => write!(f, "LOG"),
4952            RaisErrorOption::NoWait => write!(f, "NOWAIT"),
4953            RaisErrorOption::SetError => write!(f, "SETERROR"),
4954        }
4955    }
4956}
4957
4958impl fmt::Display for Statement {
4959    /// Formats a SQL statement with support for pretty printing.
4960    ///
4961    /// When using the alternate flag (`{:#}`), the statement will be formatted with proper
4962    /// indentation and line breaks. For example:
4963    ///
4964    /// ```
4965    /// # use sqlparser::dialect::GenericDialect;
4966    /// # use sqlparser::parser::Parser;
4967    /// let sql = "SELECT a, b FROM table_1";
4968    /// let ast = Parser::parse_sql(&GenericDialect, sql).unwrap();
4969    ///
4970    /// // Regular formatting
4971    /// assert_eq!(format!("{}", ast[0]), "SELECT a, b FROM table_1");
4972    ///
4973    /// // Pretty printing
4974    /// assert_eq!(format!("{:#}", ast[0]),
4975    /// r#"SELECT
4976    ///   a,
4977    ///   b
4978    /// FROM
4979    ///   table_1"#);
4980    /// ```
4981    // Clippy thinks this function is too complicated, but it is painful to
4982    // split up without extracting structs for each `Statement` variant.
4983    #[allow(clippy::cognitive_complexity)]
4984    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
4985        match self {
4986            Statement::Flush {
4987                object_type,
4988                location,
4989                channel,
4990                read_lock,
4991                export,
4992                tables,
4993            } => {
4994                write!(f, "FLUSH")?;
4995                if let Some(location) = location {
4996                    f.write_str(" ")?;
4997                    location.fmt(f)?;
4998                }
4999                write!(f, " {object_type}")?;
5000
5001                if let Some(channel) = channel {
5002                    write!(f, " FOR CHANNEL {channel}")?;
5003                }
5004
5005                write!(
5006                    f,
5007                    "{tables}{read}{export}",
5008                    tables = if !tables.is_empty() {
5009                        format!(" {}", display_comma_separated(tables))
5010                    } else {
5011                        String::new()
5012                    },
5013                    export = if *export { " FOR EXPORT" } else { "" },
5014                    read = if *read_lock { " WITH READ LOCK" } else { "" }
5015                )
5016            }
5017            Statement::Kill { modifier, id } => {
5018                write!(f, "KILL ")?;
5019
5020                if let Some(m) = modifier {
5021                    write!(f, "{m} ")?;
5022                }
5023
5024                write!(f, "{id}")
5025            }
5026            Statement::ExplainTable {
5027                describe_alias,
5028                hive_format,
5029                has_table_keyword,
5030                table_name,
5031            } => {
5032                write!(f, "{describe_alias} ")?;
5033
5034                if let Some(format) = hive_format {
5035                    write!(f, "{format} ")?;
5036                }
5037                if *has_table_keyword {
5038                    write!(f, "TABLE ")?;
5039                }
5040
5041                write!(f, "{table_name}")
5042            }
5043            Statement::Explain {
5044                describe_alias,
5045                verbose,
5046                analyze,
5047                query_plan,
5048                estimate,
5049                statement,
5050                format,
5051                options,
5052            } => {
5053                write!(f, "{describe_alias} ")?;
5054
5055                if *query_plan {
5056                    write!(f, "QUERY PLAN ")?;
5057                }
5058                if *analyze {
5059                    write!(f, "ANALYZE ")?;
5060                }
5061                if *estimate {
5062                    write!(f, "ESTIMATE ")?;
5063                }
5064
5065                if *verbose {
5066                    write!(f, "VERBOSE ")?;
5067                }
5068
5069                if let Some(format) = format {
5070                    write!(f, "{format} ")?;
5071                }
5072
5073                if let Some(options) = options {
5074                    write!(f, "({}) ", display_comma_separated(options))?;
5075                }
5076
5077                write!(f, "{statement}")
5078            }
5079            Statement::Query(s) => s.fmt(f),
5080            Statement::Declare { stmts } => {
5081                write!(f, "DECLARE ")?;
5082                write!(f, "{}", display_separated(stmts, "; "))
5083            }
5084            Statement::Fetch {
5085                name,
5086                direction,
5087                position,
5088                into,
5089            } => {
5090                write!(f, "FETCH {direction} {position} {name}")?;
5091
5092                if let Some(into) = into {
5093                    write!(f, " INTO {into}")?;
5094                }
5095
5096                Ok(())
5097            }
5098            Statement::Directory {
5099                overwrite,
5100                local,
5101                path,
5102                file_format,
5103                source,
5104            } => {
5105                write!(
5106                    f,
5107                    "INSERT{overwrite}{local} DIRECTORY '{path}'",
5108                    overwrite = if *overwrite { " OVERWRITE" } else { "" },
5109                    local = if *local { " LOCAL" } else { "" },
5110                    path = path
5111                )?;
5112                if let Some(ref ff) = file_format {
5113                    write!(f, " STORED AS {ff}")?
5114                }
5115                write!(f, " {source}")
5116            }
5117            Statement::Msck(msck) => msck.fmt(f),
5118            Statement::Truncate(truncate) => truncate.fmt(f),
5119            Statement::Case(stmt) => {
5120                write!(f, "{stmt}")
5121            }
5122            Statement::If(stmt) => {
5123                write!(f, "{stmt}")
5124            }
5125            Statement::While(stmt) => {
5126                write!(f, "{stmt}")
5127            }
5128            Statement::Raise(stmt) => {
5129                write!(f, "{stmt}")
5130            }
5131            Statement::AttachDatabase {
5132                schema_name,
5133                database_file_name,
5134                database,
5135            } => {
5136                let keyword = if *database { "DATABASE " } else { "" };
5137                write!(f, "ATTACH {keyword}{database_file_name} AS {schema_name}")
5138            }
5139            Statement::AttachDuckDBDatabase {
5140                if_not_exists,
5141                database,
5142                database_path,
5143                database_alias,
5144                attach_options,
5145            } => {
5146                write!(
5147                    f,
5148                    "ATTACH{database}{if_not_exists} {database_path}",
5149                    database = if *database { " DATABASE" } else { "" },
5150                    if_not_exists = if *if_not_exists { " IF NOT EXISTS" } else { "" },
5151                )?;
5152                if let Some(alias) = database_alias {
5153                    write!(f, " AS {alias}")?;
5154                }
5155                if !attach_options.is_empty() {
5156                    write!(f, " ({})", display_comma_separated(attach_options))?;
5157                }
5158                Ok(())
5159            }
5160            Statement::DetachDuckDBDatabase {
5161                if_exists,
5162                database,
5163                database_alias,
5164            } => {
5165                write!(
5166                    f,
5167                    "DETACH{database}{if_exists} {database_alias}",
5168                    database = if *database { " DATABASE" } else { "" },
5169                    if_exists = if *if_exists { " IF EXISTS" } else { "" },
5170                )?;
5171                Ok(())
5172            }
5173            Statement::Analyze(analyze) => analyze.fmt(f),
5174            Statement::Insert(insert) => insert.fmt(f),
5175            Statement::Install {
5176                extension_name: name,
5177            } => write!(f, "INSTALL {name}"),
5178
5179            Statement::Load {
5180                extension_name: name,
5181            } => write!(f, "LOAD {name}"),
5182
5183            Statement::Call(function) => write!(f, "CALL {function}"),
5184
5185            Statement::Copy {
5186                source,
5187                to,
5188                target,
5189                options,
5190                legacy_options,
5191                values,
5192            } => {
5193                write!(f, "COPY")?;
5194                match source {
5195                    CopySource::Query(query) => write!(f, " ({query})")?,
5196                    CopySource::Table {
5197                        table_name,
5198                        columns,
5199                    } => {
5200                        write!(f, " {table_name}")?;
5201                        if !columns.is_empty() {
5202                            write!(f, " ({})", display_comma_separated(columns))?;
5203                        }
5204                    }
5205                }
5206                write!(f, " {} {}", if *to { "TO" } else { "FROM" }, target)?;
5207                if !options.is_empty() {
5208                    write!(f, " ({})", display_comma_separated(options))?;
5209                }
5210                if !legacy_options.is_empty() {
5211                    write!(f, " {}", display_separated(legacy_options, " "))?;
5212                }
5213                if !values.is_empty() {
5214                    writeln!(f, ";")?;
5215                    let mut delim = "";
5216                    for v in values {
5217                        write!(f, "{delim}")?;
5218                        delim = "\t";
5219                        if let Some(v) = v {
5220                            write!(f, "{v}")?;
5221                        } else {
5222                            write!(f, "\\N")?;
5223                        }
5224                    }
5225                    write!(f, "\n\\.")?;
5226                }
5227                Ok(())
5228            }
5229            Statement::Update(update) => update.fmt(f),
5230            Statement::Delete(delete) => delete.fmt(f),
5231            Statement::Open(open) => open.fmt(f),
5232            Statement::Close { cursor } => {
5233                write!(f, "CLOSE {cursor}")?;
5234
5235                Ok(())
5236            }
5237            Statement::CreateDatabase {
5238                db_name,
5239                if_not_exists,
5240                location,
5241                managed_location,
5242                or_replace,
5243                transient,
5244                clone,
5245                data_retention_time_in_days,
5246                max_data_extension_time_in_days,
5247                external_volume,
5248                catalog,
5249                replace_invalid_characters,
5250                default_ddl_collation,
5251                storage_serialization_policy,
5252                comment,
5253                default_charset,
5254                default_collation,
5255                catalog_sync,
5256                catalog_sync_namespace_mode,
5257                catalog_sync_namespace_flatten_delimiter,
5258                with_tags,
5259                with_contacts,
5260            } => {
5261                write!(
5262                    f,
5263                    "CREATE {or_replace}{transient}DATABASE {if_not_exists}{name}",
5264                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
5265                    transient = if *transient { "TRANSIENT " } else { "" },
5266                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5267                    name = db_name,
5268                )?;
5269
5270                if let Some(l) = location {
5271                    write!(f, " LOCATION '{l}'")?;
5272                }
5273                if let Some(ml) = managed_location {
5274                    write!(f, " MANAGEDLOCATION '{ml}'")?;
5275                }
5276                if let Some(clone) = clone {
5277                    write!(f, " CLONE {clone}")?;
5278                }
5279
5280                if let Some(value) = data_retention_time_in_days {
5281                    write!(f, " DATA_RETENTION_TIME_IN_DAYS = {value}")?;
5282                }
5283
5284                if let Some(value) = max_data_extension_time_in_days {
5285                    write!(f, " MAX_DATA_EXTENSION_TIME_IN_DAYS = {value}")?;
5286                }
5287
5288                if let Some(vol) = external_volume {
5289                    write!(f, " EXTERNAL_VOLUME = '{vol}'")?;
5290                }
5291
5292                if let Some(cat) = catalog {
5293                    write!(f, " CATALOG = '{cat}'")?;
5294                }
5295
5296                if let Some(true) = replace_invalid_characters {
5297                    write!(f, " REPLACE_INVALID_CHARACTERS = TRUE")?;
5298                } else if let Some(false) = replace_invalid_characters {
5299                    write!(f, " REPLACE_INVALID_CHARACTERS = FALSE")?;
5300                }
5301
5302                if let Some(collation) = default_ddl_collation {
5303                    write!(f, " DEFAULT_DDL_COLLATION = '{collation}'")?;
5304                }
5305
5306                if let Some(policy) = storage_serialization_policy {
5307                    write!(f, " STORAGE_SERIALIZATION_POLICY = {policy}")?;
5308                }
5309
5310                if let Some(comment) = comment {
5311                    write!(f, " COMMENT = '{comment}'")?;
5312                }
5313
5314                if let Some(charset) = default_charset {
5315                    write!(f, " DEFAULT CHARACTER SET {charset}")?;
5316                }
5317
5318                if let Some(collation) = default_collation {
5319                    write!(f, " DEFAULT COLLATE {collation}")?;
5320                }
5321
5322                if let Some(sync) = catalog_sync {
5323                    write!(f, " CATALOG_SYNC = '{sync}'")?;
5324                }
5325
5326                if let Some(mode) = catalog_sync_namespace_mode {
5327                    write!(f, " CATALOG_SYNC_NAMESPACE_MODE = {mode}")?;
5328                }
5329
5330                if let Some(delim) = catalog_sync_namespace_flatten_delimiter {
5331                    write!(f, " CATALOG_SYNC_NAMESPACE_FLATTEN_DELIMITER = '{delim}'")?;
5332                }
5333
5334                if let Some(tags) = with_tags {
5335                    write!(f, " WITH TAG ({})", display_comma_separated(tags))?;
5336                }
5337
5338                if let Some(contacts) = with_contacts {
5339                    write!(f, " WITH CONTACT ({})", display_comma_separated(contacts))?;
5340                }
5341                Ok(())
5342            }
5343            Statement::CreateFunction(create_function) => create_function.fmt(f),
5344            Statement::CreateDomain(create_domain) => create_domain.fmt(f),
5345            Statement::CreateTrigger(create_trigger) => create_trigger.fmt(f),
5346            Statement::DropTrigger(drop_trigger) => drop_trigger.fmt(f),
5347            Statement::CreateProcedure {
5348                name,
5349                or_alter,
5350                params,
5351                language,
5352                body,
5353            } => {
5354                write!(
5355                    f,
5356                    "CREATE {or_alter}PROCEDURE {name}",
5357                    or_alter = if *or_alter { "OR ALTER " } else { "" },
5358                    name = name
5359                )?;
5360
5361                if let Some(p) = params {
5362                    if !p.is_empty() {
5363                        write!(f, " ({})", display_comma_separated(p))?;
5364                    }
5365                }
5366
5367                if let Some(language) = language {
5368                    write!(f, " LANGUAGE {language}")?;
5369                }
5370
5371                write!(f, " AS {body}")
5372            }
5373            Statement::CreateMacro {
5374                or_replace,
5375                temporary,
5376                name,
5377                args,
5378                definition,
5379            } => {
5380                write!(
5381                    f,
5382                    "CREATE {or_replace}{temp}MACRO {name}",
5383                    temp = if *temporary { "TEMPORARY " } else { "" },
5384                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
5385                )?;
5386                if let Some(args) = args {
5387                    write!(f, "({})", display_comma_separated(args))?;
5388                }
5389                match definition {
5390                    MacroDefinition::Expr(expr) => write!(f, " AS {expr}")?,
5391                    MacroDefinition::Table(query) => write!(f, " AS TABLE {query}")?,
5392                }
5393                Ok(())
5394            }
5395            Statement::CreateView(create_view) => create_view.fmt(f),
5396            Statement::CreateTable(create_table) => create_table.fmt(f),
5397            Statement::LoadData {
5398                local,
5399                inpath,
5400                overwrite,
5401                table_name,
5402                partitioned,
5403                table_format,
5404            } => {
5405                write!(
5406                    f,
5407                    "LOAD DATA {local}INPATH '{inpath}' {overwrite}INTO TABLE {table_name}",
5408                    local = if *local { "LOCAL " } else { "" },
5409                    inpath = inpath,
5410                    overwrite = if *overwrite { "OVERWRITE " } else { "" },
5411                    table_name = table_name,
5412                )?;
5413                if let Some(ref parts) = &partitioned {
5414                    if !parts.is_empty() {
5415                        write!(f, " PARTITION ({})", display_comma_separated(parts))?;
5416                    }
5417                }
5418                if let Some(HiveLoadDataFormat {
5419                    serde,
5420                    input_format,
5421                }) = &table_format
5422                {
5423                    write!(f, " INPUTFORMAT {input_format} SERDE {serde}")?;
5424                }
5425                Ok(())
5426            }
5427            Statement::CreateVirtualTable {
5428                name,
5429                if_not_exists,
5430                module_name,
5431                module_args,
5432            } => {
5433                write!(
5434                    f,
5435                    "CREATE VIRTUAL TABLE {if_not_exists}{name} USING {module_name}",
5436                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5437                    name = name,
5438                    module_name = module_name
5439                )?;
5440                if !module_args.is_empty() {
5441                    write!(f, " ({})", display_comma_separated(module_args))?;
5442                }
5443                Ok(())
5444            }
5445            Statement::CreateIndex(create_index) => create_index.fmt(f),
5446            Statement::CreateExtension(create_extension) => write!(f, "{create_extension}"),
5447            Statement::CreateCollation(create_collation) => write!(f, "{create_collation}"),
5448            Statement::DropExtension(drop_extension) => write!(f, "{drop_extension}"),
5449            Statement::DropOperator(drop_operator) => write!(f, "{drop_operator}"),
5450            Statement::DropOperatorFamily(drop_operator_family) => {
5451                write!(f, "{drop_operator_family}")
5452            }
5453            Statement::DropOperatorClass(drop_operator_class) => {
5454                write!(f, "{drop_operator_class}")
5455            }
5456            Statement::CreateRole(create_role) => write!(f, "{create_role}"),
5457            Statement::CreateSecret {
5458                or_replace,
5459                temporary,
5460                if_not_exists,
5461                name,
5462                storage_specifier,
5463                secret_type,
5464                options,
5465            } => {
5466                write!(
5467                    f,
5468                    "CREATE {or_replace}",
5469                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
5470                )?;
5471                if let Some(t) = temporary {
5472                    write!(f, "{}", if *t { "TEMPORARY " } else { "PERSISTENT " })?;
5473                }
5474                write!(
5475                    f,
5476                    "SECRET {if_not_exists}",
5477                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5478                )?;
5479                if let Some(n) = name {
5480                    write!(f, "{n} ")?;
5481                };
5482                if let Some(s) = storage_specifier {
5483                    write!(f, "IN {s} ")?;
5484                }
5485                write!(f, "( TYPE {secret_type}",)?;
5486                if !options.is_empty() {
5487                    write!(f, ", {o}", o = display_comma_separated(options))?;
5488                }
5489                write!(f, " )")?;
5490                Ok(())
5491            }
5492            Statement::CreateServer(stmt) => {
5493                write!(f, "{stmt}")
5494            }
5495            Statement::CreatePolicy(policy) => write!(f, "{policy}"),
5496            Statement::CreateConnector(create_connector) => create_connector.fmt(f),
5497            Statement::CreateOperator(create_operator) => create_operator.fmt(f),
5498            Statement::CreateOperatorFamily(create_operator_family) => {
5499                create_operator_family.fmt(f)
5500            }
5501            Statement::CreateOperatorClass(create_operator_class) => create_operator_class.fmt(f),
5502            Statement::AlterTable(alter_table) => write!(f, "{alter_table}"),
5503            Statement::AlterIndex { name, operation } => {
5504                write!(f, "ALTER INDEX {name} {operation}")
5505            }
5506            Statement::AlterView {
5507                name,
5508                columns,
5509                query,
5510                with_options,
5511            } => {
5512                write!(f, "ALTER VIEW {name}")?;
5513                if !with_options.is_empty() {
5514                    write!(f, " WITH ({})", display_comma_separated(with_options))?;
5515                }
5516                if !columns.is_empty() {
5517                    write!(f, " ({})", display_comma_separated(columns))?;
5518                }
5519                write!(f, " AS {query}")
5520            }
5521            Statement::AlterFunction(alter_function) => write!(f, "{alter_function}"),
5522            Statement::AlterType(AlterType { name, operation }) => {
5523                write!(f, "ALTER TYPE {name} {operation}")
5524            }
5525            Statement::AlterCollation(alter_collation) => write!(f, "{alter_collation}"),
5526            Statement::AlterOperator(alter_operator) => write!(f, "{alter_operator}"),
5527            Statement::AlterOperatorFamily(alter_operator_family) => {
5528                write!(f, "{alter_operator_family}")
5529            }
5530            Statement::AlterOperatorClass(alter_operator_class) => {
5531                write!(f, "{alter_operator_class}")
5532            }
5533            Statement::AlterRole { name, operation } => {
5534                write!(f, "ALTER ROLE {name} {operation}")
5535            }
5536            Statement::AlterPolicy(alter_policy) => write!(f, "{alter_policy}"),
5537            Statement::AlterConnector {
5538                name,
5539                properties,
5540                url,
5541                owner,
5542            } => {
5543                write!(f, "ALTER CONNECTOR {name}")?;
5544                if let Some(properties) = properties {
5545                    write!(
5546                        f,
5547                        " SET DCPROPERTIES({})",
5548                        display_comma_separated(properties)
5549                    )?;
5550                }
5551                if let Some(url) = url {
5552                    write!(f, " SET URL '{url}'")?;
5553                }
5554                if let Some(owner) = owner {
5555                    write!(f, " SET OWNER {owner}")?;
5556                }
5557                Ok(())
5558            }
5559            Statement::AlterSession {
5560                set,
5561                session_params,
5562            } => {
5563                write!(
5564                    f,
5565                    "ALTER SESSION {set}",
5566                    set = if *set { "SET" } else { "UNSET" }
5567                )?;
5568                if !session_params.options.is_empty() {
5569                    if *set {
5570                        write!(f, " {session_params}")?;
5571                    } else {
5572                        let options = session_params
5573                            .options
5574                            .iter()
5575                            .map(|p| p.option_name.clone())
5576                            .collect::<Vec<_>>();
5577                        write!(f, " {}", display_separated(&options, ", "))?;
5578                    }
5579                }
5580                Ok(())
5581            }
5582            Statement::Drop {
5583                object_type,
5584                if_exists,
5585                names,
5586                cascade,
5587                restrict,
5588                purge,
5589                temporary,
5590                table,
5591            } => {
5592                write!(
5593                    f,
5594                    "DROP {}{}{} {}{}{}{}",
5595                    if *temporary { "TEMPORARY " } else { "" },
5596                    object_type,
5597                    if *if_exists { " IF EXISTS" } else { "" },
5598                    display_comma_separated(names),
5599                    if *cascade { " CASCADE" } else { "" },
5600                    if *restrict { " RESTRICT" } else { "" },
5601                    if *purge { " PURGE" } else { "" },
5602                )?;
5603                if let Some(table_name) = table.as_ref() {
5604                    write!(f, " ON {table_name}")?;
5605                };
5606                Ok(())
5607            }
5608            Statement::DropFunction(drop_function) => write!(f, "{drop_function}"),
5609            Statement::DropDomain(DropDomain {
5610                if_exists,
5611                name,
5612                drop_behavior,
5613            }) => {
5614                write!(
5615                    f,
5616                    "DROP DOMAIN{} {name}",
5617                    if *if_exists { " IF EXISTS" } else { "" },
5618                )?;
5619                if let Some(op) = drop_behavior {
5620                    write!(f, " {op}")?;
5621                }
5622                Ok(())
5623            }
5624            Statement::DropProcedure {
5625                if_exists,
5626                proc_desc,
5627                drop_behavior,
5628            } => {
5629                write!(
5630                    f,
5631                    "DROP PROCEDURE{} {}",
5632                    if *if_exists { " IF EXISTS" } else { "" },
5633                    display_comma_separated(proc_desc),
5634                )?;
5635                if let Some(op) = drop_behavior {
5636                    write!(f, " {op}")?;
5637                }
5638                Ok(())
5639            }
5640            Statement::DropSecret {
5641                if_exists,
5642                temporary,
5643                name,
5644                storage_specifier,
5645            } => {
5646                write!(f, "DROP ")?;
5647                if let Some(t) = temporary {
5648                    write!(f, "{}", if *t { "TEMPORARY " } else { "PERSISTENT " })?;
5649                }
5650                write!(
5651                    f,
5652                    "SECRET {if_exists}{name}",
5653                    if_exists = if *if_exists { "IF EXISTS " } else { "" },
5654                )?;
5655                if let Some(s) = storage_specifier {
5656                    write!(f, " FROM {s}")?;
5657                }
5658                Ok(())
5659            }
5660            Statement::DropPolicy(policy) => write!(f, "{policy}"),
5661            Statement::DropConnector { if_exists, name } => {
5662                write!(
5663                    f,
5664                    "DROP CONNECTOR {if_exists}{name}",
5665                    if_exists = if *if_exists { "IF EXISTS " } else { "" }
5666                )?;
5667                Ok(())
5668            }
5669            Statement::Discard { object_type } => {
5670                write!(f, "DISCARD {object_type}")?;
5671                Ok(())
5672            }
5673            Self::Set(set) => write!(f, "{set}"),
5674            Statement::ShowVariable { variable } => {
5675                write!(f, "SHOW")?;
5676                if !variable.is_empty() {
5677                    write!(f, " {}", display_separated(variable, " "))?;
5678                }
5679                Ok(())
5680            }
5681            Statement::ShowStatus {
5682                filter,
5683                global,
5684                session,
5685            } => {
5686                write!(f, "SHOW")?;
5687                if *global {
5688                    write!(f, " GLOBAL")?;
5689                }
5690                if *session {
5691                    write!(f, " SESSION")?;
5692                }
5693                write!(f, " STATUS")?;
5694                if filter.is_some() {
5695                    write!(f, " {}", filter.as_ref().unwrap())?;
5696                }
5697                Ok(())
5698            }
5699            Statement::ShowVariables {
5700                filter,
5701                global,
5702                session,
5703            } => {
5704                write!(f, "SHOW")?;
5705                if *global {
5706                    write!(f, " GLOBAL")?;
5707                }
5708                if *session {
5709                    write!(f, " SESSION")?;
5710                }
5711                write!(f, " VARIABLES")?;
5712                if filter.is_some() {
5713                    write!(f, " {}", filter.as_ref().unwrap())?;
5714                }
5715                Ok(())
5716            }
5717            Statement::ShowCreate { obj_type, obj_name } => {
5718                write!(f, "SHOW CREATE {obj_type} {obj_name}",)?;
5719                Ok(())
5720            }
5721            Statement::ShowColumns {
5722                extended,
5723                full,
5724                show_options,
5725            } => {
5726                write!(
5727                    f,
5728                    "SHOW {extended}{full}COLUMNS{show_options}",
5729                    extended = if *extended { "EXTENDED " } else { "" },
5730                    full = if *full { "FULL " } else { "" },
5731                )?;
5732                Ok(())
5733            }
5734            Statement::ShowDatabases {
5735                terse,
5736                history,
5737                show_options,
5738            } => {
5739                write!(
5740                    f,
5741                    "SHOW {terse}DATABASES{history}{show_options}",
5742                    terse = if *terse { "TERSE " } else { "" },
5743                    history = if *history { " HISTORY" } else { "" },
5744                )?;
5745                Ok(())
5746            }
5747            Statement::ShowProcessList { full } => {
5748                write!(
5749                    f,
5750                    "SHOW {full}PROCESSLIST",
5751                    full = if *full { "FULL " } else { "" },
5752                )?;
5753                Ok(())
5754            }
5755            Statement::ShowSchemas {
5756                terse,
5757                history,
5758                show_options,
5759            } => {
5760                write!(
5761                    f,
5762                    "SHOW {terse}SCHEMAS{history}{show_options}",
5763                    terse = if *terse { "TERSE " } else { "" },
5764                    history = if *history { " HISTORY" } else { "" },
5765                )?;
5766                Ok(())
5767            }
5768            Statement::ShowObjects(ShowObjects {
5769                terse,
5770                show_options,
5771            }) => {
5772                write!(
5773                    f,
5774                    "SHOW {terse}OBJECTS{show_options}",
5775                    terse = if *terse { "TERSE " } else { "" },
5776                )?;
5777                Ok(())
5778            }
5779            Statement::ShowTables {
5780                terse,
5781                history,
5782                extended,
5783                full,
5784                external,
5785                show_options,
5786            } => {
5787                write!(
5788                    f,
5789                    "SHOW {terse}{extended}{full}{external}TABLES{history}{show_options}",
5790                    terse = if *terse { "TERSE " } else { "" },
5791                    extended = if *extended { "EXTENDED " } else { "" },
5792                    full = if *full { "FULL " } else { "" },
5793                    external = if *external { "EXTERNAL " } else { "" },
5794                    history = if *history { " HISTORY" } else { "" },
5795                )?;
5796                Ok(())
5797            }
5798            Statement::ShowViews {
5799                terse,
5800                materialized,
5801                show_options,
5802            } => {
5803                write!(
5804                    f,
5805                    "SHOW {terse}{materialized}VIEWS{show_options}",
5806                    terse = if *terse { "TERSE " } else { "" },
5807                    materialized = if *materialized { "MATERIALIZED " } else { "" }
5808                )?;
5809                Ok(())
5810            }
5811            Statement::ShowFunctions { filter } => {
5812                write!(f, "SHOW FUNCTIONS")?;
5813                if let Some(filter) = filter {
5814                    write!(f, " {filter}")?;
5815                }
5816                Ok(())
5817            }
5818            Statement::Use(use_expr) => use_expr.fmt(f),
5819            Statement::ShowCollation { filter } => {
5820                write!(f, "SHOW COLLATION")?;
5821                if let Some(filter) = filter {
5822                    write!(f, " {filter}")?;
5823                }
5824                Ok(())
5825            }
5826            Statement::ShowCharset(show_stm) => show_stm.fmt(f),
5827            Statement::StartTransaction {
5828                modes,
5829                begin: syntax_begin,
5830                transaction,
5831                modifier,
5832                statements,
5833                exception,
5834                has_end_keyword,
5835            } => {
5836                if *syntax_begin {
5837                    if let Some(modifier) = *modifier {
5838                        write!(f, "BEGIN {modifier}")?;
5839                    } else {
5840                        write!(f, "BEGIN")?;
5841                    }
5842                } else {
5843                    write!(f, "START")?;
5844                }
5845                if let Some(transaction) = transaction {
5846                    write!(f, " {transaction}")?;
5847                }
5848                if !modes.is_empty() {
5849                    write!(f, " {}", display_comma_separated(modes))?;
5850                }
5851                if !statements.is_empty() {
5852                    write!(f, " ")?;
5853                    format_statement_list(f, statements)?;
5854                }
5855                if let Some(exception_when) = exception {
5856                    write!(f, " EXCEPTION")?;
5857                    for when in exception_when {
5858                        write!(f, " {when}")?;
5859                    }
5860                }
5861                if *has_end_keyword {
5862                    write!(f, " END")?;
5863                }
5864                Ok(())
5865            }
5866            Statement::Commit {
5867                chain,
5868                end: end_syntax,
5869                modifier,
5870            } => {
5871                if *end_syntax {
5872                    write!(f, "END")?;
5873                    if let Some(modifier) = *modifier {
5874                        write!(f, " {modifier}")?;
5875                    }
5876                    if *chain {
5877                        write!(f, " AND CHAIN")?;
5878                    }
5879                } else {
5880                    write!(f, "COMMIT{}", if *chain { " AND CHAIN" } else { "" })?;
5881                }
5882                Ok(())
5883            }
5884            Statement::Rollback { chain, savepoint } => {
5885                write!(f, "ROLLBACK")?;
5886
5887                if *chain {
5888                    write!(f, " AND CHAIN")?;
5889                }
5890
5891                if let Some(savepoint) = savepoint {
5892                    write!(f, " TO SAVEPOINT {savepoint}")?;
5893                }
5894
5895                Ok(())
5896            }
5897            Statement::CreateSchema {
5898                schema_name,
5899                if_not_exists,
5900                with,
5901                options,
5902                default_collate_spec,
5903                clone,
5904            } => {
5905                write!(
5906                    f,
5907                    "CREATE SCHEMA {if_not_exists}{name}",
5908                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
5909                    name = schema_name
5910                )?;
5911
5912                if let Some(collate) = default_collate_spec {
5913                    write!(f, " DEFAULT COLLATE {collate}")?;
5914                }
5915
5916                if let Some(with) = with {
5917                    write!(f, " WITH ({})", display_comma_separated(with))?;
5918                }
5919
5920                if let Some(options) = options {
5921                    write!(f, " OPTIONS({})", display_comma_separated(options))?;
5922                }
5923
5924                if let Some(clone) = clone {
5925                    write!(f, " CLONE {clone}")?;
5926                }
5927                Ok(())
5928            }
5929            Statement::Assert { condition, message } => {
5930                write!(f, "ASSERT {condition}")?;
5931                if let Some(m) = message {
5932                    write!(f, " AS {m}")?;
5933                }
5934                Ok(())
5935            }
5936            Statement::Grant(grant) => write!(f, "{grant}"),
5937            Statement::Deny(s) => write!(f, "{s}"),
5938            Statement::Revoke(revoke) => write!(f, "{revoke}"),
5939            Statement::Deallocate { name, prepare } => write!(
5940                f,
5941                "DEALLOCATE {prepare}{name}",
5942                prepare = if *prepare { "PREPARE " } else { "" },
5943                name = name,
5944            ),
5945            Statement::Execute {
5946                name,
5947                parameters,
5948                has_parentheses,
5949                immediate,
5950                into,
5951                using,
5952                output,
5953                default,
5954            } => {
5955                let (open, close) = if *has_parentheses {
5956                    // Space before `(` only when there is no name directly preceding it.
5957                    (if name.is_some() { "(" } else { " (" }, ")")
5958                } else {
5959                    (if parameters.is_empty() { "" } else { " " }, "")
5960                };
5961                write!(f, "EXECUTE")?;
5962                if *immediate {
5963                    write!(f, " IMMEDIATE")?;
5964                }
5965                if let Some(name) = name {
5966                    write!(f, " {name}")?;
5967                }
5968                write!(f, "{open}{}{close}", display_comma_separated(parameters),)?;
5969                if !into.is_empty() {
5970                    write!(f, " INTO {}", display_comma_separated(into))?;
5971                }
5972                if !using.is_empty() {
5973                    write!(f, " USING {}", display_comma_separated(using))?;
5974                };
5975                if *output {
5976                    write!(f, " OUTPUT")?;
5977                }
5978                if *default {
5979                    write!(f, " DEFAULT")?;
5980                }
5981                Ok(())
5982            }
5983            Statement::Prepare {
5984                name,
5985                data_types,
5986                statement,
5987            } => {
5988                write!(f, "PREPARE {name} ")?;
5989                if !data_types.is_empty() {
5990                    write!(f, "({}) ", display_comma_separated(data_types))?;
5991                }
5992                write!(f, "AS {statement}")
5993            }
5994            Statement::Comment {
5995                object_type,
5996                object_name,
5997                comment,
5998                if_exists,
5999            } => {
6000                write!(f, "COMMENT ")?;
6001                if *if_exists {
6002                    write!(f, "IF EXISTS ")?
6003                };
6004                write!(f, "ON {object_type} {object_name} IS ")?;
6005                if let Some(c) = comment {
6006                    write!(f, "'{c}'")
6007                } else {
6008                    write!(f, "NULL")
6009                }
6010            }
6011            Statement::Savepoint { name } => {
6012                write!(f, "SAVEPOINT ")?;
6013                write!(f, "{name}")
6014            }
6015            Statement::ReleaseSavepoint { name } => {
6016                write!(f, "RELEASE SAVEPOINT {name}")
6017            }
6018            Statement::Merge(merge) => merge.fmt(f),
6019            Statement::Cache {
6020                table_name,
6021                table_flag,
6022                has_as,
6023                options,
6024                query,
6025            } => {
6026                if let Some(table_flag) = table_flag {
6027                    write!(f, "CACHE {table_flag} TABLE {table_name}")?;
6028                } else {
6029                    write!(f, "CACHE TABLE {table_name}")?;
6030                }
6031
6032                if !options.is_empty() {
6033                    write!(f, " OPTIONS({})", display_comma_separated(options))?;
6034                }
6035
6036                match (*has_as, query) {
6037                    (true, Some(query)) => write!(f, " AS {query}"),
6038                    (true, None) => f.write_str(" AS"),
6039                    (false, Some(query)) => write!(f, " {query}"),
6040                    (false, None) => Ok(()),
6041                }
6042            }
6043            Statement::UNCache {
6044                table_name,
6045                if_exists,
6046            } => {
6047                if *if_exists {
6048                    write!(f, "UNCACHE TABLE IF EXISTS {table_name}")
6049                } else {
6050                    write!(f, "UNCACHE TABLE {table_name}")
6051                }
6052            }
6053            Statement::CreateSequence {
6054                temporary,
6055                if_not_exists,
6056                name,
6057                data_type,
6058                sequence_options,
6059                owned_by,
6060            } => {
6061                let as_type: String = if let Some(dt) = data_type.as_ref() {
6062                    //Cannot use format!(" AS {}", dt), due to format! is not available in --target thumbv6m-none-eabi
6063                    // " AS ".to_owned() + &dt.to_string()
6064                    [" AS ", &dt.to_string()].concat()
6065                } else {
6066                    "".to_string()
6067                };
6068                write!(
6069                    f,
6070                    "CREATE {temporary}SEQUENCE {if_not_exists}{name}{as_type}",
6071                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
6072                    temporary = if *temporary { "TEMPORARY " } else { "" },
6073                    name = name,
6074                    as_type = as_type
6075                )?;
6076                for sequence_option in sequence_options {
6077                    write!(f, "{sequence_option}")?;
6078                }
6079                if let Some(ob) = owned_by.as_ref() {
6080                    write!(f, " OWNED BY {ob}")?;
6081                }
6082                write!(f, "")
6083            }
6084            Statement::CreateStage {
6085                or_replace,
6086                temporary,
6087                if_not_exists,
6088                name,
6089                stage_params,
6090                directory_table_params,
6091                file_format,
6092                copy_options,
6093                comment,
6094                ..
6095            } => {
6096                write!(
6097                    f,
6098                    "CREATE {or_replace}{temp}STAGE {if_not_exists}{name}{stage_params}",
6099                    temp = if *temporary { "TEMPORARY " } else { "" },
6100                    or_replace = if *or_replace { "OR REPLACE " } else { "" },
6101                    if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
6102                )?;
6103                if !directory_table_params.options.is_empty() {
6104                    write!(f, " DIRECTORY=({directory_table_params})")?;
6105                }
6106                if !file_format.options.is_empty() {
6107                    write!(f, " FILE_FORMAT=({file_format})")?;
6108                }
6109                if !copy_options.options.is_empty() {
6110                    write!(f, " COPY_OPTIONS=({copy_options})")?;
6111                }
6112                if comment.is_some() {
6113                    write!(f, " COMMENT='{}'", comment.as_ref().unwrap())?;
6114                }
6115                Ok(())
6116            }
6117            Statement::CopyIntoSnowflake {
6118                kind,
6119                into,
6120                into_columns,
6121                from_obj,
6122                from_obj_alias,
6123                stage_params,
6124                from_transformations,
6125                from_query,
6126                files,
6127                pattern,
6128                file_format,
6129                copy_options,
6130                validation_mode,
6131                partition,
6132            } => {
6133                write!(f, "COPY INTO {into}")?;
6134                if let Some(into_columns) = into_columns {
6135                    write!(f, " ({})", display_comma_separated(into_columns))?;
6136                }
6137                if let Some(from_transformations) = from_transformations {
6138                    // Data load with transformation
6139                    if let Some(from_stage) = from_obj {
6140                        write!(
6141                            f,
6142                            " FROM (SELECT {} FROM {}{}",
6143                            display_separated(from_transformations, ", "),
6144                            from_stage,
6145                            stage_params
6146                        )?;
6147                    }
6148                    if let Some(from_obj_alias) = from_obj_alias {
6149                        write!(f, " AS {from_obj_alias}")?;
6150                    }
6151                    write!(f, ")")?;
6152                } else if let Some(from_obj) = from_obj {
6153                    // Standard data load
6154                    write!(f, " FROM {from_obj}{stage_params}")?;
6155                    if let Some(from_obj_alias) = from_obj_alias {
6156                        write!(f, " AS {from_obj_alias}")?;
6157                    }
6158                } else if let Some(from_query) = from_query {
6159                    // Data unload from query
6160                    write!(f, " FROM ({from_query})")?;
6161                }
6162
6163                if let Some(files) = files {
6164                    write!(f, " FILES = ('{}')", display_separated(files, "', '"))?;
6165                }
6166                if let Some(pattern) = pattern {
6167                    write!(f, " PATTERN = '{pattern}'")?;
6168                }
6169                if let Some(partition) = partition {
6170                    write!(f, " PARTITION BY {partition}")?;
6171                }
6172                if !file_format.options.is_empty() {
6173                    write!(f, " FILE_FORMAT=({file_format})")?;
6174                }
6175                if !copy_options.options.is_empty() {
6176                    match kind {
6177                        CopyIntoSnowflakeKind::Table => {
6178                            write!(f, " COPY_OPTIONS=({copy_options})")?
6179                        }
6180                        CopyIntoSnowflakeKind::Location => write!(f, " {copy_options}")?,
6181                    }
6182                }
6183                if let Some(validation_mode) = validation_mode {
6184                    write!(f, " VALIDATION_MODE = {validation_mode}")?;
6185                }
6186                Ok(())
6187            }
6188            Statement::CreateType {
6189                name,
6190                representation,
6191            } => {
6192                write!(f, "CREATE TYPE {name}")?;
6193                if let Some(repr) = representation {
6194                    write!(f, " {repr}")?;
6195                }
6196                Ok(())
6197            }
6198            Statement::Pragma { name, value, is_eq } => {
6199                write!(f, "PRAGMA {name}")?;
6200                if value.is_some() {
6201                    let val = value.as_ref().unwrap();
6202                    if *is_eq {
6203                        write!(f, " = {val}")?;
6204                    } else {
6205                        write!(f, "({val})")?;
6206                    }
6207                }
6208                Ok(())
6209            }
6210            Statement::Lock(lock) => lock.fmt(f),
6211            Statement::LockTables { tables } => {
6212                write!(f, "LOCK TABLES {}", display_comma_separated(tables))
6213            }
6214            Statement::UnlockTables => {
6215                write!(f, "UNLOCK TABLES")
6216            }
6217            Statement::Unload {
6218                query,
6219                query_text,
6220                to,
6221                auth,
6222                with,
6223                options,
6224            } => {
6225                write!(f, "UNLOAD(")?;
6226                if let Some(query) = query {
6227                    write!(f, "{query}")?;
6228                }
6229                if let Some(query_text) = query_text {
6230                    write!(f, "'{query_text}'")?;
6231                }
6232                write!(f, ") TO {to}")?;
6233                if let Some(auth) = auth {
6234                    write!(f, " IAM_ROLE {auth}")?;
6235                }
6236                if !with.is_empty() {
6237                    write!(f, " WITH ({})", display_comma_separated(with))?;
6238                }
6239                if !options.is_empty() {
6240                    write!(f, " {}", display_separated(options, " "))?;
6241                }
6242                Ok(())
6243            }
6244            Statement::OptimizeTable {
6245                name,
6246                has_table_keyword,
6247                on_cluster,
6248                partition,
6249                include_final,
6250                deduplicate,
6251                predicate,
6252                zorder,
6253            } => {
6254                write!(f, "OPTIMIZE")?;
6255                if *has_table_keyword {
6256                    write!(f, " TABLE")?;
6257                }
6258                write!(f, " {name}")?;
6259                if let Some(on_cluster) = on_cluster {
6260                    write!(f, " ON CLUSTER {on_cluster}")?;
6261                }
6262                if let Some(partition) = partition {
6263                    write!(f, " {partition}")?;
6264                }
6265                if *include_final {
6266                    write!(f, " FINAL")?;
6267                }
6268                if let Some(deduplicate) = deduplicate {
6269                    write!(f, " {deduplicate}")?;
6270                }
6271                if let Some(predicate) = predicate {
6272                    write!(f, " WHERE {predicate}")?;
6273                }
6274                if let Some(zorder) = zorder {
6275                    write!(f, " ZORDER BY ({})", display_comma_separated(zorder))?;
6276                }
6277                Ok(())
6278            }
6279            Statement::LISTEN { channel } => {
6280                write!(f, "LISTEN {channel}")?;
6281                Ok(())
6282            }
6283            Statement::UNLISTEN { channel } => {
6284                write!(f, "UNLISTEN {channel}")?;
6285                Ok(())
6286            }
6287            Statement::NOTIFY { channel, payload } => {
6288                write!(f, "NOTIFY {channel}")?;
6289                if let Some(payload) = payload {
6290                    write!(f, ", '{payload}'")?;
6291                }
6292                Ok(())
6293            }
6294            Statement::RenameTable(rename_tables) => {
6295                write!(f, "RENAME TABLE {}", display_comma_separated(rename_tables))
6296            }
6297            Statement::RaisError {
6298                message,
6299                severity,
6300                state,
6301                arguments,
6302                options,
6303            } => {
6304                write!(f, "RAISERROR({message}, {severity}, {state}")?;
6305                if !arguments.is_empty() {
6306                    write!(f, ", {}", display_comma_separated(arguments))?;
6307                }
6308                write!(f, ")")?;
6309                if !options.is_empty() {
6310                    write!(f, " WITH {}", display_comma_separated(options))?;
6311                }
6312                Ok(())
6313            }
6314            Statement::Throw(s) => write!(f, "{s}"),
6315            Statement::Print(s) => write!(f, "{s}"),
6316            Statement::WaitFor(s) => write!(f, "{s}"),
6317            Statement::Return(r) => write!(f, "{r}"),
6318            Statement::List(command) => write!(f, "LIST {command}"),
6319            Statement::Remove(command) => write!(f, "REMOVE {command}"),
6320            Statement::ExportData(e) => write!(f, "{e}"),
6321            Statement::CreateUser(s) => write!(f, "{s}"),
6322            Statement::AlterSchema(s) => write!(f, "{s}"),
6323            Statement::Vacuum(s) => write!(f, "{s}"),
6324            Statement::AlterUser(s) => write!(f, "{s}"),
6325            Statement::Reset(s) => write!(f, "{s}"),
6326        }
6327    }
6328}
6329
6330/// Can use to describe options in create sequence or table column type identity
6331/// ```sql
6332/// [ INCREMENT [ BY ] increment ]
6333///     [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
6334///     [ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
6335/// ```
6336#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6337#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6338#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6339pub enum SequenceOptions {
6340    /// `INCREMENT [BY] <expr>` option; second value indicates presence of `BY` keyword.
6341    IncrementBy(Expr, bool),
6342    /// `MINVALUE <expr>` or `NO MINVALUE`.
6343    MinValue(Option<Expr>),
6344    /// `MAXVALUE <expr>` or `NO MAXVALUE`.
6345    MaxValue(Option<Expr>),
6346    /// `START [WITH] <expr>`; second value indicates presence of `WITH`.
6347    StartWith(Expr, bool),
6348    /// `CACHE <expr>` option.
6349    Cache(Expr),
6350    /// `CYCLE` or `NO CYCLE` option.
6351    Cycle(bool),
6352}
6353
6354impl fmt::Display for SequenceOptions {
6355    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6356        match self {
6357            SequenceOptions::IncrementBy(increment, by) => {
6358                write!(
6359                    f,
6360                    " INCREMENT{by} {increment}",
6361                    by = if *by { " BY" } else { "" },
6362                    increment = increment
6363                )
6364            }
6365            SequenceOptions::MinValue(Some(expr)) => {
6366                write!(f, " MINVALUE {expr}")
6367            }
6368            SequenceOptions::MinValue(None) => {
6369                write!(f, " NO MINVALUE")
6370            }
6371            SequenceOptions::MaxValue(Some(expr)) => {
6372                write!(f, " MAXVALUE {expr}")
6373            }
6374            SequenceOptions::MaxValue(None) => {
6375                write!(f, " NO MAXVALUE")
6376            }
6377            SequenceOptions::StartWith(start, with) => {
6378                write!(
6379                    f,
6380                    " START{with} {start}",
6381                    with = if *with { " WITH" } else { "" },
6382                    start = start
6383                )
6384            }
6385            SequenceOptions::Cache(cache) => {
6386                write!(f, " CACHE {}", *cache)
6387            }
6388            SequenceOptions::Cycle(no) => {
6389                write!(f, " {}CYCLE", if *no { "NO " } else { "" })
6390            }
6391        }
6392    }
6393}
6394
6395/// Assignment for a `SET` statement (name [=|TO] value)
6396#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6397#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6398#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6399pub struct SetAssignment {
6400    /// Optional context scope (e.g., SESSION or LOCAL).
6401    pub scope: Option<ContextModifier>,
6402    /// Assignment target name.
6403    pub name: ObjectName,
6404    /// Assigned expression value.
6405    pub value: Expr,
6406}
6407
6408impl fmt::Display for SetAssignment {
6409    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6410        write!(
6411            f,
6412            "{}{} = {}",
6413            self.scope.map(|s| format!("{s}")).unwrap_or_default(),
6414            self.name,
6415            self.value
6416        )
6417    }
6418}
6419
6420/// Target of a `TRUNCATE TABLE` command
6421///
6422/// Note this is its own struct because `visit_relation` requires an `ObjectName` (not a `Vec<ObjectName>`)
6423#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6424#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6425#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6426pub struct TruncateTableTarget {
6427    /// name of the table being truncated
6428    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
6429    pub name: ObjectName,
6430    /// Postgres-specific option: explicitly exclude descendants (also default without ONLY)
6431    /// ```sql
6432    /// TRUNCATE TABLE ONLY name
6433    /// ```
6434    /// <https://www.postgresql.org/docs/current/sql-truncate.html>
6435    pub only: bool,
6436    /// Postgres-specific option: asterisk after table name to explicitly indicate descendants
6437    /// ```sql
6438    /// TRUNCATE TABLE name [ * ]
6439    /// ```
6440    /// <https://www.postgresql.org/docs/current/sql-truncate.html>
6441    pub has_asterisk: bool,
6442}
6443
6444impl fmt::Display for TruncateTableTarget {
6445    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6446        if self.only {
6447            write!(f, "ONLY ")?;
6448        };
6449        write!(f, "{}", self.name)?;
6450        if self.has_asterisk {
6451            write!(f, " *")?;
6452        };
6453        Ok(())
6454    }
6455}
6456
6457/// A `LOCK` statement.
6458///
6459/// See <https://www.postgresql.org/docs/current/sql-lock.html>
6460#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6461#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6462#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6463pub struct Lock {
6464    /// List of tables to lock.
6465    pub tables: Vec<LockTableTarget>,
6466    /// Lock mode.
6467    pub lock_mode: Option<LockTableMode>,
6468    /// Whether `NOWAIT` was specified.
6469    pub nowait: bool,
6470}
6471
6472impl fmt::Display for Lock {
6473    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6474        write!(f, "LOCK TABLE {}", display_comma_separated(&self.tables))?;
6475        if let Some(lock_mode) = &self.lock_mode {
6476            write!(f, " IN {lock_mode} MODE")?;
6477        }
6478        if self.nowait {
6479            write!(f, " NOWAIT")?;
6480        }
6481        Ok(())
6482    }
6483}
6484
6485/// Target of a `LOCK TABLE` command
6486///
6487/// See <https://www.postgresql.org/docs/current/sql-lock.html>
6488#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6489#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6490#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6491pub struct LockTableTarget {
6492    /// Name of the table being locked.
6493    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
6494    pub name: ObjectName,
6495    /// Whether `ONLY` was specified to exclude descendant tables.
6496    pub only: bool,
6497    /// Whether `*` was specified to explicitly include descendant tables.
6498    pub has_asterisk: bool,
6499}
6500
6501impl fmt::Display for LockTableTarget {
6502    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6503        if self.only {
6504            write!(f, "ONLY ")?;
6505        }
6506        write!(f, "{}", self.name)?;
6507        if self.has_asterisk {
6508            write!(f, " *")?;
6509        }
6510        Ok(())
6511    }
6512}
6513
6514/// PostgreSQL lock modes for `LOCK TABLE`.
6515///
6516/// See <https://www.postgresql.org/docs/current/sql-lock.html>
6517#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6518#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6519#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6520pub enum LockTableMode {
6521    /// `ACCESS SHARE`
6522    AccessShare,
6523    /// `ROW SHARE`
6524    RowShare,
6525    /// `ROW EXCLUSIVE`
6526    RowExclusive,
6527    /// `SHARE UPDATE EXCLUSIVE`
6528    ShareUpdateExclusive,
6529    /// `SHARE`
6530    Share,
6531    /// `SHARE ROW EXCLUSIVE`
6532    ShareRowExclusive,
6533    /// `EXCLUSIVE`
6534    Exclusive,
6535    /// `ACCESS EXCLUSIVE`
6536    AccessExclusive,
6537}
6538
6539impl fmt::Display for LockTableMode {
6540    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6541        let text = match self {
6542            Self::AccessShare => "ACCESS SHARE",
6543            Self::RowShare => "ROW SHARE",
6544            Self::RowExclusive => "ROW EXCLUSIVE",
6545            Self::ShareUpdateExclusive => "SHARE UPDATE EXCLUSIVE",
6546            Self::Share => "SHARE",
6547            Self::ShareRowExclusive => "SHARE ROW EXCLUSIVE",
6548            Self::Exclusive => "EXCLUSIVE",
6549            Self::AccessExclusive => "ACCESS EXCLUSIVE",
6550        };
6551        write!(f, "{text}")
6552    }
6553}
6554
6555/// PostgreSQL identity option for TRUNCATE table
6556/// [ RESTART IDENTITY | CONTINUE IDENTITY ]
6557#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6558#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6559#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6560pub enum TruncateIdentityOption {
6561    /// Restart identity values (RESTART IDENTITY).
6562    Restart,
6563    /// Continue identity values (CONTINUE IDENTITY).
6564    Continue,
6565}
6566
6567/// Cascade/restrict option for Postgres TRUNCATE table, MySQL GRANT/REVOKE, etc.
6568/// [ CASCADE | RESTRICT ]
6569#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6570#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6571#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6572pub enum CascadeOption {
6573    /// Apply cascading action (e.g., CASCADE).
6574    Cascade,
6575    /// Restrict the action (e.g., RESTRICT).
6576    Restrict,
6577}
6578
6579impl Display for CascadeOption {
6580    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6581        match self {
6582            CascadeOption::Cascade => write!(f, "CASCADE"),
6583            CascadeOption::Restrict => write!(f, "RESTRICT"),
6584        }
6585    }
6586}
6587
6588/// Transaction started with [ TRANSACTION | WORK | TRAN ]
6589#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6590#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6591#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6592pub enum BeginTransactionKind {
6593    /// Standard `TRANSACTION` keyword.
6594    Transaction,
6595    /// Alternate `WORK` keyword.
6596    Work,
6597    /// MSSQL shorthand `TRAN` keyword.
6598    /// See <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/begin-transaction-transact-sql>
6599    Tran,
6600}
6601
6602impl Display for BeginTransactionKind {
6603    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6604        match self {
6605            BeginTransactionKind::Transaction => write!(f, "TRANSACTION"),
6606            BeginTransactionKind::Work => write!(f, "WORK"),
6607            BeginTransactionKind::Tran => write!(f, "TRAN"),
6608        }
6609    }
6610}
6611
6612/// Can use to describe options in  create sequence or table column type identity
6613/// [ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
6614#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6615#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6616#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6617pub enum MinMaxValue {
6618    /// Clause is not specified.
6619    Empty,
6620    /// NO MINVALUE / NO MAXVALUE.
6621    None,
6622    /// `MINVALUE <expr>` / `MAXVALUE <expr>`.
6623    Some(Expr),
6624}
6625
6626#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6627#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6628#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6629#[non_exhaustive]
6630/// Behavior to apply for `INSERT` when a conflict occurs.
6631pub enum OnInsert {
6632    /// ON DUPLICATE KEY UPDATE (MySQL when the key already exists, then execute an update instead)
6633    DuplicateKeyUpdate(Vec<Assignment>),
6634    /// ON CONFLICT is a PostgreSQL and Sqlite extension
6635    OnConflict(OnConflict),
6636}
6637
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))]
6641/// Optional aliases for `INSERT` targets: row alias and optional column aliases.
6642pub struct InsertAliases {
6643    /// Row alias (table-style alias) for the inserted values.
6644    pub row_alias: ObjectName,
6645    /// Optional list of column aliases for the inserted values.
6646    pub col_aliases: Option<Vec<Ident>>,
6647}
6648
6649#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6650#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6651#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6652/// Optional alias for an `INSERT` table; i.e. the table to be inserted into
6653pub struct TableAliasWithoutColumns {
6654    /// `true` if the aliases was explicitly introduced with the "AS" keyword
6655    pub explicit: bool,
6656    /// the alias name itself
6657    pub alias: Ident,
6658}
6659
6660#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6661#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6662#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6663/// `ON CONFLICT` clause representation.
6664pub struct OnConflict {
6665    /// Optional conflict target specifying columns or constraint.
6666    pub conflict_target: Option<ConflictTarget>,
6667    /// Action to take when a conflict occurs.
6668    pub action: OnConflictAction,
6669}
6670#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6671#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6672#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6673/// Target specification for an `ON CONFLICT` clause.
6674pub enum ConflictTarget {
6675    /// Target specified as a list of columns.
6676    Columns(Vec<Ident>),
6677    /// Target specified as a named constraint.
6678    OnConstraint(ObjectName),
6679}
6680#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6681#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6682#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6683/// Action to perform when an `ON CONFLICT` target is matched.
6684pub enum OnConflictAction {
6685    /// Do nothing on conflict.
6686    DoNothing,
6687    /// Perform an update on conflict.
6688    DoUpdate(DoUpdate),
6689}
6690
6691#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6692#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6693#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6694/// Details for `DO UPDATE` action of an `ON CONFLICT` clause.
6695pub struct DoUpdate {
6696    /// Column assignments to perform on update.
6697    pub assignments: Vec<Assignment>,
6698    /// Optional WHERE clause limiting the update.
6699    pub selection: Option<Expr>,
6700}
6701
6702impl fmt::Display for OnInsert {
6703    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6704        match self {
6705            Self::DuplicateKeyUpdate(expr) => write!(
6706                f,
6707                " ON DUPLICATE KEY UPDATE {}",
6708                display_comma_separated(expr)
6709            ),
6710            Self::OnConflict(o) => write!(f, "{o}"),
6711        }
6712    }
6713}
6714impl fmt::Display for OnConflict {
6715    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6716        write!(f, " ON CONFLICT")?;
6717        if let Some(target) = &self.conflict_target {
6718            write!(f, "{target}")?;
6719        }
6720        write!(f, " {}", self.action)
6721    }
6722}
6723impl fmt::Display for ConflictTarget {
6724    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6725        match self {
6726            ConflictTarget::Columns(cols) => write!(f, "({})", display_comma_separated(cols)),
6727            ConflictTarget::OnConstraint(name) => write!(f, " ON CONSTRAINT {name}"),
6728        }
6729    }
6730}
6731impl fmt::Display for OnConflictAction {
6732    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6733        match self {
6734            Self::DoNothing => write!(f, "DO NOTHING"),
6735            Self::DoUpdate(do_update) => {
6736                write!(f, "DO UPDATE")?;
6737                if !do_update.assignments.is_empty() {
6738                    write!(
6739                        f,
6740                        " SET {}",
6741                        display_comma_separated(&do_update.assignments)
6742                    )?;
6743                }
6744                if let Some(selection) = &do_update.selection {
6745                    write!(f, " WHERE {selection}")?;
6746                }
6747                Ok(())
6748            }
6749        }
6750    }
6751}
6752
6753/// Privileges granted in a GRANT statement or revoked in a REVOKE statement.
6754#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6755#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6756#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6757pub enum Privileges {
6758    /// All privileges applicable to the object type
6759    All {
6760        /// Optional keyword from the spec, ignored in practice
6761        with_privileges_keyword: bool,
6762    },
6763    /// Specific privileges (e.g. `SELECT`, `INSERT`)
6764    Actions(Vec<Action>),
6765}
6766
6767impl fmt::Display for Privileges {
6768    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6769        match self {
6770            Privileges::All {
6771                with_privileges_keyword,
6772            } => {
6773                write!(
6774                    f,
6775                    "ALL{}",
6776                    if *with_privileges_keyword {
6777                        " PRIVILEGES"
6778                    } else {
6779                        ""
6780                    }
6781                )
6782            }
6783            Privileges::Actions(actions) => {
6784                write!(f, "{}", display_comma_separated(actions))
6785            }
6786        }
6787    }
6788}
6789
6790/// Specific direction for FETCH statement
6791#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6792#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6793#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6794pub enum FetchDirection {
6795    /// Fetch a specific count of rows.
6796    Count {
6797        /// The limit value for the count.
6798        limit: ValueWithSpan,
6799    },
6800    /// Fetch the next row.
6801    Next,
6802    /// Fetch the prior row.
6803    Prior,
6804    /// Fetch the first row.
6805    First,
6806    /// Fetch the last row.
6807    Last,
6808    /// Fetch an absolute row by index.
6809    Absolute {
6810        /// The absolute index value.
6811        limit: ValueWithSpan,
6812    },
6813    /// Fetch a row relative to the current position.
6814    Relative {
6815        /// The relative offset value.
6816        limit: ValueWithSpan,
6817    },
6818    /// Fetch all rows.
6819    All,
6820    // FORWARD
6821    // FORWARD count
6822    /// Fetch forward by an optional limit.
6823    Forward {
6824        /// Optional forward limit.
6825        limit: Option<ValueWithSpan>,
6826    },
6827    /// Fetch all forward rows.
6828    ForwardAll,
6829    // BACKWARD
6830    // BACKWARD count
6831    /// Fetch backward by an optional limit.
6832    Backward {
6833        /// Optional backward limit.
6834        limit: Option<ValueWithSpan>,
6835    },
6836    /// Fetch all backward rows.
6837    BackwardAll,
6838}
6839
6840impl fmt::Display for FetchDirection {
6841    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6842        match self {
6843            FetchDirection::Count { limit } => f.write_str(&limit.to_string())?,
6844            FetchDirection::Next => f.write_str("NEXT")?,
6845            FetchDirection::Prior => f.write_str("PRIOR")?,
6846            FetchDirection::First => f.write_str("FIRST")?,
6847            FetchDirection::Last => f.write_str("LAST")?,
6848            FetchDirection::Absolute { limit } => {
6849                f.write_str("ABSOLUTE ")?;
6850                f.write_str(&limit.to_string())?;
6851            }
6852            FetchDirection::Relative { limit } => {
6853                f.write_str("RELATIVE ")?;
6854                f.write_str(&limit.to_string())?;
6855            }
6856            FetchDirection::All => f.write_str("ALL")?,
6857            FetchDirection::Forward { limit } => {
6858                f.write_str("FORWARD")?;
6859
6860                if let Some(l) = limit {
6861                    f.write_str(" ")?;
6862                    f.write_str(&l.to_string())?;
6863                }
6864            }
6865            FetchDirection::ForwardAll => f.write_str("FORWARD ALL")?,
6866            FetchDirection::Backward { limit } => {
6867                f.write_str("BACKWARD")?;
6868
6869                if let Some(l) = limit {
6870                    f.write_str(" ")?;
6871                    f.write_str(&l.to_string())?;
6872                }
6873            }
6874            FetchDirection::BackwardAll => f.write_str("BACKWARD ALL")?,
6875        };
6876
6877        Ok(())
6878    }
6879}
6880
6881/// The "position" for a FETCH statement.
6882///
6883/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/fetch-transact-sql)
6884#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6885#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6886#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6887pub enum FetchPosition {
6888    /// Use `FROM <pos>` position specifier.
6889    From,
6890    /// Use `IN <pos>` position specifier.
6891    In,
6892}
6893
6894impl fmt::Display for FetchPosition {
6895    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6896        match self {
6897            FetchPosition::From => f.write_str("FROM")?,
6898            FetchPosition::In => f.write_str("IN")?,
6899        };
6900
6901        Ok(())
6902    }
6903}
6904
6905/// A privilege on a database object (table, sequence, etc.).
6906#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
6907#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
6908#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
6909pub enum Action {
6910    /// Add a search optimization.
6911    AddSearchOptimization,
6912    /// Apply an `APPLY` operation with a specific type.
6913    Apply {
6914        /// The type of apply operation.
6915        apply_type: ActionApplyType,
6916    },
6917    /// Apply a budget operation.
6918    ApplyBudget,
6919    /// Attach a listing.
6920    AttachListing,
6921    /// Attach a policy.
6922    AttachPolicy,
6923    /// Audit operation.
6924    Audit,
6925    /// Bind a service endpoint.
6926    BindServiceEndpoint,
6927    /// Connect permission.
6928    Connect,
6929    /// Create action, optionally specifying an object type.
6930    Create {
6931        /// Optional object type to create.
6932        obj_type: Option<ActionCreateObjectType>,
6933    },
6934    /// Actions related to database roles.
6935    DatabaseRole {
6936        /// The role name.
6937        role: ObjectName,
6938    },
6939    /// Delete permission.
6940    Delete,
6941    /// Drop permission.
6942    Drop,
6943    /// Evolve schema permission.
6944    EvolveSchema,
6945    /// Exec action (execute) with optional object type.
6946    Exec {
6947        /// Optional execute object type.
6948        obj_type: Option<ActionExecuteObjectType>,
6949    },
6950    /// Execute action with optional object type.
6951    Execute {
6952        /// Optional execute object type.
6953        obj_type: Option<ActionExecuteObjectType>,
6954    },
6955    /// Failover operation.
6956    Failover,
6957    /// Use imported privileges.
6958    ImportedPrivileges,
6959    /// Import a share.
6960    ImportShare,
6961    /// Insert rows with optional column list.
6962    Insert {
6963        /// Optional list of target columns for insert.
6964        columns: Option<Vec<Ident>>,
6965    },
6966    /// Manage operation with a specific manage type.
6967    Manage {
6968        /// The specific manage sub-type.
6969        manage_type: ActionManageType,
6970    },
6971    /// Manage releases.
6972    ManageReleases,
6973    /// Manage versions.
6974    ManageVersions,
6975    /// Modify operation with an optional modify type.
6976    Modify {
6977        /// The optional modify sub-type.
6978        modify_type: Option<ActionModifyType>,
6979    },
6980    /// Monitor operation with an optional monitor type.
6981    Monitor {
6982        /// The optional monitor sub-type.
6983        monitor_type: Option<ActionMonitorType>,
6984    },
6985    /// Operate permission.
6986    Operate,
6987    /// Override share restrictions.
6988    OverrideShareRestrictions,
6989    /// Ownership permission.
6990    Ownership,
6991    /// Purchase a data exchange listing.
6992    PurchaseDataExchangeListing,
6993
6994    /// Read access.
6995    Read,
6996    /// Read session-level access.
6997    ReadSession,
6998    /// References with optional column list.
6999    References {
7000        /// Optional list of referenced column identifiers.
7001        columns: Option<Vec<Ident>>,
7002    },
7003    /// Replication permission.
7004    Replicate,
7005    /// Resolve all references.
7006    ResolveAll,
7007    /// Role-related permission with target role name.
7008    Role {
7009        /// The target role name.
7010        role: ObjectName,
7011    },
7012    /// Select permission with optional column list.
7013    Select {
7014        /// Optional list of selected columns.
7015        columns: Option<Vec<Ident>>,
7016    },
7017    /// Temporary object permission.
7018    Temporary,
7019    /// Trigger-related permission.
7020    Trigger,
7021    /// Truncate permission.
7022    Truncate,
7023    /// Update permission with optional affected columns.
7024    Update {
7025        /// Optional list of columns affected by update.
7026        columns: Option<Vec<Ident>>,
7027    },
7028    /// Usage permission.
7029    Usage,
7030}
7031
7032impl fmt::Display for Action {
7033    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7034        match self {
7035            Action::AddSearchOptimization => f.write_str("ADD SEARCH OPTIMIZATION")?,
7036            Action::Apply { apply_type } => write!(f, "APPLY {apply_type}")?,
7037            Action::ApplyBudget => f.write_str("APPLYBUDGET")?,
7038            Action::AttachListing => f.write_str("ATTACH LISTING")?,
7039            Action::AttachPolicy => f.write_str("ATTACH POLICY")?,
7040            Action::Audit => f.write_str("AUDIT")?,
7041            Action::BindServiceEndpoint => f.write_str("BIND SERVICE ENDPOINT")?,
7042            Action::Connect => f.write_str("CONNECT")?,
7043            Action::Create { obj_type } => {
7044                f.write_str("CREATE")?;
7045                if let Some(obj_type) = obj_type {
7046                    write!(f, " {obj_type}")?
7047                }
7048            }
7049            Action::DatabaseRole { role } => write!(f, "DATABASE ROLE {role}")?,
7050            Action::Delete => f.write_str("DELETE")?,
7051            Action::Drop => f.write_str("DROP")?,
7052            Action::EvolveSchema => f.write_str("EVOLVE SCHEMA")?,
7053            Action::Exec { obj_type } => {
7054                f.write_str("EXEC")?;
7055                if let Some(obj_type) = obj_type {
7056                    write!(f, " {obj_type}")?
7057                }
7058            }
7059            Action::Execute { obj_type } => {
7060                f.write_str("EXECUTE")?;
7061                if let Some(obj_type) = obj_type {
7062                    write!(f, " {obj_type}")?
7063                }
7064            }
7065            Action::Failover => f.write_str("FAILOVER")?,
7066            Action::ImportedPrivileges => f.write_str("IMPORTED PRIVILEGES")?,
7067            Action::ImportShare => f.write_str("IMPORT SHARE")?,
7068            Action::Insert { .. } => f.write_str("INSERT")?,
7069            Action::Manage { manage_type } => write!(f, "MANAGE {manage_type}")?,
7070            Action::ManageReleases => f.write_str("MANAGE RELEASES")?,
7071            Action::ManageVersions => f.write_str("MANAGE VERSIONS")?,
7072            Action::Modify { modify_type } => {
7073                write!(f, "MODIFY")?;
7074                if let Some(modify_type) = modify_type {
7075                    write!(f, " {modify_type}")?;
7076                }
7077            }
7078            Action::Monitor { monitor_type } => {
7079                write!(f, "MONITOR")?;
7080                if let Some(monitor_type) = monitor_type {
7081                    write!(f, " {monitor_type}")?
7082                }
7083            }
7084            Action::Operate => f.write_str("OPERATE")?,
7085            Action::OverrideShareRestrictions => f.write_str("OVERRIDE SHARE RESTRICTIONS")?,
7086            Action::Ownership => f.write_str("OWNERSHIP")?,
7087            Action::PurchaseDataExchangeListing => f.write_str("PURCHASE DATA EXCHANGE LISTING")?,
7088            Action::Read => f.write_str("READ")?,
7089            Action::ReadSession => f.write_str("READ SESSION")?,
7090            Action::References { .. } => f.write_str("REFERENCES")?,
7091            Action::Replicate => f.write_str("REPLICATE")?,
7092            Action::ResolveAll => f.write_str("RESOLVE ALL")?,
7093            Action::Role { role } => write!(f, "ROLE {role}")?,
7094            Action::Select { .. } => f.write_str("SELECT")?,
7095            Action::Temporary => f.write_str("TEMPORARY")?,
7096            Action::Trigger => f.write_str("TRIGGER")?,
7097            Action::Truncate => f.write_str("TRUNCATE")?,
7098            Action::Update { .. } => f.write_str("UPDATE")?,
7099            Action::Usage => f.write_str("USAGE")?,
7100        };
7101        match self {
7102            Action::Insert { columns }
7103            | Action::References { columns }
7104            | Action::Select { columns }
7105            | Action::Update { columns } => {
7106                if let Some(columns) = columns {
7107                    write!(f, " ({})", display_comma_separated(columns))?;
7108                }
7109            }
7110            _ => (),
7111        };
7112        Ok(())
7113    }
7114}
7115
7116#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7117#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7118#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7119/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
7120/// under `globalPrivileges` in the `CREATE` privilege.
7121pub enum ActionCreateObjectType {
7122    /// An account-level object.
7123    Account,
7124    /// An application object.
7125    Application,
7126    /// An application package object.
7127    ApplicationPackage,
7128    /// A compute pool object.
7129    ComputePool,
7130    /// A data exchange listing.
7131    DataExchangeListing,
7132    /// A database object.
7133    Database,
7134    /// An external volume object.
7135    ExternalVolume,
7136    /// A failover group object.
7137    FailoverGroup,
7138    /// An integration object.
7139    Integration,
7140    /// A network policy object.
7141    NetworkPolicy,
7142    /// An organization listing.
7143    OrganiationListing,
7144    /// A replication group object.
7145    ReplicationGroup,
7146    /// A role object.
7147    Role,
7148    /// A schema object.
7149    Schema,
7150    /// A share object.
7151    Share,
7152    /// A user object.
7153    User,
7154    /// A warehouse object.
7155    Warehouse,
7156}
7157
7158impl fmt::Display for ActionCreateObjectType {
7159    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7160        match self {
7161            ActionCreateObjectType::Account => write!(f, "ACCOUNT"),
7162            ActionCreateObjectType::Application => write!(f, "APPLICATION"),
7163            ActionCreateObjectType::ApplicationPackage => write!(f, "APPLICATION PACKAGE"),
7164            ActionCreateObjectType::ComputePool => write!(f, "COMPUTE POOL"),
7165            ActionCreateObjectType::DataExchangeListing => write!(f, "DATA EXCHANGE LISTING"),
7166            ActionCreateObjectType::Database => write!(f, "DATABASE"),
7167            ActionCreateObjectType::ExternalVolume => write!(f, "EXTERNAL VOLUME"),
7168            ActionCreateObjectType::FailoverGroup => write!(f, "FAILOVER GROUP"),
7169            ActionCreateObjectType::Integration => write!(f, "INTEGRATION"),
7170            ActionCreateObjectType::NetworkPolicy => write!(f, "NETWORK POLICY"),
7171            ActionCreateObjectType::OrganiationListing => write!(f, "ORGANIZATION LISTING"),
7172            ActionCreateObjectType::ReplicationGroup => write!(f, "REPLICATION GROUP"),
7173            ActionCreateObjectType::Role => write!(f, "ROLE"),
7174            ActionCreateObjectType::Schema => write!(f, "SCHEMA"),
7175            ActionCreateObjectType::Share => write!(f, "SHARE"),
7176            ActionCreateObjectType::User => write!(f, "USER"),
7177            ActionCreateObjectType::Warehouse => write!(f, "WAREHOUSE"),
7178        }
7179    }
7180}
7181
7182#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7183#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7184#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7185/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
7186/// under `globalPrivileges` in the `APPLY` privilege.
7187pub enum ActionApplyType {
7188    /// Apply an aggregation policy.
7189    AggregationPolicy,
7190    /// Apply an authentication policy.
7191    AuthenticationPolicy,
7192    /// Apply a join policy.
7193    JoinPolicy,
7194    /// Apply a masking policy.
7195    MaskingPolicy,
7196    /// Apply a packages policy.
7197    PackagesPolicy,
7198    /// Apply a password policy.
7199    PasswordPolicy,
7200    /// Apply a projection policy.
7201    ProjectionPolicy,
7202    /// Apply a row access policy.
7203    RowAccessPolicy,
7204    /// Apply a session policy.
7205    SessionPolicy,
7206    /// Apply a tag.
7207    Tag,
7208}
7209
7210impl fmt::Display for ActionApplyType {
7211    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7212        match self {
7213            ActionApplyType::AggregationPolicy => write!(f, "AGGREGATION POLICY"),
7214            ActionApplyType::AuthenticationPolicy => write!(f, "AUTHENTICATION POLICY"),
7215            ActionApplyType::JoinPolicy => write!(f, "JOIN POLICY"),
7216            ActionApplyType::MaskingPolicy => write!(f, "MASKING POLICY"),
7217            ActionApplyType::PackagesPolicy => write!(f, "PACKAGES POLICY"),
7218            ActionApplyType::PasswordPolicy => write!(f, "PASSWORD POLICY"),
7219            ActionApplyType::ProjectionPolicy => write!(f, "PROJECTION POLICY"),
7220            ActionApplyType::RowAccessPolicy => write!(f, "ROW ACCESS POLICY"),
7221            ActionApplyType::SessionPolicy => write!(f, "SESSION POLICY"),
7222            ActionApplyType::Tag => write!(f, "TAG"),
7223        }
7224    }
7225}
7226
7227#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7228#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7229#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7230/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
7231/// under `globalPrivileges` in the `EXECUTE` privilege.
7232pub enum ActionExecuteObjectType {
7233    /// Alert object.
7234    Alert,
7235    /// Data metric function object.
7236    DataMetricFunction,
7237    /// Managed alert object.
7238    ManagedAlert,
7239    /// Managed task object.
7240    ManagedTask,
7241    /// Task object.
7242    Task,
7243}
7244
7245impl fmt::Display for ActionExecuteObjectType {
7246    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7247        match self {
7248            ActionExecuteObjectType::Alert => write!(f, "ALERT"),
7249            ActionExecuteObjectType::DataMetricFunction => write!(f, "DATA METRIC FUNCTION"),
7250            ActionExecuteObjectType::ManagedAlert => write!(f, "MANAGED ALERT"),
7251            ActionExecuteObjectType::ManagedTask => write!(f, "MANAGED TASK"),
7252            ActionExecuteObjectType::Task => write!(f, "TASK"),
7253        }
7254    }
7255}
7256
7257#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7258#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7259#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7260/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
7261/// under `globalPrivileges` in the `MANAGE` privilege.
7262pub enum ActionManageType {
7263    /// Account support cases management.
7264    AccountSupportCases,
7265    /// Event sharing management.
7266    EventSharing,
7267    /// Grants management.
7268    Grants,
7269    /// Listing auto-fulfillment management.
7270    ListingAutoFulfillment,
7271    /// Organization support cases management.
7272    OrganizationSupportCases,
7273    /// User support cases management.
7274    UserSupportCases,
7275    /// Warehouses management.
7276    Warehouses,
7277}
7278
7279impl fmt::Display for ActionManageType {
7280    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7281        match self {
7282            ActionManageType::AccountSupportCases => write!(f, "ACCOUNT SUPPORT CASES"),
7283            ActionManageType::EventSharing => write!(f, "EVENT SHARING"),
7284            ActionManageType::Grants => write!(f, "GRANTS"),
7285            ActionManageType::ListingAutoFulfillment => write!(f, "LISTING AUTO FULFILLMENT"),
7286            ActionManageType::OrganizationSupportCases => write!(f, "ORGANIZATION SUPPORT CASES"),
7287            ActionManageType::UserSupportCases => write!(f, "USER SUPPORT CASES"),
7288            ActionManageType::Warehouses => write!(f, "WAREHOUSES"),
7289        }
7290    }
7291}
7292
7293#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7294#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7295#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7296/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
7297/// under `globalPrivileges` in the `MODIFY` privilege.
7298pub enum ActionModifyType {
7299    /// Modify log level.
7300    LogLevel,
7301    /// Modify trace level.
7302    TraceLevel,
7303    /// Modify session log level.
7304    SessionLogLevel,
7305    /// Modify session trace level.
7306    SessionTraceLevel,
7307}
7308
7309impl fmt::Display for ActionModifyType {
7310    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7311        match self {
7312            ActionModifyType::LogLevel => write!(f, "LOG LEVEL"),
7313            ActionModifyType::TraceLevel => write!(f, "TRACE LEVEL"),
7314            ActionModifyType::SessionLogLevel => write!(f, "SESSION LOG LEVEL"),
7315            ActionModifyType::SessionTraceLevel => write!(f, "SESSION TRACE LEVEL"),
7316        }
7317    }
7318}
7319
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))]
7323/// See <https://docs.snowflake.com/en/sql-reference/sql/grant-privilege>
7324/// under `globalPrivileges` in the `MONITOR` privilege.
7325pub enum ActionMonitorType {
7326    /// Monitor execution.
7327    Execution,
7328    /// Monitor security.
7329    Security,
7330    /// Monitor usage.
7331    Usage,
7332}
7333
7334impl fmt::Display for ActionMonitorType {
7335    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7336        match self {
7337            ActionMonitorType::Execution => write!(f, "EXECUTION"),
7338            ActionMonitorType::Security => write!(f, "SECURITY"),
7339            ActionMonitorType::Usage => write!(f, "USAGE"),
7340        }
7341    }
7342}
7343
7344/// The principal that receives the privileges
7345#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7346#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7347#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7348pub struct Grantee {
7349    /// The category/type of grantee (role, user, share, etc.).
7350    pub grantee_type: GranteesType,
7351    /// Optional name of the grantee (identifier or user@host).
7352    pub name: Option<GranteeName>,
7353}
7354
7355impl fmt::Display for Grantee {
7356    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7357        match self.grantee_type {
7358            GranteesType::Role => {
7359                write!(f, "ROLE ")?;
7360            }
7361            GranteesType::Share => {
7362                write!(f, "SHARE ")?;
7363            }
7364            GranteesType::User => {
7365                write!(f, "USER ")?;
7366            }
7367            GranteesType::Group => {
7368                write!(f, "GROUP ")?;
7369            }
7370            GranteesType::Public => {
7371                write!(f, "PUBLIC ")?;
7372            }
7373            GranteesType::DatabaseRole => {
7374                write!(f, "DATABASE ROLE ")?;
7375            }
7376            GranteesType::Application => {
7377                write!(f, "APPLICATION ")?;
7378            }
7379            GranteesType::ApplicationRole => {
7380                write!(f, "APPLICATION ROLE ")?;
7381            }
7382            GranteesType::None => (),
7383        }
7384        if let Some(ref name) = self.name {
7385            name.fmt(f)?;
7386        }
7387        Ok(())
7388    }
7389}
7390
7391#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7392#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7393#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7394/// The kind of principal receiving privileges.
7395pub enum GranteesType {
7396    /// A role principal.
7397    Role,
7398    /// A share principal.
7399    Share,
7400    /// A user principal.
7401    User,
7402    /// A group principal.
7403    Group,
7404    /// The public principal.
7405    Public,
7406    /// A database role principal.
7407    DatabaseRole,
7408    /// An application principal.
7409    Application,
7410    /// An application role principal.
7411    ApplicationRole,
7412    /// No specific principal (e.g. `NONE`).
7413    None,
7414}
7415
7416/// Users/roles designated in a GRANT/REVOKE
7417#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7418#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7419#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7420pub enum GranteeName {
7421    /// A bare identifier
7422    ObjectName(ObjectName),
7423    /// A MySQL user/host pair such as 'root'@'%'
7424    UserHost {
7425        /// The user identifier portion.
7426        user: Ident,
7427        /// The host identifier portion.
7428        host: Ident,
7429    },
7430}
7431
7432impl fmt::Display for GranteeName {
7433    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7434        match self {
7435            GranteeName::ObjectName(name) => name.fmt(f),
7436            GranteeName::UserHost { user, host } => {
7437                write!(f, "{user}@{host}")
7438            }
7439        }
7440    }
7441}
7442
7443/// Objects on which privileges are granted in a GRANT statement.
7444#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7445#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7446#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7447pub enum GrantObjects {
7448    /// Grant privileges on `ALL SEQUENCES IN SCHEMA <schema_name> [, ...]`
7449    AllSequencesInSchema {
7450        /// The target schema names.
7451        schemas: Vec<ObjectName>,
7452    },
7453    /// Grant privileges on `ALL TABLES IN SCHEMA <schema_name> [, ...]`
7454    AllTablesInSchema {
7455        /// The target schema names.
7456        schemas: Vec<ObjectName>,
7457    },
7458    /// Grant privileges on `ALL VIEWS IN SCHEMA <schema_name> [, ...]`
7459    AllViewsInSchema {
7460        /// The target schema names.
7461        schemas: Vec<ObjectName>,
7462    },
7463    /// Grant privileges on `ALL MATERIALIZED VIEWS IN SCHEMA <schema_name> [, ...]`
7464    AllMaterializedViewsInSchema {
7465        /// The target schema names.
7466        schemas: Vec<ObjectName>,
7467    },
7468    /// Grant privileges on `ALL EXTERNAL TABLES IN SCHEMA <schema_name> [, ...]`
7469    AllExternalTablesInSchema {
7470        /// The target schema names.
7471        schemas: Vec<ObjectName>,
7472    },
7473    /// Grant privileges on `ALL FUNCTIONS IN SCHEMA <schema_name> [, ...]`
7474    AllFunctionsInSchema {
7475        /// The target schema names.
7476        schemas: Vec<ObjectName>,
7477    },
7478    /// Grant privileges on `FUTURE SCHEMAS IN DATABASE <database_name> [, ...]`
7479    FutureSchemasInDatabase {
7480        /// The target database names.
7481        databases: Vec<ObjectName>,
7482    },
7483    /// Grant privileges on `FUTURE TABLES IN SCHEMA <schema_name> [, ...]`
7484    FutureTablesInSchema {
7485        /// The target schema names.
7486        schemas: Vec<ObjectName>,
7487    },
7488    /// Grant privileges on `FUTURE VIEWS IN SCHEMA <schema_name> [, ...]`
7489    FutureViewsInSchema {
7490        /// The target schema names.
7491        schemas: Vec<ObjectName>,
7492    },
7493    /// Grant privileges on `FUTURE EXTERNAL TABLES IN SCHEMA <schema_name> [, ...]`
7494    FutureExternalTablesInSchema {
7495        /// The target schema names.
7496        schemas: Vec<ObjectName>,
7497    },
7498    /// Grant privileges on `FUTURE MATERIALIZED VIEWS IN SCHEMA <schema_name> [, ...]`
7499    FutureMaterializedViewsInSchema {
7500        /// The target schema names.
7501        schemas: Vec<ObjectName>,
7502    },
7503    /// Grant privileges on `FUTURE SEQUENCES IN SCHEMA <schema_name> [, ...]`
7504    FutureSequencesInSchema {
7505        /// The target schema names.
7506        schemas: Vec<ObjectName>,
7507    },
7508    /// Grant privileges on specific databases
7509    Databases(Vec<ObjectName>),
7510    /// Grant privileges on specific schemas
7511    Schemas(Vec<ObjectName>),
7512    /// Grant privileges on specific sequences
7513    Sequences(Vec<ObjectName>),
7514    /// Grant privileges on specific tables
7515    Tables(Vec<ObjectName>),
7516    /// Grant privileges on specific views
7517    Views(Vec<ObjectName>),
7518    /// Grant privileges on specific warehouses
7519    Warehouses(Vec<ObjectName>),
7520    /// Grant privileges on specific integrations
7521    Integrations(Vec<ObjectName>),
7522    /// Grant privileges on resource monitors
7523    ResourceMonitors(Vec<ObjectName>),
7524    /// Grant privileges on users
7525    Users(Vec<ObjectName>),
7526    /// Grant privileges on compute pools
7527    ComputePools(Vec<ObjectName>),
7528    /// Grant privileges on connections
7529    Connections(Vec<ObjectName>),
7530    /// Grant privileges on failover groups
7531    FailoverGroup(Vec<ObjectName>),
7532    /// Grant privileges on replication group
7533    ReplicationGroup(Vec<ObjectName>),
7534    /// Grant privileges on external volumes
7535    ExternalVolumes(Vec<ObjectName>),
7536    /// Grant privileges on a procedure. In dialects that
7537    /// support overloading, the argument types must be specified.
7538    ///
7539    /// For example:
7540    /// `GRANT USAGE ON PROCEDURE foo(varchar) TO ROLE role1`
7541    Procedure {
7542        /// The procedure name.
7543        name: ObjectName,
7544        /// Optional argument types for overloaded procedures.
7545        arg_types: Vec<DataType>,
7546    },
7547
7548    /// Grant privileges on a function. In dialects that
7549    /// support overloading, the argument types must be specified.
7550    ///
7551    /// For example:
7552    /// `GRANT USAGE ON FUNCTION foo(varchar) TO ROLE role1`
7553    Function {
7554        /// The function name.
7555        name: ObjectName,
7556        /// Optional argument types for overloaded functions.
7557        arg_types: Vec<DataType>,
7558    },
7559}
7560
7561impl fmt::Display for GrantObjects {
7562    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7563        match self {
7564            GrantObjects::Sequences(sequences) => {
7565                write!(f, "SEQUENCE {}", display_comma_separated(sequences))
7566            }
7567            GrantObjects::Databases(databases) => {
7568                write!(f, "DATABASE {}", display_comma_separated(databases))
7569            }
7570            GrantObjects::Schemas(schemas) => {
7571                write!(f, "SCHEMA {}", display_comma_separated(schemas))
7572            }
7573            GrantObjects::Tables(tables) => {
7574                write!(f, "{}", display_comma_separated(tables))
7575            }
7576            GrantObjects::Views(views) => {
7577                write!(f, "VIEW {}", display_comma_separated(views))
7578            }
7579            GrantObjects::Warehouses(warehouses) => {
7580                write!(f, "WAREHOUSE {}", display_comma_separated(warehouses))
7581            }
7582            GrantObjects::Integrations(integrations) => {
7583                write!(f, "INTEGRATION {}", display_comma_separated(integrations))
7584            }
7585            GrantObjects::AllSequencesInSchema { schemas } => {
7586                write!(
7587                    f,
7588                    "ALL SEQUENCES IN SCHEMA {}",
7589                    display_comma_separated(schemas)
7590                )
7591            }
7592            GrantObjects::AllTablesInSchema { schemas } => {
7593                write!(
7594                    f,
7595                    "ALL TABLES IN SCHEMA {}",
7596                    display_comma_separated(schemas)
7597                )
7598            }
7599            GrantObjects::AllExternalTablesInSchema { schemas } => {
7600                write!(
7601                    f,
7602                    "ALL EXTERNAL TABLES IN SCHEMA {}",
7603                    display_comma_separated(schemas)
7604                )
7605            }
7606            GrantObjects::AllViewsInSchema { schemas } => {
7607                write!(
7608                    f,
7609                    "ALL VIEWS IN SCHEMA {}",
7610                    display_comma_separated(schemas)
7611                )
7612            }
7613            GrantObjects::AllMaterializedViewsInSchema { schemas } => {
7614                write!(
7615                    f,
7616                    "ALL MATERIALIZED VIEWS IN SCHEMA {}",
7617                    display_comma_separated(schemas)
7618                )
7619            }
7620            GrantObjects::AllFunctionsInSchema { schemas } => {
7621                write!(
7622                    f,
7623                    "ALL FUNCTIONS IN SCHEMA {}",
7624                    display_comma_separated(schemas)
7625                )
7626            }
7627            GrantObjects::FutureSchemasInDatabase { databases } => {
7628                write!(
7629                    f,
7630                    "FUTURE SCHEMAS IN DATABASE {}",
7631                    display_comma_separated(databases)
7632                )
7633            }
7634            GrantObjects::FutureTablesInSchema { schemas } => {
7635                write!(
7636                    f,
7637                    "FUTURE TABLES IN SCHEMA {}",
7638                    display_comma_separated(schemas)
7639                )
7640            }
7641            GrantObjects::FutureExternalTablesInSchema { schemas } => {
7642                write!(
7643                    f,
7644                    "FUTURE EXTERNAL TABLES IN SCHEMA {}",
7645                    display_comma_separated(schemas)
7646                )
7647            }
7648            GrantObjects::FutureViewsInSchema { schemas } => {
7649                write!(
7650                    f,
7651                    "FUTURE VIEWS IN SCHEMA {}",
7652                    display_comma_separated(schemas)
7653                )
7654            }
7655            GrantObjects::FutureMaterializedViewsInSchema { schemas } => {
7656                write!(
7657                    f,
7658                    "FUTURE MATERIALIZED VIEWS IN SCHEMA {}",
7659                    display_comma_separated(schemas)
7660                )
7661            }
7662            GrantObjects::FutureSequencesInSchema { schemas } => {
7663                write!(
7664                    f,
7665                    "FUTURE SEQUENCES IN SCHEMA {}",
7666                    display_comma_separated(schemas)
7667                )
7668            }
7669            GrantObjects::ResourceMonitors(objects) => {
7670                write!(f, "RESOURCE MONITOR {}", display_comma_separated(objects))
7671            }
7672            GrantObjects::Users(objects) => {
7673                write!(f, "USER {}", display_comma_separated(objects))
7674            }
7675            GrantObjects::ComputePools(objects) => {
7676                write!(f, "COMPUTE POOL {}", display_comma_separated(objects))
7677            }
7678            GrantObjects::Connections(objects) => {
7679                write!(f, "CONNECTION {}", display_comma_separated(objects))
7680            }
7681            GrantObjects::FailoverGroup(objects) => {
7682                write!(f, "FAILOVER GROUP {}", display_comma_separated(objects))
7683            }
7684            GrantObjects::ReplicationGroup(objects) => {
7685                write!(f, "REPLICATION GROUP {}", display_comma_separated(objects))
7686            }
7687            GrantObjects::ExternalVolumes(objects) => {
7688                write!(f, "EXTERNAL VOLUME {}", display_comma_separated(objects))
7689            }
7690            GrantObjects::Procedure { name, arg_types } => {
7691                write!(f, "PROCEDURE {name}")?;
7692                if !arg_types.is_empty() {
7693                    write!(f, "({})", display_comma_separated(arg_types))?;
7694                }
7695                Ok(())
7696            }
7697            GrantObjects::Function { name, arg_types } => {
7698                write!(f, "FUNCTION {name}")?;
7699                if !arg_types.is_empty() {
7700                    write!(f, "({})", display_comma_separated(arg_types))?;
7701                }
7702                Ok(())
7703            }
7704        }
7705    }
7706}
7707
7708/// A `DENY` statement
7709///
7710/// [MsSql](https://learn.microsoft.com/en-us/sql/t-sql/statements/deny-transact-sql)
7711#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7712#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7713#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7714pub struct DenyStatement {
7715    /// The privileges to deny.
7716    pub privileges: Privileges,
7717    /// The objects the privileges apply to.
7718    pub objects: GrantObjects,
7719    /// The grantees (users/roles) to whom the denial applies.
7720    pub grantees: Vec<Grantee>,
7721    /// Optional identifier of the principal that performed the grant.
7722    pub granted_by: Option<Ident>,
7723    /// Optional cascade option controlling dependent objects.
7724    pub cascade: Option<CascadeOption>,
7725}
7726
7727impl fmt::Display for DenyStatement {
7728    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7729        write!(f, "DENY {}", self.privileges)?;
7730        write!(f, " ON {}", self.objects)?;
7731        if !self.grantees.is_empty() {
7732            write!(f, " TO {}", display_comma_separated(&self.grantees))?;
7733        }
7734        if let Some(cascade) = &self.cascade {
7735            write!(f, " {cascade}")?;
7736        }
7737        if let Some(granted_by) = &self.granted_by {
7738            write!(f, " AS {granted_by}")?;
7739        }
7740        Ok(())
7741    }
7742}
7743
7744/// SQL assignment `foo = expr` as used in SQLUpdate
7745#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7746#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7747#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7748pub struct Assignment {
7749    /// The left-hand side of the assignment.
7750    pub target: AssignmentTarget,
7751    /// The expression assigned to the target.
7752    pub value: Expr,
7753}
7754
7755impl fmt::Display for Assignment {
7756    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7757        write!(f, "{} = {}", self.target, self.value)
7758    }
7759}
7760
7761/// Left-hand side of an assignment in an UPDATE statement,
7762/// e.g. `foo` in `foo = 5` (ColumnName assignment) or
7763/// `(a, b)` in `(a, b) = (1, 2)` (Tuple assignment).
7764#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7765#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7766#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7767pub enum AssignmentTarget {
7768    /// A single column
7769    ColumnName(ObjectName),
7770    /// A tuple of columns
7771    Tuple(Vec<ObjectName>),
7772}
7773
7774impl fmt::Display for AssignmentTarget {
7775    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7776        match self {
7777            AssignmentTarget::ColumnName(column) => write!(f, "{column}"),
7778            AssignmentTarget::Tuple(columns) => write!(f, "({})", display_comma_separated(columns)),
7779        }
7780    }
7781}
7782
7783#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7784#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7785#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7786/// Expression forms allowed as a function argument.
7787pub enum FunctionArgExpr {
7788    /// A normal expression argument.
7789    Expr(Expr),
7790    /// Qualified wildcard, e.g. `alias.*` or `schema.table.*`.
7791    QualifiedWildcard(ObjectName),
7792    /// An unqualified `*` wildcard.
7793    Wildcard,
7794    /// An unqualified `*` wildcard with additional options, e.g. `* EXCLUDE(col)`.
7795    ///
7796    /// Used in Snowflake to support expressions like `HASH(* EXCLUDE(col))`.
7797    WildcardWithOptions(WildcardAdditionalOptions),
7798}
7799
7800impl From<Expr> for FunctionArgExpr {
7801    fn from(wildcard_expr: Expr) -> Self {
7802        match wildcard_expr {
7803            Expr::QualifiedWildcard(prefix, _) => Self::QualifiedWildcard(prefix),
7804            Expr::Wildcard(_) => Self::Wildcard,
7805            expr => Self::Expr(expr),
7806        }
7807    }
7808}
7809
7810impl fmt::Display for FunctionArgExpr {
7811    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7812        match self {
7813            FunctionArgExpr::Expr(expr) => write!(f, "{expr}"),
7814            FunctionArgExpr::QualifiedWildcard(prefix) => write!(f, "{prefix}.*"),
7815            FunctionArgExpr::Wildcard => f.write_str("*"),
7816            FunctionArgExpr::WildcardWithOptions(opts) => write!(f, "*{opts}"),
7817        }
7818    }
7819}
7820
7821#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7822#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7823#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7824/// Operator used to separate function arguments
7825pub enum FunctionArgOperator {
7826    /// function(arg1 = value1)
7827    Equals,
7828    /// function(arg1 => value1)
7829    RightArrow,
7830    /// function(arg1 := value1)
7831    Assignment,
7832    /// function(arg1 : value1)
7833    Colon,
7834    /// function(arg1 VALUE value1)
7835    Value,
7836}
7837
7838impl fmt::Display for FunctionArgOperator {
7839    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7840        match self {
7841            FunctionArgOperator::Equals => f.write_str("="),
7842            FunctionArgOperator::RightArrow => f.write_str("=>"),
7843            FunctionArgOperator::Assignment => f.write_str(":="),
7844            FunctionArgOperator::Colon => f.write_str(":"),
7845            FunctionArgOperator::Value => f.write_str("VALUE"),
7846        }
7847    }
7848}
7849
7850#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7851#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7852#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7853/// Forms of function arguments (named, expression-named, or positional).
7854pub enum FunctionArg {
7855    /// `name` is identifier
7856    ///
7857    /// Enabled when `Dialect::supports_named_fn_args_with_expr_name` returns 'false'
7858    Named {
7859        /// The identifier name of the argument.
7860        name: Ident,
7861        /// The argument expression or wildcard form.
7862        arg: FunctionArgExpr,
7863        /// The operator separating name and value.
7864        operator: FunctionArgOperator,
7865    },
7866    /// `name` is arbitrary expression
7867    ///
7868    /// Enabled when `Dialect::supports_named_fn_args_with_expr_name` returns 'true'
7869    ExprNamed {
7870        /// The expression used as the argument name.
7871        name: Expr,
7872        /// The argument expression or wildcard form.
7873        arg: FunctionArgExpr,
7874        /// The operator separating name and value.
7875        operator: FunctionArgOperator,
7876    },
7877    /// An unnamed argument (positional), given by expression or wildcard.
7878    Unnamed(FunctionArgExpr),
7879}
7880
7881impl fmt::Display for FunctionArg {
7882    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7883        match self {
7884            FunctionArg::Named {
7885                name,
7886                arg,
7887                operator,
7888            } => write!(f, "{name} {operator} {arg}"),
7889            FunctionArg::ExprNamed {
7890                name,
7891                arg,
7892                operator,
7893            } => write!(f, "{name} {operator} {arg}"),
7894            FunctionArg::Unnamed(unnamed_arg) => write!(f, "{unnamed_arg}"),
7895        }
7896    }
7897}
7898
7899#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7900#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7901#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7902/// Which cursor(s) to close.
7903pub enum CloseCursor {
7904    /// Close all cursors.
7905    All,
7906    /// Close a specific cursor by name.
7907    Specific {
7908        /// The name of the cursor to close.
7909        name: Ident,
7910    },
7911}
7912
7913impl fmt::Display for CloseCursor {
7914    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7915        match self {
7916            CloseCursor::All => write!(f, "ALL"),
7917            CloseCursor::Specific { name } => write!(f, "{name}"),
7918        }
7919    }
7920}
7921
7922/// A Drop Domain statement
7923#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7924#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7925#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7926pub struct DropDomain {
7927    /// Whether to drop the domain if it exists
7928    pub if_exists: bool,
7929    /// The name of the domain to drop
7930    pub name: ObjectName,
7931    /// The behavior to apply when dropping the domain
7932    pub drop_behavior: Option<DropBehavior>,
7933}
7934
7935/// A constant of form `<data_type> 'value'`.
7936/// This can represent ANSI SQL `DATE`, `TIME`, and `TIMESTAMP` literals (such as `DATE '2020-01-01'`),
7937/// as well as constants of other types (a non-standard PostgreSQL extension).
7938#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7939#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7940#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7941pub struct TypedString {
7942    /// The data type of the typed string (e.g. DATE, TIME, TIMESTAMP).
7943    pub data_type: DataType,
7944    /// The value of the constant.
7945    /// Hint: you can unwrap the string value using `value.into_string()`.
7946    pub value: ValueWithSpan,
7947    /// Flags whether this TypedString uses the [ODBC syntax].
7948    ///
7949    /// Example:
7950    /// ```sql
7951    /// -- An ODBC date literal:
7952    /// SELECT {d '2025-07-16'}
7953    /// -- This is equivalent to the standard ANSI SQL literal:
7954    /// SELECT DATE '2025-07-16'
7955    ///
7956    /// [ODBC syntax]: https://learn.microsoft.com/en-us/sql/odbc/reference/develop-app/date-time-and-timestamp-literals?view=sql-server-2017
7957    pub uses_odbc_syntax: bool,
7958}
7959
7960impl fmt::Display for TypedString {
7961    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7962        let data_type = &self.data_type;
7963        let value = &self.value;
7964        match self.uses_odbc_syntax {
7965            false => {
7966                write!(f, "{data_type}")?;
7967                write!(f, " {value}")
7968            }
7969            true => {
7970                let prefix = match data_type {
7971                    DataType::Date => "d",
7972                    DataType::Time(..) => "t",
7973                    DataType::Timestamp(..) => "ts",
7974                    _ => "?",
7975                };
7976                write!(f, "{{{prefix} {value}}}")
7977            }
7978        }
7979    }
7980}
7981
7982/// A function call
7983#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
7984#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7985#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
7986pub struct Function {
7987    /// The function name (may be qualified).
7988    pub name: ObjectName,
7989    /// Flags whether this function call uses the [ODBC syntax].
7990    ///
7991    /// Example:
7992    /// ```sql
7993    /// SELECT {fn CONCAT('foo', 'bar')}
7994    /// ```
7995    ///
7996    /// [ODBC syntax]: https://learn.microsoft.com/en-us/sql/odbc/reference/develop-app/scalar-function-calls?view=sql-server-2017
7997    pub uses_odbc_syntax: bool,
7998    /// The parameters to the function, including any options specified within the
7999    /// delimiting parentheses.
8000    ///
8001    /// Example:
8002    /// ```plaintext
8003    /// HISTOGRAM(0.5, 0.6)(x, y)
8004    /// ```
8005    ///
8006    /// [ClickHouse](https://clickhouse.com/docs/en/sql-reference/aggregate-functions/parametric-functions)
8007    pub parameters: FunctionArguments,
8008    /// The arguments to the function, including any options specified within the
8009    /// delimiting parentheses.
8010    pub args: FunctionArguments,
8011    /// e.g. `x > 5` in `COUNT(x) FILTER (WHERE x > 5)`
8012    pub filter: Option<Box<Expr>>,
8013    /// Indicates how `NULL`s should be handled in the calculation.
8014    ///
8015    /// Example:
8016    /// ```plaintext
8017    /// FIRST_VALUE( <expr> ) [ { IGNORE | RESPECT } NULLS ] OVER ...
8018    /// ```
8019    ///
8020    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/functions/first_value)
8021    pub null_treatment: Option<NullTreatment>,
8022    /// The `OVER` clause, indicating a window function call.
8023    pub over: Option<WindowType>,
8024    /// A clause used with certain aggregate functions to control the ordering
8025    /// within grouped sets before the function is applied.
8026    ///
8027    /// Syntax:
8028    /// ```plaintext
8029    /// <aggregate_function>(expression) WITHIN GROUP (ORDER BY key [ASC | DESC], ...)
8030    /// ```
8031    pub within_group: Vec<OrderByExpr>,
8032}
8033
8034impl fmt::Display for Function {
8035    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8036        if self.uses_odbc_syntax {
8037            write!(f, "{{fn ")?;
8038        }
8039
8040        write!(f, "{}{}{}", self.name, self.parameters, self.args)?;
8041
8042        if !self.within_group.is_empty() {
8043            write!(
8044                f,
8045                " WITHIN GROUP (ORDER BY {})",
8046                display_comma_separated(&self.within_group)
8047            )?;
8048        }
8049
8050        if let Some(filter_cond) = &self.filter {
8051            write!(f, " FILTER (WHERE {filter_cond})")?;
8052        }
8053
8054        if let Some(null_treatment) = &self.null_treatment {
8055            write!(f, " {null_treatment}")?;
8056        }
8057
8058        if let Some(o) = &self.over {
8059            f.write_str(" OVER ")?;
8060            o.fmt(f)?;
8061        }
8062
8063        if self.uses_odbc_syntax {
8064            write!(f, "}}")?;
8065        }
8066
8067        Ok(())
8068    }
8069}
8070
8071/// The arguments passed to a function call.
8072#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8073#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8074#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8075pub enum FunctionArguments {
8076    /// Used for special functions like `CURRENT_TIMESTAMP` that are invoked
8077    /// without parentheses.
8078    None,
8079    /// On some dialects, a subquery can be passed without surrounding
8080    /// parentheses if it's the sole argument to the function.
8081    Subquery(Box<Query>),
8082    /// A normal function argument list, including any clauses within it such as
8083    /// `DISTINCT` or `ORDER BY`.
8084    List(FunctionArgumentList),
8085}
8086
8087impl fmt::Display for FunctionArguments {
8088    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8089        match self {
8090            FunctionArguments::None => Ok(()),
8091            FunctionArguments::Subquery(query) => write!(f, "({query})"),
8092            FunctionArguments::List(args) => write!(f, "({args})"),
8093        }
8094    }
8095}
8096
8097/// This represents everything inside the parentheses when calling a function.
8098#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8099#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8100#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8101pub struct FunctionArgumentList {
8102    /// `[ ALL | DISTINCT ]`
8103    pub duplicate_treatment: Option<DuplicateTreatment>,
8104    /// The function arguments.
8105    pub args: Vec<FunctionArg>,
8106    /// Additional clauses specified within the argument list.
8107    pub clauses: Vec<FunctionArgumentClause>,
8108}
8109
8110impl fmt::Display for FunctionArgumentList {
8111    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8112        if let Some(duplicate_treatment) = self.duplicate_treatment {
8113            write!(f, "{duplicate_treatment} ")?;
8114        }
8115        write!(f, "{}", display_comma_separated(&self.args))?;
8116        if !self.clauses.is_empty() {
8117            if !self.args.is_empty() {
8118                write!(f, " ")?;
8119            }
8120            write!(f, "{}", display_separated(&self.clauses, " "))?;
8121        }
8122        Ok(())
8123    }
8124}
8125
8126#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8127#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8128#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8129/// Clauses that can appear inside a function argument list.
8130pub enum FunctionArgumentClause {
8131    /// Indicates how `NULL`s should be handled in the calculation, e.g. in `FIRST_VALUE` on [BigQuery].
8132    ///
8133    /// Syntax:
8134    /// ```plaintext
8135    /// { IGNORE | RESPECT } NULLS ]
8136    /// ```
8137    ///
8138    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/navigation_functions#first_value
8139    IgnoreOrRespectNulls(NullTreatment),
8140    /// Specifies the the ordering for some ordered set aggregates, e.g. `ARRAY_AGG` on [BigQuery].
8141    ///
8142    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#array_agg
8143    OrderBy(Vec<OrderByExpr>),
8144    /// Specifies a limit for the `ARRAY_AGG` and `ARRAY_CONCAT_AGG` functions on BigQuery.
8145    Limit(Expr),
8146    /// Specifies the behavior on overflow of the `LISTAGG` function.
8147    ///
8148    /// See <https://trino.io/docs/current/functions/aggregate.html>.
8149    OnOverflow(ListAggOnOverflow),
8150    /// Specifies a minimum or maximum bound on the input to [`ANY_VALUE`] on BigQuery.
8151    ///
8152    /// Syntax:
8153    /// ```plaintext
8154    /// HAVING { MAX | MIN } expression
8155    /// ```
8156    ///
8157    /// [`ANY_VALUE`]: https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#any_value
8158    Having(HavingBound),
8159    /// The `SEPARATOR` clause to the [`GROUP_CONCAT`] function in MySQL.
8160    ///
8161    /// [`GROUP_CONCAT`]: https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat
8162    Separator(ValueWithSpan),
8163    /// The `ON NULL` clause for some JSON functions.
8164    ///
8165    /// [MSSQL `JSON_ARRAY`](https://learn.microsoft.com/en-us/sql/t-sql/functions/json-array-transact-sql?view=sql-server-ver16)
8166    /// [MSSQL `JSON_OBJECT`](https://learn.microsoft.com/en-us/sql/t-sql/functions/json-object-transact-sql?view=sql-server-ver16>)
8167    /// [PostgreSQL JSON functions](https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-JSON-PROCESSING)
8168    JsonNullClause(JsonNullClause),
8169    /// The `RETURNING` clause for some JSON functions in PostgreSQL
8170    ///
8171    /// [`JSON_OBJECT`](https://www.postgresql.org/docs/current/functions-json.html#:~:text=json_object)
8172    JsonReturningClause(JsonReturningClause),
8173}
8174
8175impl fmt::Display for FunctionArgumentClause {
8176    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8177        match self {
8178            FunctionArgumentClause::IgnoreOrRespectNulls(null_treatment) => {
8179                write!(f, "{null_treatment}")
8180            }
8181            FunctionArgumentClause::OrderBy(order_by) => {
8182                write!(f, "ORDER BY {}", display_comma_separated(order_by))
8183            }
8184            FunctionArgumentClause::Limit(limit) => write!(f, "LIMIT {limit}"),
8185            FunctionArgumentClause::OnOverflow(on_overflow) => write!(f, "{on_overflow}"),
8186            FunctionArgumentClause::Having(bound) => write!(f, "{bound}"),
8187            FunctionArgumentClause::Separator(sep) => write!(f, "SEPARATOR {sep}"),
8188            FunctionArgumentClause::JsonNullClause(null_clause) => write!(f, "{null_clause}"),
8189            FunctionArgumentClause::JsonReturningClause(returning_clause) => {
8190                write!(f, "{returning_clause}")
8191            }
8192        }
8193    }
8194}
8195
8196/// A method call
8197#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8198#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8199#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8200pub struct Method {
8201    /// The expression on which the method is invoked.
8202    pub expr: Box<Expr>,
8203    // always non-empty
8204    /// The sequence of chained method calls.
8205    pub method_chain: Vec<Function>,
8206}
8207
8208impl fmt::Display for Method {
8209    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8210        write!(
8211            f,
8212            "{}.{}",
8213            self.expr,
8214            display_separated(&self.method_chain, ".")
8215        )
8216    }
8217}
8218
8219#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8220#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8221#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8222/// How duplicate values are treated inside function argument lists.
8223pub enum DuplicateTreatment {
8224    /// Consider only unique values.
8225    Distinct,
8226    /// Retain all duplicate values (the default).
8227    All,
8228}
8229
8230impl fmt::Display for DuplicateTreatment {
8231    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8232        match self {
8233            DuplicateTreatment::Distinct => write!(f, "DISTINCT"),
8234            DuplicateTreatment::All => write!(f, "ALL"),
8235        }
8236    }
8237}
8238
8239#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8240#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8241#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8242/// How the `ANALYZE`/`EXPLAIN ANALYZE` format is specified.
8243pub enum AnalyzeFormatKind {
8244    /// Format provided as a keyword, e.g. `FORMAT JSON`.
8245    Keyword(AnalyzeFormat),
8246    /// Format provided as an assignment, e.g. `FORMAT=JSON`.
8247    Assignment(AnalyzeFormat),
8248}
8249
8250impl fmt::Display for AnalyzeFormatKind {
8251    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8252        match self {
8253            AnalyzeFormatKind::Keyword(format) => write!(f, "FORMAT {format}"),
8254            AnalyzeFormatKind::Assignment(format) => write!(f, "FORMAT={format}"),
8255        }
8256    }
8257}
8258
8259#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8260#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8261#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8262/// Output formats supported for `ANALYZE`/`EXPLAIN ANALYZE`.
8263pub enum AnalyzeFormat {
8264    /// Plain text format.
8265    TEXT,
8266    /// Graphviz DOT format.
8267    GRAPHVIZ,
8268    /// JSON format.
8269    JSON,
8270    /// Traditional explain output.
8271    TRADITIONAL,
8272    /// Tree-style explain output.
8273    TREE,
8274}
8275
8276impl fmt::Display for AnalyzeFormat {
8277    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
8278        f.write_str(match self {
8279            AnalyzeFormat::TEXT => "TEXT",
8280            AnalyzeFormat::GRAPHVIZ => "GRAPHVIZ",
8281            AnalyzeFormat::JSON => "JSON",
8282            AnalyzeFormat::TRADITIONAL => "TRADITIONAL",
8283            AnalyzeFormat::TREE => "TREE",
8284        })
8285    }
8286}
8287
8288/// External table's available file format
8289#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8290#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8291#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8292pub enum FileFormat {
8293    /// Text file format.
8294    TEXTFILE,
8295    /// Sequence file format.
8296    SEQUENCEFILE,
8297    /// ORC file format.
8298    ORC,
8299    /// Parquet file format.
8300    PARQUET,
8301    /// Avro file format.
8302    AVRO,
8303    /// RCFile format.
8304    RCFILE,
8305    /// JSON file format.
8306    JSONFILE,
8307}
8308
8309impl fmt::Display for FileFormat {
8310    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8311        use self::FileFormat::*;
8312        f.write_str(match self {
8313            TEXTFILE => "TEXTFILE",
8314            SEQUENCEFILE => "SEQUENCEFILE",
8315            ORC => "ORC",
8316            PARQUET => "PARQUET",
8317            AVRO => "AVRO",
8318            RCFILE => "RCFILE",
8319            JSONFILE => "JSONFILE",
8320        })
8321    }
8322}
8323
8324/// The `ON OVERFLOW` clause of a LISTAGG invocation
8325#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8326#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8327#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8328pub enum ListAggOnOverflow {
8329    /// `ON OVERFLOW ERROR`
8330    Error,
8331
8332    /// `ON OVERFLOW TRUNCATE [ <filler> ] WITH[OUT] COUNT`
8333    Truncate {
8334        /// Optional filler expression used when truncating.
8335        filler: Option<Box<Expr>>,
8336        /// Whether to include a count when truncating.
8337        with_count: bool,
8338    },
8339}
8340
8341impl fmt::Display for ListAggOnOverflow {
8342    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8343        write!(f, "ON OVERFLOW")?;
8344        match self {
8345            ListAggOnOverflow::Error => write!(f, " ERROR"),
8346            ListAggOnOverflow::Truncate { filler, with_count } => {
8347                write!(f, " TRUNCATE")?;
8348                if let Some(filler) = filler {
8349                    write!(f, " {filler}")?;
8350                }
8351                if *with_count {
8352                    write!(f, " WITH")?;
8353                } else {
8354                    write!(f, " WITHOUT")?;
8355                }
8356                write!(f, " COUNT")
8357            }
8358        }
8359    }
8360}
8361
8362/// The `HAVING` clause in a call to `ANY_VALUE` on BigQuery.
8363#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8364#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8365#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8366pub struct HavingBound(pub HavingBoundKind, pub Expr);
8367
8368impl fmt::Display for HavingBound {
8369    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8370        write!(f, "HAVING {} {}", self.0, self.1)
8371    }
8372}
8373
8374#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8375#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8376#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8377/// Which bound is used in a HAVING clause for ANY_VALUE on BigQuery.
8378pub enum HavingBoundKind {
8379    /// The minimum bound.
8380    Min,
8381    /// The maximum bound.
8382    Max,
8383}
8384
8385impl fmt::Display for HavingBoundKind {
8386    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8387        match self {
8388            HavingBoundKind::Min => write!(f, "MIN"),
8389            HavingBoundKind::Max => write!(f, "MAX"),
8390        }
8391    }
8392}
8393
8394#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8395#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8396#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8397/// Types of database objects referenced by DDL statements.
8398pub enum ObjectType {
8399    /// A collation.
8400    Collation,
8401    /// A table.
8402    Table,
8403    /// A view.
8404    View,
8405    /// A materialized view.
8406    MaterializedView,
8407    /// An index.
8408    Index,
8409    /// A schema.
8410    Schema,
8411    /// A database.
8412    Database,
8413    /// A role.
8414    Role,
8415    /// A sequence.
8416    Sequence,
8417    /// A stage.
8418    Stage,
8419    /// A type definition.
8420    Type,
8421    /// A user.
8422    User,
8423    /// A stream.
8424    Stream,
8425}
8426
8427impl fmt::Display for ObjectType {
8428    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8429        f.write_str(match self {
8430            ObjectType::Collation => "COLLATION",
8431            ObjectType::Table => "TABLE",
8432            ObjectType::View => "VIEW",
8433            ObjectType::MaterializedView => "MATERIALIZED VIEW",
8434            ObjectType::Index => "INDEX",
8435            ObjectType::Schema => "SCHEMA",
8436            ObjectType::Database => "DATABASE",
8437            ObjectType::Role => "ROLE",
8438            ObjectType::Sequence => "SEQUENCE",
8439            ObjectType::Stage => "STAGE",
8440            ObjectType::Type => "TYPE",
8441            ObjectType::User => "USER",
8442            ObjectType::Stream => "STREAM",
8443        })
8444    }
8445}
8446
8447#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8448#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8449#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8450/// Types supported by `KILL` statements.
8451pub enum KillType {
8452    /// Kill a connection.
8453    Connection,
8454    /// Kill a running query.
8455    Query,
8456    /// Kill a mutation (ClickHouse).
8457    Mutation,
8458}
8459
8460impl fmt::Display for KillType {
8461    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8462        f.write_str(match self {
8463            // MySQL
8464            KillType::Connection => "CONNECTION",
8465            KillType::Query => "QUERY",
8466            // Clickhouse supports Mutation
8467            KillType::Mutation => "MUTATION",
8468        })
8469    }
8470}
8471
8472#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8473#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8474#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8475/// Distribution style options for Hive tables.
8476pub enum HiveDistributionStyle {
8477    /// Partitioned distribution with the given columns.
8478    PARTITIONED {
8479        /// Columns used for partitioning.
8480        columns: Vec<ColumnDef>,
8481    },
8482    /// Skewed distribution definition.
8483    SKEWED {
8484        /// Columns participating in the skew definition.
8485        columns: Vec<ColumnDef>,
8486        /// Columns listed in the `ON` clause for skewing.
8487        on: Vec<ColumnDef>,
8488        /// Whether skewed data is stored as directories.
8489        stored_as_directories: bool,
8490    },
8491    /// No distribution style specified.
8492    NONE,
8493}
8494
8495#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8496#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8497#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8498/// Row format specification for Hive tables (SERDE or DELIMITED).
8499pub enum HiveRowFormat {
8500    /// SerDe class specification with the implementing class name.
8501    SERDE {
8502        /// The SerDe implementation class name.
8503        class: String,
8504    },
8505    /// Delimited row format with one or more delimiter specifications.
8506    DELIMITED {
8507        /// The list of delimiters used for delimiting fields/lines.
8508        delimiters: Vec<HiveRowDelimiter>,
8509    },
8510}
8511
8512#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8513#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8514#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8515/// Format specification for `LOAD DATA` Hive operations.
8516pub struct HiveLoadDataFormat {
8517    /// SerDe expression used for the table.
8518    pub serde: Expr,
8519    /// Input format expression.
8520    pub input_format: Expr,
8521}
8522
8523#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8524#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8525#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8526/// A single row delimiter specification for Hive `ROW FORMAT`.
8527pub struct HiveRowDelimiter {
8528    /// The delimiter kind (fields/lines/etc.).
8529    pub delimiter: HiveDelimiter,
8530    /// The delimiter character identifier.
8531    pub char: Ident,
8532}
8533
8534impl fmt::Display for HiveRowDelimiter {
8535    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8536        write!(f, "{} ", self.delimiter)?;
8537        write!(f, "{}", self.char)
8538    }
8539}
8540
8541#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8542#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8543#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8544/// Kind of delimiter used in Hive `ROW FORMAT` definitions.
8545pub enum HiveDelimiter {
8546    /// Fields terminated by a delimiter.
8547    FieldsTerminatedBy,
8548    /// Fields escaped by a character.
8549    FieldsEscapedBy,
8550    /// Collection items terminated by a delimiter.
8551    CollectionItemsTerminatedBy,
8552    /// Map keys terminated by a delimiter.
8553    MapKeysTerminatedBy,
8554    /// Lines terminated by a delimiter.
8555    LinesTerminatedBy,
8556    /// Null represented by a specific token.
8557    NullDefinedAs,
8558}
8559
8560impl fmt::Display for HiveDelimiter {
8561    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8562        use HiveDelimiter::*;
8563        f.write_str(match self {
8564            FieldsTerminatedBy => "FIELDS TERMINATED BY",
8565            FieldsEscapedBy => "ESCAPED BY",
8566            CollectionItemsTerminatedBy => "COLLECTION ITEMS TERMINATED BY",
8567            MapKeysTerminatedBy => "MAP KEYS TERMINATED BY",
8568            LinesTerminatedBy => "LINES TERMINATED BY",
8569            NullDefinedAs => "NULL DEFINED AS",
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))]
8577/// Describe output format options for Hive `DESCRIBE`/`EXPLAIN`.
8578pub enum HiveDescribeFormat {
8579    /// Extended describe output.
8580    Extended,
8581    /// Formatted describe output.
8582    Formatted,
8583}
8584
8585impl fmt::Display for HiveDescribeFormat {
8586    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8587        use HiveDescribeFormat::*;
8588        f.write_str(match self {
8589            Extended => "EXTENDED",
8590            Formatted => "FORMATTED",
8591        })
8592    }
8593}
8594
8595#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8596#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8597#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8598/// Aliases accepted for describe-style commands.
8599pub enum DescribeAlias {
8600    /// `DESCRIBE` alias.
8601    Describe,
8602    /// `EXPLAIN` alias.
8603    Explain,
8604    /// `DESC` alias.
8605    Desc,
8606}
8607
8608impl fmt::Display for DescribeAlias {
8609    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8610        use DescribeAlias::*;
8611        f.write_str(match self {
8612            Describe => "DESCRIBE",
8613            Explain => "EXPLAIN",
8614            Desc => "DESC",
8615        })
8616    }
8617}
8618
8619#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8620#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8621#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8622#[allow(clippy::large_enum_variant)]
8623/// Hive input/output format specification used in `CREATE TABLE`.
8624pub enum HiveIOFormat {
8625    /// Generic IO format with separate input and output expressions.
8626    IOF {
8627        /// Expression for the input format.
8628        input_format: Expr,
8629        /// Expression for the output format.
8630        output_format: Expr,
8631    },
8632    /// File format wrapper referencing a `FileFormat` variant.
8633    FileFormat {
8634        /// The file format used for storage.
8635        format: FileFormat,
8636    },
8637}
8638
8639#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
8640#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8641#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8642/// Hive table format and storage-related options.
8643pub struct HiveFormat {
8644    /// Optional row format specification.
8645    pub row_format: Option<HiveRowFormat>,
8646    /// Optional SerDe properties expressed as SQL options.
8647    pub serde_properties: Option<Vec<SqlOption>>,
8648    /// Optional input/output storage format details.
8649    pub storage: Option<HiveIOFormat>,
8650    /// Optional location (URI or path) for table data.
8651    pub location: Option<String>,
8652}
8653
8654#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8655#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8656#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8657/// A clustered index column specification.
8658pub struct ClusteredIndex {
8659    /// Column identifier for the clustered index entry.
8660    pub name: Ident,
8661    /// Optional sort direction: `Some(true)` for ASC, `Some(false)` for DESC, `None` for unspecified.
8662    pub asc: Option<bool>,
8663}
8664
8665impl fmt::Display for ClusteredIndex {
8666    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8667        write!(f, "{}", self.name)?;
8668        match self.asc {
8669            Some(true) => write!(f, " ASC"),
8670            Some(false) => write!(f, " DESC"),
8671            _ => Ok(()),
8672        }
8673    }
8674}
8675
8676#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8677#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8678#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8679/// Clustered options used for `CREATE TABLE` clustered/indexed storage.
8680pub enum TableOptionsClustered {
8681    /// Use a columnstore index.
8682    ColumnstoreIndex,
8683    /// Columnstore index with an explicit ordering of columns.
8684    ColumnstoreIndexOrder(Vec<Ident>),
8685    /// A named clustered index with one or more columns.
8686    Index(Vec<ClusteredIndex>),
8687}
8688
8689impl fmt::Display for TableOptionsClustered {
8690    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8691        match self {
8692            TableOptionsClustered::ColumnstoreIndex => {
8693                write!(f, "CLUSTERED COLUMNSTORE INDEX")
8694            }
8695            TableOptionsClustered::ColumnstoreIndexOrder(values) => {
8696                write!(
8697                    f,
8698                    "CLUSTERED COLUMNSTORE INDEX ORDER ({})",
8699                    display_comma_separated(values)
8700                )
8701            }
8702            TableOptionsClustered::Index(values) => {
8703                write!(f, "CLUSTERED INDEX ({})", display_comma_separated(values))
8704            }
8705        }
8706    }
8707}
8708
8709/// Specifies which partition the boundary values on table partitioning belongs to.
8710#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Hash)]
8711#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8712#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8713pub enum PartitionRangeDirection {
8714    /// LEFT range direction.
8715    Left,
8716    /// RIGHT range direction.
8717    Right,
8718}
8719
8720#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8721#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8722#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8723/// SQL option syntax used in table and server definitions.
8724pub enum SqlOption {
8725    /// Clustered represents the clustered version of table storage for MSSQL.
8726    ///
8727    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#TableOptions>
8728    Clustered(TableOptionsClustered),
8729    /// Single identifier options, e.g. `HEAP` for MSSQL.
8730    ///
8731    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#TableOptions>
8732    Ident(Ident),
8733    /// Any option that consists of a key value pair where the value is an expression. e.g.
8734    ///
8735    ///   WITH(DISTRIBUTION = ROUND_ROBIN)
8736    KeyValue {
8737        /// The option key identifier.
8738        key: Ident,
8739        /// The expression value for the option.
8740        value: Expr,
8741    },
8742    /// One or more table partitions and represents which partition the boundary values belong to,
8743    /// e.g.
8744    ///
8745    ///   PARTITION (id RANGE LEFT FOR VALUES (10, 20, 30, 40))
8746    ///
8747    /// <https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-azure-sql-data-warehouse?view=aps-pdw-2016-au7#TablePartitionOptions>
8748    Partition {
8749        /// The partition column name.
8750        column_name: Ident,
8751        /// Optional direction for the partition range (LEFT/RIGHT).
8752        range_direction: Option<PartitionRangeDirection>,
8753        /// Values that define the partition boundaries.
8754        for_values: Vec<Expr>,
8755    },
8756    /// Comment parameter (supports `=` and no `=` syntax)
8757    Comment(CommentDef),
8758    /// MySQL TableSpace option
8759    /// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
8760    TableSpace(TablespaceOption),
8761    /// An option representing a key value pair, where the value is a parenthesized list and with an optional name
8762    /// e.g.
8763    ///
8764    ///   UNION  = (tbl_name\[,tbl_name\]...) <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
8765    ///   ENGINE = ReplicatedMergeTree('/table_name','{replica}', ver) <https://clickhouse.com/docs/engines/table-engines/mergetree-family/replication>
8766    ///   ENGINE = SummingMergeTree(\[columns\]) <https://clickhouse.com/docs/engines/table-engines/mergetree-family/summingmergetree>
8767    NamedParenthesizedList(NamedParenthesizedList),
8768}
8769
8770impl fmt::Display for SqlOption {
8771    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8772        match self {
8773            SqlOption::Clustered(c) => write!(f, "{c}"),
8774            SqlOption::Ident(ident) => {
8775                write!(f, "{ident}")
8776            }
8777            SqlOption::KeyValue { key: name, value } => {
8778                write!(f, "{name} = {value}")
8779            }
8780            SqlOption::Partition {
8781                column_name,
8782                range_direction,
8783                for_values,
8784            } => {
8785                let direction = match range_direction {
8786                    Some(PartitionRangeDirection::Left) => " LEFT",
8787                    Some(PartitionRangeDirection::Right) => " RIGHT",
8788                    None => "",
8789                };
8790
8791                write!(
8792                    f,
8793                    "PARTITION ({} RANGE{} FOR VALUES ({}))",
8794                    column_name,
8795                    direction,
8796                    display_comma_separated(for_values)
8797                )
8798            }
8799            SqlOption::TableSpace(tablespace_option) => {
8800                write!(f, "TABLESPACE {}", tablespace_option.name)?;
8801                match tablespace_option.storage {
8802                    Some(StorageType::Disk) => write!(f, " STORAGE DISK"),
8803                    Some(StorageType::Memory) => write!(f, " STORAGE MEMORY"),
8804                    None => Ok(()),
8805                }
8806            }
8807            SqlOption::Comment(comment) => match comment {
8808                CommentDef::WithEq(comment) => {
8809                    write!(f, "COMMENT = '{comment}'")
8810                }
8811                CommentDef::WithoutEq(comment) => {
8812                    write!(f, "COMMENT '{comment}'")
8813                }
8814            },
8815            SqlOption::NamedParenthesizedList(value) => {
8816                write!(f, "{} = ", value.key)?;
8817                if let Some(key) = &value.name {
8818                    write!(f, "{key}")?;
8819                }
8820                if !value.values.is_empty() {
8821                    write!(f, "({})", display_comma_separated(&value.values))?
8822                }
8823                Ok(())
8824            }
8825        }
8826    }
8827}
8828
8829#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
8830#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8831#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8832/// Storage type options for a tablespace.
8833pub enum StorageType {
8834    /// Store on disk.
8835    Disk,
8836    /// Store in memory.
8837    Memory,
8838}
8839
8840#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
8841#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8842#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8843/// MySql TableSpace option
8844/// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
8845pub struct TablespaceOption {
8846    /// Name of the tablespace.
8847    pub name: String,
8848    /// Optional storage type for the tablespace.
8849    pub storage: Option<StorageType>,
8850}
8851
8852#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8853#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8854#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8855/// A key/value identifier pair used for secret or key-based options.
8856pub struct SecretOption {
8857    /// The option key identifier.
8858    pub key: Ident,
8859    /// The option value identifier.
8860    pub value: Ident,
8861}
8862
8863impl fmt::Display for SecretOption {
8864    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8865        write!(f, "{} {}", self.key, self.value)
8866    }
8867}
8868
8869/// A `CREATE SERVER` statement.
8870///
8871/// [PostgreSQL Documentation](https://www.postgresql.org/docs/current/sql-createserver.html)
8872#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8873#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8874#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8875pub struct CreateServerStatement {
8876    /// The server name.
8877    pub name: ObjectName,
8878    /// Whether `IF NOT EXISTS` was specified.
8879    pub if_not_exists: bool,
8880    /// Optional server type identifier.
8881    pub server_type: Option<Ident>,
8882    /// Optional server version identifier.
8883    pub version: Option<Ident>,
8884    /// Foreign-data wrapper object name.
8885    pub foreign_data_wrapper: ObjectName,
8886    /// Optional list of server options.
8887    pub options: Option<Vec<CreateServerOption>>,
8888}
8889
8890impl fmt::Display for CreateServerStatement {
8891    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8892        let CreateServerStatement {
8893            name,
8894            if_not_exists,
8895            server_type,
8896            version,
8897            foreign_data_wrapper,
8898            options,
8899        } = self;
8900
8901        write!(
8902            f,
8903            "CREATE SERVER {if_not_exists}{name} ",
8904            if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
8905        )?;
8906
8907        if let Some(st) = server_type {
8908            write!(f, "TYPE {st} ")?;
8909        }
8910
8911        if let Some(v) = version {
8912            write!(f, "VERSION {v} ")?;
8913        }
8914
8915        write!(f, "FOREIGN DATA WRAPPER {foreign_data_wrapper}")?;
8916
8917        if let Some(o) = options {
8918            write!(f, " OPTIONS ({o})", o = display_comma_separated(o))?;
8919        }
8920
8921        Ok(())
8922    }
8923}
8924
8925/// A key/value option for `CREATE SERVER`.
8926#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8927#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8928#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8929pub struct CreateServerOption {
8930    /// Option key identifier.
8931    pub key: Ident,
8932    /// Option value identifier.
8933    pub value: Ident,
8934}
8935
8936impl fmt::Display for CreateServerOption {
8937    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8938        write!(f, "{} {}", self.key, self.value)
8939    }
8940}
8941
8942#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8943#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8944#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8945/// Options supported by DuckDB for `ATTACH DATABASE`.
8946pub enum AttachDuckDBDatabaseOption {
8947    /// READ_ONLY option, optional boolean value.
8948    ReadOnly(Option<bool>),
8949    /// TYPE option specifying a database type identifier.
8950    Type(Ident),
8951}
8952
8953impl fmt::Display for AttachDuckDBDatabaseOption {
8954    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8955        match self {
8956            AttachDuckDBDatabaseOption::ReadOnly(Some(true)) => write!(f, "READ_ONLY true"),
8957            AttachDuckDBDatabaseOption::ReadOnly(Some(false)) => write!(f, "READ_ONLY false"),
8958            AttachDuckDBDatabaseOption::ReadOnly(None) => write!(f, "READ_ONLY"),
8959            AttachDuckDBDatabaseOption::Type(t) => write!(f, "TYPE {t}"),
8960        }
8961    }
8962}
8963
8964#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8965#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8966#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8967/// Mode for transactions: access mode or isolation level.
8968pub enum TransactionMode {
8969    /// Access mode for a transaction (e.g. `READ ONLY` / `READ WRITE`).
8970    AccessMode(TransactionAccessMode),
8971    /// Isolation level for a transaction (e.g. `SERIALIZABLE`).
8972    IsolationLevel(TransactionIsolationLevel),
8973}
8974
8975impl fmt::Display for TransactionMode {
8976    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8977        use TransactionMode::*;
8978        match self {
8979            AccessMode(access_mode) => write!(f, "{access_mode}"),
8980            IsolationLevel(iso_level) => write!(f, "ISOLATION LEVEL {iso_level}"),
8981        }
8982    }
8983}
8984
8985#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
8986#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8987#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
8988/// Transaction access mode (READ ONLY / READ WRITE).
8989pub enum TransactionAccessMode {
8990    /// READ ONLY access mode.
8991    ReadOnly,
8992    /// READ WRITE access mode.
8993    ReadWrite,
8994}
8995
8996impl fmt::Display for TransactionAccessMode {
8997    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
8998        use TransactionAccessMode::*;
8999        f.write_str(match self {
9000            ReadOnly => "READ ONLY",
9001            ReadWrite => "READ WRITE",
9002        })
9003    }
9004}
9005
9006#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9007#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9008#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9009/// Transaction isolation levels.
9010pub enum TransactionIsolationLevel {
9011    /// READ UNCOMMITTED isolation level.
9012    ReadUncommitted,
9013    /// READ COMMITTED isolation level.
9014    ReadCommitted,
9015    /// REPEATABLE READ isolation level.
9016    RepeatableRead,
9017    /// SERIALIZABLE isolation level.
9018    Serializable,
9019    /// SNAPSHOT isolation level.
9020    Snapshot,
9021}
9022
9023impl fmt::Display for TransactionIsolationLevel {
9024    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9025        use TransactionIsolationLevel::*;
9026        f.write_str(match self {
9027            ReadUncommitted => "READ UNCOMMITTED",
9028            ReadCommitted => "READ COMMITTED",
9029            RepeatableRead => "REPEATABLE READ",
9030            Serializable => "SERIALIZABLE",
9031            Snapshot => "SNAPSHOT",
9032        })
9033    }
9034}
9035
9036/// Modifier for the transaction in the `BEGIN` syntax
9037///
9038/// SQLite: <https://sqlite.org/lang_transaction.html>
9039/// MS-SQL: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql>
9040#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9041#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9042#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9043pub enum TransactionModifier {
9044    /// DEFERRED transaction modifier.
9045    Deferred,
9046    /// IMMEDIATE transaction modifier.
9047    Immediate,
9048    /// EXCLUSIVE transaction modifier.
9049    Exclusive,
9050    /// TRY block modifier (MS-SQL style TRY/CATCH).
9051    Try,
9052    /// CATCH block modifier (MS-SQL style TRY/CATCH).
9053    Catch,
9054}
9055
9056impl fmt::Display for TransactionModifier {
9057    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9058        use TransactionModifier::*;
9059        f.write_str(match self {
9060            Deferred => "DEFERRED",
9061            Immediate => "IMMEDIATE",
9062            Exclusive => "EXCLUSIVE",
9063            Try => "TRY",
9064            Catch => "CATCH",
9065        })
9066    }
9067}
9068
9069#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9070#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9071#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9072/// Filter forms usable in SHOW statements.
9073pub enum ShowStatementFilter {
9074    /// Filter using LIKE pattern.
9075    Like(String),
9076    /// Filter using ILIKE pattern.
9077    ILike(String),
9078    /// Filter using a WHERE expression.
9079    Where(Expr),
9080    /// Filter provided without a keyword (raw string).
9081    NoKeyword(String),
9082}
9083
9084impl fmt::Display for ShowStatementFilter {
9085    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9086        use ShowStatementFilter::*;
9087        match self {
9088            Like(pattern) => write!(f, "LIKE '{}'", value::escape_single_quote_string(pattern)),
9089            ILike(pattern) => write!(f, "ILIKE {}", value::escape_single_quote_string(pattern)),
9090            Where(expr) => write!(f, "WHERE {expr}"),
9091            NoKeyword(pattern) => write!(f, "'{}'", value::escape_single_quote_string(pattern)),
9092        }
9093    }
9094}
9095
9096#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9097#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9098#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9099/// Clause types used with SHOW ... IN/FROM.
9100pub enum ShowStatementInClause {
9101    /// Use the `IN` clause.
9102    IN,
9103    /// Use the `FROM` clause.
9104    FROM,
9105}
9106
9107impl fmt::Display for ShowStatementInClause {
9108    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9109        use ShowStatementInClause::*;
9110        match self {
9111            FROM => write!(f, "FROM"),
9112            IN => write!(f, "IN"),
9113        }
9114    }
9115}
9116
9117/// Sqlite specific syntax
9118///
9119/// See [Sqlite documentation](https://sqlite.org/lang_conflict.html)
9120/// for more details.
9121#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9122#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9123#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9124pub enum SqliteOnConflict {
9125    /// Use ROLLBACK on conflict.
9126    Rollback,
9127    /// Use ABORT on conflict.
9128    Abort,
9129    /// Use FAIL on conflict.
9130    Fail,
9131    /// Use IGNORE on conflict.
9132    Ignore,
9133    /// Use REPLACE on conflict.
9134    Replace,
9135}
9136
9137impl fmt::Display for SqliteOnConflict {
9138    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9139        use SqliteOnConflict::*;
9140        match self {
9141            Rollback => write!(f, "OR ROLLBACK"),
9142            Abort => write!(f, "OR ABORT"),
9143            Fail => write!(f, "OR FAIL"),
9144            Ignore => write!(f, "OR IGNORE"),
9145            Replace => write!(f, "OR REPLACE"),
9146        }
9147    }
9148}
9149
9150/// Mysql specific syntax
9151///
9152/// See [Mysql documentation](https://dev.mysql.com/doc/refman/8.0/en/replace.html)
9153/// See [Mysql documentation](https://dev.mysql.com/doc/refman/8.0/en/insert.html)
9154/// for more details.
9155#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9156#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9157#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9158pub enum MysqlInsertPriority {
9159    /// LOW_PRIORITY modifier for INSERT/REPLACE.
9160    LowPriority,
9161    /// DELAYED modifier for INSERT/REPLACE.
9162    Delayed,
9163    /// HIGH_PRIORITY modifier for INSERT/REPLACE.
9164    HighPriority,
9165}
9166
9167impl fmt::Display for crate::ast::MysqlInsertPriority {
9168    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9169        use MysqlInsertPriority::*;
9170        match self {
9171            LowPriority => write!(f, "LOW_PRIORITY"),
9172            Delayed => write!(f, "DELAYED"),
9173            HighPriority => write!(f, "HIGH_PRIORITY"),
9174        }
9175    }
9176}
9177
9178#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9179#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9180#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9181/// Source for the `COPY` command: a table or a query.
9182pub enum CopySource {
9183    /// Copy from a table with optional column list.
9184    Table {
9185        /// The name of the table to copy from.
9186        table_name: ObjectName,
9187        /// A list of column names to copy. Empty list means that all columns
9188        /// are copied.
9189        columns: Vec<Ident>,
9190    },
9191    /// Copy from the results of a query.
9192    Query(Box<Query>),
9193}
9194
9195#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9196#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9197#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9198/// Target for the `COPY` command: STDIN, STDOUT, a file, or a program.
9199pub enum CopyTarget {
9200    /// Use standard input as the source.
9201    Stdin,
9202    /// Use standard output as the target.
9203    Stdout,
9204    /// Read from or write to a file.
9205    File {
9206        /// The path name of the input or output file.
9207        filename: String,
9208    },
9209    /// Use a program as the source or target (shell command).
9210    Program {
9211        /// A command to execute
9212        command: String,
9213    },
9214}
9215
9216impl fmt::Display for CopyTarget {
9217    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9218        use CopyTarget::*;
9219        match self {
9220            Stdin => write!(f, "STDIN"),
9221            Stdout => write!(f, "STDOUT"),
9222            File { filename } => write!(f, "'{}'", value::escape_single_quote_string(filename)),
9223            Program { command } => write!(
9224                f,
9225                "PROGRAM '{}'",
9226                value::escape_single_quote_string(command)
9227            ),
9228        }
9229    }
9230}
9231
9232#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9233#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9234#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9235/// Action to take `ON COMMIT` for temporary tables.
9236pub enum OnCommit {
9237    /// Delete rows on commit.
9238    DeleteRows,
9239    /// Preserve rows on commit.
9240    PreserveRows,
9241    /// Drop the table on commit.
9242    Drop,
9243}
9244
9245/// An option in `COPY` statement.
9246///
9247/// <https://www.postgresql.org/docs/14/sql-copy.html>
9248#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9249#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9250#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9251pub enum CopyOption {
9252    /// FORMAT format_name
9253    Format(Ident),
9254    /// FREEZE \[ boolean \]
9255    Freeze(bool),
9256    /// DELIMITER 'delimiter_character'
9257    Delimiter(char),
9258    /// NULL 'null_string'
9259    Null(String),
9260    /// HEADER \[ boolean \]
9261    Header(bool),
9262    /// QUOTE 'quote_character'
9263    Quote(char),
9264    /// ESCAPE 'escape_character'
9265    Escape(char),
9266    /// FORCE_QUOTE { ( column_name [, ...] ) | * }
9267    ForceQuote(Vec<Ident>),
9268    /// FORCE_NOT_NULL ( column_name [, ...] )
9269    ForceNotNull(Vec<Ident>),
9270    /// FORCE_NULL ( column_name [, ...] )
9271    ForceNull(Vec<Ident>),
9272    /// ENCODING 'encoding_name'
9273    Encoding(String),
9274}
9275
9276impl fmt::Display for CopyOption {
9277    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9278        use CopyOption::*;
9279        match self {
9280            Format(name) => write!(f, "FORMAT {name}"),
9281            Freeze(true) => write!(f, "FREEZE"),
9282            Freeze(false) => write!(f, "FREEZE FALSE"),
9283            Delimiter(char) => write!(f, "DELIMITER '{char}'"),
9284            Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
9285            Header(true) => write!(f, "HEADER"),
9286            Header(false) => write!(f, "HEADER FALSE"),
9287            Quote(char) => write!(f, "QUOTE '{char}'"),
9288            Escape(char) => write!(f, "ESCAPE '{char}'"),
9289            ForceQuote(columns) => write!(f, "FORCE_QUOTE ({})", display_comma_separated(columns)),
9290            ForceNotNull(columns) => {
9291                write!(f, "FORCE_NOT_NULL ({})", display_comma_separated(columns))
9292            }
9293            ForceNull(columns) => write!(f, "FORCE_NULL ({})", display_comma_separated(columns)),
9294            Encoding(name) => write!(f, "ENCODING '{}'", value::escape_single_quote_string(name)),
9295        }
9296    }
9297}
9298
9299/// An option in `COPY` statement before PostgreSQL version 9.0.
9300///
9301/// [PostgreSQL](https://www.postgresql.org/docs/8.4/sql-copy.html)
9302/// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_COPY-alphabetical-parm-list.html)
9303#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9304#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9305#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9306pub enum CopyLegacyOption {
9307    /// ACCEPTANYDATE
9308    AcceptAnyDate,
9309    /// ACCEPTINVCHARS
9310    AcceptInvChars(Option<String>),
9311    /// ADDQUOTES
9312    AddQuotes,
9313    /// ALLOWOVERWRITE
9314    AllowOverwrite,
9315    /// BINARY
9316    Binary,
9317    /// BLANKSASNULL
9318    BlankAsNull,
9319    /// BZIP2
9320    Bzip2,
9321    /// CLEANPATH
9322    CleanPath,
9323    /// COMPUPDATE [ PRESET | { ON | TRUE } | { OFF | FALSE } ]
9324    CompUpdate {
9325        /// Whether the COMPUPDATE PRESET option was used.
9326        preset: bool,
9327        /// Optional enabled flag for COMPUPDATE.
9328        enabled: Option<bool>,
9329    },
9330    /// CSV ...
9331    Csv(Vec<CopyLegacyCsvOption>),
9332    /// DATEFORMAT \[ AS \] {'dateformat_string' | 'auto' }
9333    DateFormat(Option<String>),
9334    /// DELIMITER \[ AS \] 'delimiter_character'
9335    Delimiter(char),
9336    /// EMPTYASNULL
9337    EmptyAsNull,
9338    /// `ENCRYPTED \[ AUTO \]`
9339    Encrypted {
9340        /// Whether `AUTO` was specified for encryption.
9341        auto: bool,
9342    },
9343    /// ESCAPE
9344    Escape,
9345    /// EXTENSION 'extension-name'
9346    Extension(String),
9347    /// FIXEDWIDTH \[ AS \] 'fixedwidth-spec'
9348    FixedWidth(String),
9349    /// GZIP
9350    Gzip,
9351    /// HEADER
9352    Header,
9353    /// IAM_ROLE { DEFAULT | 'arn:aws:iam::123456789:role/role1' }
9354    IamRole(IamRoleKind),
9355    /// IGNOREHEADER \[ AS \] number_rows
9356    IgnoreHeader(u64),
9357    /// JSON \[ AS \] 'json_option'
9358    Json(Option<String>),
9359    /// MANIFEST \[ VERBOSE \]
9360    Manifest {
9361        /// Whether the MANIFEST is verbose.
9362        verbose: bool,
9363    },
9364    /// MAXFILESIZE \[ AS \] max-size \[ MB | GB \]
9365    MaxFileSize(FileSize),
9366    /// `NULL \[ AS \] 'null_string'`
9367    Null(String),
9368    /// `PARALLEL [ { ON | TRUE } | { OFF | FALSE } ]`
9369    Parallel(Option<bool>),
9370    /// PARQUET
9371    Parquet,
9372    /// PARTITION BY ( column_name [, ... ] ) \[ INCLUDE \]
9373    PartitionBy(UnloadPartitionBy),
9374    /// REGION \[ AS \] 'aws-region' }
9375    Region(String),
9376    /// REMOVEQUOTES
9377    RemoveQuotes,
9378    /// ROWGROUPSIZE \[ AS \] size \[ MB | GB \]
9379    RowGroupSize(FileSize),
9380    /// STATUPDATE [ { ON | TRUE } | { OFF | FALSE } ]
9381    StatUpdate(Option<bool>),
9382    /// TIMEFORMAT \[ AS \] {'timeformat_string' | 'auto' | 'epochsecs' | 'epochmillisecs' }
9383    TimeFormat(Option<String>),
9384    /// TRUNCATECOLUMNS
9385    TruncateColumns,
9386    /// ZSTD
9387    Zstd,
9388    /// Redshift `CREDENTIALS 'auth-args'`
9389    /// <https://docs.aws.amazon.com/redshift/latest/dg/copy-parameters-authorization.html>
9390    Credentials(String),
9391}
9392
9393impl fmt::Display for CopyLegacyOption {
9394    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9395        use CopyLegacyOption::*;
9396        match self {
9397            AcceptAnyDate => write!(f, "ACCEPTANYDATE"),
9398            AcceptInvChars(ch) => {
9399                write!(f, "ACCEPTINVCHARS")?;
9400                if let Some(ch) = ch {
9401                    write!(f, " '{}'", value::escape_single_quote_string(ch))?;
9402                }
9403                Ok(())
9404            }
9405            AddQuotes => write!(f, "ADDQUOTES"),
9406            AllowOverwrite => write!(f, "ALLOWOVERWRITE"),
9407            Binary => write!(f, "BINARY"),
9408            BlankAsNull => write!(f, "BLANKSASNULL"),
9409            Bzip2 => write!(f, "BZIP2"),
9410            CleanPath => write!(f, "CLEANPATH"),
9411            CompUpdate { preset, enabled } => {
9412                write!(f, "COMPUPDATE")?;
9413                if *preset {
9414                    write!(f, " PRESET")?;
9415                } else if let Some(enabled) = enabled {
9416                    write!(
9417                        f,
9418                        "{}",
9419                        match enabled {
9420                            true => " TRUE",
9421                            false => " FALSE",
9422                        }
9423                    )?;
9424                }
9425                Ok(())
9426            }
9427            Csv(opts) => {
9428                write!(f, "CSV")?;
9429                if !opts.is_empty() {
9430                    write!(f, " {}", display_separated(opts, " "))?;
9431                }
9432                Ok(())
9433            }
9434            DateFormat(fmt) => {
9435                write!(f, "DATEFORMAT")?;
9436                if let Some(fmt) = fmt {
9437                    write!(f, " '{}'", value::escape_single_quote_string(fmt))?;
9438                }
9439                Ok(())
9440            }
9441            Delimiter(char) => write!(f, "DELIMITER '{char}'"),
9442            EmptyAsNull => write!(f, "EMPTYASNULL"),
9443            Encrypted { auto } => write!(f, "ENCRYPTED{}", if *auto { " AUTO" } else { "" }),
9444            Escape => write!(f, "ESCAPE"),
9445            Extension(ext) => write!(f, "EXTENSION '{}'", value::escape_single_quote_string(ext)),
9446            FixedWidth(spec) => write!(
9447                f,
9448                "FIXEDWIDTH '{}'",
9449                value::escape_single_quote_string(spec)
9450            ),
9451            Gzip => write!(f, "GZIP"),
9452            Header => write!(f, "HEADER"),
9453            IamRole(role) => write!(f, "IAM_ROLE {role}"),
9454            IgnoreHeader(num_rows) => write!(f, "IGNOREHEADER {num_rows}"),
9455            Json(opt) => {
9456                write!(f, "JSON")?;
9457                if let Some(opt) = opt {
9458                    write!(f, " AS '{}'", value::escape_single_quote_string(opt))?;
9459                }
9460                Ok(())
9461            }
9462            Manifest { verbose } => write!(f, "MANIFEST{}", if *verbose { " VERBOSE" } else { "" }),
9463            MaxFileSize(file_size) => write!(f, "MAXFILESIZE {file_size}"),
9464            Null(string) => write!(f, "NULL '{}'", value::escape_single_quote_string(string)),
9465            Parallel(enabled) => {
9466                write!(
9467                    f,
9468                    "PARALLEL{}",
9469                    match enabled {
9470                        Some(true) => " TRUE",
9471                        Some(false) => " FALSE",
9472                        _ => "",
9473                    }
9474                )
9475            }
9476            Parquet => write!(f, "PARQUET"),
9477            PartitionBy(p) => write!(f, "{p}"),
9478            Region(region) => write!(f, "REGION '{}'", value::escape_single_quote_string(region)),
9479            RemoveQuotes => write!(f, "REMOVEQUOTES"),
9480            RowGroupSize(file_size) => write!(f, "ROWGROUPSIZE {file_size}"),
9481            StatUpdate(enabled) => {
9482                write!(
9483                    f,
9484                    "STATUPDATE{}",
9485                    match enabled {
9486                        Some(true) => " TRUE",
9487                        Some(false) => " FALSE",
9488                        _ => "",
9489                    }
9490                )
9491            }
9492            TimeFormat(fmt) => {
9493                write!(f, "TIMEFORMAT")?;
9494                if let Some(fmt) = fmt {
9495                    write!(f, " '{}'", value::escape_single_quote_string(fmt))?;
9496                }
9497                Ok(())
9498            }
9499            TruncateColumns => write!(f, "TRUNCATECOLUMNS"),
9500            Zstd => write!(f, "ZSTD"),
9501            Credentials(s) => write!(f, "CREDENTIALS '{}'", value::escape_single_quote_string(s)),
9502        }
9503    }
9504}
9505
9506/// ```sql
9507/// SIZE \[ MB | GB \]
9508/// ```
9509#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9510#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9511#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9512pub struct FileSize {
9513    /// Numeric size value.
9514    pub size: ValueWithSpan,
9515    /// Optional unit for the size (MB or GB).
9516    pub unit: Option<FileSizeUnit>,
9517}
9518
9519impl fmt::Display for FileSize {
9520    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9521        write!(f, "{}", self.size)?;
9522        if let Some(unit) = &self.unit {
9523            write!(f, " {unit}")?;
9524        }
9525        Ok(())
9526    }
9527}
9528
9529/// Units for `FileSize` (MB or GB).
9530#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9531#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9532#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9533pub enum FileSizeUnit {
9534    /// Megabytes.
9535    MB,
9536    /// Gigabytes.
9537    GB,
9538}
9539
9540impl fmt::Display for FileSizeUnit {
9541    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9542        match self {
9543            FileSizeUnit::MB => write!(f, "MB"),
9544            FileSizeUnit::GB => write!(f, "GB"),
9545        }
9546    }
9547}
9548
9549/// Specifies the partition keys for the unload operation
9550///
9551/// ```sql
9552/// PARTITION BY ( column_name [, ... ] ) [ INCLUDE ]
9553/// ```
9554#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9555#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9556#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9557pub struct UnloadPartitionBy {
9558    /// Columns used to partition the unload output.
9559    pub columns: Vec<Ident>,
9560    /// Whether to include the partition in the output.
9561    pub include: bool,
9562}
9563
9564impl fmt::Display for UnloadPartitionBy {
9565    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9566        write!(
9567            f,
9568            "PARTITION BY ({}){}",
9569            display_comma_separated(&self.columns),
9570            if self.include { " INCLUDE" } else { "" }
9571        )
9572    }
9573}
9574
9575/// An `IAM_ROLE` option in the AWS ecosystem
9576///
9577/// [Redshift COPY](https://docs.aws.amazon.com/redshift/latest/dg/copy-parameters-authorization.html#copy-iam-role)
9578#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9579#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9580#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9581pub enum IamRoleKind {
9582    /// Default role
9583    Default,
9584    /// Specific role ARN, for example: `arn:aws:iam::123456789:role/role1`
9585    Arn(String),
9586}
9587
9588impl fmt::Display for IamRoleKind {
9589    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9590        match self {
9591            IamRoleKind::Default => write!(f, "DEFAULT"),
9592            IamRoleKind::Arn(arn) => write!(f, "'{arn}'"),
9593        }
9594    }
9595}
9596
9597/// A `CSV` option in `COPY` statement before PostgreSQL version 9.0.
9598///
9599/// <https://www.postgresql.org/docs/8.4/sql-copy.html>
9600#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9601#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9602#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9603pub enum CopyLegacyCsvOption {
9604    /// HEADER
9605    Header,
9606    /// QUOTE \[ AS \] 'quote_character'
9607    Quote(char),
9608    /// ESCAPE \[ AS \] 'escape_character'
9609    Escape(char),
9610    /// FORCE QUOTE { column_name [, ...] | * }
9611    ForceQuote(Vec<Ident>),
9612    /// FORCE NOT NULL column_name [, ...]
9613    ForceNotNull(Vec<Ident>),
9614}
9615
9616impl fmt::Display for CopyLegacyCsvOption {
9617    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9618        use CopyLegacyCsvOption::*;
9619        match self {
9620            Header => write!(f, "HEADER"),
9621            Quote(char) => write!(f, "QUOTE '{char}'"),
9622            Escape(char) => write!(f, "ESCAPE '{char}'"),
9623            ForceQuote(columns) => write!(f, "FORCE QUOTE {}", display_comma_separated(columns)),
9624            ForceNotNull(columns) => {
9625                write!(f, "FORCE NOT NULL {}", display_comma_separated(columns))
9626            }
9627        }
9628    }
9629}
9630
9631/// Objects that can be discarded with `DISCARD`.
9632#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9633#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9634#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9635pub enum DiscardObject {
9636    /// Discard all session state.
9637    ALL,
9638    /// Discard cached plans.
9639    PLANS,
9640    /// Discard sequence values.
9641    SEQUENCES,
9642    /// Discard temporary objects.
9643    TEMP,
9644}
9645
9646impl fmt::Display for DiscardObject {
9647    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9648        match self {
9649            DiscardObject::ALL => f.write_str("ALL"),
9650            DiscardObject::PLANS => f.write_str("PLANS"),
9651            DiscardObject::SEQUENCES => f.write_str("SEQUENCES"),
9652            DiscardObject::TEMP => f.write_str("TEMP"),
9653        }
9654    }
9655}
9656
9657/// Types of flush operations supported by `FLUSH`.
9658#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9659#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9660#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9661pub enum FlushType {
9662    /// Flush binary logs.
9663    BinaryLogs,
9664    /// Flush engine logs.
9665    EngineLogs,
9666    /// Flush error logs.
9667    ErrorLogs,
9668    /// Flush general logs.
9669    GeneralLogs,
9670    /// Flush hosts information.
9671    Hosts,
9672    /// Flush logs.
9673    Logs,
9674    /// Flush privileges.
9675    Privileges,
9676    /// Flush optimizer costs.
9677    OptimizerCosts,
9678    /// Flush relay logs.
9679    RelayLogs,
9680    /// Flush slow logs.
9681    SlowLogs,
9682    /// Flush status.
9683    Status,
9684    /// Flush user resources.
9685    UserResources,
9686    /// Flush table data.
9687    Tables,
9688}
9689
9690impl fmt::Display for FlushType {
9691    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9692        match self {
9693            FlushType::BinaryLogs => f.write_str("BINARY LOGS"),
9694            FlushType::EngineLogs => f.write_str("ENGINE LOGS"),
9695            FlushType::ErrorLogs => f.write_str("ERROR LOGS"),
9696            FlushType::GeneralLogs => f.write_str("GENERAL LOGS"),
9697            FlushType::Hosts => f.write_str("HOSTS"),
9698            FlushType::Logs => f.write_str("LOGS"),
9699            FlushType::Privileges => f.write_str("PRIVILEGES"),
9700            FlushType::OptimizerCosts => f.write_str("OPTIMIZER_COSTS"),
9701            FlushType::RelayLogs => f.write_str("RELAY LOGS"),
9702            FlushType::SlowLogs => f.write_str("SLOW LOGS"),
9703            FlushType::Status => f.write_str("STATUS"),
9704            FlushType::UserResources => f.write_str("USER_RESOURCES"),
9705            FlushType::Tables => f.write_str("TABLES"),
9706        }
9707    }
9708}
9709
9710/// Location modifier for flush commands.
9711#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9712#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9713#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9714pub enum FlushLocation {
9715    /// Do not write changes to the binary log.
9716    NoWriteToBinlog,
9717    /// Apply flush locally.
9718    Local,
9719}
9720
9721impl fmt::Display for FlushLocation {
9722    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9723        match self {
9724            FlushLocation::NoWriteToBinlog => f.write_str("NO_WRITE_TO_BINLOG"),
9725            FlushLocation::Local => f.write_str("LOCAL"),
9726        }
9727    }
9728}
9729
9730/// Optional context modifier for statements that can be or `LOCAL`, `GLOBAL`, or `SESSION`.
9731#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9732#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9733#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9734pub enum ContextModifier {
9735    /// `LOCAL` identifier, usually related to transactional states.
9736    Local,
9737    /// `SESSION` identifier
9738    Session,
9739    /// `GLOBAL` identifier
9740    Global,
9741}
9742
9743impl fmt::Display for ContextModifier {
9744    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9745        match self {
9746            Self::Local => {
9747                write!(f, "LOCAL ")
9748            }
9749            Self::Session => {
9750                write!(f, "SESSION ")
9751            }
9752            Self::Global => {
9753                write!(f, "GLOBAL ")
9754            }
9755        }
9756    }
9757}
9758
9759/// Function describe in DROP FUNCTION.
9760#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9761#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9762pub enum DropFunctionOption {
9763    /// `RESTRICT` option for DROP FUNCTION.
9764    Restrict,
9765    /// `CASCADE` option for DROP FUNCTION.
9766    Cascade,
9767}
9768
9769impl fmt::Display for DropFunctionOption {
9770    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9771        match self {
9772            DropFunctionOption::Restrict => write!(f, "RESTRICT "),
9773            DropFunctionOption::Cascade => write!(f, "CASCADE  "),
9774        }
9775    }
9776}
9777
9778/// Generic function description for DROP FUNCTION and CREATE TRIGGER.
9779#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9780#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9781#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9782pub struct FunctionDesc {
9783    /// The function name.
9784    pub name: ObjectName,
9785    /// Optional list of function arguments.
9786    pub args: Option<Vec<OperateFunctionArg>>,
9787}
9788
9789impl fmt::Display for FunctionDesc {
9790    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9791        write!(f, "{}", self.name)?;
9792        if let Some(args) = &self.args {
9793            write!(f, "({})", display_comma_separated(args))?;
9794        }
9795        Ok(())
9796    }
9797}
9798
9799/// Function argument in CREATE OR DROP FUNCTION.
9800#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9801#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9802#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9803pub struct OperateFunctionArg {
9804    /// Optional argument mode (`IN`, `OUT`, `INOUT`).
9805    pub mode: Option<ArgMode>,
9806    /// Optional argument identifier/name.
9807    pub name: Option<Ident>,
9808    /// The data type of the argument.
9809    pub data_type: DataType,
9810    /// Optional default expression for the argument.
9811    pub default_expr: Option<Expr>,
9812}
9813
9814impl OperateFunctionArg {
9815    /// Returns an unnamed argument.
9816    pub fn unnamed(data_type: DataType) -> Self {
9817        Self {
9818            mode: None,
9819            name: None,
9820            data_type,
9821            default_expr: None,
9822        }
9823    }
9824
9825    /// Returns an argument with name.
9826    pub fn with_name(name: &str, data_type: DataType) -> Self {
9827        Self {
9828            mode: None,
9829            name: Some(name.into()),
9830            data_type,
9831            default_expr: None,
9832        }
9833    }
9834}
9835
9836impl fmt::Display for OperateFunctionArg {
9837    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9838        if let Some(mode) = &self.mode {
9839            write!(f, "{mode} ")?;
9840        }
9841        if let Some(name) = &self.name {
9842            write!(f, "{name} ")?;
9843        }
9844        write!(f, "{}", self.data_type)?;
9845        if let Some(default_expr) = &self.default_expr {
9846            write!(f, " = {default_expr}")?;
9847        }
9848        Ok(())
9849    }
9850}
9851
9852/// The mode of an argument in CREATE FUNCTION.
9853#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9854#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9855#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9856pub enum ArgMode {
9857    /// `IN` mode.
9858    In,
9859    /// `OUT` mode.
9860    Out,
9861    /// `INOUT` mode.
9862    InOut,
9863    /// `VARIADIC` mode.
9864    Variadic,
9865}
9866
9867impl fmt::Display for ArgMode {
9868    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9869        match self {
9870            ArgMode::In => write!(f, "IN"),
9871            ArgMode::Out => write!(f, "OUT"),
9872            ArgMode::InOut => write!(f, "INOUT"),
9873            ArgMode::Variadic => write!(f, "VARIADIC"),
9874        }
9875    }
9876}
9877
9878/// These attributes inform the query optimizer about the behavior of the function.
9879#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9880#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9881#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9882pub enum FunctionBehavior {
9883    /// Function is immutable.
9884    Immutable,
9885    /// Function is stable.
9886    Stable,
9887    /// Function is volatile.
9888    Volatile,
9889}
9890
9891impl fmt::Display for FunctionBehavior {
9892    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9893        match self {
9894            FunctionBehavior::Immutable => write!(f, "IMMUTABLE"),
9895            FunctionBehavior::Stable => write!(f, "STABLE"),
9896            FunctionBehavior::Volatile => write!(f, "VOLATILE"),
9897        }
9898    }
9899}
9900
9901/// Security attribute for functions: SECURITY DEFINER or SECURITY INVOKER.
9902///
9903/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
9904#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9905#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9906#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9907pub enum FunctionSecurity {
9908    /// Execute the function with the privileges of the user who defined it.
9909    Definer,
9910    /// Execute the function with the privileges of the user who invokes it.
9911    Invoker,
9912}
9913
9914impl fmt::Display for FunctionSecurity {
9915    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9916        match self {
9917            FunctionSecurity::Definer => write!(f, "SECURITY DEFINER"),
9918            FunctionSecurity::Invoker => write!(f, "SECURITY INVOKER"),
9919        }
9920    }
9921}
9922
9923/// Value for a SET configuration parameter in a CREATE FUNCTION statement.
9924///
9925/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
9926#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9927#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9928#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9929pub enum FunctionSetValue {
9930    /// SET param = DEFAULT / SET param TO DEFAULT
9931    Default,
9932    /// SET param = value1, value2, ...
9933    Values(Vec<Expr>),
9934    /// SET param FROM CURRENT
9935    FromCurrent,
9936}
9937
9938/// A SET configuration_parameter clause in a CREATE FUNCTION statement.
9939///
9940/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-createfunction.html)
9941#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9942#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9943#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9944pub struct FunctionDefinitionSetParam {
9945    /// The name of the configuration parameter.
9946    pub name: ObjectName,
9947    /// The value to set for the parameter.
9948    pub value: FunctionSetValue,
9949}
9950
9951impl fmt::Display for FunctionDefinitionSetParam {
9952    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9953        write!(f, "SET {} ", self.name)?;
9954        match &self.value {
9955            FunctionSetValue::Default => write!(f, "= DEFAULT"),
9956            FunctionSetValue::Values(values) => {
9957                write!(f, "= {}", display_comma_separated(values))
9958            }
9959            FunctionSetValue::FromCurrent => write!(f, "FROM CURRENT"),
9960        }
9961    }
9962}
9963
9964/// These attributes describe the behavior of the function when called with a null argument.
9965#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9966#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9967#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9968pub enum FunctionCalledOnNull {
9969    /// Function is called even when inputs are null.
9970    CalledOnNullInput,
9971    /// Function returns null when any input is null.
9972    ReturnsNullOnNullInput,
9973    /// Function is strict about null inputs.
9974    Strict,
9975}
9976
9977impl fmt::Display for FunctionCalledOnNull {
9978    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
9979        match self {
9980            FunctionCalledOnNull::CalledOnNullInput => write!(f, "CALLED ON NULL INPUT"),
9981            FunctionCalledOnNull::ReturnsNullOnNullInput => write!(f, "RETURNS NULL ON NULL INPUT"),
9982            FunctionCalledOnNull::Strict => write!(f, "STRICT"),
9983        }
9984    }
9985}
9986
9987/// If it is safe for PostgreSQL to call the function from multiple threads at once
9988#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
9989#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
9990#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
9991pub enum FunctionParallel {
9992    /// The function is not safe to run in parallel.
9993    Unsafe,
9994    /// The function is restricted for parallel execution.
9995    Restricted,
9996    /// The function is safe to run in parallel.
9997    Safe,
9998}
9999
10000impl fmt::Display for FunctionParallel {
10001    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10002        match self {
10003            FunctionParallel::Unsafe => write!(f, "PARALLEL UNSAFE"),
10004            FunctionParallel::Restricted => write!(f, "PARALLEL RESTRICTED"),
10005            FunctionParallel::Safe => write!(f, "PARALLEL SAFE"),
10006        }
10007    }
10008}
10009
10010/// [BigQuery] Determinism specifier used in a UDF definition.
10011///
10012/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
10013#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10014#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10015#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10016pub enum FunctionDeterminismSpecifier {
10017    /// Function is deterministic.
10018    Deterministic,
10019    /// Function is not deterministic.
10020    NotDeterministic,
10021}
10022
10023impl fmt::Display for FunctionDeterminismSpecifier {
10024    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10025        match self {
10026            FunctionDeterminismSpecifier::Deterministic => {
10027                write!(f, "DETERMINISTIC")
10028            }
10029            FunctionDeterminismSpecifier::NotDeterministic => {
10030                write!(f, "NOT DETERMINISTIC")
10031            }
10032        }
10033    }
10034}
10035
10036/// Represent the expression body of a `CREATE FUNCTION` statement as well as
10037/// where within the statement, the body shows up.
10038///
10039/// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
10040/// [PostgreSQL]: https://www.postgresql.org/docs/15/sql-createfunction.html
10041/// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
10042#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10043#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10044#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10045pub enum CreateFunctionBody {
10046    /// A function body expression using the 'AS' keyword and shows up
10047    /// before any `OPTIONS` clause.
10048    ///
10049    /// Example:
10050    /// ```sql
10051    /// CREATE FUNCTION myfunc(x FLOAT64, y FLOAT64) RETURNS FLOAT64
10052    /// AS (x * y)
10053    /// OPTIONS(description="desc");
10054    /// ```
10055    ///
10056    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
10057    /// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
10058    AsBeforeOptions {
10059        /// The primary expression.
10060        body: Expr,
10061        /// Link symbol if the primary expression contains the name of shared library file.
10062        ///
10063        /// Example:
10064        /// ```sql
10065        /// CREATE FUNCTION cas_in(input cstring) RETURNS cas
10066        /// AS 'MODULE_PATHNAME', 'cas_in_wrapper'
10067        /// ```
10068        /// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
10069        link_symbol: Option<Expr>,
10070    },
10071    /// A function body expression using the 'AS' keyword and shows up
10072    /// after any `OPTIONS` clause.
10073    ///
10074    /// Example:
10075    /// ```sql
10076    /// CREATE FUNCTION myfunc(x FLOAT64, y FLOAT64) RETURNS FLOAT64
10077    /// OPTIONS(description="desc")
10078    /// AS (x * y);
10079    /// ```
10080    ///
10081    /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#syntax_11
10082    AsAfterOptions(Expr),
10083    /// Function body with statements before the `RETURN` keyword.
10084    ///
10085    /// Example:
10086    /// ```sql
10087    /// CREATE FUNCTION my_scalar_udf(a INT, b INT)
10088    /// RETURNS INT
10089    /// AS
10090    /// BEGIN
10091    ///     DECLARE c INT;
10092    ///     SET c = a + b;
10093    ///     RETURN c;
10094    /// END
10095    /// ```
10096    ///
10097    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
10098    AsBeginEnd(BeginEndStatements),
10099    /// Function body expression using the 'RETURN' keyword.
10100    ///
10101    /// Example:
10102    /// ```sql
10103    /// CREATE FUNCTION myfunc(a INTEGER, IN b INTEGER = 1) RETURNS INTEGER
10104    /// LANGUAGE SQL
10105    /// RETURN a + b;
10106    /// ```
10107    ///
10108    /// [PostgreSQL]: https://www.postgresql.org/docs/current/sql-createfunction.html
10109    Return(Expr),
10110
10111    /// Function body expression using the 'AS RETURN' keywords
10112    ///
10113    /// Example:
10114    /// ```sql
10115    /// CREATE FUNCTION myfunc(a INT, b INT)
10116    /// RETURNS TABLE
10117    /// AS RETURN (SELECT a + b AS sum);
10118    /// ```
10119    ///
10120    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql
10121    AsReturnExpr(Expr),
10122
10123    /// Function body expression using the 'AS RETURN' keywords, with an un-parenthesized SELECT query
10124    ///
10125    /// Example:
10126    /// ```sql
10127    /// CREATE FUNCTION myfunc(a INT, b INT)
10128    /// RETURNS TABLE
10129    /// AS RETURN SELECT a + b AS sum;
10130    /// ```
10131    ///
10132    /// [MsSql]: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql?view=sql-server-ver16#select_stmt
10133    AsReturnSelect(Select),
10134}
10135
10136#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10137#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10138#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10139/// `USING` clause options for `CREATE FUNCTION` (e.g., JAR, FILE, ARCHIVE).
10140pub enum CreateFunctionUsing {
10141    /// Use a JAR file located at the given URI.
10142    Jar(String),
10143    /// Use a file located at the given URI.
10144    File(String),
10145    /// Use an archive located at the given URI.
10146    Archive(String),
10147}
10148
10149impl fmt::Display for CreateFunctionUsing {
10150    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10151        write!(f, "USING ")?;
10152        match self {
10153            CreateFunctionUsing::Jar(uri) => write!(f, "JAR '{uri}'"),
10154            CreateFunctionUsing::File(uri) => write!(f, "FILE '{uri}'"),
10155            CreateFunctionUsing::Archive(uri) => write!(f, "ARCHIVE '{uri}'"),
10156        }
10157    }
10158}
10159
10160/// `NAME = <EXPR>` arguments for DuckDB macros
10161///
10162/// See [Create Macro - DuckDB](https://duckdb.org/docs/sql/statements/create_macro)
10163/// for more details
10164#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10165#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10166#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10167pub struct MacroArg {
10168    /// The argument name.
10169    pub name: Ident,
10170    /// Optional default expression for the argument.
10171    pub default_expr: Option<Expr>,
10172}
10173
10174impl MacroArg {
10175    /// Returns an argument with name.
10176    pub fn new(name: &str) -> Self {
10177        Self {
10178            name: name.into(),
10179            default_expr: None,
10180        }
10181    }
10182}
10183
10184impl fmt::Display for MacroArg {
10185    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10186        write!(f, "{}", self.name)?;
10187        if let Some(default_expr) = &self.default_expr {
10188            write!(f, " := {default_expr}")?;
10189        }
10190        Ok(())
10191    }
10192}
10193
10194#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10195#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10196#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10197/// Definition for a DuckDB macro: either an expression or a table-producing query.
10198pub enum MacroDefinition {
10199    /// The macro is defined as an expression.
10200    Expr(Expr),
10201    /// The macro is defined as a table (query).
10202    Table(Box<Query>),
10203}
10204
10205impl fmt::Display for MacroDefinition {
10206    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10207        match self {
10208            MacroDefinition::Expr(expr) => write!(f, "{expr}")?,
10209            MacroDefinition::Table(query) => write!(f, "{query}")?,
10210        }
10211        Ok(())
10212    }
10213}
10214
10215/// Schema possible naming variants ([1]).
10216///
10217/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#schema-definition
10218#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10219#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10220#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10221pub enum SchemaName {
10222    /// Only schema name specified: `<schema name>`.
10223    Simple(ObjectName),
10224    /// Only authorization identifier specified: `AUTHORIZATION <schema authorization identifier>`.
10225    UnnamedAuthorization(Ident),
10226    /// Both schema name and authorization identifier specified: `<schema name>  AUTHORIZATION <schema authorization identifier>`.
10227    NamedAuthorization(ObjectName, Ident),
10228}
10229
10230impl fmt::Display for SchemaName {
10231    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10232        match self {
10233            SchemaName::Simple(name) => {
10234                write!(f, "{name}")
10235            }
10236            SchemaName::UnnamedAuthorization(authorization) => {
10237                write!(f, "AUTHORIZATION {authorization}")
10238            }
10239            SchemaName::NamedAuthorization(name, authorization) => {
10240                write!(f, "{name} AUTHORIZATION {authorization}")
10241            }
10242        }
10243    }
10244}
10245
10246/// Fulltext search modifiers ([1]).
10247///
10248/// [1]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html#function_match
10249#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10250#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10251#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10252pub enum SearchModifier {
10253    /// `IN NATURAL LANGUAGE MODE`.
10254    InNaturalLanguageMode,
10255    /// `IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION`.
10256    InNaturalLanguageModeWithQueryExpansion,
10257    ///`IN BOOLEAN MODE`.
10258    InBooleanMode,
10259    ///`WITH QUERY EXPANSION`.
10260    WithQueryExpansion,
10261}
10262
10263impl fmt::Display for SearchModifier {
10264    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10265        match self {
10266            Self::InNaturalLanguageMode => {
10267                write!(f, "IN NATURAL LANGUAGE MODE")?;
10268            }
10269            Self::InNaturalLanguageModeWithQueryExpansion => {
10270                write!(f, "IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION")?;
10271            }
10272            Self::InBooleanMode => {
10273                write!(f, "IN BOOLEAN MODE")?;
10274            }
10275            Self::WithQueryExpansion => {
10276                write!(f, "WITH QUERY EXPANSION")?;
10277            }
10278        }
10279
10280        Ok(())
10281    }
10282}
10283
10284/// Represents a `LOCK TABLE` clause with optional alias and lock type.
10285#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10286#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10287#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10288pub struct LockTable {
10289    /// The table identifier to lock.
10290    pub table: Ident,
10291    /// Optional alias for the table.
10292    pub alias: Option<Ident>,
10293    /// The type of lock to apply to the table.
10294    pub lock_type: LockTableType,
10295}
10296
10297impl fmt::Display for LockTable {
10298    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10299        let Self {
10300            table: tbl_name,
10301            alias,
10302            lock_type,
10303        } = self;
10304
10305        write!(f, "{tbl_name} ")?;
10306        if let Some(alias) = alias {
10307            write!(f, "AS {alias} ")?;
10308        }
10309        write!(f, "{lock_type}")?;
10310        Ok(())
10311    }
10312}
10313
10314#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10315#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10316#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10317/// The type of lock used in `LOCK TABLE` statements.
10318pub enum LockTableType {
10319    /// Shared/read lock. If `local` is true, it's a local read lock.
10320    Read {
10321        /// Whether the read lock is local.
10322        local: bool,
10323    },
10324    /// Exclusive/write lock. If `low_priority` is true, the write is low priority.
10325    Write {
10326        /// Whether the write lock is low priority.
10327        low_priority: bool,
10328    },
10329}
10330
10331impl fmt::Display for LockTableType {
10332    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10333        match self {
10334            Self::Read { local } => {
10335                write!(f, "READ")?;
10336                if *local {
10337                    write!(f, " LOCAL")?;
10338                }
10339            }
10340            Self::Write { low_priority } => {
10341                if *low_priority {
10342                    write!(f, "LOW_PRIORITY ")?;
10343                }
10344                write!(f, "WRITE")?;
10345            }
10346        }
10347
10348        Ok(())
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))]
10355/// Hive-specific `SET LOCATION` helper used in some `LOAD DATA` statements.
10356pub struct HiveSetLocation {
10357    /// Whether the `SET` keyword was present.
10358    pub has_set: bool,
10359    /// The location identifier.
10360    pub location: Ident,
10361}
10362
10363impl fmt::Display for HiveSetLocation {
10364    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10365        if self.has_set {
10366            write!(f, "SET ")?;
10367        }
10368        write!(f, "LOCATION {}", self.location)
10369    }
10370}
10371
10372/// MySQL `ALTER TABLE` only  [FIRST | AFTER column_name]
10373#[allow(clippy::large_enum_variant)]
10374#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10375#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10376#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10377/// MySQL `ALTER TABLE` column position specifier: `FIRST` or `AFTER <column>`.
10378pub enum MySQLColumnPosition {
10379    /// Place the column first in the table.
10380    First,
10381    /// Place the column after the specified identifier.
10382    After(Ident),
10383}
10384
10385impl Display for MySQLColumnPosition {
10386    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10387        match self {
10388            MySQLColumnPosition::First => write!(f, "FIRST"),
10389            MySQLColumnPosition::After(ident) => {
10390                let column_name = &ident.value;
10391                write!(f, "AFTER {column_name}")
10392            }
10393        }
10394    }
10395}
10396
10397/// MySQL `CREATE VIEW` algorithm parameter: [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
10398#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10399#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10400#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10401/// MySQL `CREATE VIEW` algorithm options.
10402pub enum CreateViewAlgorithm {
10403    /// `UNDEFINED` algorithm.
10404    Undefined,
10405    /// `MERGE` algorithm.
10406    Merge,
10407    /// `TEMPTABLE` algorithm.
10408    TempTable,
10409}
10410
10411impl Display for CreateViewAlgorithm {
10412    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10413        match self {
10414            CreateViewAlgorithm::Undefined => write!(f, "UNDEFINED"),
10415            CreateViewAlgorithm::Merge => write!(f, "MERGE"),
10416            CreateViewAlgorithm::TempTable => write!(f, "TEMPTABLE"),
10417        }
10418    }
10419}
10420/// MySQL `CREATE VIEW` security parameter: [SQL SECURITY { DEFINER | INVOKER }]
10421#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10422#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10423#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10424/// MySQL `CREATE VIEW` SQL SECURITY options.
10425pub enum CreateViewSecurity {
10426    /// The view runs with the privileges of the definer.
10427    Definer,
10428    /// The view runs with the privileges of the invoker.
10429    Invoker,
10430}
10431
10432impl Display for CreateViewSecurity {
10433    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10434        match self {
10435            CreateViewSecurity::Definer => write!(f, "DEFINER"),
10436            CreateViewSecurity::Invoker => write!(f, "INVOKER"),
10437        }
10438    }
10439}
10440
10441/// [MySQL] `CREATE VIEW` additional parameters
10442///
10443/// [MySQL]: https://dev.mysql.com/doc/refman/9.1/en/create-view.html
10444#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10445#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10446#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10447pub struct CreateViewParams {
10448    /// Optional view algorithm (e.g., MERGE, TEMPTABLE).
10449    pub algorithm: Option<CreateViewAlgorithm>,
10450    /// Optional definer (the security principal that will own the view).
10451    pub definer: Option<GranteeName>,
10452    /// Optional SQL SECURITY setting for the view.
10453    pub security: Option<CreateViewSecurity>,
10454}
10455
10456impl Display for CreateViewParams {
10457    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10458        let CreateViewParams {
10459            algorithm,
10460            definer,
10461            security,
10462        } = self;
10463        if let Some(algorithm) = algorithm {
10464            write!(f, "ALGORITHM = {algorithm} ")?;
10465        }
10466        if let Some(definers) = definer {
10467            write!(f, "DEFINER = {definers} ")?;
10468        }
10469        if let Some(security) = security {
10470            write!(f, "SQL SECURITY {security} ")?;
10471        }
10472        Ok(())
10473    }
10474}
10475
10476#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10477#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10478#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10479/// Key/Value, where the value is a (optionally named) list of identifiers
10480///
10481/// ```sql
10482/// UNION = (tbl_name[,tbl_name]...)
10483/// ENGINE = ReplicatedMergeTree('/table_name','{replica}', ver)
10484/// ENGINE = SummingMergeTree([columns])
10485/// ```
10486pub struct NamedParenthesizedList {
10487    /// The option key (identifier) for this named list.
10488    pub key: Ident,
10489    /// Optional secondary name associated with the key.
10490    pub name: Option<Ident>,
10491    /// The list of identifier values for the key.
10492    pub values: Vec<Ident>,
10493}
10494
10495/// Snowflake `WITH ROW ACCESS POLICY policy_name ON (identifier, ...)`
10496///
10497/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
10498/// <https://docs.snowflake.com/en/user-guide/security-row-intro>
10499#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10500#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10501#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10502pub struct RowAccessPolicy {
10503    /// The fully-qualified policy object name.
10504    pub policy: ObjectName,
10505    /// Identifiers for the columns or objects the policy applies to.
10506    pub on: Vec<Ident>,
10507}
10508
10509impl RowAccessPolicy {
10510    /// Create a new `RowAccessPolicy` for the given `policy` and `on` identifiers.
10511    pub fn new(policy: ObjectName, on: Vec<Ident>) -> Self {
10512        Self { policy, on }
10513    }
10514}
10515
10516impl Display for RowAccessPolicy {
10517    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10518        write!(
10519            f,
10520            "WITH ROW ACCESS POLICY {} ON ({})",
10521            self.policy,
10522            display_comma_separated(self.on.as_slice())
10523        )
10524    }
10525}
10526
10527/// Snowflake `[ WITH ] STORAGE LIFECYCLE POLICY <policy_name> ON ( <col_name> [ , ... ] )`
10528///
10529/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
10530#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10531#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10532#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10533pub struct StorageLifecyclePolicy {
10534    /// The fully-qualified policy object name.
10535    pub policy: ObjectName,
10536    /// Column names the policy applies to.
10537    pub on: Vec<Ident>,
10538}
10539
10540impl Display for StorageLifecyclePolicy {
10541    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10542        write!(
10543            f,
10544            "WITH STORAGE LIFECYCLE POLICY {} ON ({})",
10545            self.policy,
10546            display_comma_separated(self.on.as_slice())
10547        )
10548    }
10549}
10550
10551/// Snowflake `WITH TAG ( tag_name = '<tag_value>', ...)`
10552///
10553/// <https://docs.snowflake.com/en/sql-reference/sql/create-table>
10554#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10555#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10556#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10557pub struct Tag {
10558    /// The tag key (can be qualified).
10559    pub key: ObjectName,
10560    /// The tag value as a string.
10561    pub value: String,
10562}
10563
10564impl Tag {
10565    /// Create a new `Tag` with the given key and value.
10566    pub fn new(key: ObjectName, value: String) -> Self {
10567        Self { key, value }
10568    }
10569}
10570
10571impl Display for Tag {
10572    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10573        write!(f, "{}='{}'", self.key, self.value)
10574    }
10575}
10576
10577/// Snowflake `WITH CONTACT ( purpose = contact [ , purpose = contact ...] )`
10578///
10579/// <https://docs.snowflake.com/en/sql-reference/sql/create-database>
10580#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10581#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10582#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10583pub struct ContactEntry {
10584    /// The purpose label for the contact entry.
10585    pub purpose: String,
10586    /// The contact information associated with the purpose.
10587    pub contact: String,
10588}
10589
10590impl Display for ContactEntry {
10591    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10592        write!(f, "{} = {}", self.purpose, self.contact)
10593    }
10594}
10595
10596/// Helper to indicate if a comment includes the `=` in the display form
10597#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10598#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10599#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10600pub enum CommentDef {
10601    /// Includes `=` when printing the comment, as `COMMENT = 'comment'`
10602    /// Does not include `=` when printing the comment, as `COMMENT 'comment'`
10603    WithEq(String),
10604    /// Comment variant that omits the `=` when displayed.
10605    WithoutEq(String),
10606}
10607
10608impl Display for CommentDef {
10609    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10610        match self {
10611            CommentDef::WithEq(comment) | CommentDef::WithoutEq(comment) => write!(f, "{comment}"),
10612        }
10613    }
10614}
10615
10616/// Helper to indicate if a collection should be wrapped by a symbol in the display form
10617///
10618/// [`Display`] is implemented for every [`Vec<T>`] where `T: Display`.
10619/// The string output is a comma separated list for the vec items
10620///
10621/// # Examples
10622/// ```
10623/// # use sqlparser::ast::WrappedCollection;
10624/// let items = WrappedCollection::Parentheses(vec!["one", "two", "three"]);
10625/// assert_eq!("(one, two, three)", items.to_string());
10626///
10627/// let items = WrappedCollection::NoWrapping(vec!["one", "two", "three"]);
10628/// assert_eq!("one, two, three", items.to_string());
10629/// ```
10630#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10631#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10632#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10633pub enum WrappedCollection<T> {
10634    /// Print the collection without wrapping symbols, as `item, item, item`
10635    NoWrapping(T),
10636    /// Wraps the collection in Parentheses, as `(item, item, item)`
10637    Parentheses(T),
10638}
10639
10640impl<T> Display for WrappedCollection<Vec<T>>
10641where
10642    T: Display,
10643{
10644    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10645        match self {
10646            WrappedCollection::NoWrapping(inner) => {
10647                write!(f, "{}", display_comma_separated(inner.as_slice()))
10648            }
10649            WrappedCollection::Parentheses(inner) => {
10650                write!(f, "({})", display_comma_separated(inner.as_slice()))
10651            }
10652        }
10653    }
10654}
10655
10656/// Represents a single PostgreSQL utility option.
10657///
10658/// A utility option is a key-value pair where the key is an identifier (IDENT) and the value
10659/// can be one of the following:
10660/// - A number with an optional sign (`+` or `-`). Example: `+10`, `-10.2`, `3`
10661/// - A non-keyword string. Example: `option1`, `'option2'`, `"option3"`
10662/// - keyword: `TRUE`, `FALSE`, `ON` (`off` is also accept).
10663/// - Empty. Example: `ANALYZE` (identifier only)
10664///
10665/// Utility options are used in various PostgreSQL DDL statements, including statements such as
10666/// `CLUSTER`, `EXPLAIN`, `VACUUM`, and `REINDEX`. These statements format options as `( option [, ...] )`.
10667///
10668/// [CLUSTER](https://www.postgresql.org/docs/current/sql-cluster.html)
10669/// [EXPLAIN](https://www.postgresql.org/docs/current/sql-explain.html)
10670/// [VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html)
10671/// [REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html)
10672///
10673/// For example, the `EXPLAIN` AND `VACUUM` statements with options might look like this:
10674/// ```sql
10675/// EXPLAIN (ANALYZE, VERBOSE TRUE, FORMAT TEXT) SELECT * FROM my_table;
10676///
10677/// VACUUM (VERBOSE, ANALYZE ON, PARALLEL 10) my_table;
10678/// ```
10679#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10680#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10681#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10682pub struct UtilityOption {
10683    /// The option name (identifier).
10684    pub name: Ident,
10685    /// Optional argument for the option (number, string, keyword, etc.).
10686    pub arg: Option<Expr>,
10687}
10688
10689impl Display for UtilityOption {
10690    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10691        if let Some(ref arg) = self.arg {
10692            write!(f, "{} {}", self.name, arg)
10693        } else {
10694            write!(f, "{}", self.name)
10695        }
10696    }
10697}
10698
10699/// Represents the different options available for `SHOW`
10700/// statements to filter the results. Example from Snowflake:
10701/// <https://docs.snowflake.com/en/sql-reference/sql/show-tables>
10702#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10703#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10704#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10705pub struct ShowStatementOptions {
10706    /// Optional scope to show in (for example: TABLE, SCHEMA).
10707    pub show_in: Option<ShowStatementIn>,
10708    /// Optional `STARTS WITH` filter value.
10709    pub starts_with: Option<ValueWithSpan>,
10710    /// Optional `LIMIT` expression.
10711    pub limit: Option<Expr>,
10712    /// Optional `FROM` value used with `LIMIT`.
10713    pub limit_from: Option<ValueWithSpan>,
10714    /// Optional filter position (infix or suffix) for `LIKE`/`FILTER`.
10715    pub filter_position: Option<ShowStatementFilterPosition>,
10716}
10717
10718impl Display for ShowStatementOptions {
10719    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10720        let (like_in_infix, like_in_suffix) = match &self.filter_position {
10721            Some(ShowStatementFilterPosition::Infix(filter)) => {
10722                (format!(" {filter}"), "".to_string())
10723            }
10724            Some(ShowStatementFilterPosition::Suffix(filter)) => {
10725                ("".to_string(), format!(" {filter}"))
10726            }
10727            None => ("".to_string(), "".to_string()),
10728        };
10729        write!(
10730            f,
10731            "{like_in_infix}{show_in}{starts_with}{limit}{from}{like_in_suffix}",
10732            show_in = match &self.show_in {
10733                Some(i) => format!(" {i}"),
10734                None => String::new(),
10735            },
10736            starts_with = match &self.starts_with {
10737                Some(s) => format!(" STARTS WITH {s}"),
10738                None => String::new(),
10739            },
10740            limit = match &self.limit {
10741                Some(l) => format!(" LIMIT {l}"),
10742                None => String::new(),
10743            },
10744            from = match &self.limit_from {
10745                Some(f) => format!(" FROM {f}"),
10746                None => String::new(),
10747            }
10748        )?;
10749        Ok(())
10750    }
10751}
10752
10753#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10754#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10755#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10756/// Where a `SHOW` filter appears relative to the main clause.
10757pub enum ShowStatementFilterPosition {
10758    /// Put the filter in an infix position (e.g. `SHOW COLUMNS LIKE '%name%' IN TABLE tbl`).
10759    Infix(ShowStatementFilter), // For example: SHOW COLUMNS LIKE '%name%' IN TABLE tbl
10760    /// Put the filter in a suffix position (e.g. `SHOW COLUMNS IN tbl LIKE '%name%'`).
10761    Suffix(ShowStatementFilter), // For example: SHOW COLUMNS IN tbl LIKE '%name%'
10762}
10763
10764#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10765#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10766#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10767/// Parent object types usable with `SHOW ... IN <parent>` clauses.
10768pub enum ShowStatementInParentType {
10769    /// ACCOUNT parent type for SHOW statements.
10770    Account,
10771    /// DATABASE parent type for SHOW statements.
10772    Database,
10773    /// SCHEMA parent type for SHOW statements.
10774    Schema,
10775    /// TABLE parent type for SHOW statements.
10776    Table,
10777    /// VIEW parent type for SHOW statements.
10778    View,
10779}
10780
10781impl fmt::Display for ShowStatementInParentType {
10782    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10783        match self {
10784            ShowStatementInParentType::Account => write!(f, "ACCOUNT"),
10785            ShowStatementInParentType::Database => write!(f, "DATABASE"),
10786            ShowStatementInParentType::Schema => write!(f, "SCHEMA"),
10787            ShowStatementInParentType::Table => write!(f, "TABLE"),
10788            ShowStatementInParentType::View => write!(f, "VIEW"),
10789        }
10790    }
10791}
10792
10793#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10794#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10795#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10796/// Represents a `SHOW ... IN` clause with optional parent qualifier and name.
10797pub struct ShowStatementIn {
10798    /// The clause that specifies what to show (e.g. COLUMNS, TABLES).
10799    pub clause: ShowStatementInClause,
10800    /// Optional parent type qualifier (ACCOUNT/DATABASE/...).
10801    pub parent_type: Option<ShowStatementInParentType>,
10802    /// Optional parent object name for the SHOW clause.
10803    #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))]
10804    pub parent_name: Option<ObjectName>,
10805}
10806
10807impl fmt::Display for ShowStatementIn {
10808    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10809        write!(f, "{}", self.clause)?;
10810        if let Some(parent_type) = &self.parent_type {
10811            write!(f, " {parent_type}")?;
10812        }
10813        if let Some(parent_name) = &self.parent_name {
10814            write!(f, " {parent_name}")?;
10815        }
10816        Ok(())
10817    }
10818}
10819
10820/// A Show Charset statement
10821#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10822#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10823#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10824pub struct ShowCharset {
10825    /// The statement can be written as `SHOW CHARSET` or `SHOW CHARACTER SET`
10826    /// true means CHARSET was used and false means CHARACTER SET was used
10827    pub is_shorthand: bool,
10828    /// Optional `LIKE`/`WHERE`-style filter for the statement.
10829    pub filter: Option<ShowStatementFilter>,
10830}
10831
10832impl fmt::Display for ShowCharset {
10833    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10834        write!(f, "SHOW")?;
10835        if self.is_shorthand {
10836            write!(f, " CHARSET")?;
10837        } else {
10838            write!(f, " CHARACTER SET")?;
10839        }
10840        if let Some(filter) = &self.filter {
10841            write!(f, " {filter}")?;
10842        }
10843        Ok(())
10844    }
10845}
10846
10847#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10848#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10849#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10850/// Options for a `SHOW OBJECTS` statement.
10851pub struct ShowObjects {
10852    /// Whether to show terse output.
10853    pub terse: bool,
10854    /// Additional options controlling the SHOW output.
10855    pub show_options: ShowStatementOptions,
10856}
10857
10858/// MSSQL's json null clause
10859///
10860/// ```plaintext
10861/// <json_null_clause> ::=
10862///       NULL ON NULL
10863///     | ABSENT ON NULL
10864/// ```
10865///
10866/// <https://learn.microsoft.com/en-us/sql/t-sql/functions/json-object-transact-sql?view=sql-server-ver16#json_null_clause>
10867#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10868#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10869#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10870pub enum JsonNullClause {
10871    /// `NULL ON NULL` behavior for JSON functions.
10872    NullOnNull,
10873    /// `ABSENT ON NULL` behavior for JSON functions.
10874    AbsentOnNull,
10875}
10876
10877impl Display for JsonNullClause {
10878    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10879        match self {
10880            JsonNullClause::NullOnNull => write!(f, "NULL ON NULL"),
10881            JsonNullClause::AbsentOnNull => write!(f, "ABSENT ON NULL"),
10882        }
10883    }
10884}
10885
10886/// PostgreSQL JSON function RETURNING clause
10887///
10888/// Example:
10889/// ```sql
10890/// JSON_OBJECT('a': 1 RETURNING jsonb)
10891/// ```
10892#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10893#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10894#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10895pub struct JsonReturningClause {
10896    /// The data type to return from the JSON function (e.g. JSON/JSONB).
10897    pub data_type: DataType,
10898}
10899
10900impl Display for JsonReturningClause {
10901    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10902        write!(f, "RETURNING {}", self.data_type)
10903    }
10904}
10905
10906/// rename object definition
10907#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10908#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10909#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10910pub struct RenameTable {
10911    /// The current name of the object to rename.
10912    pub old_name: ObjectName,
10913    /// The new name for the object.
10914    pub new_name: ObjectName,
10915}
10916
10917impl fmt::Display for RenameTable {
10918    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10919        write!(f, "{} TO {}", self.old_name, self.new_name)?;
10920        Ok(())
10921    }
10922}
10923
10924/// Represents the referenced table in an `INSERT INTO` statement
10925#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10926#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10927#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10928pub enum TableObject {
10929    /// Table specified by name.
10930    /// Example:
10931    /// ```sql
10932    /// INSERT INTO my_table
10933    /// ```
10934    TableName(#[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] ObjectName),
10935
10936    /// Table specified as a function.
10937    /// Example:
10938    /// ```sql
10939    /// INSERT INTO TABLE FUNCTION remote('localhost', default.simple_table)
10940    /// ```
10941    /// [Clickhouse](https://clickhouse.com/docs/en/sql-reference/table-functions)
10942    TableFunction(Function),
10943
10944    /// Table specified through a sub-query
10945    /// Example:
10946    /// ```sql
10947    /// INSERT INTO
10948    /// (SELECT employee_id, last_name, email, hire_date, job_id,  salary, commission_pct FROM employees)
10949    /// VALUES (207, 'Gregory', 'pgregory@example.com', sysdate, 'PU_CLERK', 1.2E3, NULL);
10950    /// ```
10951    /// [Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/INSERT.html#GUID-903F8043-0254-4EE9-ACC1-CB8AC0AF3423__I2126242)
10952    TableQuery(Box<Query>),
10953}
10954
10955impl fmt::Display for TableObject {
10956    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10957        match self {
10958            Self::TableName(table_name) => write!(f, "{table_name}"),
10959            Self::TableFunction(func) => write!(f, "FUNCTION {func}"),
10960            Self::TableQuery(table_query) => write!(f, "({table_query})"),
10961        }
10962    }
10963}
10964
10965/// Represents a SET SESSION AUTHORIZATION statement
10966#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10967#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10968#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10969pub struct SetSessionAuthorizationParam {
10970    /// The scope for the `SET SESSION AUTHORIZATION` (e.g., GLOBAL/SESSION).
10971    pub scope: ContextModifier,
10972    /// The specific authorization parameter kind.
10973    pub kind: SetSessionAuthorizationParamKind,
10974}
10975
10976impl fmt::Display for SetSessionAuthorizationParam {
10977    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10978        write!(f, "{}", self.kind)
10979    }
10980}
10981
10982/// Represents the parameter kind for SET SESSION AUTHORIZATION
10983#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
10984#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
10985#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
10986pub enum SetSessionAuthorizationParamKind {
10987    /// Default authorization
10988    Default,
10989
10990    /// User name
10991    User(Ident),
10992}
10993
10994impl fmt::Display for SetSessionAuthorizationParamKind {
10995    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
10996        match self {
10997            SetSessionAuthorizationParamKind::Default => write!(f, "DEFAULT"),
10998            SetSessionAuthorizationParamKind::User(name) => write!(f, "{}", name),
10999        }
11000    }
11001}
11002
11003#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11004#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11005#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11006/// Kind of session parameter being set by `SET SESSION`.
11007pub enum SetSessionParamKind {
11008    /// Generic session parameter (name/value pair).
11009    Generic(SetSessionParamGeneric),
11010    /// Identity insert related parameter.
11011    IdentityInsert(SetSessionParamIdentityInsert),
11012    /// Offsets-related parameter.
11013    Offsets(SetSessionParamOffsets),
11014    /// Statistics-related parameter.
11015    Statistics(SetSessionParamStatistics),
11016}
11017
11018impl fmt::Display for SetSessionParamKind {
11019    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11020        match self {
11021            SetSessionParamKind::Generic(x) => write!(f, "{x}"),
11022            SetSessionParamKind::IdentityInsert(x) => write!(f, "{x}"),
11023            SetSessionParamKind::Offsets(x) => write!(f, "{x}"),
11024            SetSessionParamKind::Statistics(x) => write!(f, "{x}"),
11025        }
11026    }
11027}
11028
11029#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11030#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11031#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11032/// Generic `SET SESSION` parameter represented as name(s) and value.
11033pub struct SetSessionParamGeneric {
11034    /// Names of the session parameters being set.
11035    pub names: Vec<String>,
11036    /// The value to assign to the parameter(s).
11037    pub value: String,
11038}
11039
11040impl fmt::Display for SetSessionParamGeneric {
11041    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11042        write!(f, "{} {}", display_comma_separated(&self.names), self.value)
11043    }
11044}
11045
11046#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11047#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11048#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11049/// `IDENTITY_INSERT` session parameter for a specific object.
11050pub struct SetSessionParamIdentityInsert {
11051    /// Object name targeted by `IDENTITY_INSERT`.
11052    pub obj: ObjectName,
11053    /// Value (ON/OFF) for the identity insert setting.
11054    pub value: SessionParamValue,
11055}
11056
11057impl fmt::Display for SetSessionParamIdentityInsert {
11058    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11059        write!(f, "IDENTITY_INSERT {} {}", self.obj, self.value)
11060    }
11061}
11062
11063#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11064#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11065#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11066/// Offsets-related session parameter with keywords and a value.
11067pub struct SetSessionParamOffsets {
11068    /// Keywords specifying which offsets to modify.
11069    pub keywords: Vec<String>,
11070    /// Value (ON/OFF) for the offsets setting.
11071    pub value: SessionParamValue,
11072}
11073
11074impl fmt::Display for SetSessionParamOffsets {
11075    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11076        write!(
11077            f,
11078            "OFFSETS {} {}",
11079            display_comma_separated(&self.keywords),
11080            self.value
11081        )
11082    }
11083}
11084
11085#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11086#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11087#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11088/// Statistics-related session parameter specifying topic and value.
11089pub struct SetSessionParamStatistics {
11090    /// Statistics topic to set (IO/PROFILE/TIME/XML).
11091    pub topic: SessionParamStatsTopic,
11092    /// Value (ON/OFF) for the statistics topic.
11093    pub value: SessionParamValue,
11094}
11095
11096impl fmt::Display for SetSessionParamStatistics {
11097    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11098        write!(f, "STATISTICS {} {}", self.topic, self.value)
11099    }
11100}
11101
11102#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11103#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11104#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11105/// Topics available for session statistics configuration.
11106pub enum SessionParamStatsTopic {
11107    /// Input/output statistics.
11108    IO,
11109    /// Profile statistics.
11110    Profile,
11111    /// Time statistics.
11112    Time,
11113    /// XML-related statistics.
11114    Xml,
11115}
11116
11117impl fmt::Display for SessionParamStatsTopic {
11118    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11119        match self {
11120            SessionParamStatsTopic::IO => write!(f, "IO"),
11121            SessionParamStatsTopic::Profile => write!(f, "PROFILE"),
11122            SessionParamStatsTopic::Time => write!(f, "TIME"),
11123            SessionParamStatsTopic::Xml => write!(f, "XML"),
11124        }
11125    }
11126}
11127
11128#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11129#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11130#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11131/// Value for a session boolean-like parameter (ON/OFF).
11132pub enum SessionParamValue {
11133    /// Session parameter enabled.
11134    On,
11135    /// Session parameter disabled.
11136    Off,
11137}
11138
11139impl fmt::Display for SessionParamValue {
11140    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11141        match self {
11142            SessionParamValue::On => write!(f, "ON"),
11143            SessionParamValue::Off => write!(f, "OFF"),
11144        }
11145    }
11146}
11147
11148/// Snowflake StorageSerializationPolicy for Iceberg Tables
11149/// ```sql
11150/// [ STORAGE_SERIALIZATION_POLICY = { COMPATIBLE | OPTIMIZED } ]
11151/// ```
11152///
11153/// <https://docs.snowflake.com/en/sql-reference/sql/create-iceberg-table>
11154#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11155#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11156#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11157pub enum StorageSerializationPolicy {
11158    /// Use compatible serialization mode.
11159    Compatible,
11160    /// Use optimized serialization mode.
11161    Optimized,
11162}
11163
11164impl Display for StorageSerializationPolicy {
11165    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11166        match self {
11167            StorageSerializationPolicy::Compatible => write!(f, "COMPATIBLE"),
11168            StorageSerializationPolicy::Optimized => write!(f, "OPTIMIZED"),
11169        }
11170    }
11171}
11172
11173/// Snowflake CatalogSyncNamespaceMode
11174/// ```sql
11175/// [ CATALOG_SYNC_NAMESPACE_MODE = { NEST | FLATTEN } ]
11176/// ```
11177///
11178/// <https://docs.snowflake.com/en/sql-reference/sql/create-database>
11179#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11180#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11181#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11182pub enum CatalogSyncNamespaceMode {
11183    /// Nest namespaces when syncing catalog.
11184    Nest,
11185    /// Flatten namespaces when syncing catalog.
11186    Flatten,
11187}
11188
11189impl Display for CatalogSyncNamespaceMode {
11190    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11191        match self {
11192            CatalogSyncNamespaceMode::Nest => write!(f, "NEST"),
11193            CatalogSyncNamespaceMode::Flatten => write!(f, "FLATTEN"),
11194        }
11195    }
11196}
11197
11198/// Variants of the Snowflake `COPY INTO` statement
11199#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11200#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11201#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11202pub enum CopyIntoSnowflakeKind {
11203    /// Loads data from files to a table
11204    /// See: <https://docs.snowflake.com/en/sql-reference/sql/copy-into-table>
11205    Table,
11206    /// Unloads data from a table or query to external files
11207    /// See: <https://docs.snowflake.com/en/sql-reference/sql/copy-into-location>
11208    Location,
11209}
11210
11211#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11212#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11213#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11214/// `PRINT` statement for producing debug/output messages.
11215pub struct PrintStatement {
11216    /// The expression producing the message to print.
11217    pub message: Box<Expr>,
11218}
11219
11220impl fmt::Display for PrintStatement {
11221    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11222        write!(f, "PRINT {}", self.message)
11223    }
11224}
11225
11226/// The type of `WAITFOR` statement (MSSQL).
11227///
11228/// See: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/waitfor-transact-sql>
11229#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11230#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11231#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11232pub enum WaitForType {
11233    /// `WAITFOR DELAY 'time_to_pass'`
11234    Delay,
11235    /// `WAITFOR TIME 'time_to_execute'`
11236    Time,
11237}
11238
11239impl fmt::Display for WaitForType {
11240    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11241        match self {
11242            WaitForType::Delay => write!(f, "DELAY"),
11243            WaitForType::Time => write!(f, "TIME"),
11244        }
11245    }
11246}
11247
11248/// MSSQL `WAITFOR` statement.
11249///
11250/// See: <https://learn.microsoft.com/en-us/sql/t-sql/language-elements/waitfor-transact-sql>
11251#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11252#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11253#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11254pub struct WaitForStatement {
11255    /// `DELAY` or `TIME`.
11256    pub wait_type: WaitForType,
11257    /// The time expression.
11258    pub expr: Expr,
11259}
11260
11261impl fmt::Display for WaitForStatement {
11262    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11263        write!(f, "WAITFOR {} {}", self.wait_type, self.expr)
11264    }
11265}
11266
11267/// Represents a `Return` statement.
11268///
11269/// [MsSql triggers](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-trigger-transact-sql)
11270/// [MsSql functions](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-function-transact-sql)
11271#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11272#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11273#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11274pub struct ReturnStatement {
11275    /// Optional return value expression.
11276    pub value: Option<ReturnStatementValue>,
11277}
11278
11279impl fmt::Display for ReturnStatement {
11280    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11281        match &self.value {
11282            Some(ReturnStatementValue::Expr(expr)) => write!(f, "RETURN {expr}"),
11283            None => write!(f, "RETURN"),
11284        }
11285    }
11286}
11287
11288/// Variants of a `RETURN` statement
11289#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11290#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11291#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11292pub enum ReturnStatementValue {
11293    /// Return an expression from a function or trigger.
11294    Expr(Expr),
11295}
11296
11297/// Represents an `OPEN` statement.
11298#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11299#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11300#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11301pub struct OpenStatement {
11302    /// Cursor name
11303    pub cursor_name: Ident,
11304}
11305
11306impl fmt::Display for OpenStatement {
11307    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11308        write!(f, "OPEN {}", self.cursor_name)
11309    }
11310}
11311
11312/// Specifies Include / Exclude NULL within UNPIVOT command.
11313/// For example
11314/// `UNPIVOT (column1 FOR new_column IN (col3, col4, col5, col6))`
11315#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11316#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11317#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11318pub enum NullInclusion {
11319    /// Include NULL values in the UNPIVOT output.
11320    IncludeNulls,
11321    /// Exclude NULL values from the UNPIVOT output.
11322    ExcludeNulls,
11323}
11324
11325impl fmt::Display for NullInclusion {
11326    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11327        match self {
11328            NullInclusion::IncludeNulls => write!(f, "INCLUDE NULLS"),
11329            NullInclusion::ExcludeNulls => write!(f, "EXCLUDE NULLS"),
11330        }
11331    }
11332}
11333
11334/// Checks membership of a value in a JSON array
11335///
11336/// Syntax:
11337/// ```sql
11338/// <value> MEMBER OF(<array>)
11339/// ```
11340/// [MySQL](https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#operator_member-of)
11341#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11342#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11343#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11344pub struct MemberOf {
11345    /// The value to check for membership.
11346    pub value: Box<Expr>,
11347    /// The JSON array expression to check against.
11348    pub array: Box<Expr>,
11349}
11350
11351impl fmt::Display for MemberOf {
11352    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11353        write!(f, "{} MEMBER OF({})", self.value, self.array)
11354    }
11355}
11356
11357#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11358#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11359#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11360/// Represents an `EXPORT DATA` statement.
11361pub struct ExportData {
11362    /// Options for the export operation.
11363    pub options: Vec<SqlOption>,
11364    /// The query producing the data to export.
11365    pub query: Box<Query>,
11366    /// Optional named connection to use for export.
11367    pub connection: Option<ObjectName>,
11368}
11369
11370impl fmt::Display for ExportData {
11371    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11372        if let Some(connection) = &self.connection {
11373            write!(
11374                f,
11375                "EXPORT DATA WITH CONNECTION {connection} OPTIONS({}) AS {}",
11376                display_comma_separated(&self.options),
11377                self.query
11378            )
11379        } else {
11380            write!(
11381                f,
11382                "EXPORT DATA OPTIONS({}) AS {}",
11383                display_comma_separated(&self.options),
11384                self.query
11385            )
11386        }
11387    }
11388}
11389/// Creates a user
11390///
11391/// Syntax:
11392/// ```sql
11393/// CREATE [OR REPLACE] USER [IF NOT EXISTS] <name> [OPTIONS]
11394/// ```
11395///
11396/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-user)
11397#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11398#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11399#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11400pub struct CreateUser {
11401    /// Replace existing user if present.
11402    pub or_replace: bool,
11403    /// Only create the user if it does not already exist.
11404    pub if_not_exists: bool,
11405    /// The name of the user to create.
11406    pub name: Ident,
11407    /// Key/value options for user creation.
11408    pub options: KeyValueOptions,
11409    /// Whether tags are specified using `WITH TAG`.
11410    pub with_tags: bool,
11411    /// Tags for the user.
11412    pub tags: KeyValueOptions,
11413}
11414
11415impl fmt::Display for CreateUser {
11416    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11417        write!(f, "CREATE")?;
11418        if self.or_replace {
11419            write!(f, " OR REPLACE")?;
11420        }
11421        write!(f, " USER")?;
11422        if self.if_not_exists {
11423            write!(f, " IF NOT EXISTS")?;
11424        }
11425        write!(f, " {}", self.name)?;
11426        if !self.options.options.is_empty() {
11427            write!(f, " {}", self.options)?;
11428        }
11429        if !self.tags.options.is_empty() {
11430            if self.with_tags {
11431                write!(f, " WITH")?;
11432            }
11433            write!(f, " TAG ({})", self.tags)?;
11434        }
11435        Ok(())
11436    }
11437}
11438
11439/// Modifies the properties of a user
11440///
11441/// [Snowflake Syntax:](https://docs.snowflake.com/en/sql-reference/sql/alter-user)
11442/// ```sql
11443/// ALTER USER [ IF EXISTS ] [ <name> ] [ OPTIONS ]
11444/// ```
11445///
11446/// [PostgreSQL Syntax:](https://www.postgresql.org/docs/current/sql-alteruser.html)
11447/// ```sql
11448/// ALTER USER <role_specification> [ WITH ] option [ ... ]
11449/// ```
11450#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11451#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11452#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11453pub struct AlterUser {
11454    /// Whether to only alter the user if it exists.
11455    pub if_exists: bool,
11456    /// The name of the user to alter.
11457    pub name: Ident,
11458    /// Optional new name for the user (Snowflake-specific).
11459    /// See: <https://docs.snowflake.com/en/sql-reference/sql/alter-user#syntax>
11460    pub rename_to: Option<Ident>,
11461    /// Reset the user's password.
11462    pub reset_password: bool,
11463    /// Abort all running queries for the user.
11464    pub abort_all_queries: bool,
11465    /// Optionally add a delegated role authorization.
11466    pub add_role_delegation: Option<AlterUserAddRoleDelegation>,
11467    /// Optionally remove a delegated role authorization.
11468    pub remove_role_delegation: Option<AlterUserRemoveRoleDelegation>,
11469    /// Enroll the user in MFA.
11470    pub enroll_mfa: bool,
11471    /// Set the default MFA method for the user.
11472    pub set_default_mfa_method: Option<MfaMethodKind>,
11473    /// Remove the user's default MFA method.
11474    pub remove_mfa_method: Option<MfaMethodKind>,
11475    /// Modify an MFA method for the user.
11476    pub modify_mfa_method: Option<AlterUserModifyMfaMethod>,
11477    /// Add an MFA OTP method with optional count.
11478    pub add_mfa_method_otp: Option<AlterUserAddMfaMethodOtp>,
11479    /// Set a user policy.
11480    pub set_policy: Option<AlterUserSetPolicy>,
11481    /// Unset a user policy.
11482    pub unset_policy: Option<UserPolicyKind>,
11483    /// Key/value tag options to set on the user.
11484    pub set_tag: KeyValueOptions,
11485    /// Tags to unset on the user.
11486    pub unset_tag: Vec<String>,
11487    /// Key/value properties to set on the user.
11488    pub set_props: KeyValueOptions,
11489    /// Properties to unset on the user.
11490    pub unset_props: Vec<String>,
11491    /// The following options are PostgreSQL-specific: <https://www.postgresql.org/docs/current/sql-alteruser.html>
11492    pub password: Option<AlterUserPassword>,
11493}
11494
11495/// ```sql
11496/// ALTER USER [ IF EXISTS ] [ <name> ] ADD DELEGATED AUTHORIZATION OF ROLE <role_name> TO SECURITY INTEGRATION <integration_name>
11497/// ```
11498#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11499#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11500#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11501pub struct AlterUserAddRoleDelegation {
11502    /// Role name to delegate.
11503    pub role: Ident,
11504    /// Security integration receiving the delegation.
11505    pub integration: Ident,
11506}
11507
11508/// ```sql
11509/// ALTER USER [ IF EXISTS ] [ <name> ] REMOVE DELEGATED { AUTHORIZATION OF ROLE <role_name> | AUTHORIZATIONS } FROM SECURITY INTEGRATION <integration_name>
11510/// ```
11511#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11512#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11513#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11514pub struct AlterUserRemoveRoleDelegation {
11515    /// Optional role name to remove delegation for.
11516    pub role: Option<Ident>,
11517    /// Security integration from which to remove delegation.
11518    pub integration: Ident,
11519}
11520
11521/// ```sql
11522/// ADD MFA METHOD OTP [ COUNT = number ]
11523/// ```
11524#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11525#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11526#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11527pub struct AlterUserAddMfaMethodOtp {
11528    /// Optional OTP count parameter.
11529    pub count: Option<ValueWithSpan>,
11530}
11531
11532/// ```sql
11533/// ALTER USER [ IF EXISTS ] [ <name> ] MODIFY MFA METHOD <mfa_method> SET COMMENT = '<string>'
11534/// ```
11535#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11536#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11537#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11538pub struct AlterUserModifyMfaMethod {
11539    /// The MFA method being modified.
11540    pub method: MfaMethodKind,
11541    /// The new comment for the MFA method.
11542    pub comment: String,
11543}
11544
11545/// Types of MFA methods
11546#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11547#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11548#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11549pub enum MfaMethodKind {
11550    /// PassKey (hardware or platform passkey) MFA method.
11551    PassKey,
11552    /// Time-based One-Time Password (TOTP) MFA method.
11553    Totp,
11554    /// Duo Security MFA method.
11555    Duo,
11556}
11557
11558impl fmt::Display for MfaMethodKind {
11559    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11560        match self {
11561            MfaMethodKind::PassKey => write!(f, "PASSKEY"),
11562            MfaMethodKind::Totp => write!(f, "TOTP"),
11563            MfaMethodKind::Duo => write!(f, "DUO"),
11564        }
11565    }
11566}
11567
11568/// ```sql
11569/// ALTER USER [ IF EXISTS ] [ <name> ] SET { AUTHENTICATION | PASSWORD | SESSION } POLICY <policy_name>
11570/// ```
11571#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11572#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11573#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11574pub struct AlterUserSetPolicy {
11575    /// The kind of user policy being set (authentication/password/session).
11576    pub policy_kind: UserPolicyKind,
11577    /// The identifier of the policy to apply.
11578    pub policy: Ident,
11579}
11580
11581/// Types of user-based policies
11582#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11583#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11584#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11585pub enum UserPolicyKind {
11586    /// Authentication policy.
11587    Authentication,
11588    /// Password policy.
11589    Password,
11590    /// Session policy.
11591    Session,
11592}
11593
11594impl fmt::Display for UserPolicyKind {
11595    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11596        match self {
11597            UserPolicyKind::Authentication => write!(f, "AUTHENTICATION"),
11598            UserPolicyKind::Password => write!(f, "PASSWORD"),
11599            UserPolicyKind::Session => write!(f, "SESSION"),
11600        }
11601    }
11602}
11603
11604impl fmt::Display for AlterUser {
11605    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11606        write!(f, "ALTER")?;
11607        write!(f, " USER")?;
11608        if self.if_exists {
11609            write!(f, " IF EXISTS")?;
11610        }
11611        write!(f, " {}", self.name)?;
11612        if let Some(new_name) = &self.rename_to {
11613            write!(f, " RENAME TO {new_name}")?;
11614        }
11615        if self.reset_password {
11616            write!(f, " RESET PASSWORD")?;
11617        }
11618        if self.abort_all_queries {
11619            write!(f, " ABORT ALL QUERIES")?;
11620        }
11621        if let Some(role_delegation) = &self.add_role_delegation {
11622            let role = &role_delegation.role;
11623            let integration = &role_delegation.integration;
11624            write!(
11625                f,
11626                " ADD DELEGATED AUTHORIZATION OF ROLE {role} TO SECURITY INTEGRATION {integration}"
11627            )?;
11628        }
11629        if let Some(role_delegation) = &self.remove_role_delegation {
11630            write!(f, " REMOVE DELEGATED")?;
11631            match &role_delegation.role {
11632                Some(role) => write!(f, " AUTHORIZATION OF ROLE {role}")?,
11633                None => write!(f, " AUTHORIZATIONS")?,
11634            }
11635            let integration = &role_delegation.integration;
11636            write!(f, " FROM SECURITY INTEGRATION {integration}")?;
11637        }
11638        if self.enroll_mfa {
11639            write!(f, " ENROLL MFA")?;
11640        }
11641        if let Some(method) = &self.set_default_mfa_method {
11642            write!(f, " SET DEFAULT_MFA_METHOD {method}")?
11643        }
11644        if let Some(method) = &self.remove_mfa_method {
11645            write!(f, " REMOVE MFA METHOD {method}")?;
11646        }
11647        if let Some(modify) = &self.modify_mfa_method {
11648            let method = &modify.method;
11649            let comment = &modify.comment;
11650            write!(
11651                f,
11652                " MODIFY MFA METHOD {method} SET COMMENT '{}'",
11653                value::escape_single_quote_string(comment)
11654            )?;
11655        }
11656        if let Some(add_mfa_method_otp) = &self.add_mfa_method_otp {
11657            write!(f, " ADD MFA METHOD OTP")?;
11658            if let Some(count) = &add_mfa_method_otp.count {
11659                write!(f, " COUNT = {count}")?;
11660            }
11661        }
11662        if let Some(policy) = &self.set_policy {
11663            let policy_kind = &policy.policy_kind;
11664            let name = &policy.policy;
11665            write!(f, " SET {policy_kind} POLICY {name}")?;
11666        }
11667        if let Some(policy_kind) = &self.unset_policy {
11668            write!(f, " UNSET {policy_kind} POLICY")?;
11669        }
11670        if !self.set_tag.options.is_empty() {
11671            write!(f, " SET TAG {}", self.set_tag)?;
11672        }
11673        if !self.unset_tag.is_empty() {
11674            write!(f, " UNSET TAG {}", display_comma_separated(&self.unset_tag))?;
11675        }
11676        let has_props = !self.set_props.options.is_empty();
11677        if has_props {
11678            write!(f, " SET")?;
11679            write!(f, " {}", &self.set_props)?;
11680        }
11681        if !self.unset_props.is_empty() {
11682            write!(f, " UNSET {}", display_comma_separated(&self.unset_props))?;
11683        }
11684        if let Some(password) = &self.password {
11685            write!(f, " {}", password)?;
11686        }
11687        Ok(())
11688    }
11689}
11690
11691/// ```sql
11692/// ALTER USER <role_specification> [ WITH ] PASSWORD { 'password' | NULL }``
11693/// ```
11694#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11695#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11696#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11697pub struct AlterUserPassword {
11698    /// Whether the password is encrypted.
11699    pub encrypted: bool,
11700    /// The password string, or `None` for `NULL`.
11701    pub password: Option<String>,
11702}
11703
11704impl Display for AlterUserPassword {
11705    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11706        if self.encrypted {
11707            write!(f, "ENCRYPTED ")?;
11708        }
11709        write!(f, "PASSWORD")?;
11710        match &self.password {
11711            None => write!(f, " NULL")?,
11712            Some(password) => write!(f, " '{}'", value::escape_single_quote_string(password))?,
11713        }
11714        Ok(())
11715    }
11716}
11717
11718/// Specifies how to create a new table based on an existing table's schema.
11719/// '''sql
11720/// CREATE TABLE new LIKE old ...
11721/// '''
11722#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11723#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11724#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11725pub enum CreateTableLikeKind {
11726    /// '''sql
11727    /// CREATE TABLE new (LIKE old ...)
11728    /// '''
11729    /// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html)
11730    Parenthesized(CreateTableLike),
11731    /// '''sql
11732    /// CREATE TABLE new LIKE old ...
11733    /// '''
11734    /// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-table#label-create-table-like)
11735    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/data-definition-language#create_table_like)
11736    Plain(CreateTableLike),
11737}
11738
11739#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11740#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11741#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11742/// Controls whether defaults are included when creating a table FROM/LILE another.
11743pub enum CreateTableLikeDefaults {
11744    /// Include default values from the source table.
11745    Including,
11746    /// Exclude default values from the source table.
11747    Excluding,
11748}
11749
11750impl fmt::Display for CreateTableLikeDefaults {
11751    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11752        match self {
11753            CreateTableLikeDefaults::Including => write!(f, "INCLUDING DEFAULTS"),
11754            CreateTableLikeDefaults::Excluding => write!(f, "EXCLUDING DEFAULTS"),
11755        }
11756    }
11757}
11758
11759#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11760#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11761#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11762/// Represents the `LIKE` clause of a `CREATE TABLE` statement.
11763pub struct CreateTableLike {
11764    /// The source table name to copy the schema from.
11765    pub name: ObjectName,
11766    /// Optional behavior controlling whether defaults are copied.
11767    pub defaults: Option<CreateTableLikeDefaults>,
11768}
11769
11770impl fmt::Display for CreateTableLike {
11771    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11772        write!(f, "LIKE {}", self.name)?;
11773        if let Some(defaults) = &self.defaults {
11774            write!(f, " {defaults}")?;
11775        }
11776        Ok(())
11777    }
11778}
11779
11780/// Specifies the refresh mode for the dynamic table.
11781///
11782/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table)
11783#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11784#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11785#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11786pub enum RefreshModeKind {
11787    /// Automatic refresh mode (`AUTO`).
11788    Auto,
11789    /// Full refresh mode (`FULL`).
11790    Full,
11791    /// Incremental refresh mode (`INCREMENTAL`).
11792    Incremental,
11793}
11794
11795impl fmt::Display for RefreshModeKind {
11796    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11797        match self {
11798            RefreshModeKind::Auto => write!(f, "AUTO"),
11799            RefreshModeKind::Full => write!(f, "FULL"),
11800            RefreshModeKind::Incremental => write!(f, "INCREMENTAL"),
11801        }
11802    }
11803}
11804
11805/// Specifies the behavior of the initial refresh of the dynamic table.
11806///
11807/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table)
11808#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11809#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11810#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11811pub enum InitializeKind {
11812    /// Initialize on creation (`ON CREATE`).
11813    OnCreate,
11814    /// Initialize on schedule (`ON SCHEDULE`).
11815    OnSchedule,
11816}
11817
11818impl fmt::Display for InitializeKind {
11819    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11820        match self {
11821            InitializeKind::OnCreate => write!(f, "ON_CREATE"),
11822            InitializeKind::OnSchedule => write!(f, "ON_SCHEDULE"),
11823        }
11824    }
11825}
11826
11827/// Re-sorts rows and reclaims space in either a specified table or all tables in the current database
11828///
11829/// '''sql
11830/// VACUUM [ FULL | SORT ONLY | DELETE ONLY | REINDEX | RECLUSTER ] [ \[ table_name \] [ TO threshold PERCENT ] \[ BOOST \] ]
11831/// '''
11832/// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)
11833#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11834#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11835#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11836pub struct VacuumStatement {
11837    /// Whether `FULL` was specified.
11838    pub full: bool,
11839    /// Whether `SORT ONLY` was specified.
11840    pub sort_only: bool,
11841    /// Whether `DELETE ONLY` was specified.
11842    pub delete_only: bool,
11843    /// Whether `REINDEX` was specified.
11844    pub reindex: bool,
11845    /// Whether `RECLUSTER` was specified.
11846    pub recluster: bool,
11847    /// Optional table to run `VACUUM` on.
11848    pub table_name: Option<ObjectName>,
11849    /// Optional threshold value (percent) for `TO threshold PERCENT`.
11850    pub threshold: Option<ValueWithSpan>,
11851    /// Whether `BOOST` was specified.
11852    pub boost: bool,
11853}
11854
11855impl fmt::Display for VacuumStatement {
11856    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11857        write!(
11858            f,
11859            "VACUUM{}{}{}{}{}",
11860            if self.full { " FULL" } else { "" },
11861            if self.sort_only { " SORT ONLY" } else { "" },
11862            if self.delete_only { " DELETE ONLY" } else { "" },
11863            if self.reindex { " REINDEX" } else { "" },
11864            if self.recluster { " RECLUSTER" } else { "" },
11865        )?;
11866        if let Some(table_name) = &self.table_name {
11867            write!(f, " {table_name}")?;
11868        }
11869        if let Some(threshold) = &self.threshold {
11870            write!(f, " TO {threshold} PERCENT")?;
11871        }
11872        if self.boost {
11873            write!(f, " BOOST")?;
11874        }
11875        Ok(())
11876    }
11877}
11878
11879/// Variants of the RESET statement
11880#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11881#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11882#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11883pub enum Reset {
11884    /// Resets all session parameters to their default values.
11885    ALL,
11886
11887    /// Resets a specific session parameter to its default value.
11888    ConfigurationParameter(ObjectName),
11889}
11890
11891/// Resets a session parameter to its default value.
11892/// ```sql
11893/// RESET { ALL | <configuration_parameter> }
11894/// ```
11895#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11896#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11897#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11898pub struct ResetStatement {
11899    /// The reset action to perform (either `ALL` or a specific configuration parameter).
11900    pub reset: Reset,
11901}
11902
11903/// Query optimizer hints are optionally supported comments after the
11904/// `SELECT`, `INSERT`, `UPDATE`, `REPLACE`, `MERGE`, and `DELETE` keywords in
11905/// the corresponding statements.
11906///
11907/// See [Select::optimizer_hints]
11908#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11909#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11910#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11911pub struct OptimizerHint {
11912    /// An optional prefix between the comment marker and `+`.
11913    ///
11914    /// Standard optimizer hints like `/*+ ... */` have an empty prefix,
11915    /// while system-specific hints like `/*abc+ ... */` have `prefix = "abc"`.
11916    /// The prefix is any sequence of ASCII alphanumeric characters
11917    /// immediately before the `+` marker.
11918    pub prefix: String,
11919    /// the raw text of the optimizer hint without its markers
11920    pub text: String,
11921    /// the style of the comment which `text` was extracted from,
11922    /// e.g. `/*+...*/` or `--+...`
11923    ///
11924    /// Not all dialects support all styles, though.
11925    pub style: OptimizerHintStyle,
11926}
11927
11928/// The commentary style of an [optimizer hint](OptimizerHint)
11929#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
11930#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11931#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
11932pub enum OptimizerHintStyle {
11933    /// A hint corresponding to a single line comment,
11934    /// e.g. `--+ LEADING(v.e v.d t)`
11935    SingleLine {
11936        /// the comment prefix, e.g. `--`
11937        prefix: String,
11938    },
11939    /// A hint corresponding to a multi line comment,
11940    /// e.g. `/*+ LEADING(v.e v.d t) */`
11941    MultiLine,
11942}
11943
11944impl fmt::Display for OptimizerHint {
11945    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11946        match &self.style {
11947            OptimizerHintStyle::SingleLine { prefix } => {
11948                f.write_str(prefix)?;
11949                f.write_str(&self.prefix)?;
11950                f.write_str("+")?;
11951                f.write_str(&self.text)
11952            }
11953            OptimizerHintStyle::MultiLine => {
11954                f.write_str("/*")?;
11955                f.write_str(&self.prefix)?;
11956                f.write_str("+")?;
11957                f.write_str(&self.text)?;
11958                f.write_str("*/")
11959            }
11960        }
11961    }
11962}
11963
11964impl fmt::Display for ResetStatement {
11965    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
11966        match &self.reset {
11967            Reset::ALL => write!(f, "RESET ALL"),
11968            Reset::ConfigurationParameter(param) => write!(f, "RESET {}", param),
11969        }
11970    }
11971}
11972
11973impl From<Set> for Statement {
11974    fn from(s: Set) -> Self {
11975        Self::Set(s)
11976    }
11977}
11978
11979impl From<Query> for Statement {
11980    fn from(q: Query) -> Self {
11981        Box::new(q).into()
11982    }
11983}
11984
11985impl From<Box<Query>> for Statement {
11986    fn from(q: Box<Query>) -> Self {
11987        Self::Query(q)
11988    }
11989}
11990
11991impl From<Insert> for Statement {
11992    fn from(i: Insert) -> Self {
11993        Self::Insert(i)
11994    }
11995}
11996
11997impl From<Update> for Statement {
11998    fn from(u: Update) -> Self {
11999        Self::Update(u)
12000    }
12001}
12002
12003impl From<CreateView> for Statement {
12004    fn from(cv: CreateView) -> Self {
12005        Self::CreateView(cv)
12006    }
12007}
12008
12009impl From<CreateRole> for Statement {
12010    fn from(cr: CreateRole) -> Self {
12011        Self::CreateRole(cr)
12012    }
12013}
12014
12015impl From<AlterTable> for Statement {
12016    fn from(at: AlterTable) -> Self {
12017        Self::AlterTable(at)
12018    }
12019}
12020
12021impl From<DropFunction> for Statement {
12022    fn from(df: DropFunction) -> Self {
12023        Self::DropFunction(df)
12024    }
12025}
12026
12027impl From<CreateExtension> for Statement {
12028    fn from(ce: CreateExtension) -> Self {
12029        Self::CreateExtension(ce)
12030    }
12031}
12032
12033impl From<CreateCollation> for Statement {
12034    fn from(c: CreateCollation) -> Self {
12035        Self::CreateCollation(c)
12036    }
12037}
12038
12039impl From<DropExtension> for Statement {
12040    fn from(de: DropExtension) -> Self {
12041        Self::DropExtension(de)
12042    }
12043}
12044
12045impl From<CaseStatement> for Statement {
12046    fn from(c: CaseStatement) -> Self {
12047        Self::Case(c)
12048    }
12049}
12050
12051impl From<IfStatement> for Statement {
12052    fn from(i: IfStatement) -> Self {
12053        Self::If(i)
12054    }
12055}
12056
12057impl From<WhileStatement> for Statement {
12058    fn from(w: WhileStatement) -> Self {
12059        Self::While(w)
12060    }
12061}
12062
12063impl From<RaiseStatement> for Statement {
12064    fn from(r: RaiseStatement) -> Self {
12065        Self::Raise(r)
12066    }
12067}
12068
12069impl From<ThrowStatement> for Statement {
12070    fn from(t: ThrowStatement) -> Self {
12071        Self::Throw(t)
12072    }
12073}
12074
12075impl From<Function> for Statement {
12076    fn from(f: Function) -> Self {
12077        Self::Call(f)
12078    }
12079}
12080
12081impl From<OpenStatement> for Statement {
12082    fn from(o: OpenStatement) -> Self {
12083        Self::Open(o)
12084    }
12085}
12086
12087impl From<Delete> for Statement {
12088    fn from(d: Delete) -> Self {
12089        Self::Delete(d)
12090    }
12091}
12092
12093impl From<CreateTable> for Statement {
12094    fn from(c: CreateTable) -> Self {
12095        Self::CreateTable(c)
12096    }
12097}
12098
12099impl From<CreateIndex> for Statement {
12100    fn from(c: CreateIndex) -> Self {
12101        Self::CreateIndex(c)
12102    }
12103}
12104
12105impl From<CreateServerStatement> for Statement {
12106    fn from(c: CreateServerStatement) -> Self {
12107        Self::CreateServer(c)
12108    }
12109}
12110
12111impl From<CreateConnector> for Statement {
12112    fn from(c: CreateConnector) -> Self {
12113        Self::CreateConnector(c)
12114    }
12115}
12116
12117impl From<CreateOperator> for Statement {
12118    fn from(c: CreateOperator) -> Self {
12119        Self::CreateOperator(c)
12120    }
12121}
12122
12123impl From<CreateOperatorFamily> for Statement {
12124    fn from(c: CreateOperatorFamily) -> Self {
12125        Self::CreateOperatorFamily(c)
12126    }
12127}
12128
12129impl From<CreateOperatorClass> for Statement {
12130    fn from(c: CreateOperatorClass) -> Self {
12131        Self::CreateOperatorClass(c)
12132    }
12133}
12134
12135impl From<AlterSchema> for Statement {
12136    fn from(a: AlterSchema) -> Self {
12137        Self::AlterSchema(a)
12138    }
12139}
12140
12141impl From<AlterFunction> for Statement {
12142    fn from(a: AlterFunction) -> Self {
12143        Self::AlterFunction(a)
12144    }
12145}
12146
12147impl From<AlterType> for Statement {
12148    fn from(a: AlterType) -> Self {
12149        Self::AlterType(a)
12150    }
12151}
12152
12153impl From<AlterCollation> for Statement {
12154    fn from(a: AlterCollation) -> Self {
12155        Self::AlterCollation(a)
12156    }
12157}
12158
12159impl From<AlterOperator> for Statement {
12160    fn from(a: AlterOperator) -> Self {
12161        Self::AlterOperator(a)
12162    }
12163}
12164
12165impl From<AlterOperatorFamily> for Statement {
12166    fn from(a: AlterOperatorFamily) -> Self {
12167        Self::AlterOperatorFamily(a)
12168    }
12169}
12170
12171impl From<AlterOperatorClass> for Statement {
12172    fn from(a: AlterOperatorClass) -> Self {
12173        Self::AlterOperatorClass(a)
12174    }
12175}
12176
12177impl From<Merge> for Statement {
12178    fn from(m: Merge) -> Self {
12179        Self::Merge(m)
12180    }
12181}
12182
12183impl From<AlterUser> for Statement {
12184    fn from(a: AlterUser) -> Self {
12185        Self::AlterUser(a)
12186    }
12187}
12188
12189impl From<DropDomain> for Statement {
12190    fn from(d: DropDomain) -> Self {
12191        Self::DropDomain(d)
12192    }
12193}
12194
12195impl From<ShowCharset> for Statement {
12196    fn from(s: ShowCharset) -> Self {
12197        Self::ShowCharset(s)
12198    }
12199}
12200
12201impl From<ShowObjects> for Statement {
12202    fn from(s: ShowObjects) -> Self {
12203        Self::ShowObjects(s)
12204    }
12205}
12206
12207impl From<Use> for Statement {
12208    fn from(u: Use) -> Self {
12209        Self::Use(u)
12210    }
12211}
12212
12213impl From<CreateFunction> for Statement {
12214    fn from(c: CreateFunction) -> Self {
12215        Self::CreateFunction(c)
12216    }
12217}
12218
12219impl From<CreateTrigger> for Statement {
12220    fn from(c: CreateTrigger) -> Self {
12221        Self::CreateTrigger(c)
12222    }
12223}
12224
12225impl From<DropTrigger> for Statement {
12226    fn from(d: DropTrigger) -> Self {
12227        Self::DropTrigger(d)
12228    }
12229}
12230
12231impl From<DropOperator> for Statement {
12232    fn from(d: DropOperator) -> Self {
12233        Self::DropOperator(d)
12234    }
12235}
12236
12237impl From<DropOperatorFamily> for Statement {
12238    fn from(d: DropOperatorFamily) -> Self {
12239        Self::DropOperatorFamily(d)
12240    }
12241}
12242
12243impl From<DropOperatorClass> for Statement {
12244    fn from(d: DropOperatorClass) -> Self {
12245        Self::DropOperatorClass(d)
12246    }
12247}
12248
12249impl From<DenyStatement> for Statement {
12250    fn from(d: DenyStatement) -> Self {
12251        Self::Deny(d)
12252    }
12253}
12254
12255impl From<CreateDomain> for Statement {
12256    fn from(c: CreateDomain) -> Self {
12257        Self::CreateDomain(c)
12258    }
12259}
12260
12261impl From<RenameTable> for Statement {
12262    fn from(r: RenameTable) -> Self {
12263        vec![r].into()
12264    }
12265}
12266
12267impl From<Vec<RenameTable>> for Statement {
12268    fn from(r: Vec<RenameTable>) -> Self {
12269        Self::RenameTable(r)
12270    }
12271}
12272
12273impl From<PrintStatement> for Statement {
12274    fn from(p: PrintStatement) -> Self {
12275        Self::Print(p)
12276    }
12277}
12278
12279impl From<ReturnStatement> for Statement {
12280    fn from(r: ReturnStatement) -> Self {
12281        Self::Return(r)
12282    }
12283}
12284
12285impl From<ExportData> for Statement {
12286    fn from(e: ExportData) -> Self {
12287        Self::ExportData(e)
12288    }
12289}
12290
12291impl From<CreateUser> for Statement {
12292    fn from(c: CreateUser) -> Self {
12293        Self::CreateUser(c)
12294    }
12295}
12296
12297impl From<VacuumStatement> for Statement {
12298    fn from(v: VacuumStatement) -> Self {
12299        Self::Vacuum(v)
12300    }
12301}
12302
12303impl From<ResetStatement> for Statement {
12304    fn from(r: ResetStatement) -> Self {
12305        Self::Reset(r)
12306    }
12307}
12308
12309#[cfg(test)]
12310mod tests {
12311    use crate::tokenizer::Location;
12312
12313    use super::*;
12314
12315    #[test]
12316    fn test_window_frame_default() {
12317        let window_frame = WindowFrame::default();
12318        assert_eq!(WindowFrameBound::Preceding(None), window_frame.start_bound);
12319    }
12320
12321    #[test]
12322    fn test_grouping_sets_display() {
12323        // a and b in different group
12324        let grouping_sets = Expr::GroupingSets(vec![
12325            vec![Expr::Identifier(Ident::new("a"))],
12326            vec![Expr::Identifier(Ident::new("b"))],
12327        ]);
12328        assert_eq!("GROUPING SETS ((a), (b))", format!("{grouping_sets}"));
12329
12330        // a and b in the same group
12331        let grouping_sets = Expr::GroupingSets(vec![vec![
12332            Expr::Identifier(Ident::new("a")),
12333            Expr::Identifier(Ident::new("b")),
12334        ]]);
12335        assert_eq!("GROUPING SETS ((a, b))", format!("{grouping_sets}"));
12336
12337        // (a, b) and (c, d) in different group
12338        let grouping_sets = Expr::GroupingSets(vec![
12339            vec![
12340                Expr::Identifier(Ident::new("a")),
12341                Expr::Identifier(Ident::new("b")),
12342            ],
12343            vec![
12344                Expr::Identifier(Ident::new("c")),
12345                Expr::Identifier(Ident::new("d")),
12346            ],
12347        ]);
12348        assert_eq!("GROUPING SETS ((a, b), (c, d))", format!("{grouping_sets}"));
12349    }
12350
12351    #[test]
12352    fn test_rollup_display() {
12353        let rollup = Expr::Rollup(vec![vec![Expr::Identifier(Ident::new("a"))]]);
12354        assert_eq!("ROLLUP (a)", format!("{rollup}"));
12355
12356        let rollup = Expr::Rollup(vec![vec![
12357            Expr::Identifier(Ident::new("a")),
12358            Expr::Identifier(Ident::new("b")),
12359        ]]);
12360        assert_eq!("ROLLUP ((a, b))", format!("{rollup}"));
12361
12362        let rollup = Expr::Rollup(vec![
12363            vec![Expr::Identifier(Ident::new("a"))],
12364            vec![Expr::Identifier(Ident::new("b"))],
12365        ]);
12366        assert_eq!("ROLLUP (a, b)", format!("{rollup}"));
12367
12368        let rollup = Expr::Rollup(vec![
12369            vec![Expr::Identifier(Ident::new("a"))],
12370            vec![
12371                Expr::Identifier(Ident::new("b")),
12372                Expr::Identifier(Ident::new("c")),
12373            ],
12374            vec![Expr::Identifier(Ident::new("d"))],
12375        ]);
12376        assert_eq!("ROLLUP (a, (b, c), d)", format!("{rollup}"));
12377    }
12378
12379    #[test]
12380    fn test_cube_display() {
12381        let cube = Expr::Cube(vec![vec![Expr::Identifier(Ident::new("a"))]]);
12382        assert_eq!("CUBE (a)", format!("{cube}"));
12383
12384        let cube = Expr::Cube(vec![vec![
12385            Expr::Identifier(Ident::new("a")),
12386            Expr::Identifier(Ident::new("b")),
12387        ]]);
12388        assert_eq!("CUBE ((a, b))", format!("{cube}"));
12389
12390        let cube = Expr::Cube(vec![
12391            vec![Expr::Identifier(Ident::new("a"))],
12392            vec![Expr::Identifier(Ident::new("b"))],
12393        ]);
12394        assert_eq!("CUBE (a, b)", format!("{cube}"));
12395
12396        let cube = Expr::Cube(vec![
12397            vec![Expr::Identifier(Ident::new("a"))],
12398            vec![
12399                Expr::Identifier(Ident::new("b")),
12400                Expr::Identifier(Ident::new("c")),
12401            ],
12402            vec![Expr::Identifier(Ident::new("d"))],
12403        ]);
12404        assert_eq!("CUBE (a, (b, c), d)", format!("{cube}"));
12405    }
12406
12407    #[test]
12408    fn test_interval_display() {
12409        let interval = Expr::Interval(Interval {
12410            value: Box::new(Expr::Value(
12411                Value::SingleQuotedString(String::from("123:45.67")).with_empty_span(),
12412            )),
12413            leading_field: Some(DateTimeField::Minute),
12414            leading_precision: Some(10),
12415            last_field: Some(DateTimeField::Second),
12416            fractional_seconds_precision: Some(9),
12417        });
12418        assert_eq!(
12419            "INTERVAL '123:45.67' MINUTE (10) TO SECOND (9)",
12420            format!("{interval}"),
12421        );
12422
12423        let interval = Expr::Interval(Interval {
12424            value: Box::new(Expr::Value(
12425                Value::SingleQuotedString(String::from("5")).with_empty_span(),
12426            )),
12427            leading_field: Some(DateTimeField::Second),
12428            leading_precision: Some(1),
12429            last_field: None,
12430            fractional_seconds_precision: Some(3),
12431        });
12432        assert_eq!("INTERVAL '5' SECOND (1, 3)", format!("{interval}"));
12433    }
12434
12435    #[test]
12436    fn test_one_or_many_with_parens_deref() {
12437        use core::ops::Index;
12438
12439        let one = OneOrManyWithParens::One("a");
12440
12441        assert_eq!(one.deref(), &["a"]);
12442        assert_eq!(<OneOrManyWithParens<_> as Deref>::deref(&one), &["a"]);
12443
12444        assert_eq!(one[0], "a");
12445        assert_eq!(one.index(0), &"a");
12446        assert_eq!(
12447            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&one, 0),
12448            &"a"
12449        );
12450
12451        assert_eq!(one.len(), 1);
12452        assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&one), 1);
12453
12454        let many1 = OneOrManyWithParens::Many(vec!["b"]);
12455
12456        assert_eq!(many1.deref(), &["b"]);
12457        assert_eq!(<OneOrManyWithParens<_> as Deref>::deref(&many1), &["b"]);
12458
12459        assert_eq!(many1[0], "b");
12460        assert_eq!(many1.index(0), &"b");
12461        assert_eq!(
12462            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many1, 0),
12463            &"b"
12464        );
12465
12466        assert_eq!(many1.len(), 1);
12467        assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&many1), 1);
12468
12469        let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
12470
12471        assert_eq!(many2.deref(), &["c", "d"]);
12472        assert_eq!(
12473            <OneOrManyWithParens<_> as Deref>::deref(&many2),
12474            &["c", "d"]
12475        );
12476
12477        assert_eq!(many2[0], "c");
12478        assert_eq!(many2.index(0), &"c");
12479        assert_eq!(
12480            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many2, 0),
12481            &"c"
12482        );
12483
12484        assert_eq!(many2[1], "d");
12485        assert_eq!(many2.index(1), &"d");
12486        assert_eq!(
12487            <<OneOrManyWithParens<_> as Deref>::Target as Index<usize>>::index(&many2, 1),
12488            &"d"
12489        );
12490
12491        assert_eq!(many2.len(), 2);
12492        assert_eq!(<OneOrManyWithParens<_> as Deref>::Target::len(&many2), 2);
12493    }
12494
12495    #[test]
12496    fn test_one_or_many_with_parens_as_ref() {
12497        let one = OneOrManyWithParens::One("a");
12498
12499        assert_eq!(one.as_ref(), &["a"]);
12500        assert_eq!(<OneOrManyWithParens<_> as AsRef<_>>::as_ref(&one), &["a"]);
12501
12502        let many1 = OneOrManyWithParens::Many(vec!["b"]);
12503
12504        assert_eq!(many1.as_ref(), &["b"]);
12505        assert_eq!(<OneOrManyWithParens<_> as AsRef<_>>::as_ref(&many1), &["b"]);
12506
12507        let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
12508
12509        assert_eq!(many2.as_ref(), &["c", "d"]);
12510        assert_eq!(
12511            <OneOrManyWithParens<_> as AsRef<_>>::as_ref(&many2),
12512            &["c", "d"]
12513        );
12514    }
12515
12516    #[test]
12517    fn test_one_or_many_with_parens_ref_into_iter() {
12518        let one = OneOrManyWithParens::One("a");
12519
12520        assert_eq!(Vec::from_iter(&one), vec![&"a"]);
12521
12522        let many1 = OneOrManyWithParens::Many(vec!["b"]);
12523
12524        assert_eq!(Vec::from_iter(&many1), vec![&"b"]);
12525
12526        let many2 = OneOrManyWithParens::Many(vec!["c", "d"]);
12527
12528        assert_eq!(Vec::from_iter(&many2), vec![&"c", &"d"]);
12529    }
12530
12531    #[test]
12532    fn test_one_or_many_with_parens_value_into_iter() {
12533        use core::iter::once;
12534
12535        //tests that our iterator implemented methods behaves exactly as it's inner iterator, at every step up to n calls to next/next_back
12536        fn test_steps<I>(ours: OneOrManyWithParens<usize>, inner: I, n: usize)
12537        where
12538            I: IntoIterator<Item = usize, IntoIter: DoubleEndedIterator + Clone> + Clone,
12539        {
12540            fn checks<I>(ours: OneOrManyWithParensIntoIter<usize>, inner: I)
12541            where
12542                I: Iterator<Item = usize> + Clone + DoubleEndedIterator,
12543            {
12544                assert_eq!(ours.size_hint(), inner.size_hint());
12545                assert_eq!(ours.clone().count(), inner.clone().count());
12546
12547                assert_eq!(
12548                    ours.clone().fold(1, |a, v| a + v),
12549                    inner.clone().fold(1, |a, v| a + v)
12550                );
12551
12552                assert_eq!(Vec::from_iter(ours.clone()), Vec::from_iter(inner.clone()));
12553                assert_eq!(
12554                    Vec::from_iter(ours.clone().rev()),
12555                    Vec::from_iter(inner.clone().rev())
12556                );
12557            }
12558
12559            let mut ours_next = ours.clone().into_iter();
12560            let mut inner_next = inner.clone().into_iter();
12561
12562            for _ in 0..n {
12563                checks(ours_next.clone(), inner_next.clone());
12564
12565                assert_eq!(ours_next.next(), inner_next.next());
12566            }
12567
12568            let mut ours_next_back = ours.clone().into_iter();
12569            let mut inner_next_back = inner.clone().into_iter();
12570
12571            for _ in 0..n {
12572                checks(ours_next_back.clone(), inner_next_back.clone());
12573
12574                assert_eq!(ours_next_back.next_back(), inner_next_back.next_back());
12575            }
12576
12577            let mut ours_mixed = ours.clone().into_iter();
12578            let mut inner_mixed = inner.clone().into_iter();
12579
12580            for i in 0..n {
12581                checks(ours_mixed.clone(), inner_mixed.clone());
12582
12583                if i % 2 == 0 {
12584                    assert_eq!(ours_mixed.next_back(), inner_mixed.next_back());
12585                } else {
12586                    assert_eq!(ours_mixed.next(), inner_mixed.next());
12587                }
12588            }
12589
12590            let mut ours_mixed2 = ours.into_iter();
12591            let mut inner_mixed2 = inner.into_iter();
12592
12593            for i in 0..n {
12594                checks(ours_mixed2.clone(), inner_mixed2.clone());
12595
12596                if i % 2 == 0 {
12597                    assert_eq!(ours_mixed2.next(), inner_mixed2.next());
12598                } else {
12599                    assert_eq!(ours_mixed2.next_back(), inner_mixed2.next_back());
12600                }
12601            }
12602        }
12603
12604        test_steps(OneOrManyWithParens::One(1), once(1), 3);
12605        test_steps(OneOrManyWithParens::Many(vec![2]), vec![2], 3);
12606        test_steps(OneOrManyWithParens::Many(vec![3, 4]), vec![3, 4], 4);
12607    }
12608
12609    // Tests that the position in the code of an `Ident` does not affect its
12610    // ordering.
12611    #[test]
12612    fn test_ident_ord() {
12613        let mut a = Ident::with_span(Span::new(Location::new(1, 1), Location::new(1, 1)), "a");
12614        let mut b = Ident::with_span(Span::new(Location::new(2, 2), Location::new(2, 2)), "b");
12615
12616        assert!(a < b);
12617        std::mem::swap(&mut a.span, &mut b.span);
12618        assert!(a < b);
12619    }
12620}