Skip to content

Commit

Permalink
Support DELETE with ORDER BY and LIMIT (MySQL)
Browse files Browse the repository at this point in the history
  • Loading branch information
ulrichsg committed Sep 30, 2023
1 parent 7723ea5 commit c53eba4
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 1 deletion.
12 changes: 12 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,10 @@ pub enum Statement {
selection: Option<Expr>,
/// RETURNING
returning: Option<Vec<SelectItem>>,
/// ORDER BY (MySQL)
order_by: Vec<OrderByExpr>,
/// LIMIT (MySQL)
limit: Option<Expr>,
},
/// CREATE VIEW
CreateView {
Expand Down Expand Up @@ -2123,6 +2127,8 @@ impl fmt::Display for Statement {
using,
selection,
returning,
order_by,
limit,
} => {
write!(f, "DELETE ")?;
if !tables.is_empty() {
Expand All @@ -2138,6 +2144,12 @@ impl fmt::Display for Statement {
if let Some(returning) = 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(())
}
Statement::Close { cursor } => {
Expand Down
13 changes: 12 additions & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5289,19 +5289,30 @@ impl<'a> Parser<'a> {
} else {
None
};

let returning = if self.parse_keyword(Keyword::RETURNING) {
Some(self.parse_comma_separated(Parser::parse_select_item)?)
} else {
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 {
tables,
from,
using,
selection,
returning,
order_by,
limit,
})
}

Expand Down
2 changes: 2 additions & 0 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ fn parse_where_delete_statement() {
using,
selection,
returning,
..
} => {
assert_eq!(
TableFactor::Table {
Expand Down Expand Up @@ -565,6 +566,7 @@ fn parse_where_delete_with_alias_statement() {
using,
selection,
returning,
..
} => {
assert_eq!(
TableFactor::Table {
Expand Down
32 changes: 32 additions & 0 deletions tests/sqlparser_mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
fn parse_alter_table_drop_primary_key() {
assert_matches!(
Expand Down

0 comments on commit c53eba4

Please sign in to comment.