From 161c87212ec5ed996fb7bfd71c588e2ffc5b293f Mon Sep 17 00:00:00 2001 From: TcMits Date: Wed, 13 Aug 2025 14:07:28 +0700 Subject: [PATCH] finish all DROP --- parser/src/parser.rs | 155 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) diff --git a/parser/src/parser.rs b/parser/src/parser.rs index 990d65dce..7eb3d8b32 100644 --- a/parser/src/parser.rs +++ b/parser/src/parser.rs @@ -576,6 +576,7 @@ impl<'a> Parser<'a> { TokenType::TK_VACUUM, TokenType::TK_ALTER, TokenType::TK_DELETE, + TokenType::TK_DROP, // add more ])?; @@ -595,6 +596,7 @@ impl<'a> Parser<'a> { TokenType::TK_VACUUM => self.parse_vacuum(), TokenType::TK_ALTER => self.parse_alter(), TokenType::TK_DELETE => self.parse_delete(), + TokenType::TK_DROP => self.parse_drop_stmt(), _ => unreachable!(), } } @@ -3838,6 +3840,67 @@ impl<'a> Parser<'a> { let with = self.parse_with()?; self.parse_delete_without_cte(with) } + + fn parse_if_exists(&mut self) -> Result { + match self.peek()? { + Some(tok) if tok.token_type == Some(TokenType::TK_IF) => { + self.eat_assert(&[TokenType::TK_IF]); + self.eat_expect(&[TokenType::TK_EXISTS])?; + Ok(true) + } + _ => Ok(false), + } + } + + fn parse_drop_stmt(&mut self) -> Result { + self.eat_assert(&[TokenType::TK_DROP]); + let tok = self.peek_expect(&[ + TokenType::TK_TABLE, + TokenType::TK_INDEX, + TokenType::TK_TRIGGER, + TokenType::TK_VIEW, + ])?; + + match tok.token_type.unwrap() { + TokenType::TK_TABLE => { + self.eat_expect(&[TokenType::TK_TABLE])?; + let if_exists = self.parse_if_exists()?; + let tbl_name = self.parse_fullname(false)?; + Ok(Stmt::DropTable { + if_exists, + tbl_name, + }) + } + TokenType::TK_INDEX => { + self.eat_expect(&[TokenType::TK_INDEX])?; + let if_exists = self.parse_if_exists()?; + let idx_name = self.parse_fullname(false)?; + Ok(Stmt::DropIndex { + if_exists, + idx_name, + }) + } + TokenType::TK_TRIGGER => { + self.eat_expect(&[TokenType::TK_TRIGGER])?; + let if_exists = self.parse_if_exists()?; + let trigger_name = self.parse_fullname(false)?; + Ok(Stmt::DropTrigger { + if_exists, + trigger_name, + }) + } + TokenType::TK_VIEW => { + self.eat_expect(&[TokenType::TK_VIEW])?; + let if_exists = self.parse_if_exists()?; + let view_name = self.parse_fullname(false)?; + Ok(Stmt::DropView { + if_exists, + view_name, + }) + } + _ => unreachable!(), + } + } } #[cfg(test)] @@ -10755,6 +10818,98 @@ mod tests { }), })], ), + // parse drop index + ( + b"DROP INDEX foo".as_slice(), + vec![Cmd::Stmt(Stmt::DropIndex { + if_exists: false, + idx_name: QualifiedName { + db_name: None, + name: Name::Ident("foo".to_owned()), + alias: None, + }, + })], + ), + ( + b"DROP INDEX IF EXISTS foo".as_slice(), + vec![Cmd::Stmt(Stmt::DropIndex { + if_exists: true, + idx_name: QualifiedName { + db_name: None, + name: Name::Ident("foo".to_owned()), + alias: None, + }, + })], + ), + // parse drop table + ( + b"DROP TABLE foo".as_slice(), + vec![Cmd::Stmt(Stmt::DropTable { + if_exists: false, + tbl_name: QualifiedName { + db_name: None, + name: Name::Ident("foo".to_owned()), + alias: None, + }, + })], + ), + ( + b"DROP TABLE IF EXISTS foo".as_slice(), + vec![Cmd::Stmt(Stmt::DropTable { + if_exists: true, + tbl_name: QualifiedName { + db_name: None, + name: Name::Ident("foo".to_owned()), + alias: None, + }, + })], + ), + // parse drop trigger + ( + b"DROP TRIGGER foo".as_slice(), + vec![Cmd::Stmt(Stmt::DropTrigger { + if_exists: false, + trigger_name: QualifiedName { + db_name: None, + name: Name::Ident("foo".to_owned()), + alias: None, + }, + })], + ), + ( + b"DROP TRIGGER IF EXISTS foo".as_slice(), + vec![Cmd::Stmt(Stmt::DropTrigger { + if_exists: true, + trigger_name: QualifiedName { + db_name: None, + name: Name::Ident("foo".to_owned()), + alias: None, + }, + })], + ), + // parse drop view + ( + b"DROP VIEW foo".as_slice(), + vec![Cmd::Stmt(Stmt::DropView { + if_exists: false, + view_name: QualifiedName { + db_name: None, + name: Name::Ident("foo".to_owned()), + alias: None, + }, + })], + ), + ( + b"DROP VIEW IF EXISTS foo".as_slice(), + vec![Cmd::Stmt(Stmt::DropView { + if_exists: true, + view_name: QualifiedName { + db_name: None, + name: Name::Ident("foo".to_owned()), + alias: None, + }, + })], + ), ]; for (input, expected) in test_cases {