Skip to main content

sqlparser/ast/
dml.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18#[cfg(not(feature = "std"))]
19use alloc::{boxed::Box, format, string::ToString, vec::Vec};
20
21use core::fmt::{self, Display};
22#[cfg(feature = "serde")]
23use serde::{Deserialize, Serialize};
24#[cfg(feature = "visitor")]
25use sqlparser_derive::{Visit, VisitMut};
26
27use crate::{
28    ast::display_separated,
29    display_utils::{indented_list, Indent, SpaceOrNewline},
30};
31
32use super::{
33    display_comma_separated, helpers::attached_token::AttachedToken, query::InputFormatClause,
34    Assignment, Expr, FromTable, Ident, InsertAliases, MysqlInsertPriority, ObjectName, OnInsert,
35    OptimizerHint, OrderByExpr, Query, SelectInto, SelectItem, Setting, SqliteOnConflict,
36    TableFactor, TableObject, TableWithJoins, UpdateTableFromKind, Values,
37};
38
39/// INSERT statement.
40#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Insert {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["insert_token", "optimizer_hint", "or", "ignore", "into",
                        "table", "table_alias", "columns", "overwrite", "source",
                        "assignments", "partitioned", "after_columns",
                        "has_table_keyword", "on", "returning", "replace_into",
                        "priority", "insert_alias", "settings", "format_clause"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.insert_token, &self.optimizer_hint, &self.or,
                        &self.ignore, &self.into, &self.table, &self.table_alias,
                        &self.columns, &self.overwrite, &self.source,
                        &self.assignments, &self.partitioned, &self.after_columns,
                        &self.has_table_keyword, &self.on, &self.returning,
                        &self.replace_into, &self.priority, &self.insert_alias,
                        &self.settings, &&self.format_clause];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "Insert", names,
            values)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Insert {
    #[inline]
    fn clone(&self) -> Insert {
        Insert {
            insert_token: ::core::clone::Clone::clone(&self.insert_token),
            optimizer_hint: ::core::clone::Clone::clone(&self.optimizer_hint),
            or: ::core::clone::Clone::clone(&self.or),
            ignore: ::core::clone::Clone::clone(&self.ignore),
            into: ::core::clone::Clone::clone(&self.into),
            table: ::core::clone::Clone::clone(&self.table),
            table_alias: ::core::clone::Clone::clone(&self.table_alias),
            columns: ::core::clone::Clone::clone(&self.columns),
            overwrite: ::core::clone::Clone::clone(&self.overwrite),
            source: ::core::clone::Clone::clone(&self.source),
            assignments: ::core::clone::Clone::clone(&self.assignments),
            partitioned: ::core::clone::Clone::clone(&self.partitioned),
            after_columns: ::core::clone::Clone::clone(&self.after_columns),
            has_table_keyword: ::core::clone::Clone::clone(&self.has_table_keyword),
            on: ::core::clone::Clone::clone(&self.on),
            returning: ::core::clone::Clone::clone(&self.returning),
            replace_into: ::core::clone::Clone::clone(&self.replace_into),
            priority: ::core::clone::Clone::clone(&self.priority),
            insert_alias: ::core::clone::Clone::clone(&self.insert_alias),
            settings: ::core::clone::Clone::clone(&self.settings),
            format_clause: ::core::clone::Clone::clone(&self.format_clause),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Insert {
    #[inline]
    fn eq(&self, other: &Insert) -> bool {
        self.ignore == other.ignore && self.into == other.into &&
                                                                                    self.overwrite == other.overwrite &&
                                                                                self.has_table_keyword == other.has_table_keyword &&
                                                                            self.replace_into == other.replace_into &&
                                                                        self.insert_token == other.insert_token &&
                                                                    self.optimizer_hint == other.optimizer_hint &&
                                                                self.or == other.or && self.table == other.table &&
                                                        self.table_alias == other.table_alias &&
                                                    self.columns == other.columns && self.source == other.source
                                            && self.assignments == other.assignments &&
                                        self.partitioned == other.partitioned &&
                                    self.after_columns == other.after_columns &&
                                self.on == other.on && self.returning == other.returning &&
                        self.priority == other.priority &&
                    self.insert_alias == other.insert_alias &&
                self.settings == other.settings &&
            self.format_clause == other.format_clause
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Insert {
    #[inline]
    fn partial_cmp(&self, other: &Insert)
        -> ::core::option::Option<::core::cmp::Ordering> {
        match ::core::cmp::PartialOrd::partial_cmp(&self.insert_token,
                &other.insert_token) {
            ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
                match ::core::cmp::PartialOrd::partial_cmp(&self.optimizer_hint,
                        &other.optimizer_hint) {
                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                        =>
                        match ::core::cmp::PartialOrd::partial_cmp(&self.or,
                                &other.or) {
                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                =>
                                match ::core::cmp::PartialOrd::partial_cmp(&self.ignore,
                                        &other.ignore) {
                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                        =>
                                        match ::core::cmp::PartialOrd::partial_cmp(&self.into,
                                                &other.into) {
                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                =>
                                                match ::core::cmp::PartialOrd::partial_cmp(&self.table,
                                                        &other.table) {
                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                        =>
                                                        match ::core::cmp::PartialOrd::partial_cmp(&self.table_alias,
                                                                &other.table_alias) {
                                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                =>
                                                                match ::core::cmp::PartialOrd::partial_cmp(&self.columns,
                                                                        &other.columns) {
                                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                        =>
                                                                        match ::core::cmp::PartialOrd::partial_cmp(&self.overwrite,
                                                                                &other.overwrite) {
                                                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                                =>
                                                                                match ::core::cmp::PartialOrd::partial_cmp(&self.source,
                                                                                        &other.source) {
                                                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                                        =>
                                                                                        match ::core::cmp::PartialOrd::partial_cmp(&self.assignments,
                                                                                                &other.assignments) {
                                                                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                                                =>
                                                                                                match ::core::cmp::PartialOrd::partial_cmp(&self.partitioned,
                                                                                                        &other.partitioned) {
                                                                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                                                        =>
                                                                                                        match ::core::cmp::PartialOrd::partial_cmp(&self.after_columns,
                                                                                                                &other.after_columns) {
                                                                                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                                                                =>
                                                                                                                match ::core::cmp::PartialOrd::partial_cmp(&self.has_table_keyword,
                                                                                                                        &other.has_table_keyword) {
                                                                                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                                                                        =>
                                                                                                                        match ::core::cmp::PartialOrd::partial_cmp(&self.on,
                                                                                                                                &other.on) {
                                                                                                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                                                                                =>
                                                                                                                                match ::core::cmp::PartialOrd::partial_cmp(&self.returning,
                                                                                                                                        &other.returning) {
                                                                                                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                                                                                        =>
                                                                                                                                        match ::core::cmp::PartialOrd::partial_cmp(&self.replace_into,
                                                                                                                                                &other.replace_into) {
                                                                                                                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                                                                                                =>
                                                                                                                                                match ::core::cmp::PartialOrd::partial_cmp(&self.priority,
                                                                                                                                                        &other.priority) {
                                                                                                                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                                                                                                        =>
                                                                                                                                                        match ::core::cmp::PartialOrd::partial_cmp(&self.insert_alias,
                                                                                                                                                                &other.insert_alias) {
                                                                                                                                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                                                                                                                =>
                                                                                                                                                                match ::core::cmp::PartialOrd::partial_cmp(&self.settings,
                                                                                                                                                                        &other.settings) {
                                                                                                                                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                                                                                                                        =>
                                                                                                                                                                        ::core::cmp::PartialOrd::partial_cmp(&self.format_clause,
                                                                                                                                                                            &other.format_clause),
                                                                                                                                                                    cmp => cmp,
                                                                                                                                                                },
                                                                                                                                                            cmp => cmp,
                                                                                                                                                        },
                                                                                                                                                    cmp => cmp,
                                                                                                                                                },
                                                                                                                                            cmp => cmp,
                                                                                                                                        },
                                                                                                                                    cmp => cmp,
                                                                                                                                },
                                                                                                                            cmp => cmp,
                                                                                                                        },
                                                                                                                    cmp => cmp,
                                                                                                                },
                                                                                                            cmp => cmp,
                                                                                                        },
                                                                                                    cmp => cmp,
                                                                                                },
                                                                                            cmp => cmp,
                                                                                        },
                                                                                    cmp => cmp,
                                                                                },
                                                                            cmp => cmp,
                                                                        },
                                                                    cmp => cmp,
                                                                },
                                                            cmp => cmp,
                                                        },
                                                    cmp => cmp,
                                                },
                                            cmp => cmp,
                                        },
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for Insert {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<AttachedToken>;
        let _: ::core::cmp::AssertParamIsEq<Option<OptimizerHint>>;
        let _: ::core::cmp::AssertParamIsEq<Option<SqliteOnConflict>>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
        let _: ::core::cmp::AssertParamIsEq<TableObject>;
        let _: ::core::cmp::AssertParamIsEq<Option<Ident>>;
        let _: ::core::cmp::AssertParamIsEq<Vec<Ident>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Box<Query>>>;
        let _: ::core::cmp::AssertParamIsEq<Vec<Assignment>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Vec<Expr>>>;
        let _: ::core::cmp::AssertParamIsEq<Vec<Ident>>;
        let _: ::core::cmp::AssertParamIsEq<Option<OnInsert>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Vec<SelectItem>>>;
        let _: ::core::cmp::AssertParamIsEq<Option<MysqlInsertPriority>>;
        let _: ::core::cmp::AssertParamIsEq<Option<InsertAliases>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Vec<Setting>>>;
        let _: ::core::cmp::AssertParamIsEq<Option<InputFormatClause>>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for Insert {
    #[inline]
    fn cmp(&self, other: &Insert) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.insert_token, &other.insert_token) {
            ::core::cmp::Ordering::Equal =>
                match ::core::cmp::Ord::cmp(&self.optimizer_hint,
                        &other.optimizer_hint) {
                    ::core::cmp::Ordering::Equal =>
                        match ::core::cmp::Ord::cmp(&self.or, &other.or) {
                            ::core::cmp::Ordering::Equal =>
                                match ::core::cmp::Ord::cmp(&self.ignore, &other.ignore) {
                                    ::core::cmp::Ordering::Equal =>
                                        match ::core::cmp::Ord::cmp(&self.into, &other.into) {
                                            ::core::cmp::Ordering::Equal =>
                                                match ::core::cmp::Ord::cmp(&self.table, &other.table) {
                                                    ::core::cmp::Ordering::Equal =>
                                                        match ::core::cmp::Ord::cmp(&self.table_alias,
                                                                &other.table_alias) {
                                                            ::core::cmp::Ordering::Equal =>
                                                                match ::core::cmp::Ord::cmp(&self.columns, &other.columns) {
                                                                    ::core::cmp::Ordering::Equal =>
                                                                        match ::core::cmp::Ord::cmp(&self.overwrite,
                                                                                &other.overwrite) {
                                                                            ::core::cmp::Ordering::Equal =>
                                                                                match ::core::cmp::Ord::cmp(&self.source, &other.source) {
                                                                                    ::core::cmp::Ordering::Equal =>
                                                                                        match ::core::cmp::Ord::cmp(&self.assignments,
                                                                                                &other.assignments) {
                                                                                            ::core::cmp::Ordering::Equal =>
                                                                                                match ::core::cmp::Ord::cmp(&self.partitioned,
                                                                                                        &other.partitioned) {
                                                                                                    ::core::cmp::Ordering::Equal =>
                                                                                                        match ::core::cmp::Ord::cmp(&self.after_columns,
                                                                                                                &other.after_columns) {
                                                                                                            ::core::cmp::Ordering::Equal =>
                                                                                                                match ::core::cmp::Ord::cmp(&self.has_table_keyword,
                                                                                                                        &other.has_table_keyword) {
                                                                                                                    ::core::cmp::Ordering::Equal =>
                                                                                                                        match ::core::cmp::Ord::cmp(&self.on, &other.on) {
                                                                                                                            ::core::cmp::Ordering::Equal =>
                                                                                                                                match ::core::cmp::Ord::cmp(&self.returning,
                                                                                                                                        &other.returning) {
                                                                                                                                    ::core::cmp::Ordering::Equal =>
                                                                                                                                        match ::core::cmp::Ord::cmp(&self.replace_into,
                                                                                                                                                &other.replace_into) {
                                                                                                                                            ::core::cmp::Ordering::Equal =>
                                                                                                                                                match ::core::cmp::Ord::cmp(&self.priority, &other.priority)
                                                                                                                                                    {
                                                                                                                                                    ::core::cmp::Ordering::Equal =>
                                                                                                                                                        match ::core::cmp::Ord::cmp(&self.insert_alias,
                                                                                                                                                                &other.insert_alias) {
                                                                                                                                                            ::core::cmp::Ordering::Equal =>
                                                                                                                                                                match ::core::cmp::Ord::cmp(&self.settings, &other.settings)
                                                                                                                                                                    {
                                                                                                                                                                    ::core::cmp::Ordering::Equal =>
                                                                                                                                                                        ::core::cmp::Ord::cmp(&self.format_clause,
                                                                                                                                                                            &other.format_clause),
                                                                                                                                                                    cmp => cmp,
                                                                                                                                                                },
                                                                                                                                                            cmp => cmp,
                                                                                                                                                        },
                                                                                                                                                    cmp => cmp,
                                                                                                                                                },
                                                                                                                                            cmp => cmp,
                                                                                                                                        },
                                                                                                                                    cmp => cmp,
                                                                                                                                },
                                                                                                                            cmp => cmp,
                                                                                                                        },
                                                                                                                    cmp => cmp,
                                                                                                                },
                                                                                                            cmp => cmp,
                                                                                                        },
                                                                                                    cmp => cmp,
                                                                                                },
                                                                                            cmp => cmp,
                                                                                        },
                                                                                    cmp => cmp,
                                                                                },
                                                                            cmp => cmp,
                                                                        },
                                                                    cmp => cmp,
                                                                },
                                                            cmp => cmp,
                                                        },
                                                    cmp => cmp,
                                                },
                                            cmp => cmp,
                                        },
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Insert {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.insert_token, state);
        ::core::hash::Hash::hash(&self.optimizer_hint, state);
        ::core::hash::Hash::hash(&self.or, state);
        ::core::hash::Hash::hash(&self.ignore, state);
        ::core::hash::Hash::hash(&self.into, state);
        ::core::hash::Hash::hash(&self.table, state);
        ::core::hash::Hash::hash(&self.table_alias, state);
        ::core::hash::Hash::hash(&self.columns, state);
        ::core::hash::Hash::hash(&self.overwrite, state);
        ::core::hash::Hash::hash(&self.source, state);
        ::core::hash::Hash::hash(&self.assignments, state);
        ::core::hash::Hash::hash(&self.partitioned, state);
        ::core::hash::Hash::hash(&self.after_columns, state);
        ::core::hash::Hash::hash(&self.has_table_keyword, state);
        ::core::hash::Hash::hash(&self.on, state);
        ::core::hash::Hash::hash(&self.returning, state);
        ::core::hash::Hash::hash(&self.replace_into, state);
        ::core::hash::Hash::hash(&self.priority, state);
        ::core::hash::Hash::hash(&self.insert_alias, state);
        ::core::hash::Hash::hash(&self.settings, state);
        ::core::hash::Hash::hash(&self.format_clause, state)
    }
}Hash)]
41#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
42#[cfg_attr(feature = "visitor", derive(impl sqlparser::ast::Visit for Insert {
    fn visit<V: sqlparser::ast::Visitor>(&self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::Visit::visit(&self.insert_token, visitor)?;
                        sqlparser::ast::Visit::visit(&self.optimizer_hint,
                                visitor)?;
                        sqlparser::ast::Visit::visit(&self.or, visitor)?;
                        sqlparser::ast::Visit::visit(&self.ignore, visitor)?;
                        sqlparser::ast::Visit::visit(&self.into, visitor)?;
                        sqlparser::ast::Visit::visit(&self.table, visitor)?;
                        sqlparser::ast::Visit::visit(&self.table_alias, visitor)?;
                        sqlparser::ast::Visit::visit(&self.columns, visitor)?;
                        sqlparser::ast::Visit::visit(&self.overwrite, visitor)?;
                        sqlparser::ast::Visit::visit(&self.source, visitor)?;
                        sqlparser::ast::Visit::visit(&self.assignments, visitor)?;
                        sqlparser::ast::Visit::visit(&self.partitioned, visitor)?;
                        sqlparser::ast::Visit::visit(&self.after_columns, visitor)?;
                        sqlparser::ast::Visit::visit(&self.has_table_keyword,
                                visitor)?;
                        sqlparser::ast::Visit::visit(&self.on, visitor)?;
                        sqlparser::ast::Visit::visit(&self.returning, visitor)?;
                        sqlparser::ast::Visit::visit(&self.replace_into, visitor)?;
                        sqlparser::ast::Visit::visit(&self.priority, visitor)?;
                        sqlparser::ast::Visit::visit(&self.insert_alias, visitor)?;
                        sqlparser::ast::Visit::visit(&self.settings, visitor)?;
                        sqlparser::ast::Visit::visit(&self.format_clause, visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}Visit, impl sqlparser::ast::VisitMut for Insert {
    fn visit<V: sqlparser::ast::VisitorMut>(&mut self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::VisitMut::visit(&mut self.insert_token,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.optimizer_hint,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.or, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.ignore, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.into, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.table, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.table_alias,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.columns,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.overwrite,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.source, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.assignments,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.partitioned,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.after_columns,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.has_table_keyword,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.on, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.returning,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.replace_into,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.priority,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.insert_alias,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.settings,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.format_clause,
                                visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}VisitMut))]
43pub struct Insert {
44    /// Token for the `INSERT` keyword (or its substitutes)
45    pub insert_token: AttachedToken,
46    /// A query optimizer hint
47    ///
48    /// [MySQL](https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html)
49    /// [Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/Comments.html#GUID-D316D545-89E2-4D54-977F-FC97815CD62E)
50    pub optimizer_hint: Option<OptimizerHint>,
51    /// Only for Sqlite
52    pub or: Option<SqliteOnConflict>,
53    /// Only for mysql
54    pub ignore: bool,
55    /// INTO - optional keyword
56    pub into: bool,
57    /// TABLE
58    pub table: TableObject,
59    /// table_name as foo (for PostgreSQL)
60    pub table_alias: Option<Ident>,
61    /// COLUMNS
62    pub columns: Vec<Ident>,
63    /// Overwrite (Hive)
64    pub overwrite: bool,
65    /// A SQL query that specifies what to insert
66    pub source: Option<Box<Query>>,
67    /// MySQL `INSERT INTO ... SET`
68    /// See: <https://dev.mysql.com/doc/refman/8.4/en/insert.html>
69    pub assignments: Vec<Assignment>,
70    /// partitioned insert (Hive)
71    pub partitioned: Option<Vec<Expr>>,
72    /// Columns defined after PARTITION
73    pub after_columns: Vec<Ident>,
74    /// whether the insert has the table keyword (Hive)
75    pub has_table_keyword: bool,
76    /// ON INSERT
77    pub on: Option<OnInsert>,
78    /// RETURNING
79    pub returning: Option<Vec<SelectItem>>,
80    /// Only for mysql
81    pub replace_into: bool,
82    /// Only for mysql
83    pub priority: Option<MysqlInsertPriority>,
84    /// Only for mysql
85    pub insert_alias: Option<InsertAliases>,
86    /// Settings used for ClickHouse.
87    ///
88    /// ClickHouse syntax: `INSERT INTO tbl SETTINGS format_template_resultset = '/some/path/resultset.format'`
89    ///
90    /// [ClickHouse `INSERT INTO`](https://clickhouse.com/docs/en/sql-reference/statements/insert-into)
91    pub settings: Option<Vec<Setting>>,
92    /// Format for `INSERT` statement when not using standard SQL format. Can be e.g. `CSV`,
93    /// `JSON`, `JSONAsString`, `LineAsString` and more.
94    ///
95    /// ClickHouse syntax: `INSERT INTO tbl FORMAT JSONEachRow {"foo": 1, "bar": 2}, {"foo": 3}`
96    ///
97    /// [ClickHouse formats JSON insert](https://clickhouse.com/docs/en/interfaces/formats#json-inserting-data)
98    pub format_clause: Option<InputFormatClause>,
99}
100
101impl Display for Insert {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        let table_name = if let Some(alias) = &self.table_alias {
104            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} AS {1}", self.table, alias))
    })format!("{0} AS {alias}", self.table)
105        } else {
106            self.table.to_string()
107        };
108
109        if let Some(on_conflict) = self.or {
110            f.write_str("INSERT")?;
111            if let Some(hint) = self.optimizer_hint.as_ref() {
112                f.write_fmt(format_args!(" {0}", hint))write!(f, " {hint}")?;
113            }
114            f.write_fmt(format_args!(" {0} INTO {1} ", on_conflict, table_name))write!(f, " {on_conflict} INTO {table_name} ")?;
115        } else {
116            f.write_fmt(format_args!("{0}",
        if self.replace_into { "REPLACE" } else { "INSERT" }))write!(
117                f,
118                "{start}",
119                start = if self.replace_into {
120                    "REPLACE"
121                } else {
122                    "INSERT"
123                }
124            )?;
125            if let Some(hint) = self.optimizer_hint.as_ref() {
126                f.write_fmt(format_args!(" {0}", hint))write!(f, " {hint}")?;
127            }
128            if let Some(priority) = self.priority {
129                f.write_fmt(format_args!(" {0}", priority))write!(f, " {priority}",)?;
130            }
131
132            f.write_fmt(format_args!("{1}{2}{3}{4} {0} ", table_name,
        if self.ignore { " IGNORE" } else { "" },
        if self.overwrite { " OVERWRITE" } else { "" },
        if self.into { " INTO" } else { "" },
        if self.has_table_keyword { " TABLE" } else { "" }))write!(
133                f,
134                "{ignore}{over}{int}{tbl} {table_name} ",
135                table_name = table_name,
136                ignore = if self.ignore { " IGNORE" } else { "" },
137                over = if self.overwrite { " OVERWRITE" } else { "" },
138                int = if self.into { " INTO" } else { "" },
139                tbl = if self.has_table_keyword { " TABLE" } else { "" },
140            )?;
141        }
142        if !self.columns.is_empty() {
143            f.write_fmt(format_args!("({0})", display_comma_separated(&self.columns)))write!(f, "({})", display_comma_separated(&self.columns))?;
144            SpaceOrNewline.fmt(f)?;
145        }
146        if let Some(ref parts) = self.partitioned {
147            if !parts.is_empty() {
148                f.write_fmt(format_args!("PARTITION ({0})", display_comma_separated(parts)))write!(f, "PARTITION ({})", display_comma_separated(parts))?;
149                SpaceOrNewline.fmt(f)?;
150            }
151        }
152        if !self.after_columns.is_empty() {
153            f.write_fmt(format_args!("({0})",
        display_comma_separated(&self.after_columns)))write!(f, "({})", display_comma_separated(&self.after_columns))?;
154            SpaceOrNewline.fmt(f)?;
155        }
156
157        if let Some(settings) = &self.settings {
158            f.write_fmt(format_args!("SETTINGS {0}", display_comma_separated(settings)))write!(f, "SETTINGS {}", display_comma_separated(settings))?;
159            SpaceOrNewline.fmt(f)?;
160        }
161
162        if let Some(source) = &self.source {
163            source.fmt(f)?;
164        } else if !self.assignments.is_empty() {
165            f.write_fmt(format_args!("SET"))write!(f, "SET")?;
166            indented_list(f, &self.assignments)?;
167        } else if let Some(format_clause) = &self.format_clause {
168            format_clause.fmt(f)?;
169        } else if self.columns.is_empty() {
170            f.write_fmt(format_args!("DEFAULT VALUES"))write!(f, "DEFAULT VALUES")?;
171        }
172
173        if let Some(insert_alias) = &self.insert_alias {
174            f.write_fmt(format_args!(" AS {0}", insert_alias.row_alias))write!(f, " AS {0}", insert_alias.row_alias)?;
175
176            if let Some(col_aliases) = &insert_alias.col_aliases {
177                if !col_aliases.is_empty() {
178                    f.write_fmt(format_args!(" ({0})", display_comma_separated(col_aliases)))write!(f, " ({})", display_comma_separated(col_aliases))?;
179                }
180            }
181        }
182
183        if let Some(on) = &self.on {
184            f.write_fmt(format_args!("{0}", on))write!(f, "{on}")?;
185        }
186
187        if let Some(returning) = &self.returning {
188            SpaceOrNewline.fmt(f)?;
189            f.write_str("RETURNING")?;
190            indented_list(f, returning)?;
191        }
192        Ok(())
193    }
194}
195
196/// DELETE statement.
197#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Delete {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["delete_token", "optimizer_hint", "tables", "from", "using",
                        "selection", "returning", "order_by", "limit"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.delete_token, &self.optimizer_hint, &self.tables,
                        &self.from, &self.using, &self.selection, &self.returning,
                        &self.order_by, &&self.limit];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "Delete", names,
            values)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Delete {
    #[inline]
    fn clone(&self) -> Delete {
        Delete {
            delete_token: ::core::clone::Clone::clone(&self.delete_token),
            optimizer_hint: ::core::clone::Clone::clone(&self.optimizer_hint),
            tables: ::core::clone::Clone::clone(&self.tables),
            from: ::core::clone::Clone::clone(&self.from),
            using: ::core::clone::Clone::clone(&self.using),
            selection: ::core::clone::Clone::clone(&self.selection),
            returning: ::core::clone::Clone::clone(&self.returning),
            order_by: ::core::clone::Clone::clone(&self.order_by),
            limit: ::core::clone::Clone::clone(&self.limit),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Delete {
    #[inline]
    fn eq(&self, other: &Delete) -> bool {
        self.delete_token == other.delete_token &&
                                        self.optimizer_hint == other.optimizer_hint &&
                                    self.tables == other.tables && self.from == other.from &&
                            self.using == other.using &&
                        self.selection == other.selection &&
                    self.returning == other.returning &&
                self.order_by == other.order_by && self.limit == other.limit
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Delete {
    #[inline]
    fn partial_cmp(&self, other: &Delete)
        -> ::core::option::Option<::core::cmp::Ordering> {
        match ::core::cmp::PartialOrd::partial_cmp(&self.delete_token,
                &other.delete_token) {
            ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
                match ::core::cmp::PartialOrd::partial_cmp(&self.optimizer_hint,
                        &other.optimizer_hint) {
                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                        =>
                        match ::core::cmp::PartialOrd::partial_cmp(&self.tables,
                                &other.tables) {
                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                =>
                                match ::core::cmp::PartialOrd::partial_cmp(&self.from,
                                        &other.from) {
                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                        =>
                                        match ::core::cmp::PartialOrd::partial_cmp(&self.using,
                                                &other.using) {
                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                =>
                                                match ::core::cmp::PartialOrd::partial_cmp(&self.selection,
                                                        &other.selection) {
                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                        =>
                                                        match ::core::cmp::PartialOrd::partial_cmp(&self.returning,
                                                                &other.returning) {
                                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                =>
                                                                match ::core::cmp::PartialOrd::partial_cmp(&self.order_by,
                                                                        &other.order_by) {
                                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                        =>
                                                                        ::core::cmp::PartialOrd::partial_cmp(&self.limit,
                                                                            &other.limit),
                                                                    cmp => cmp,
                                                                },
                                                            cmp => cmp,
                                                        },
                                                    cmp => cmp,
                                                },
                                            cmp => cmp,
                                        },
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for Delete {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<AttachedToken>;
        let _: ::core::cmp::AssertParamIsEq<Option<OptimizerHint>>;
        let _: ::core::cmp::AssertParamIsEq<Vec<ObjectName>>;
        let _: ::core::cmp::AssertParamIsEq<FromTable>;
        let _: ::core::cmp::AssertParamIsEq<Option<Vec<TableWithJoins>>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Expr>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Vec<SelectItem>>>;
        let _: ::core::cmp::AssertParamIsEq<Vec<OrderByExpr>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Expr>>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for Delete {
    #[inline]
    fn cmp(&self, other: &Delete) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.delete_token, &other.delete_token) {
            ::core::cmp::Ordering::Equal =>
                match ::core::cmp::Ord::cmp(&self.optimizer_hint,
                        &other.optimizer_hint) {
                    ::core::cmp::Ordering::Equal =>
                        match ::core::cmp::Ord::cmp(&self.tables, &other.tables) {
                            ::core::cmp::Ordering::Equal =>
                                match ::core::cmp::Ord::cmp(&self.from, &other.from) {
                                    ::core::cmp::Ordering::Equal =>
                                        match ::core::cmp::Ord::cmp(&self.using, &other.using) {
                                            ::core::cmp::Ordering::Equal =>
                                                match ::core::cmp::Ord::cmp(&self.selection,
                                                        &other.selection) {
                                                    ::core::cmp::Ordering::Equal =>
                                                        match ::core::cmp::Ord::cmp(&self.returning,
                                                                &other.returning) {
                                                            ::core::cmp::Ordering::Equal =>
                                                                match ::core::cmp::Ord::cmp(&self.order_by, &other.order_by)
                                                                    {
                                                                    ::core::cmp::Ordering::Equal =>
                                                                        ::core::cmp::Ord::cmp(&self.limit, &other.limit),
                                                                    cmp => cmp,
                                                                },
                                                            cmp => cmp,
                                                        },
                                                    cmp => cmp,
                                                },
                                            cmp => cmp,
                                        },
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Delete {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.delete_token, state);
        ::core::hash::Hash::hash(&self.optimizer_hint, state);
        ::core::hash::Hash::hash(&self.tables, state);
        ::core::hash::Hash::hash(&self.from, state);
        ::core::hash::Hash::hash(&self.using, state);
        ::core::hash::Hash::hash(&self.selection, state);
        ::core::hash::Hash::hash(&self.returning, state);
        ::core::hash::Hash::hash(&self.order_by, state);
        ::core::hash::Hash::hash(&self.limit, state)
    }
}Hash)]
198#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
199#[cfg_attr(feature = "visitor", derive(impl sqlparser::ast::Visit for Delete {
    fn visit<V: sqlparser::ast::Visitor>(&self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::Visit::visit(&self.delete_token, visitor)?;
                        sqlparser::ast::Visit::visit(&self.optimizer_hint,
                                visitor)?;
                        sqlparser::ast::Visit::visit(&self.tables, visitor)?;
                        sqlparser::ast::Visit::visit(&self.from, visitor)?;
                        sqlparser::ast::Visit::visit(&self.using, visitor)?;
                        sqlparser::ast::Visit::visit(&self.selection, visitor)?;
                        sqlparser::ast::Visit::visit(&self.returning, visitor)?;
                        sqlparser::ast::Visit::visit(&self.order_by, visitor)?;
                        sqlparser::ast::Visit::visit(&self.limit, visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}Visit, impl sqlparser::ast::VisitMut for Delete {
    fn visit<V: sqlparser::ast::VisitorMut>(&mut self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::VisitMut::visit(&mut self.delete_token,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.optimizer_hint,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.tables, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.from, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.using, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.selection,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.returning,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.order_by,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.limit, visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}VisitMut))]
200pub struct Delete {
201    /// Token for the `DELETE` keyword
202    pub delete_token: AttachedToken,
203    /// A query optimizer hint
204    ///
205    /// [MySQL](https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html)
206    /// [Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/Comments.html#GUID-D316D545-89E2-4D54-977F-FC97815CD62E)
207    pub optimizer_hint: Option<OptimizerHint>,
208    /// Multi tables delete are supported in mysql
209    pub tables: Vec<ObjectName>,
210    /// FROM
211    pub from: FromTable,
212    /// USING (Snowflake, Postgres, MySQL)
213    pub using: Option<Vec<TableWithJoins>>,
214    /// WHERE
215    pub selection: Option<Expr>,
216    /// RETURNING
217    pub returning: Option<Vec<SelectItem>>,
218    /// ORDER BY (MySQL)
219    pub order_by: Vec<OrderByExpr>,
220    /// LIMIT (MySQL)
221    pub limit: Option<Expr>,
222}
223
224impl Display for Delete {
225    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226        f.write_str("DELETE")?;
227        if let Some(hint) = self.optimizer_hint.as_ref() {
228            f.write_str(" ")?;
229            hint.fmt(f)?;
230        }
231        if !self.tables.is_empty() {
232            indented_list(f, &self.tables)?;
233        }
234        match &self.from {
235            FromTable::WithFromKeyword(from) => {
236                f.write_str(" FROM")?;
237                indented_list(f, from)?;
238            }
239            FromTable::WithoutKeyword(from) => {
240                indented_list(f, from)?;
241            }
242        }
243        if let Some(using) = &self.using {
244            SpaceOrNewline.fmt(f)?;
245            f.write_str("USING")?;
246            indented_list(f, using)?;
247        }
248        if let Some(selection) = &self.selection {
249            SpaceOrNewline.fmt(f)?;
250            f.write_str("WHERE")?;
251            SpaceOrNewline.fmt(f)?;
252            Indent(selection).fmt(f)?;
253        }
254        if let Some(returning) = &self.returning {
255            SpaceOrNewline.fmt(f)?;
256            f.write_str("RETURNING")?;
257            indented_list(f, returning)?;
258        }
259        if !self.order_by.is_empty() {
260            SpaceOrNewline.fmt(f)?;
261            f.write_str("ORDER BY")?;
262            indented_list(f, &self.order_by)?;
263        }
264        if let Some(limit) = &self.limit {
265            SpaceOrNewline.fmt(f)?;
266            f.write_str("LIMIT")?;
267            SpaceOrNewline.fmt(f)?;
268            Indent(limit).fmt(f)?;
269        }
270        Ok(())
271    }
272}
273
274/// UPDATE statement.
275#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Update {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["update_token", "optimizer_hint", "table", "assignments",
                        "from", "selection", "returning", "or", "limit"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.update_token, &self.optimizer_hint, &self.table,
                        &self.assignments, &self.from, &self.selection,
                        &self.returning, &self.or, &&self.limit];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "Update", names,
            values)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Update {
    #[inline]
    fn clone(&self) -> Update {
        Update {
            update_token: ::core::clone::Clone::clone(&self.update_token),
            optimizer_hint: ::core::clone::Clone::clone(&self.optimizer_hint),
            table: ::core::clone::Clone::clone(&self.table),
            assignments: ::core::clone::Clone::clone(&self.assignments),
            from: ::core::clone::Clone::clone(&self.from),
            selection: ::core::clone::Clone::clone(&self.selection),
            returning: ::core::clone::Clone::clone(&self.returning),
            or: ::core::clone::Clone::clone(&self.or),
            limit: ::core::clone::Clone::clone(&self.limit),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Update {
    #[inline]
    fn eq(&self, other: &Update) -> bool {
        self.update_token == other.update_token &&
                                        self.optimizer_hint == other.optimizer_hint &&
                                    self.table == other.table &&
                                self.assignments == other.assignments &&
                            self.from == other.from && self.selection == other.selection
                    && self.returning == other.returning && self.or == other.or
            && self.limit == other.limit
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Update {
    #[inline]
    fn partial_cmp(&self, other: &Update)
        -> ::core::option::Option<::core::cmp::Ordering> {
        match ::core::cmp::PartialOrd::partial_cmp(&self.update_token,
                &other.update_token) {
            ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
                match ::core::cmp::PartialOrd::partial_cmp(&self.optimizer_hint,
                        &other.optimizer_hint) {
                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                        =>
                        match ::core::cmp::PartialOrd::partial_cmp(&self.table,
                                &other.table) {
                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                =>
                                match ::core::cmp::PartialOrd::partial_cmp(&self.assignments,
                                        &other.assignments) {
                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                        =>
                                        match ::core::cmp::PartialOrd::partial_cmp(&self.from,
                                                &other.from) {
                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                =>
                                                match ::core::cmp::PartialOrd::partial_cmp(&self.selection,
                                                        &other.selection) {
                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                        =>
                                                        match ::core::cmp::PartialOrd::partial_cmp(&self.returning,
                                                                &other.returning) {
                                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                =>
                                                                match ::core::cmp::PartialOrd::partial_cmp(&self.or,
                                                                        &other.or) {
                                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                        =>
                                                                        ::core::cmp::PartialOrd::partial_cmp(&self.limit,
                                                                            &other.limit),
                                                                    cmp => cmp,
                                                                },
                                                            cmp => cmp,
                                                        },
                                                    cmp => cmp,
                                                },
                                            cmp => cmp,
                                        },
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for Update {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<AttachedToken>;
        let _: ::core::cmp::AssertParamIsEq<Option<OptimizerHint>>;
        let _: ::core::cmp::AssertParamIsEq<TableWithJoins>;
        let _: ::core::cmp::AssertParamIsEq<Vec<Assignment>>;
        let _: ::core::cmp::AssertParamIsEq<Option<UpdateTableFromKind>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Expr>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Vec<SelectItem>>>;
        let _: ::core::cmp::AssertParamIsEq<Option<SqliteOnConflict>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Expr>>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for Update {
    #[inline]
    fn cmp(&self, other: &Update) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.update_token, &other.update_token) {
            ::core::cmp::Ordering::Equal =>
                match ::core::cmp::Ord::cmp(&self.optimizer_hint,
                        &other.optimizer_hint) {
                    ::core::cmp::Ordering::Equal =>
                        match ::core::cmp::Ord::cmp(&self.table, &other.table) {
                            ::core::cmp::Ordering::Equal =>
                                match ::core::cmp::Ord::cmp(&self.assignments,
                                        &other.assignments) {
                                    ::core::cmp::Ordering::Equal =>
                                        match ::core::cmp::Ord::cmp(&self.from, &other.from) {
                                            ::core::cmp::Ordering::Equal =>
                                                match ::core::cmp::Ord::cmp(&self.selection,
                                                        &other.selection) {
                                                    ::core::cmp::Ordering::Equal =>
                                                        match ::core::cmp::Ord::cmp(&self.returning,
                                                                &other.returning) {
                                                            ::core::cmp::Ordering::Equal =>
                                                                match ::core::cmp::Ord::cmp(&self.or, &other.or) {
                                                                    ::core::cmp::Ordering::Equal =>
                                                                        ::core::cmp::Ord::cmp(&self.limit, &other.limit),
                                                                    cmp => cmp,
                                                                },
                                                            cmp => cmp,
                                                        },
                                                    cmp => cmp,
                                                },
                                            cmp => cmp,
                                        },
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Update {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.update_token, state);
        ::core::hash::Hash::hash(&self.optimizer_hint, state);
        ::core::hash::Hash::hash(&self.table, state);
        ::core::hash::Hash::hash(&self.assignments, state);
        ::core::hash::Hash::hash(&self.from, state);
        ::core::hash::Hash::hash(&self.selection, state);
        ::core::hash::Hash::hash(&self.returning, state);
        ::core::hash::Hash::hash(&self.or, state);
        ::core::hash::Hash::hash(&self.limit, state)
    }
}Hash)]
276#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
277#[cfg_attr(feature = "visitor", derive(impl sqlparser::ast::Visit for Update {
    fn visit<V: sqlparser::ast::Visitor>(&self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::Visit::visit(&self.update_token, visitor)?;
                        sqlparser::ast::Visit::visit(&self.optimizer_hint,
                                visitor)?;
                        sqlparser::ast::Visit::visit(&self.table, visitor)?;
                        sqlparser::ast::Visit::visit(&self.assignments, visitor)?;
                        sqlparser::ast::Visit::visit(&self.from, visitor)?;
                        sqlparser::ast::Visit::visit(&self.selection, visitor)?;
                        sqlparser::ast::Visit::visit(&self.returning, visitor)?;
                        sqlparser::ast::Visit::visit(&self.or, visitor)?;
                        sqlparser::ast::Visit::visit(&self.limit, visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}Visit, impl sqlparser::ast::VisitMut for Update {
    fn visit<V: sqlparser::ast::VisitorMut>(&mut self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::VisitMut::visit(&mut self.update_token,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.optimizer_hint,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.table, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.assignments,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.from, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.selection,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.returning,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.or, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.limit, visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}VisitMut))]
278pub struct Update {
279    /// Token for the `UPDATE` keyword
280    pub update_token: AttachedToken,
281    /// A query optimizer hint
282    ///
283    /// [MySQL](https://dev.mysql.com/doc/refman/8.4/en/optimizer-hints.html)
284    /// [Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/Comments.html#GUID-D316D545-89E2-4D54-977F-FC97815CD62E)
285    pub optimizer_hint: Option<OptimizerHint>,
286    /// TABLE
287    pub table: TableWithJoins,
288    /// Column assignments
289    pub assignments: Vec<Assignment>,
290    /// Table which provide value to be set
291    pub from: Option<UpdateTableFromKind>,
292    /// WHERE
293    pub selection: Option<Expr>,
294    /// RETURNING
295    pub returning: Option<Vec<SelectItem>>,
296    /// SQLite-specific conflict resolution clause
297    pub or: Option<SqliteOnConflict>,
298    /// LIMIT
299    pub limit: Option<Expr>,
300}
301
302impl Display for Update {
303    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
304        f.write_str("UPDATE ")?;
305        if let Some(hint) = self.optimizer_hint.as_ref() {
306            hint.fmt(f)?;
307            f.write_str(" ")?;
308        }
309        if let Some(or) = &self.or {
310            or.fmt(f)?;
311            f.write_str(" ")?;
312        }
313        self.table.fmt(f)?;
314        if let Some(UpdateTableFromKind::BeforeSet(from)) = &self.from {
315            SpaceOrNewline.fmt(f)?;
316            f.write_str("FROM")?;
317            indented_list(f, from)?;
318        }
319        if !self.assignments.is_empty() {
320            SpaceOrNewline.fmt(f)?;
321            f.write_str("SET")?;
322            indented_list(f, &self.assignments)?;
323        }
324        if let Some(UpdateTableFromKind::AfterSet(from)) = &self.from {
325            SpaceOrNewline.fmt(f)?;
326            f.write_str("FROM")?;
327            indented_list(f, from)?;
328        }
329        if let Some(selection) = &self.selection {
330            SpaceOrNewline.fmt(f)?;
331            f.write_str("WHERE")?;
332            SpaceOrNewline.fmt(f)?;
333            Indent(selection).fmt(f)?;
334        }
335        if let Some(returning) = &self.returning {
336            SpaceOrNewline.fmt(f)?;
337            f.write_str("RETURNING")?;
338            indented_list(f, returning)?;
339        }
340        if let Some(limit) = &self.limit {
341            SpaceOrNewline.fmt(f)?;
342            f.write_fmt(format_args!("LIMIT {0}", limit))write!(f, "LIMIT {limit}")?;
343        }
344        Ok(())
345    }
346}
347
348/// A `MERGE` statement.
349#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Merge {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["merge_token", "optimizer_hint", "into", "table", "source",
                        "on", "clauses", "output"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.merge_token, &self.optimizer_hint, &self.into,
                        &self.table, &self.source, &self.on, &self.clauses,
                        &&self.output];
        ::core::fmt::Formatter::debug_struct_fields_finish(f, "Merge", names,
            values)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Merge {
    #[inline]
    fn clone(&self) -> Merge {
        Merge {
            merge_token: ::core::clone::Clone::clone(&self.merge_token),
            optimizer_hint: ::core::clone::Clone::clone(&self.optimizer_hint),
            into: ::core::clone::Clone::clone(&self.into),
            table: ::core::clone::Clone::clone(&self.table),
            source: ::core::clone::Clone::clone(&self.source),
            on: ::core::clone::Clone::clone(&self.on),
            clauses: ::core::clone::Clone::clone(&self.clauses),
            output: ::core::clone::Clone::clone(&self.output),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Merge {
    #[inline]
    fn eq(&self, other: &Merge) -> bool {
        self.into == other.into && self.merge_token == other.merge_token &&
                                self.optimizer_hint == other.optimizer_hint &&
                            self.table == other.table && self.source == other.source &&
                    self.on == other.on && self.clauses == other.clauses &&
            self.output == other.output
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Merge {
    #[inline]
    fn partial_cmp(&self, other: &Merge)
        -> ::core::option::Option<::core::cmp::Ordering> {
        match ::core::cmp::PartialOrd::partial_cmp(&self.merge_token,
                &other.merge_token) {
            ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
                match ::core::cmp::PartialOrd::partial_cmp(&self.optimizer_hint,
                        &other.optimizer_hint) {
                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                        =>
                        match ::core::cmp::PartialOrd::partial_cmp(&self.into,
                                &other.into) {
                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                =>
                                match ::core::cmp::PartialOrd::partial_cmp(&self.table,
                                        &other.table) {
                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                        =>
                                        match ::core::cmp::PartialOrd::partial_cmp(&self.source,
                                                &other.source) {
                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                =>
                                                match ::core::cmp::PartialOrd::partial_cmp(&self.on,
                                                        &other.on) {
                                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                        =>
                                                        match ::core::cmp::PartialOrd::partial_cmp(&self.clauses,
                                                                &other.clauses) {
                                                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                                                =>
                                                                ::core::cmp::PartialOrd::partial_cmp(&self.output,
                                                                    &other.output),
                                                            cmp => cmp,
                                                        },
                                                    cmp => cmp,
                                                },
                                            cmp => cmp,
                                        },
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for Merge {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<AttachedToken>;
        let _: ::core::cmp::AssertParamIsEq<Option<OptimizerHint>>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
        let _: ::core::cmp::AssertParamIsEq<TableFactor>;
        let _: ::core::cmp::AssertParamIsEq<Box<Expr>>;
        let _: ::core::cmp::AssertParamIsEq<Vec<MergeClause>>;
        let _: ::core::cmp::AssertParamIsEq<Option<OutputClause>>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for Merge {
    #[inline]
    fn cmp(&self, other: &Merge) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.merge_token, &other.merge_token) {
            ::core::cmp::Ordering::Equal =>
                match ::core::cmp::Ord::cmp(&self.optimizer_hint,
                        &other.optimizer_hint) {
                    ::core::cmp::Ordering::Equal =>
                        match ::core::cmp::Ord::cmp(&self.into, &other.into) {
                            ::core::cmp::Ordering::Equal =>
                                match ::core::cmp::Ord::cmp(&self.table, &other.table) {
                                    ::core::cmp::Ordering::Equal =>
                                        match ::core::cmp::Ord::cmp(&self.source, &other.source) {
                                            ::core::cmp::Ordering::Equal =>
                                                match ::core::cmp::Ord::cmp(&self.on, &other.on) {
                                                    ::core::cmp::Ordering::Equal =>
                                                        match ::core::cmp::Ord::cmp(&self.clauses, &other.clauses) {
                                                            ::core::cmp::Ordering::Equal =>
                                                                ::core::cmp::Ord::cmp(&self.output, &other.output),
                                                            cmp => cmp,
                                                        },
                                                    cmp => cmp,
                                                },
                                            cmp => cmp,
                                        },
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Merge {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.merge_token, state);
        ::core::hash::Hash::hash(&self.optimizer_hint, state);
        ::core::hash::Hash::hash(&self.into, state);
        ::core::hash::Hash::hash(&self.table, state);
        ::core::hash::Hash::hash(&self.source, state);
        ::core::hash::Hash::hash(&self.on, state);
        ::core::hash::Hash::hash(&self.clauses, state);
        ::core::hash::Hash::hash(&self.output, state)
    }
}Hash)]
350#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
351#[cfg_attr(feature = "visitor", derive(impl sqlparser::ast::Visit for Merge {
    fn visit<V: sqlparser::ast::Visitor>(&self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::Visit::visit(&self.merge_token, visitor)?;
                        sqlparser::ast::Visit::visit(&self.optimizer_hint,
                                visitor)?;
                        sqlparser::ast::Visit::visit(&self.into, visitor)?;
                        sqlparser::ast::Visit::visit(&self.table, visitor)?;
                        sqlparser::ast::Visit::visit(&self.source, visitor)?;
                        sqlparser::ast::Visit::visit(&self.on, visitor)?;
                        sqlparser::ast::Visit::visit(&self.clauses, visitor)?;
                        sqlparser::ast::Visit::visit(&self.output, visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}Visit, impl sqlparser::ast::VisitMut for Merge {
    fn visit<V: sqlparser::ast::VisitorMut>(&mut self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::VisitMut::visit(&mut self.merge_token,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.optimizer_hint,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.into, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.table, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.source, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.on, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.clauses,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.output, visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}VisitMut))]
352pub struct Merge {
353    /// The `MERGE` token that starts the statement.
354    pub merge_token: AttachedToken,
355    /// A query optimizer hint
356    ///
357    /// [Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/Comments.html#GUID-D316D545-89E2-4D54-977F-FC97815CD62E)
358    pub optimizer_hint: Option<OptimizerHint>,
359    /// optional INTO keyword
360    pub into: bool,
361    /// Specifies the table to merge
362    pub table: TableFactor,
363    /// Specifies the table or subquery to join with the target table
364    pub source: TableFactor,
365    /// Specifies the expression on which to join the target table and source
366    pub on: Box<Expr>,
367    /// Specifies the actions to perform when values match or do not match.
368    pub clauses: Vec<MergeClause>,
369    /// Specifies the output to save changes in MSSQL
370    pub output: Option<OutputClause>,
371}
372
373impl Display for Merge {
374    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
375        f.write_str("MERGE")?;
376        if let Some(hint) = self.optimizer_hint.as_ref() {
377            f.write_fmt(format_args!(" {0}", hint))write!(f, " {hint}")?;
378        }
379        if self.into {
380            f.write_fmt(format_args!(" INTO"))write!(f, " INTO")?;
381        }
382        f.write_fmt(format_args!(" {0} USING {1} ", self.table, self.source))write!(
383            f,
384            " {table} USING {source} ",
385            table = self.table,
386            source = self.source
387        )?;
388        f.write_fmt(format_args!("ON {0} ", self.on))write!(f, "ON {on} ", on = self.on)?;
389        f.write_fmt(format_args!("{0}", display_separated(&self.clauses, " ")))write!(f, "{}", display_separated(&self.clauses, " "))?;
390        if let Some(ref output) = self.output {
391            f.write_fmt(format_args!(" {0}", output))write!(f, " {output}")?;
392        }
393        Ok(())
394    }
395}
396
397/// A `WHEN` clause within a `MERGE` Statement
398///
399/// Example:
400/// ```sql
401/// WHEN NOT MATCHED BY SOURCE AND product LIKE '%washer%' THEN DELETE
402/// ```
403/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/merge)
404/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
405#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MergeClause {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f, "MergeClause",
            "when_token", &self.when_token, "clause_kind", &self.clause_kind,
            "predicate", &self.predicate, "action", &&self.action)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for MergeClause {
    #[inline]
    fn clone(&self) -> MergeClause {
        MergeClause {
            when_token: ::core::clone::Clone::clone(&self.when_token),
            clause_kind: ::core::clone::Clone::clone(&self.clause_kind),
            predicate: ::core::clone::Clone::clone(&self.predicate),
            action: ::core::clone::Clone::clone(&self.action),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for MergeClause {
    #[inline]
    fn eq(&self, other: &MergeClause) -> bool {
        self.when_token == other.when_token &&
                    self.clause_kind == other.clause_kind &&
                self.predicate == other.predicate &&
            self.action == other.action
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for MergeClause {
    #[inline]
    fn partial_cmp(&self, other: &MergeClause)
        -> ::core::option::Option<::core::cmp::Ordering> {
        match ::core::cmp::PartialOrd::partial_cmp(&self.when_token,
                &other.when_token) {
            ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
                match ::core::cmp::PartialOrd::partial_cmp(&self.clause_kind,
                        &other.clause_kind) {
                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                        =>
                        match ::core::cmp::PartialOrd::partial_cmp(&self.predicate,
                                &other.predicate) {
                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                =>
                                ::core::cmp::PartialOrd::partial_cmp(&self.action,
                                    &other.action),
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for MergeClause {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<AttachedToken>;
        let _: ::core::cmp::AssertParamIsEq<MergeClauseKind>;
        let _: ::core::cmp::AssertParamIsEq<Option<Expr>>;
        let _: ::core::cmp::AssertParamIsEq<MergeAction>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for MergeClause {
    #[inline]
    fn cmp(&self, other: &MergeClause) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.when_token, &other.when_token) {
            ::core::cmp::Ordering::Equal =>
                match ::core::cmp::Ord::cmp(&self.clause_kind,
                        &other.clause_kind) {
                    ::core::cmp::Ordering::Equal =>
                        match ::core::cmp::Ord::cmp(&self.predicate,
                                &other.predicate) {
                            ::core::cmp::Ordering::Equal =>
                                ::core::cmp::Ord::cmp(&self.action, &other.action),
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for MergeClause {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.when_token, state);
        ::core::hash::Hash::hash(&self.clause_kind, state);
        ::core::hash::Hash::hash(&self.predicate, state);
        ::core::hash::Hash::hash(&self.action, state)
    }
}Hash)]
406#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
407#[cfg_attr(feature = "visitor", derive(impl sqlparser::ast::Visit for MergeClause {
    fn visit<V: sqlparser::ast::Visitor>(&self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::Visit::visit(&self.when_token, visitor)?;
                        sqlparser::ast::Visit::visit(&self.clause_kind, visitor)?;
                        sqlparser::ast::Visit::visit(&self.predicate, visitor)?;
                        sqlparser::ast::Visit::visit(&self.action, visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}Visit, impl sqlparser::ast::VisitMut for MergeClause {
    fn visit<V: sqlparser::ast::VisitorMut>(&mut self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::VisitMut::visit(&mut self.when_token,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.clause_kind,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.predicate,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.action, visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}VisitMut))]
408pub struct MergeClause {
409    /// The `WHEN` token that starts the sub-expression.
410    pub when_token: AttachedToken,
411    /// The type of `WHEN` clause.
412    pub clause_kind: MergeClauseKind,
413    /// An optional predicate to further restrict the clause.
414    pub predicate: Option<Expr>,
415    /// The action to perform when the clause is matched.
416    pub action: MergeAction,
417}
418
419impl Display for MergeClause {
420    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
421        let MergeClause {
422            when_token: _,
423            clause_kind,
424            predicate,
425            action,
426        } = self;
427
428        f.write_fmt(format_args!("WHEN {0}", clause_kind))write!(f, "WHEN {clause_kind}")?;
429        if let Some(pred) = predicate {
430            f.write_fmt(format_args!(" AND {0}", pred))write!(f, " AND {pred}")?;
431        }
432        f.write_fmt(format_args!(" THEN {0}", action))write!(f, " THEN {action}")
433    }
434}
435
436/// Variant of `WHEN` clause used within a `MERGE` Statement.
437///
438/// Example:
439/// ```sql
440/// MERGE INTO T USING U ON FALSE WHEN MATCHED THEN DELETE
441/// ```
442/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/merge)
443/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
444#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MergeClauseKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                MergeClauseKind::Matched => "Matched",
                MergeClauseKind::NotMatched => "NotMatched",
                MergeClauseKind::NotMatchedByTarget => "NotMatchedByTarget",
                MergeClauseKind::NotMatchedBySource => "NotMatchedBySource",
            })
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for MergeClauseKind {
    #[inline]
    fn clone(&self) -> MergeClauseKind { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for MergeClauseKind { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for MergeClauseKind {
    #[inline]
    fn eq(&self, other: &MergeClauseKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for MergeClauseKind {
    #[inline]
    fn partial_cmp(&self, other: &MergeClauseKind)
        -> ::core::option::Option<::core::cmp::Ordering> {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for MergeClauseKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for MergeClauseKind {
    #[inline]
    fn cmp(&self, other: &MergeClauseKind) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for MergeClauseKind {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash)]
445#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
446#[cfg_attr(feature = "visitor", derive(impl sqlparser::ast::Visit for MergeClauseKind {
    fn visit<V: sqlparser::ast::Visitor>(&self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        match self {
                            Self::Matched => {}
                            Self::NotMatched => {}
                            Self::NotMatchedByTarget => {}
                            Self::NotMatchedBySource => {}
                        }
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}Visit, impl sqlparser::ast::VisitMut for MergeClauseKind {
    fn visit<V: sqlparser::ast::VisitorMut>(&mut self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        match self {
                            Self::Matched => {}
                            Self::NotMatched => {}
                            Self::NotMatchedByTarget => {}
                            Self::NotMatchedBySource => {}
                        }
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}VisitMut))]
447pub enum MergeClauseKind {
448    /// `WHEN MATCHED`
449    Matched,
450    /// `WHEN NOT MATCHED`
451    NotMatched,
452    /// `WHEN MATCHED BY TARGET`
453    ///
454    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
455    NotMatchedByTarget,
456    /// `WHEN MATCHED BY SOURCE`
457    ///
458    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
459    NotMatchedBySource,
460}
461
462impl Display for MergeClauseKind {
463    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
464        match self {
465            MergeClauseKind::Matched => f.write_fmt(format_args!("MATCHED"))write!(f, "MATCHED"),
466            MergeClauseKind::NotMatched => f.write_fmt(format_args!("NOT MATCHED"))write!(f, "NOT MATCHED"),
467            MergeClauseKind::NotMatchedByTarget => f.write_fmt(format_args!("NOT MATCHED BY TARGET"))write!(f, "NOT MATCHED BY TARGET"),
468            MergeClauseKind::NotMatchedBySource => f.write_fmt(format_args!("NOT MATCHED BY SOURCE"))write!(f, "NOT MATCHED BY SOURCE"),
469        }
470    }
471}
472
473/// Underlying statement of a `WHEN` clause within a `MERGE` Statement
474///
475/// Example
476/// ```sql
477/// INSERT (product, quantity) VALUES(product, quantity)
478/// ```
479///
480/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/merge)
481/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
482/// [Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/MERGE.html)
483#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MergeAction {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            MergeAction::Insert(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Insert",
                    &__self_0),
            MergeAction::Update(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Update",
                    &__self_0),
            MergeAction::Delete { delete_token: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "Delete", "delete_token", &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for MergeAction {
    #[inline]
    fn clone(&self) -> MergeAction {
        match self {
            MergeAction::Insert(__self_0) =>
                MergeAction::Insert(::core::clone::Clone::clone(__self_0)),
            MergeAction::Update(__self_0) =>
                MergeAction::Update(::core::clone::Clone::clone(__self_0)),
            MergeAction::Delete { delete_token: __self_0 } =>
                MergeAction::Delete {
                    delete_token: ::core::clone::Clone::clone(__self_0),
                },
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for MergeAction {
    #[inline]
    fn eq(&self, other: &MergeAction) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (MergeAction::Insert(__self_0), MergeAction::Insert(__arg1_0))
                    => __self_0 == __arg1_0,
                (MergeAction::Update(__self_0), MergeAction::Update(__arg1_0))
                    => __self_0 == __arg1_0,
                (MergeAction::Delete { delete_token: __self_0 },
                    MergeAction::Delete { delete_token: __arg1_0 }) =>
                    __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for MergeAction {
    #[inline]
    fn partial_cmp(&self, other: &MergeAction)
        -> ::core::option::Option<::core::cmp::Ordering> {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match (self, other) {
            (MergeAction::Insert(__self_0), MergeAction::Insert(__arg1_0)) =>
                ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
            (MergeAction::Update(__self_0), MergeAction::Update(__arg1_0)) =>
                ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
            (MergeAction::Delete { delete_token: __self_0 },
                MergeAction::Delete { delete_token: __arg1_0 }) =>
                ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
            _ =>
                ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
                    &__arg1_discr),
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for MergeAction {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<MergeInsertExpr>;
        let _: ::core::cmp::AssertParamIsEq<MergeUpdateExpr>;
        let _: ::core::cmp::AssertParamIsEq<AttachedToken>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for MergeAction {
    #[inline]
    fn cmp(&self, other: &MergeAction) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
            ::core::cmp::Ordering::Equal =>
                match (self, other) {
                    (MergeAction::Insert(__self_0),
                        MergeAction::Insert(__arg1_0)) =>
                        ::core::cmp::Ord::cmp(__self_0, __arg1_0),
                    (MergeAction::Update(__self_0),
                        MergeAction::Update(__arg1_0)) =>
                        ::core::cmp::Ord::cmp(__self_0, __arg1_0),
                    (MergeAction::Delete { delete_token: __self_0 },
                        MergeAction::Delete { delete_token: __arg1_0 }) =>
                        ::core::cmp::Ord::cmp(__self_0, __arg1_0),
                    _ => unsafe { ::core::intrinsics::unreachable() }
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for MergeAction {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            MergeAction::Insert(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            MergeAction::Update(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            MergeAction::Delete { delete_token: __self_0 } =>
                ::core::hash::Hash::hash(__self_0, state),
        }
    }
}Hash)]
484#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
485#[cfg_attr(feature = "visitor", derive(impl sqlparser::ast::Visit for MergeAction {
    fn visit<V: sqlparser::ast::Visitor>(&self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        match self {
                            Self::Insert(_0) => {
                                sqlparser::ast::Visit::visit(_0, visitor)?;
                            }
                            Self::Update(_0) => {
                                sqlparser::ast::Visit::visit(_0, visitor)?;
                            }
                            Self::Delete { delete_token } => {
                                sqlparser::ast::Visit::visit(delete_token, visitor)?;
                            }
                        }
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}Visit, impl sqlparser::ast::VisitMut for MergeAction {
    fn visit<V: sqlparser::ast::VisitorMut>(&mut self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        match self {
                            Self::Insert(_0) => {
                                sqlparser::ast::VisitMut::visit(_0, visitor)?;
                            }
                            Self::Update(_0) => {
                                sqlparser::ast::VisitMut::visit(_0, visitor)?;
                            }
                            Self::Delete { delete_token } => {
                                sqlparser::ast::VisitMut::visit(delete_token, visitor)?;
                            }
                        }
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}VisitMut))]
486pub enum MergeAction {
487    /// An `INSERT` clause
488    ///
489    /// Example:
490    /// ```sql
491    /// INSERT (product, quantity) VALUES(product, quantity)
492    /// ```
493    Insert(MergeInsertExpr),
494    /// An `UPDATE` clause
495    ///
496    /// Example:
497    /// ```sql
498    /// UPDATE SET quantity = T.quantity + S.quantity
499    /// ```
500    Update(MergeUpdateExpr),
501    /// A plain `DELETE` clause
502    Delete {
503        /// The `DELETE` token that starts the sub-expression.
504        delete_token: AttachedToken,
505    },
506}
507
508impl Display for MergeAction {
509    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
510        match self {
511            MergeAction::Insert(insert) => {
512                f.write_fmt(format_args!("INSERT {0}", insert))write!(f, "INSERT {insert}")
513            }
514            MergeAction::Update(update) => {
515                f.write_fmt(format_args!("UPDATE {0}", update))write!(f, "UPDATE {update}")
516            }
517            MergeAction::Delete { .. } => {
518                f.write_fmt(format_args!("DELETE"))write!(f, "DELETE")
519            }
520        }
521    }
522}
523
524/// The type of expression used to insert rows within a `MERGE` statement.
525///
526/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/merge)
527/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
528#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MergeInsertKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            MergeInsertKind::Values(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Values",
                    &__self_0),
            MergeInsertKind::Row =>
                ::core::fmt::Formatter::write_str(f, "Row"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for MergeInsertKind {
    #[inline]
    fn clone(&self) -> MergeInsertKind {
        match self {
            MergeInsertKind::Values(__self_0) =>
                MergeInsertKind::Values(::core::clone::Clone::clone(__self_0)),
            MergeInsertKind::Row => MergeInsertKind::Row,
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for MergeInsertKind {
    #[inline]
    fn eq(&self, other: &MergeInsertKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (MergeInsertKind::Values(__self_0),
                    MergeInsertKind::Values(__arg1_0)) => __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for MergeInsertKind {
    #[inline]
    fn partial_cmp(&self, other: &MergeInsertKind)
        -> ::core::option::Option<::core::cmp::Ordering> {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match (self, other) {
            (MergeInsertKind::Values(__self_0),
                MergeInsertKind::Values(__arg1_0)) =>
                ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
            _ =>
                ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
                    &__arg1_discr),
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for MergeInsertKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Values>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for MergeInsertKind {
    #[inline]
    fn cmp(&self, other: &MergeInsertKind) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
            ::core::cmp::Ordering::Equal =>
                match (self, other) {
                    (MergeInsertKind::Values(__self_0),
                        MergeInsertKind::Values(__arg1_0)) =>
                        ::core::cmp::Ord::cmp(__self_0, __arg1_0),
                    _ => ::core::cmp::Ordering::Equal,
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for MergeInsertKind {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            MergeInsertKind::Values(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash)]
529#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
530#[cfg_attr(feature = "visitor", derive(impl sqlparser::ast::Visit for MergeInsertKind {
    fn visit<V: sqlparser::ast::Visitor>(&self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        match self {
                            Self::Values(_0) => {
                                sqlparser::ast::Visit::visit(_0, visitor)?;
                            }
                            Self::Row => {}
                        }
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}Visit, impl sqlparser::ast::VisitMut for MergeInsertKind {
    fn visit<V: sqlparser::ast::VisitorMut>(&mut self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        match self {
                            Self::Values(_0) => {
                                sqlparser::ast::VisitMut::visit(_0, visitor)?;
                            }
                            Self::Row => {}
                        }
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}VisitMut))]
531pub enum MergeInsertKind {
532    /// The insert expression is defined from an explicit `VALUES` clause
533    ///
534    /// Example:
535    /// ```sql
536    /// INSERT VALUES(product, quantity)
537    /// ```
538    Values(Values),
539    /// The insert expression is defined using only the `ROW` keyword.
540    ///
541    /// Example:
542    /// ```sql
543    /// INSERT ROW
544    /// ```
545    /// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
546    Row,
547}
548
549impl Display for MergeInsertKind {
550    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
551        match self {
552            MergeInsertKind::Values(values) => {
553                f.write_fmt(format_args!("{0}", values))write!(f, "{values}")
554            }
555            MergeInsertKind::Row => {
556                f.write_fmt(format_args!("ROW"))write!(f, "ROW")
557            }
558        }
559    }
560}
561
562/// The expression used to insert rows within a `MERGE` statement.
563///
564/// Examples
565/// ```sql
566/// INSERT (product, quantity) VALUES(product, quantity)
567/// INSERT ROW
568/// ```
569///
570/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/merge)
571/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
572/// [Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/MERGE.html)
573#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MergeInsertExpr {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f,
            "MergeInsertExpr", "insert_token", &self.insert_token, "columns",
            &self.columns, "kind_token", &self.kind_token, "kind", &self.kind,
            "insert_predicate", &&self.insert_predicate)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for MergeInsertExpr {
    #[inline]
    fn clone(&self) -> MergeInsertExpr {
        MergeInsertExpr {
            insert_token: ::core::clone::Clone::clone(&self.insert_token),
            columns: ::core::clone::Clone::clone(&self.columns),
            kind_token: ::core::clone::Clone::clone(&self.kind_token),
            kind: ::core::clone::Clone::clone(&self.kind),
            insert_predicate: ::core::clone::Clone::clone(&self.insert_predicate),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for MergeInsertExpr {
    #[inline]
    fn eq(&self, other: &MergeInsertExpr) -> bool {
        self.insert_token == other.insert_token &&
                        self.columns == other.columns &&
                    self.kind_token == other.kind_token &&
                self.kind == other.kind &&
            self.insert_predicate == other.insert_predicate
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for MergeInsertExpr {
    #[inline]
    fn partial_cmp(&self, other: &MergeInsertExpr)
        -> ::core::option::Option<::core::cmp::Ordering> {
        match ::core::cmp::PartialOrd::partial_cmp(&self.insert_token,
                &other.insert_token) {
            ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
                match ::core::cmp::PartialOrd::partial_cmp(&self.columns,
                        &other.columns) {
                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                        =>
                        match ::core::cmp::PartialOrd::partial_cmp(&self.kind_token,
                                &other.kind_token) {
                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                =>
                                match ::core::cmp::PartialOrd::partial_cmp(&self.kind,
                                        &other.kind) {
                                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                        =>
                                        ::core::cmp::PartialOrd::partial_cmp(&self.insert_predicate,
                                            &other.insert_predicate),
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for MergeInsertExpr {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<AttachedToken>;
        let _: ::core::cmp::AssertParamIsEq<Vec<ObjectName>>;
        let _: ::core::cmp::AssertParamIsEq<MergeInsertKind>;
        let _: ::core::cmp::AssertParamIsEq<Option<Expr>>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for MergeInsertExpr {
    #[inline]
    fn cmp(&self, other: &MergeInsertExpr) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.insert_token, &other.insert_token) {
            ::core::cmp::Ordering::Equal =>
                match ::core::cmp::Ord::cmp(&self.columns, &other.columns) {
                    ::core::cmp::Ordering::Equal =>
                        match ::core::cmp::Ord::cmp(&self.kind_token,
                                &other.kind_token) {
                            ::core::cmp::Ordering::Equal =>
                                match ::core::cmp::Ord::cmp(&self.kind, &other.kind) {
                                    ::core::cmp::Ordering::Equal =>
                                        ::core::cmp::Ord::cmp(&self.insert_predicate,
                                            &other.insert_predicate),
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for MergeInsertExpr {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.insert_token, state);
        ::core::hash::Hash::hash(&self.columns, state);
        ::core::hash::Hash::hash(&self.kind_token, state);
        ::core::hash::Hash::hash(&self.kind, state);
        ::core::hash::Hash::hash(&self.insert_predicate, state)
    }
}Hash)]
574#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
575#[cfg_attr(feature = "visitor", derive(impl sqlparser::ast::Visit for MergeInsertExpr {
    fn visit<V: sqlparser::ast::Visitor>(&self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::Visit::visit(&self.insert_token, visitor)?;
                        sqlparser::ast::Visit::visit(&self.columns, visitor)?;
                        sqlparser::ast::Visit::visit(&self.kind_token, visitor)?;
                        sqlparser::ast::Visit::visit(&self.kind, visitor)?;
                        sqlparser::ast::Visit::visit(&self.insert_predicate,
                                visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}Visit, impl sqlparser::ast::VisitMut for MergeInsertExpr {
    fn visit<V: sqlparser::ast::VisitorMut>(&mut self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::VisitMut::visit(&mut self.insert_token,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.columns,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.kind_token,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.kind, visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.insert_predicate,
                                visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}VisitMut))]
576pub struct MergeInsertExpr {
577    /// The `INSERT` token that starts the sub-expression.
578    pub insert_token: AttachedToken,
579    /// Columns (if any) specified by the insert.
580    ///
581    /// Example:
582    /// ```sql
583    /// INSERT (product, quantity) VALUES(product, quantity)
584    /// INSERT (product, quantity) ROW
585    /// ```
586    pub columns: Vec<ObjectName>,
587    /// The token, `[VALUES | ROW]` starting `kind`.
588    pub kind_token: AttachedToken,
589    /// The insert type used by the statement.
590    pub kind: MergeInsertKind,
591    /// An optional condition to restrict the insertion (Oracle specific)
592    pub insert_predicate: Option<Expr>,
593}
594
595impl Display for MergeInsertExpr {
596    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
597        if !self.columns.is_empty() {
598            f.write_fmt(format_args!("({0}) ",
        display_comma_separated(self.columns.as_slice())))write!(f, "({}) ", display_comma_separated(self.columns.as_slice()))?;
599        }
600        f.write_fmt(format_args!("{0}", self.kind))write!(f, "{}", self.kind)?;
601        if let Some(predicate) = self.insert_predicate.as_ref() {
602            f.write_fmt(format_args!(" WHERE {0}", predicate))write!(f, " WHERE {}", predicate)?;
603        }
604        Ok(())
605    }
606}
607
608/// The expression used to update rows within a `MERGE` statement.
609///
610/// Examples
611/// ```sql
612/// UPDATE SET quantity = T.quantity + S.quantity
613/// ```
614///
615/// [Snowflake](https://docs.snowflake.com/en/sql-reference/sql/merge)
616/// [BigQuery](https://cloud.google.com/bigquery/docs/reference/standard-sql/dml-syntax#merge_statement)
617/// [Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/MERGE.html)
618#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MergeUpdateExpr {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f,
            "MergeUpdateExpr", "update_token", &self.update_token,
            "assignments", &self.assignments, "update_predicate",
            &self.update_predicate, "delete_predicate",
            &&self.delete_predicate)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for MergeUpdateExpr {
    #[inline]
    fn clone(&self) -> MergeUpdateExpr {
        MergeUpdateExpr {
            update_token: ::core::clone::Clone::clone(&self.update_token),
            assignments: ::core::clone::Clone::clone(&self.assignments),
            update_predicate: ::core::clone::Clone::clone(&self.update_predicate),
            delete_predicate: ::core::clone::Clone::clone(&self.delete_predicate),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for MergeUpdateExpr {
    #[inline]
    fn eq(&self, other: &MergeUpdateExpr) -> bool {
        self.update_token == other.update_token &&
                    self.assignments == other.assignments &&
                self.update_predicate == other.update_predicate &&
            self.delete_predicate == other.delete_predicate
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for MergeUpdateExpr {
    #[inline]
    fn partial_cmp(&self, other: &MergeUpdateExpr)
        -> ::core::option::Option<::core::cmp::Ordering> {
        match ::core::cmp::PartialOrd::partial_cmp(&self.update_token,
                &other.update_token) {
            ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
                match ::core::cmp::PartialOrd::partial_cmp(&self.assignments,
                        &other.assignments) {
                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                        =>
                        match ::core::cmp::PartialOrd::partial_cmp(&self.update_predicate,
                                &other.update_predicate) {
                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                =>
                                ::core::cmp::PartialOrd::partial_cmp(&self.delete_predicate,
                                    &other.delete_predicate),
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for MergeUpdateExpr {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<AttachedToken>;
        let _: ::core::cmp::AssertParamIsEq<Vec<Assignment>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Expr>>;
        let _: ::core::cmp::AssertParamIsEq<Option<Expr>>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for MergeUpdateExpr {
    #[inline]
    fn cmp(&self, other: &MergeUpdateExpr) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.update_token, &other.update_token) {
            ::core::cmp::Ordering::Equal =>
                match ::core::cmp::Ord::cmp(&self.assignments,
                        &other.assignments) {
                    ::core::cmp::Ordering::Equal =>
                        match ::core::cmp::Ord::cmp(&self.update_predicate,
                                &other.update_predicate) {
                            ::core::cmp::Ordering::Equal =>
                                ::core::cmp::Ord::cmp(&self.delete_predicate,
                                    &other.delete_predicate),
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for MergeUpdateExpr {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.update_token, state);
        ::core::hash::Hash::hash(&self.assignments, state);
        ::core::hash::Hash::hash(&self.update_predicate, state);
        ::core::hash::Hash::hash(&self.delete_predicate, state)
    }
}Hash)]
619#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
620#[cfg_attr(feature = "visitor", derive(impl sqlparser::ast::Visit for MergeUpdateExpr {
    fn visit<V: sqlparser::ast::Visitor>(&self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::Visit::visit(&self.update_token, visitor)?;
                        sqlparser::ast::Visit::visit(&self.assignments, visitor)?;
                        sqlparser::ast::Visit::visit(&self.update_predicate,
                                visitor)?;
                        sqlparser::ast::Visit::visit(&self.delete_predicate,
                                visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}Visit, impl sqlparser::ast::VisitMut for MergeUpdateExpr {
    fn visit<V: sqlparser::ast::VisitorMut>(&mut self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        sqlparser::ast::VisitMut::visit(&mut self.update_token,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.assignments,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.update_predicate,
                                visitor)?;
                        sqlparser::ast::VisitMut::visit(&mut self.delete_predicate,
                                visitor)?;
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}VisitMut))]
621pub struct MergeUpdateExpr {
622    /// The `UPDATE` token that starts the sub-expression.
623    pub update_token: AttachedToken,
624    /// The update assiment expressions
625    pub assignments: Vec<Assignment>,
626    /// `where_clause` for the update (Oralce specific)
627    pub update_predicate: Option<Expr>,
628    /// `delete_clause` for the update "delete where" (Oracle specific)
629    pub delete_predicate: Option<Expr>,
630}
631
632impl Display for MergeUpdateExpr {
633    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
634        f.write_fmt(format_args!("SET {0}",
        display_comma_separated(&self.assignments)))write!(f, "SET {}", display_comma_separated(&self.assignments))?;
635        if let Some(predicate) = self.update_predicate.as_ref() {
636            f.write_fmt(format_args!(" WHERE {0}", predicate))write!(f, " WHERE {predicate}")?;
637        }
638        if let Some(predicate) = self.delete_predicate.as_ref() {
639            f.write_fmt(format_args!(" DELETE WHERE {0}", predicate))write!(f, " DELETE WHERE {predicate}")?;
640        }
641        Ok(())
642    }
643}
644
645/// A `OUTPUT` Clause in the end of a `MERGE` Statement
646///
647/// Example:
648/// OUTPUT $action, deleted.* INTO dbo.temp_products;
649/// [mssql](https://learn.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql)
650#[derive(#[automatically_derived]
impl ::core::fmt::Debug for OutputClause {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            OutputClause::Output {
                output_token: __self_0,
                select_items: __self_1,
                into_table: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f,
                    "Output", "output_token", __self_0, "select_items",
                    __self_1, "into_table", &__self_2),
            OutputClause::Returning {
                returning_token: __self_0, select_items: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "Returning", "returning_token", __self_0, "select_items",
                    &__self_1),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for OutputClause {
    #[inline]
    fn clone(&self) -> OutputClause {
        match self {
            OutputClause::Output {
                output_token: __self_0,
                select_items: __self_1,
                into_table: __self_2 } =>
                OutputClause::Output {
                    output_token: ::core::clone::Clone::clone(__self_0),
                    select_items: ::core::clone::Clone::clone(__self_1),
                    into_table: ::core::clone::Clone::clone(__self_2),
                },
            OutputClause::Returning {
                returning_token: __self_0, select_items: __self_1 } =>
                OutputClause::Returning {
                    returning_token: ::core::clone::Clone::clone(__self_0),
                    select_items: ::core::clone::Clone::clone(__self_1),
                },
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for OutputClause {
    #[inline]
    fn eq(&self, other: &OutputClause) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (OutputClause::Output {
                    output_token: __self_0,
                    select_items: __self_1,
                    into_table: __self_2 }, OutputClause::Output {
                    output_token: __arg1_0,
                    select_items: __arg1_1,
                    into_table: __arg1_2 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                        __self_2 == __arg1_2,
                (OutputClause::Returning {
                    returning_token: __self_0, select_items: __self_1 },
                    OutputClause::Returning {
                    returning_token: __arg1_0, select_items: __arg1_1 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for OutputClause {
    #[inline]
    fn partial_cmp(&self, other: &OutputClause)
        -> ::core::option::Option<::core::cmp::Ordering> {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match (self, other) {
            (OutputClause::Output {
                output_token: __self_0,
                select_items: __self_1,
                into_table: __self_2 }, OutputClause::Output {
                output_token: __arg1_0,
                select_items: __arg1_1,
                into_table: __arg1_2 }) =>
                match ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0)
                    {
                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                        =>
                        match ::core::cmp::PartialOrd::partial_cmp(__self_1,
                                __arg1_1) {
                            ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                                => ::core::cmp::PartialOrd::partial_cmp(__self_2, __arg1_2),
                            cmp => cmp,
                        },
                    cmp => cmp,
                },
            (OutputClause::Returning {
                returning_token: __self_0, select_items: __self_1 },
                OutputClause::Returning {
                returning_token: __arg1_0, select_items: __arg1_1 }) =>
                match ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0)
                    {
                    ::core::option::Option::Some(::core::cmp::Ordering::Equal)
                        => ::core::cmp::PartialOrd::partial_cmp(__self_1, __arg1_1),
                    cmp => cmp,
                },
            _ =>
                ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
                    &__arg1_discr),
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for OutputClause {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<AttachedToken>;
        let _: ::core::cmp::AssertParamIsEq<Vec<SelectItem>>;
        let _: ::core::cmp::AssertParamIsEq<Option<SelectInto>>;
        let _: ::core::cmp::AssertParamIsEq<Vec<SelectItem>>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for OutputClause {
    #[inline]
    fn cmp(&self, other: &OutputClause) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
            ::core::cmp::Ordering::Equal =>
                match (self, other) {
                    (OutputClause::Output {
                        output_token: __self_0,
                        select_items: __self_1,
                        into_table: __self_2 }, OutputClause::Output {
                        output_token: __arg1_0,
                        select_items: __arg1_1,
                        into_table: __arg1_2 }) =>
                        match ::core::cmp::Ord::cmp(__self_0, __arg1_0) {
                            ::core::cmp::Ordering::Equal =>
                                match ::core::cmp::Ord::cmp(__self_1, __arg1_1) {
                                    ::core::cmp::Ordering::Equal =>
                                        ::core::cmp::Ord::cmp(__self_2, __arg1_2),
                                    cmp => cmp,
                                },
                            cmp => cmp,
                        },
                    (OutputClause::Returning {
                        returning_token: __self_0, select_items: __self_1 },
                        OutputClause::Returning {
                        returning_token: __arg1_0, select_items: __arg1_1 }) =>
                        match ::core::cmp::Ord::cmp(__self_0, __arg1_0) {
                            ::core::cmp::Ordering::Equal =>
                                ::core::cmp::Ord::cmp(__self_1, __arg1_1),
                            cmp => cmp,
                        },
                    _ => unsafe { ::core::intrinsics::unreachable() }
                },
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for OutputClause {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            OutputClause::Output {
                output_token: __self_0,
                select_items: __self_1,
                into_table: __self_2 } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state);
                ::core::hash::Hash::hash(__self_2, state)
            }
            OutputClause::Returning {
                returning_token: __self_0, select_items: __self_1 } => {
                ::core::hash::Hash::hash(__self_0, state);
                ::core::hash::Hash::hash(__self_1, state)
            }
        }
    }
}Hash)]
651#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
652#[cfg_attr(feature = "visitor", derive(impl sqlparser::ast::Visit for OutputClause {
    fn visit<V: sqlparser::ast::Visitor>(&self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        match self {
                            Self::Output { output_token, select_items, into_table } => {
                                sqlparser::ast::Visit::visit(output_token, visitor)?;
                                sqlparser::ast::Visit::visit(select_items, visitor)?;
                                sqlparser::ast::Visit::visit(into_table, visitor)?;
                            }
                            Self::Returning { returning_token, select_items } => {
                                sqlparser::ast::Visit::visit(returning_token, visitor)?;
                                sqlparser::ast::Visit::visit(select_items, visitor)?;
                            }
                        }
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}Visit, impl sqlparser::ast::VisitMut for OutputClause {
    fn visit<V: sqlparser::ast::VisitorMut>(&mut self, visitor: &mut V)
        -> ::std::ops::ControlFlow<V::Break> {
        ::recursive::__impl::stacker::maybe_grow(::recursive::get_minimum_stack_size(),
            ::recursive::get_stack_allocation_size(),
            move || -> ::std::ops::ControlFlow<V::Break>
                {
                    {
                        match self {
                            Self::Output { output_token, select_items, into_table } => {
                                sqlparser::ast::VisitMut::visit(output_token, visitor)?;
                                sqlparser::ast::VisitMut::visit(select_items, visitor)?;
                                sqlparser::ast::VisitMut::visit(into_table, visitor)?;
                            }
                            Self::Returning { returning_token, select_items } => {
                                sqlparser::ast::VisitMut::visit(returning_token, visitor)?;
                                sqlparser::ast::VisitMut::visit(select_items, visitor)?;
                            }
                        }
                        ::std::ops::ControlFlow::Continue(())
                    }
                })
    }
}VisitMut))]
653pub enum OutputClause {
654    /// `OUTPUT` clause
655    Output {
656        /// The `OUTPUT` token that starts the sub-expression.
657        output_token: AttachedToken,
658        /// The select items to output
659        select_items: Vec<SelectItem>,
660        /// Optional `INTO` table to direct the output
661        into_table: Option<SelectInto>,
662    },
663    /// `RETURNING` clause
664    Returning {
665        /// The `RETURNING` token that starts the sub-expression.
666        returning_token: AttachedToken,
667        /// The select items to return
668        select_items: Vec<SelectItem>,
669    },
670}
671
672impl fmt::Display for OutputClause {
673    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
674        match self {
675            OutputClause::Output {
676                output_token: _,
677                select_items,
678                into_table,
679            } => {
680                f.write_str("OUTPUT ")?;
681                display_comma_separated(select_items).fmt(f)?;
682                if let Some(into_table) = into_table {
683                    f.write_str(" ")?;
684                    into_table.fmt(f)?;
685                }
686                Ok(())
687            }
688            OutputClause::Returning {
689                returning_token: _,
690                select_items,
691            } => {
692                f.write_str("RETURNING ")?;
693                display_comma_separated(select_items).fmt(f)
694            }
695        }
696    }
697}