Support DELETE with ORDER BY and LIMIT (MySQL) (#992)

This commit is contained in:
Ulrich Schmidt-Goertz 2023-10-02 14:42:58 +02:00 committed by GitHub
parent ed39329060
commit 6ffc3b3a52
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 58 additions and 1 deletions

View file

@ -1301,6 +1301,10 @@ pub enum Statement {
selection: Option<Expr>, selection: Option<Expr>,
/// RETURNING /// RETURNING
returning: Option<Vec<SelectItem>>, returning: Option<Vec<SelectItem>>,
/// ORDER BY (MySQL)
order_by: Vec<OrderByExpr>,
/// LIMIT (MySQL)
limit: Option<Expr>,
}, },
/// CREATE VIEW /// CREATE VIEW
CreateView { CreateView {
@ -2141,6 +2145,8 @@ impl fmt::Display for Statement {
using, using,
selection, selection,
returning, returning,
order_by,
limit,
} => { } => {
write!(f, "DELETE ")?; write!(f, "DELETE ")?;
if !tables.is_empty() { if !tables.is_empty() {
@ -2156,6 +2162,12 @@ impl fmt::Display for Statement {
if let Some(returning) = returning { if let Some(returning) = returning {
write!(f, " RETURNING {}", display_comma_separated(returning))?; write!(f, " RETURNING {}", display_comma_separated(returning))?;
} }
if !order_by.is_empty() {
write!(f, " ORDER BY {}", display_comma_separated(order_by))?;
}
if let Some(limit) = limit {
write!(f, " LIMIT {limit}")?;
}
Ok(()) Ok(())
} }
Statement::Close { cursor } => { Statement::Close { cursor } => {

View file

@ -5306,12 +5306,21 @@ impl<'a> Parser<'a> {
} else { } else {
None None
}; };
let returning = if self.parse_keyword(Keyword::RETURNING) { let returning = if self.parse_keyword(Keyword::RETURNING) {
Some(self.parse_comma_separated(Parser::parse_select_item)?) Some(self.parse_comma_separated(Parser::parse_select_item)?)
} else { } else {
None None
}; };
let order_by = if self.parse_keywords(&[Keyword::ORDER, Keyword::BY]) {
self.parse_comma_separated(Parser::parse_order_by_expr)?
} else {
vec![]
};
let limit = if self.parse_keyword(Keyword::LIMIT) {
self.parse_limit()?
} else {
None
};
Ok(Statement::Delete { Ok(Statement::Delete {
tables, tables,
@ -5319,6 +5328,8 @@ impl<'a> Parser<'a> {
using, using,
selection, selection,
returning, returning,
order_by,
limit,
}) })
} }

View file

@ -525,6 +525,7 @@ fn parse_where_delete_statement() {
using, using,
selection, selection,
returning, returning,
..
} => { } => {
assert_eq!( assert_eq!(
TableFactor::Table { TableFactor::Table {
@ -565,6 +566,7 @@ fn parse_where_delete_with_alias_statement() {
using, using,
selection, selection,
returning, returning,
..
} => { } => {
assert_eq!( assert_eq!(
TableFactor::Table { TableFactor::Table {

View file

@ -1315,6 +1315,38 @@ fn parse_update_with_joins() {
} }
} }
#[test]
fn parse_delete_with_order_by() {
let sql = "DELETE FROM customers ORDER BY id DESC";
match mysql().verified_stmt(sql) {
Statement::Delete { order_by, .. } => {
assert_eq!(
vec![OrderByExpr {
expr: Expr::Identifier(Ident {
value: "id".to_owned(),
quote_style: None
}),
asc: Some(false),
nulls_first: None,
}],
order_by
);
}
_ => unreachable!(),
}
}
#[test]
fn parse_delete_with_limit() {
let sql = "DELETE FROM customers LIMIT 100";
match mysql().verified_stmt(sql) {
Statement::Delete { limit, .. } => {
assert_eq!(Some(Expr::Value(number("100"))), limit);
}
_ => unreachable!(),
}
}
#[test] #[test]
fn parse_alter_table_drop_primary_key() { fn parse_alter_table_drop_primary_key() {
assert_matches!( assert_matches!(