@@ -265,6 +265,22 @@ impl ParserOptions {
265265 self.unescape = unescape;
266266 self
267267 }
268+
269+ /// Set if semicolon statement delimiters are required.
270+ ///
271+ /// If this option is `true`, the following SQL will not parse. If the option is `false`, the SQL will parse.
272+ ///
273+ /// ```sql
274+ /// SELECT 1
275+ /// SELECT 2
276+ /// ```
277+ pub fn with_require_semicolon_stmt_delimiter(
278+ mut self,
279+ require_semicolon_stmt_delimiter: bool,
280+ ) -> Self {
281+ self.require_semicolon_stmt_delimiter = require_semicolon_stmt_delimiter;
282+ self
283+ }
268284}
269285
270286#[derive(Copy, Clone)]
@@ -355,7 +371,11 @@ impl<'a> Parser<'a> {
355371 state: ParserState::Normal,
356372 dialect,
357373 recursion_counter: RecursionCounter::new(DEFAULT_REMAINING_DEPTH),
358- options: ParserOptions::new().with_trailing_commas(dialect.supports_trailing_commas()),
374+ options: ParserOptions::new()
375+ .with_trailing_commas(dialect.supports_trailing_commas())
376+ .with_require_semicolon_stmt_delimiter(
377+ !dialect.supports_statements_without_semicolon_delimiter(),
378+ ),
359379 }
360380 }
361381
@@ -478,10 +498,10 @@ impl<'a> Parser<'a> {
478498 match self.peek_token().token {
479499 Token::EOF => break,
480500
481- // end of statement
482- Token::Word(word ) => {
483- if expecting_statement_delimiter && word.keyword == Keyword::END {
484- break ;
501+ // don't expect a semicolon statement delimiter after a newline when not otherwise required
502+ Token::Whitespace(Whitespace::Newline ) => {
503+ if !self.options.require_semicolon_stmt_delimiter {
504+ expecting_statement_delimiter = false ;
485505 }
486506 }
487507 _ => {}
@@ -493,7 +513,7 @@ impl<'a> Parser<'a> {
493513
494514 let statement = self.parse_statement()?;
495515 stmts.push(statement);
496- expecting_statement_delimiter = true ;
516+ expecting_statement_delimiter = self.options.require_semicolon_stmt_delimiter ;
497517 }
498518 Ok(stmts)
499519 }
@@ -4533,6 +4553,9 @@ impl<'a> Parser<'a> {
45334553 ) -> Result<Vec<Statement>, ParserError> {
45344554 let mut values = vec![];
45354555 loop {
4556+ // ignore empty statements (between successive statement delimiters)
4557+ while self.consume_token(&Token::SemiColon) {}
4558+
45364559 match &self.peek_nth_token_ref(0).token {
45374560 Token::EOF => break,
45384561 Token::Word(w) => {
@@ -4544,7 +4567,13 @@ impl<'a> Parser<'a> {
45444567 }
45454568
45464569 values.push(self.parse_statement()?);
4547- self.expect_token(&Token::SemiColon)?;
4570+
4571+ if self.options.require_semicolon_stmt_delimiter {
4572+ self.expect_token(&Token::SemiColon)?;
4573+ }
4574+
4575+ // ignore empty statements (between successive statement delimiters)
4576+ while self.consume_token(&Token::SemiColon) {}
45484577 }
45494578 Ok(values)
45504579 }
@@ -16370,7 +16399,28 @@ impl<'a> Parser<'a> {
1637016399
1637116400 /// Parse [Statement::Return]
1637216401 fn parse_return(&mut self) -> Result<Statement, ParserError> {
16373- match self.maybe_parse(|p| p.parse_expr())? {
16402+ let rs = self.maybe_parse(|p| {
16403+ let expr = p.parse_expr()?;
16404+
16405+ match &expr {
16406+ Expr::Value(_)
16407+ | Expr::Function(_)
16408+ | Expr::UnaryOp { .. }
16409+ | Expr::BinaryOp { .. }
16410+ | Expr::Case { .. }
16411+ | Expr::Cast { .. }
16412+ | Expr::Convert { .. }
16413+ | Expr::Subquery(_) => Ok(expr),
16414+ // todo: how to retstrict to variables?
16415+ Expr::Identifier(id) if id.value.starts_with('@') => Ok(expr),
16416+ _ => parser_err!(
16417+ "Non-returnable expression found following RETURN",
16418+ p.peek_token().span.start
16419+ ),
16420+ }
16421+ })?;
16422+
16423+ match rs {
1637416424 Some(expr) => Ok(Statement::Return(ReturnStatement {
1637516425 value: Some(ReturnStatementValue::Expr(expr)),
1637616426 })),
0 commit comments