diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 000000000..d090dbab8 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +rust 1.73.0 \ No newline at end of file diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 1735b9618..670242b79 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -420,7 +420,11 @@ impl<'a> Parser<'a> { Token::EOF => break, // end of statement - Token::Word(word) if word.keyword == Keyword::END => break, + Token::Word(word) => { + if expecting_statement_delimiter && word.keyword == Keyword::END { + break; + } + } _ => {} } @@ -501,6 +505,10 @@ impl<'a> Parser<'a> { // standard `START TRANSACTION` statement. It is supported // by at least PostgreSQL and MySQL. Keyword::BEGIN => Ok(self.parse_begin()?), + // `END` is a nonstandard but common alias for the + // standard `COMMIT TRANSACTION` statement. It is supported + // by PostgreSQL. + Keyword::END => Ok(self.parse_end()?), Keyword::SAVEPOINT => Ok(self.parse_savepoint()?), Keyword::RELEASE => Ok(self.parse_release()?), Keyword::COMMIT => Ok(self.parse_commit()?), @@ -7808,6 +7816,12 @@ impl<'a> Parser<'a> { }) } + pub fn parse_end(&mut self) -> Result { + Ok(Statement::Commit { + chain: self.parse_commit_rollback_chain()?, + }) + } + pub fn parse_transaction_modes(&mut self) -> Result, ParserError> { let mut modes = vec![]; let mut required = false; diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index e28db9278..cea9b529e 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -6231,6 +6231,17 @@ fn parse_commit() { one_statement_parses_to("COMMIT TRANSACTION", "COMMIT"); } +#[test] +fn parse_end() { + one_statement_parses_to("END AND NO CHAIN", "COMMIT"); + one_statement_parses_to("END WORK AND NO CHAIN", "COMMIT"); + one_statement_parses_to("END TRANSACTION AND NO CHAIN", "COMMIT"); + one_statement_parses_to("END WORK AND CHAIN", "COMMIT AND CHAIN"); + one_statement_parses_to("END TRANSACTION AND CHAIN", "COMMIT AND CHAIN"); + one_statement_parses_to("END WORK", "COMMIT"); + one_statement_parses_to("END TRANSACTION", "COMMIT"); +} + #[test] fn parse_rollback() { match verified_stmt("ROLLBACK") {