From 549ed6e83ab0a853cced5f8f7ac5b665aaa2c84d Mon Sep 17 00:00:00 2001 From: crw5996 Date: Thu, 6 Sep 2018 16:00:46 -0400 Subject: [PATCH] Implemented DELETE keyword. Not much to do, all of the subexpressions were already handled --- src/.sqlparser.rs.swo | Bin 0 -> 45056 bytes src/sqlast.rs | 6 +++ src/sqlparser.rs | 95 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 src/.sqlparser.rs.swo diff --git a/src/.sqlparser.rs.swo b/src/.sqlparser.rs.swo new file mode 100644 index 0000000000000000000000000000000000000000..1829715fed0b1cdc509b2b4dd3663c1f816ea777 GIT binary patch literal 45056 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, limit: Option>, }, + SQLDelete { + relation: Option>, // FROM statement + selection: Option>, // WHERE statement + order_by: Option>, + limit: Option>, + }, SQLCreateTable { /// Table name name: String, diff --git a/src/sqlparser.rs b/src/sqlparser.rs index e59fee35..d698dafb 100644 --- a/src/sqlparser.rs +++ b/src/sqlparser.rs @@ -87,6 +87,7 @@ impl Parser { Token::Keyword(k) => match k.to_uppercase().as_ref() { "SELECT" => Ok(self.parse_select()?), "CREATE" => Ok(self.parse_create()?), + "DELETE" => Ok(self.parse_delete()?), _ => return parser_err!(format!("No prefix parser for keyword {}", k)), }, Token::Mult => Ok(ASTNode::SQLWildcard), @@ -440,6 +441,49 @@ impl Parser { } } + pub fn parse_delete(&mut self) -> Result { + + let relation: Option> = if self.parse_keyword("FROM") { + Some(Box::new(self.parse_expr(0)?)) + } else { + None + }; + + let order_by = if self.parse_keywords(vec!["ORDER", "BY"]) { + Some(self.parse_order_by_expr_list()?) + } else { + None + }; + + let limit = if self.parse_keyword("LIMIT") { + self.parse_limit()? + } else { + None + }; + + let selection = if self.parse_keyword("WHERE") { + Some(Box::new(self.parse_expr(0)?)) + } else { + None + }; + + // parse next token + if let Some(next_token) = self.peek_token() { + parser_err!(format!( + "Unexpected token at end of DELETE: {:?}", + next_token + )) + } else { + Ok(ASTNode::SQLDelete { + relation, + selection, + order_by, + limit, + }) + } + + } + /// Parse a SELECT statement pub fn parse_select(&mut self) -> Result { let projection = self.parse_expr_list()?; @@ -581,6 +625,56 @@ mod tests { use super::*; + #[test] + fn parse_delete_statement() { + + let sql: &str = "DELETE FROM 'table'"; + + match parse_sql(&sql) { + + ASTNode::SQLDelete { + relation, + .. + } => { + assert_eq!(Some(Box::new(ASTNode::SQLLiteralString("table".to_string()))), relation); + }, + + _ => assert!(false), + } + } + + #[test] + fn parse_where_delete_statement() { + + let sql: &str = "DELETE FROM 'table' WHERE name = 5"; + + use self::ASTNode::*; + use self::SQLOperator::*; + + match parse_sql(&sql) { + + ASTNode::SQLDelete { + relation, + selection, + .. + } => { + assert_eq!(Some(Box::new(ASTNode::SQLLiteralString("table".to_string()))), relation); + + assert_eq!( + SQLBinaryExpr { + left: Box::new(SQLIdentifier("name".to_string())), + op: Eq, + right: Box::new(SQLLiteralLong(5)), + }, + *selection.unwrap(), + ); + + }, + + _ => assert!(false), + } + } + #[test] fn parse_simple_select() { let sql = String::from("SELECT id, fname, lname FROM customer WHERE id = 1 LIMIT 5"); @@ -851,6 +945,7 @@ mod tests { } + #[test] fn parse_select_version() { let sql = "SELECT @@version";