diff --git a/src/ast/dml.rs b/src/ast/dml.rs new file mode 100644 index 000000000..badc58a7d --- /dev/null +++ b/src/ast/dml.rs @@ -0,0 +1,84 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[cfg(not(feature = "std"))] +use alloc::{boxed::Box, vec::Vec}; + +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; +#[cfg(feature = "visitor")] +use sqlparser_derive::{Visit, VisitMut}; + +use super::{ + Expr, FromTable, Ident, InsertAliases, MysqlInsertPriority, ObjectName, OnInsert, OrderByExpr, + Query, SelectItem, SqliteOnConflict, TableWithJoins, +}; + +/// INSERT statement. +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] +pub struct Insert { + /// Only for Sqlite + pub or: Option, + /// Only for mysql + pub ignore: bool, + /// INTO - optional keyword + pub into: bool, + /// TABLE + #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] + pub table_name: ObjectName, + /// table_name as foo (for PostgreSQL) + pub table_alias: Option, + /// COLUMNS + pub columns: Vec, + /// Overwrite (Hive) + pub overwrite: bool, + /// A SQL query that specifies what to insert + pub source: Option>, + /// partitioned insert (Hive) + pub partitioned: Option>, + /// Columns defined after PARTITION + pub after_columns: Vec, + /// whether the insert has the table keyword (Hive) + pub table: bool, + pub on: Option, + /// RETURNING + pub returning: Option>, + /// Only for mysql + pub replace_into: bool, + /// Only for mysql + pub priority: Option, + /// Only for mysql + pub insert_alias: Option, +} + +/// DELETE statement. +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))] +pub struct Delete { + /// Multi tables delete are supported in mysql + pub tables: Vec, + /// FROM + pub from: FromTable, + /// USING (Snowflake, Postgres, MySQL) + pub using: Option>, + /// WHERE + pub selection: Option, + /// RETURNING + pub returning: Option>, + /// ORDER BY (MySQL) + pub order_by: Vec, + /// LIMIT (MySQL) + pub limit: Option, +} diff --git a/src/ast/mod.rs b/src/ast/mod.rs index e02741aac..210b5b1a9 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -37,6 +37,7 @@ pub use self::ddl::{ ReferentialAction, TableConstraint, UserDefinedTypeCompositeAttributeDef, UserDefinedTypeRepresentation, ViewColumnDef, }; +pub use self::dml::{Delete, Insert}; pub use self::operator::{BinaryOperator, UnaryOperator}; pub use self::query::{ Cte, CteAsMaterialized, Distinct, ExceptSelectItem, ExcludeSelectItem, Fetch, ForClause, @@ -60,6 +61,7 @@ pub use visitor::*; mod data_type; mod dcl; mod ddl; +mod dml; pub mod helpers; mod operator; mod query; @@ -1800,40 +1802,7 @@ pub enum Statement { /// ```sql /// INSERT /// ``` - Insert { - /// Only for Sqlite - or: Option, - /// Only for mysql - ignore: bool, - /// INTO - optional keyword - into: bool, - /// TABLE - #[cfg_attr(feature = "visitor", visit(with = "visit_relation"))] - table_name: ObjectName, - /// table_name as foo (for PostgreSQL) - table_alias: Option, - /// COLUMNS - columns: Vec, - /// Overwrite (Hive) - overwrite: bool, - /// A SQL query that specifies what to insert - source: Option>, - /// partitioned insert (Hive) - partitioned: Option>, - /// Columns defined after PARTITION - after_columns: Vec, - /// whether the insert has the table keyword (Hive) - table: bool, - on: Option, - /// RETURNING - returning: Option>, - /// Only for mysql - replace_into: bool, - /// Only for mysql - priority: Option, - /// Only for mysql - insert_alias: Option, - }, + Insert(Insert), /// ```sql /// INSTALL /// ``` @@ -1923,22 +1892,7 @@ pub enum Statement { /// ```sql /// DELETE /// ``` - Delete { - /// Multi tables delete are supported in mysql - tables: Vec, - /// FROM - from: FromTable, - /// USING (Snowflake, Postgres, MySQL) - using: Option>, - /// WHERE - selection: Option, - /// RETURNING - returning: Option>, - /// ORDER BY (MySQL) - order_by: Vec, - /// LIMIT (MySQL) - limit: Option, - }, + Delete(Delete), /// ```sql /// CREATE VIEW /// ``` @@ -2912,24 +2866,25 @@ impl fmt::Display for Statement { } Ok(()) } - Statement::Insert { - or, - ignore, - into, - table_name, - table_alias, - overwrite, - partitioned, - columns, - after_columns, - source, - table, - on, - returning, - replace_into, - priority, - insert_alias, - } => { + Statement::Insert(insert) => { + let Insert { + or, + ignore, + into, + table_name, + table_alias, + overwrite, + partitioned, + columns, + after_columns, + source, + table, + on, + returning, + replace_into, + priority, + insert_alias, + } = insert; let table_name = if let Some(alias) = table_alias { format!("{table_name} AS {alias}") } else { @@ -3074,15 +3029,16 @@ impl fmt::Display for Statement { } Ok(()) } - Statement::Delete { - tables, - from, - using, - selection, - returning, - order_by, - limit, - } => { + Statement::Delete(delete) => { + let Delete { + tables, + from, + using, + selection, + returning, + order_by, + limit, + } = delete; write!(f, "DELETE ")?; if !tables.is_empty() { write!(f, "{} ", display_comma_separated(tables))?; diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 5bae7a133..5f7553dcd 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -7088,7 +7088,7 @@ impl<'a> Parser<'a> { None }; - Ok(Statement::Delete { + Ok(Statement::Delete(Delete { tables, from: if with_from_keyword { FromTable::WithFromKeyword(from) @@ -7100,7 +7100,7 @@ impl<'a> Parser<'a> { returning, order_by, limit, - }) + })) } // KILL [CONNECTION | QUERY | MUTATION] processlist_id @@ -8664,7 +8664,7 @@ impl<'a> Parser<'a> { } let insert = &mut self.parse_insert()?; - if let Statement::Insert { replace_into, .. } = insert { + if let Statement::Insert(Insert { replace_into, .. }) = insert { *replace_into = true; } @@ -8832,7 +8832,7 @@ impl<'a> Parser<'a> { None }; - Ok(Statement::Insert { + Ok(Statement::Insert(Insert { or, table_name, table_alias, @@ -8849,7 +8849,7 @@ impl<'a> Parser<'a> { replace_into, priority, insert_alias, - }) + })) } } diff --git a/tests/sqlparser_bigquery.rs b/tests/sqlparser_bigquery.rs index c8f1bb7c1..85744b245 100644 --- a/tests/sqlparser_bigquery.rs +++ b/tests/sqlparser_bigquery.rs @@ -90,10 +90,10 @@ fn parse_raw_literal() { fn parse_delete_statement() { let sql = "DELETE \"table\" WHERE 1"; match bigquery_and_generic().verified_stmt(sql) { - Statement::Delete { + Statement::Delete(Delete { from: FromTable::WithoutKeyword(from), .. - } => { + }) => { assert_eq!( TableFactor::Table { name: ObjectName(vec![Ident::with_quote('"', "table")]), diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index c94bd3779..9acb1e370 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -84,12 +84,12 @@ fn parse_insert_values() { expected_rows: &[Vec], ) { match verified_stmt(sql) { - Statement::Insert { + Statement::Insert(Insert { table_name, columns, source: Some(source), .. - } => { + }) => { assert_eq!(table_name.to_string(), expected_table_name); assert_eq!(columns.len(), expected_columns.len()); for (index, column) in columns.iter().enumerate() { @@ -125,7 +125,7 @@ fn parse_insert_default_values() { let insert_with_default_values = verified_stmt("INSERT INTO test_table DEFAULT VALUES"); match insert_with_default_values { - Statement::Insert { + Statement::Insert(Insert { after_columns, columns, on, @@ -134,7 +134,7 @@ fn parse_insert_default_values() { source, table_name, .. - } => { + }) => { assert_eq!(columns, vec![]); assert_eq!(after_columns, vec![]); assert_eq!(on, None); @@ -150,7 +150,7 @@ fn parse_insert_default_values() { verified_stmt("INSERT INTO test_table DEFAULT VALUES RETURNING test_column"); match insert_with_default_values_and_returning { - Statement::Insert { + Statement::Insert(Insert { after_columns, columns, on, @@ -159,7 +159,7 @@ fn parse_insert_default_values() { source, table_name, .. - } => { + }) => { assert_eq!(after_columns, vec![]); assert_eq!(columns, vec![]); assert_eq!(on, None); @@ -175,7 +175,7 @@ fn parse_insert_default_values() { verified_stmt("INSERT INTO test_table DEFAULT VALUES ON CONFLICT DO NOTHING"); match insert_with_default_values_and_on_conflict { - Statement::Insert { + Statement::Insert(Insert { after_columns, columns, on, @@ -184,7 +184,7 @@ fn parse_insert_default_values() { source, table_name, .. - } => { + }) => { assert_eq!(after_columns, vec![]); assert_eq!(columns, vec![]); assert!(on.is_some()); @@ -230,11 +230,11 @@ fn parse_insert_select_returning() { verified_stmt("INSERT INTO t SELECT 1 RETURNING 2"); let stmt = verified_stmt("INSERT INTO t SELECT x RETURNING x AS y"); match stmt { - Statement::Insert { + Statement::Insert(Insert { returning: Some(ret), source: Some(_), .. - } => assert_eq!(ret.len(), 1), + }) => assert_eq!(ret.len(), 1), _ => unreachable!(), } } @@ -255,7 +255,7 @@ fn parse_insert_sqlite() { .pop() .unwrap() { - Statement::Insert { or, .. } => assert_eq!(or, expected_action), + Statement::Insert(Insert { or, .. }) => assert_eq!(or, expected_action), _ => panic!("{}", sql), }; @@ -545,10 +545,10 @@ fn parse_no_table_name() { fn parse_delete_statement() { let sql = "DELETE FROM \"table\""; match verified_stmt(sql) { - Statement::Delete { + Statement::Delete(Delete { from: FromTable::WithFromKeyword(from), .. - } => { + }) => { assert_eq!( TableFactor::Table { name: ObjectName(vec![Ident::with_quote('"', "table")]), @@ -582,11 +582,11 @@ fn parse_delete_statement_for_multi_tables() { let sql = "DELETE schema1.table1, schema2.table2 FROM schema1.table1 JOIN schema2.table2 ON schema2.table2.col1 = schema1.table1.col1 WHERE schema2.table2.col2 = 1"; let dialects = all_dialects_except(|d| d.is::() || d.is::()); match dialects.verified_stmt(sql) { - Statement::Delete { + Statement::Delete(Delete { tables, from: FromTable::WithFromKeyword(from), .. - } => { + }) => { assert_eq!( ObjectName(vec![Ident::new("schema1"), Ident::new("table1")]), tables[0] @@ -626,11 +626,11 @@ fn parse_delete_statement_for_multi_tables() { fn parse_delete_statement_for_multi_tables_with_using() { let sql = "DELETE FROM schema1.table1, schema2.table2 USING schema1.table1 JOIN schema2.table2 ON schema2.table2.pk = schema1.table1.col1 WHERE schema2.table2.col2 = 1"; match verified_stmt(sql) { - Statement::Delete { + Statement::Delete(Delete { from: FromTable::WithFromKeyword(from), using: Some(using), .. - } => { + }) => { assert_eq!( TableFactor::Table { name: ObjectName(vec![Ident::new("schema1"), Ident::new("table1")]), @@ -686,14 +686,14 @@ fn parse_where_delete_statement() { let sql = "DELETE FROM foo WHERE name = 5"; match verified_stmt(sql) { - Statement::Delete { + Statement::Delete(Delete { tables: _, from: FromTable::WithFromKeyword(from), using, selection, returning, .. - } => { + }) => { assert_eq!( TableFactor::Table { name: ObjectName(vec![Ident::new("foo")]), @@ -727,14 +727,14 @@ fn parse_where_delete_with_alias_statement() { let sql = "DELETE FROM basket AS a USING basket AS b WHERE a.id < b.id"; match verified_stmt(sql) { - Statement::Delete { + Statement::Delete(Delete { tables: _, from: FromTable::WithFromKeyword(from), using, selection, returning, .. - } => { + }) => { assert_eq!( TableFactor::Table { name: ObjectName(vec![Ident::new("basket")]), diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs index 5f64079a6..32da4bcfa 100644 --- a/tests/sqlparser_mysql.rs +++ b/tests/sqlparser_mysql.rs @@ -1283,13 +1283,13 @@ fn parse_simple_insert() { let sql = r"INSERT INTO tasks (title, priority) VALUES ('Test Some Inserts', 1), ('Test Entry 2', 2), ('Test Entry 3', 3)"; match mysql().verified_stmt(sql) { - Statement::Insert { + Statement::Insert(Insert { table_name, columns, source, on, .. - } => { + }) => { assert_eq!(ObjectName(vec![Ident::new("tasks")]), table_name); assert_eq!(vec![Ident::new("title"), Ident::new("priority")], columns); assert!(on.is_none()); @@ -1335,14 +1335,14 @@ fn parse_ignore_insert() { let sql = r"INSERT IGNORE INTO tasks (title, priority) VALUES ('Test Some Inserts', 1)"; match mysql_and_generic().verified_stmt(sql) { - Statement::Insert { + Statement::Insert(Insert { table_name, columns, source, on, ignore, .. - } => { + }) => { assert_eq!(ObjectName(vec![Ident::new("tasks")]), table_name); assert_eq!(vec![Ident::new("title"), Ident::new("priority")], columns); assert!(on.is_none()); @@ -1377,14 +1377,14 @@ fn parse_priority_insert() { let sql = r"INSERT HIGH_PRIORITY INTO tasks (title, priority) VALUES ('Test Some Inserts', 1)"; match mysql_and_generic().verified_stmt(sql) { - Statement::Insert { + Statement::Insert(Insert { table_name, columns, source, on, priority, .. - } => { + }) => { assert_eq!(ObjectName(vec![Ident::new("tasks")]), table_name); assert_eq!(vec![Ident::new("title"), Ident::new("priority")], columns); assert!(on.is_none()); @@ -1416,14 +1416,14 @@ fn parse_priority_insert() { let sql2 = r"INSERT LOW_PRIORITY INTO tasks (title, priority) VALUES ('Test Some Inserts', 1)"; match mysql().verified_stmt(sql2) { - Statement::Insert { + Statement::Insert(Insert { table_name, columns, source, on, priority, .. - } => { + }) => { assert_eq!(ObjectName(vec![Ident::new("tasks")]), table_name); assert_eq!(vec![Ident::new("title"), Ident::new("priority")], columns); assert!(on.is_none()); @@ -1457,13 +1457,13 @@ fn parse_priority_insert() { fn parse_insert_as() { let sql = r"INSERT INTO `table` (`date`) VALUES ('2024-01-01') AS `alias`"; match mysql_and_generic().verified_stmt(sql) { - Statement::Insert { + Statement::Insert(Insert { table_name, columns, source, insert_alias, .. - } => { + }) => { assert_eq!( ObjectName(vec![Ident::with_quote('`', "table")]), table_name @@ -1507,13 +1507,13 @@ fn parse_insert_as() { let sql = r"INSERT INTO `table` (`id`, `date`) VALUES (1, '2024-01-01') AS `alias` (`mek_id`, `mek_date`)"; match mysql_and_generic().verified_stmt(sql) { - Statement::Insert { + Statement::Insert(Insert { table_name, columns, source, insert_alias, .. - } => { + }) => { assert_eq!( ObjectName(vec![Ident::with_quote('`', "table")]), table_name @@ -1563,7 +1563,7 @@ fn parse_insert_as() { fn parse_replace_insert() { let sql = r"REPLACE DELAYED INTO tasks (title, priority) VALUES ('Test Some Inserts', 1)"; match mysql().verified_stmt(sql) { - Statement::Insert { + Statement::Insert(Insert { table_name, columns, source, @@ -1571,7 +1571,7 @@ fn parse_replace_insert() { replace_into, priority, .. - } => { + }) => { assert_eq!(ObjectName(vec![Ident::new("tasks")]), table_name); assert_eq!(vec![Ident::new("title"), Ident::new("priority")], columns); assert!(on.is_none()); @@ -1607,13 +1607,13 @@ fn parse_empty_row_insert() { let sql = "INSERT INTO tb () VALUES (), ()"; match mysql().one_statement_parses_to(sql, "INSERT INTO tb VALUES (), ()") { - Statement::Insert { + Statement::Insert(Insert { table_name, columns, source, on, .. - } => { + }) => { assert_eq!(ObjectName(vec![Ident::new("tb")]), table_name); assert!(columns.is_empty()); assert!(on.is_none()); @@ -1644,13 +1644,13 @@ fn parse_insert_with_on_duplicate_update() { let sql = "INSERT INTO permission_groups (name, description, perm_create, perm_read, perm_update, perm_delete) VALUES ('accounting_manager', 'Some description about the group', true, true, true, true) ON DUPLICATE KEY UPDATE description = VALUES(description), perm_create = VALUES(perm_create), perm_read = VALUES(perm_read), perm_update = VALUES(perm_update), perm_delete = VALUES(perm_delete)"; match mysql().verified_stmt(sql) { - Statement::Insert { + Statement::Insert(Insert { table_name, columns, source, on, .. - } => { + }) => { assert_eq!( ObjectName(vec![Ident::new("permission_groups")]), table_name @@ -1876,11 +1876,11 @@ fn parse_select_with_concatenation_of_exp_number_and_numeric_prefix_column() { fn parse_insert_with_numeric_prefix_column_name() { let sql = "INSERT INTO s1.t1 (123col_$@length123) VALUES (67.654)"; match mysql().verified_stmt(sql) { - Statement::Insert { + Statement::Insert(Insert { table_name, columns, .. - } => { + }) => { assert_eq!( ObjectName(vec![Ident::new("s1"), Ident::new("t1")]), table_name @@ -1970,7 +1970,7 @@ fn parse_update_with_joins() { fn parse_delete_with_order_by() { let sql = "DELETE FROM customers ORDER BY id DESC"; match mysql().verified_stmt(sql) { - Statement::Delete { order_by, .. } => { + Statement::Delete(Delete { order_by, .. }) => { assert_eq!( vec![OrderByExpr { expr: Expr::Identifier(Ident { @@ -1991,7 +1991,7 @@ fn parse_delete_with_order_by() { fn parse_delete_with_limit() { let sql = "DELETE FROM customers LIMIT 100"; match mysql().verified_stmt(sql) { - Statement::Delete { limit, .. } => { + Statement::Delete(Delete { limit, .. }) => { assert_eq!(Some(Expr::Value(number("100"))), limit); } _ => unreachable!(), diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index ea5c9875b..9cf8bf2f5 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -1481,12 +1481,12 @@ fn parse_prepare() { _ => unreachable!(), }; match sub_stmt.as_ref() { - Statement::Insert { + Statement::Insert(Insert { table_name, columns, source: Some(source), .. - } => { + }) => { assert_eq!(table_name.to_string(), "customers"); assert!(columns.is_empty()); @@ -1538,14 +1538,14 @@ fn parse_pg_on_conflict() { DO UPDATE SET dname = EXCLUDED.dname", ); match stmt { - Statement::Insert { + Statement::Insert(Insert { on: Some(OnInsert::OnConflict(OnConflict { conflict_target: Some(ConflictTarget::Columns(cols)), action, })), .. - } => { + }) => { assert_eq!(vec![Ident::from("did")], cols); assert_eq!( OnConflictAction::DoUpdate(DoUpdate { @@ -1568,14 +1568,14 @@ fn parse_pg_on_conflict() { DO UPDATE SET dname = EXCLUDED.dname, area = EXCLUDED.area", ); match stmt { - Statement::Insert { + Statement::Insert(Insert { on: Some(OnInsert::OnConflict(OnConflict { conflict_target: Some(ConflictTarget::Columns(cols)), action, })), .. - } => { + }) => { assert_eq!(vec![Ident::from("did"), Ident::from("area"),], cols); assert_eq!( OnConflictAction::DoUpdate(DoUpdate { @@ -1606,14 +1606,14 @@ fn parse_pg_on_conflict() { ON CONFLICT DO NOTHING", ); match stmt { - Statement::Insert { + Statement::Insert(Insert { on: Some(OnInsert::OnConflict(OnConflict { conflict_target: None, action, })), .. - } => { + }) => { assert_eq!(OnConflictAction::DoNothing, action); } _ => unreachable!(), @@ -1626,14 +1626,14 @@ fn parse_pg_on_conflict() { DO UPDATE SET dname = $1 WHERE dsize > $2", ); match stmt { - Statement::Insert { + Statement::Insert(Insert { on: Some(OnInsert::OnConflict(OnConflict { conflict_target: Some(ConflictTarget::Columns(cols)), action, })), .. - } => { + }) => { assert_eq!(vec![Ident::from("did")], cols); assert_eq!( OnConflictAction::DoUpdate(DoUpdate { @@ -1663,14 +1663,14 @@ fn parse_pg_on_conflict() { DO UPDATE SET dname = $1 WHERE dsize > $2", ); match stmt { - Statement::Insert { + Statement::Insert(Insert { on: Some(OnInsert::OnConflict(OnConflict { conflict_target: Some(ConflictTarget::OnConstraint(cname)), action, })), .. - } => { + }) => { assert_eq!(vec![Ident::from("distributors_did_pkey")], cname.0); assert_eq!( OnConflictAction::DoUpdate(DoUpdate { @@ -1700,7 +1700,7 @@ fn parse_pg_returning() { "INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets') RETURNING did", ); match stmt { - Statement::Insert { returning, .. } => { + Statement::Insert(Insert { returning, .. }) => { assert_eq!( Some(vec![SelectItem::UnnamedExpr(Expr::Identifier( "did".into() @@ -1738,7 +1738,7 @@ fn parse_pg_returning() { let stmt = pg_and_generic().verified_stmt("DELETE FROM tasks WHERE status = 'DONE' RETURNING *"); match stmt { - Statement::Delete { returning, .. } => { + Statement::Delete(Delete { returning, .. }) => { assert_eq!( Some(vec![SelectItem::Wildcard( WildcardAdditionalOptions::default() @@ -3677,7 +3677,7 @@ fn test_simple_postgres_insert_with_alias() { assert_eq!( statement, - Statement::Insert { + Statement::Insert(Insert { or: None, ignore: false, into: true, @@ -3728,7 +3728,7 @@ fn test_simple_postgres_insert_with_alias() { replace_into: false, priority: None, insert_alias: None - } + }) ) } @@ -3741,7 +3741,7 @@ fn test_simple_postgres_insert_with_alias() { assert_eq!( statement, - Statement::Insert { + Statement::Insert(Insert { or: None, ignore: false, into: true, @@ -3795,7 +3795,7 @@ fn test_simple_postgres_insert_with_alias() { replace_into: false, priority: None, insert_alias: None - } + }) ) } @@ -3807,7 +3807,7 @@ fn test_simple_insert_with_quoted_alias() { assert_eq!( statement, - Statement::Insert { + Statement::Insert(Insert { or: None, ignore: false, into: true, @@ -3858,7 +3858,7 @@ fn test_simple_insert_with_quoted_alias() { replace_into: false, priority: None, insert_alias: None, - } + }) ) }