diff --git a/src/ast/mod.rs b/src/ast/mod.rs index eb8830bb1..4abc18c9d 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -1301,6 +1301,10 @@ pub enum Statement { selection: Option, /// RETURNING returning: Option>, + /// ORDER BY (MySQL) + order_by: Vec, + /// LIMIT (MySQL) + limit: Option, }, /// CREATE VIEW CreateView { @@ -2123,6 +2127,8 @@ impl fmt::Display for Statement { using, selection, returning, + order_by, + limit, } => { write!(f, "DELETE ")?; if !tables.is_empty() { @@ -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 } => { diff --git a/src/parser/mod.rs b/src/parser/mod.rs index ba8f5784f..b999b7459 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -5289,12 +5289,21 @@ 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, @@ -5302,6 +5311,8 @@ impl<'a> Parser<'a> { using, selection, returning, + order_by, + limit, }) } diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 6f780de9e..d9f3bcf65 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -525,6 +525,7 @@ fn parse_where_delete_statement() { using, selection, returning, + .. } => { assert_eq!( TableFactor::Table { @@ -565,6 +566,7 @@ fn parse_where_delete_with_alias_statement() { using, selection, returning, + .. } => { assert_eq!( TableFactor::Table { diff --git a/tests/sqlparser_mysql.rs b/tests/sqlparser_mysql.rs index 80ef9f981..f1a054bfb 100644 --- a/tests/sqlparser_mysql.rs +++ b/tests/sqlparser_mysql.rs @@ -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!(