Encapsulate Insert and Delete into specific structs (#1224)

Signed-off-by: tison <wander4096@gmail.com>
This commit is contained in:
tison 2024-04-21 21:13:18 +08:00 committed by GitHub
parent d2c2b15f9e
commit bf89b7d808
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 187 additions and 147 deletions

84
src/ast/dml.rs Normal file
View file

@ -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<SqliteOnConflict>,
/// 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<Ident>,
/// COLUMNS
pub columns: Vec<Ident>,
/// Overwrite (Hive)
pub overwrite: bool,
/// A SQL query that specifies what to insert
pub source: Option<Box<Query>>,
/// partitioned insert (Hive)
pub partitioned: Option<Vec<Expr>>,
/// Columns defined after PARTITION
pub after_columns: Vec<Ident>,
/// whether the insert has the table keyword (Hive)
pub table: bool,
pub on: Option<OnInsert>,
/// RETURNING
pub returning: Option<Vec<SelectItem>>,
/// Only for mysql
pub replace_into: bool,
/// Only for mysql
pub priority: Option<MysqlInsertPriority>,
/// Only for mysql
pub insert_alias: Option<InsertAliases>,
}
/// 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<ObjectName>,
/// FROM
pub from: FromTable,
/// USING (Snowflake, Postgres, MySQL)
pub using: Option<Vec<TableWithJoins>>,
/// WHERE
pub selection: Option<Expr>,
/// RETURNING
pub returning: Option<Vec<SelectItem>>,
/// ORDER BY (MySQL)
pub order_by: Vec<OrderByExpr>,
/// LIMIT (MySQL)
pub limit: Option<Expr>,
}

View file

@ -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<SqliteOnConflict>,
/// 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<Ident>,
/// COLUMNS
columns: Vec<Ident>,
/// Overwrite (Hive)
overwrite: bool,
/// A SQL query that specifies what to insert
source: Option<Box<Query>>,
/// partitioned insert (Hive)
partitioned: Option<Vec<Expr>>,
/// Columns defined after PARTITION
after_columns: Vec<Ident>,
/// whether the insert has the table keyword (Hive)
table: bool,
on: Option<OnInsert>,
/// RETURNING
returning: Option<Vec<SelectItem>>,
/// Only for mysql
replace_into: bool,
/// Only for mysql
priority: Option<MysqlInsertPriority>,
/// Only for mysql
insert_alias: Option<InsertAliases>,
},
Insert(Insert),
/// ```sql
/// INSTALL
/// ```
@ -1923,22 +1892,7 @@ pub enum Statement {
/// ```sql
/// DELETE
/// ```
Delete {
/// Multi tables delete are supported in mysql
tables: Vec<ObjectName>,
/// FROM
from: FromTable,
/// USING (Snowflake, Postgres, MySQL)
using: Option<Vec<TableWithJoins>>,
/// WHERE
selection: Option<Expr>,
/// RETURNING
returning: Option<Vec<SelectItem>>,
/// ORDER BY (MySQL)
order_by: Vec<OrderByExpr>,
/// LIMIT (MySQL)
limit: Option<Expr>,
},
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))?;

View file

@ -7082,7 +7082,7 @@ impl<'a> Parser<'a> {
None
};
Ok(Statement::Delete {
Ok(Statement::Delete(Delete {
tables,
from: if with_from_keyword {
FromTable::WithFromKeyword(from)
@ -7094,7 +7094,7 @@ impl<'a> Parser<'a> {
returning,
order_by,
limit,
})
}))
}
// KILL [CONNECTION | QUERY | MUTATION] processlist_id
@ -8658,7 +8658,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;
}
@ -8826,7 +8826,7 @@ impl<'a> Parser<'a> {
None
};
Ok(Statement::Insert {
Ok(Statement::Insert(Insert {
or,
table_name,
table_alias,
@ -8843,7 +8843,7 @@ impl<'a> Parser<'a> {
replace_into,
priority,
insert_alias,
})
}))
}
}