@@ -288,6 +288,22 @@ impl ParserOptions {
288288 self.unescape = unescape;
289289 self
290290 }
291+
292+ /// Set if semicolon statement delimiters are required.
293+ ///
294+ /// If this option is `true`, the following SQL will not parse. If the option is `false`, the SQL will parse.
295+ ///
296+ /// ```sql
297+ /// SELECT 1
298+ /// SELECT 2
299+ /// ```
300+ pub fn with_require_semicolon_stmt_delimiter(
301+ mut self,
302+ require_semicolon_stmt_delimiter: bool,
303+ ) -> Self {
304+ self.require_semicolon_stmt_delimiter = require_semicolon_stmt_delimiter;
305+ self
306+ }
291307}
292308
293309#[derive(Copy, Clone)]
@@ -384,7 +400,11 @@ impl<'a> Parser<'a> {
384400 state: ParserState::Normal,
385401 dialect,
386402 recursion_counter: RecursionCounter::new(DEFAULT_REMAINING_DEPTH),
387- options: ParserOptions::new().with_trailing_commas(dialect.supports_trailing_commas()),
403+ options: ParserOptions::new()
404+ .with_trailing_commas(dialect.supports_trailing_commas())
405+ .with_require_semicolon_stmt_delimiter(
406+ !dialect.supports_statements_without_semicolon_delimiter(),
407+ ),
388408 }
389409 }
390410
@@ -507,10 +527,10 @@ impl<'a> Parser<'a> {
507527 match &self.peek_token_ref().token {
508528 Token::EOF => break,
509529
510- // end of statement
511- Token::Word(word ) => {
512- if expecting_statement_delimiter && word.keyword == Keyword::END {
513- break ;
530+ // don't expect a semicolon statement delimiter after a newline when not otherwise required
531+ Token::Whitespace(Whitespace::Newline ) => {
532+ if !self.options.require_semicolon_stmt_delimiter {
533+ expecting_statement_delimiter = false ;
514534 }
515535 }
516536 _ => {}
@@ -522,7 +542,7 @@ impl<'a> Parser<'a> {
522542
523543 let statement = self.parse_statement()?;
524544 stmts.push(statement);
525- expecting_statement_delimiter = true ;
545+ expecting_statement_delimiter = self.options.require_semicolon_stmt_delimiter ;
526546 }
527547 Ok(stmts)
528548 }
@@ -4987,6 +5007,9 @@ impl<'a> Parser<'a> {
49875007 ) -> Result<Vec<Statement>, ParserError> {
49885008 let mut values = vec![];
49895009 loop {
5010+ // ignore empty statements (between successive statement delimiters)
5011+ while self.consume_token(&Token::SemiColon) {}
5012+
49905013 match &self.peek_nth_token_ref(0).token {
49915014 Token::EOF => break,
49925015 Token::Word(w) => {
@@ -4998,7 +5021,13 @@ impl<'a> Parser<'a> {
49985021 }
49995022
50005023 values.push(self.parse_statement()?);
5001- self.expect_token(&Token::SemiColon)?;
5024+
5025+ if self.options.require_semicolon_stmt_delimiter {
5026+ self.expect_token(&Token::SemiColon)?;
5027+ }
5028+
5029+ // ignore empty statements (between successive statement delimiters)
5030+ while self.consume_token(&Token::SemiColon) {}
50025031 }
50035032 Ok(values)
50045033 }
@@ -19571,7 +19600,28 @@ impl<'a> Parser<'a> {
1957119600
1957219601 /// Parse [Statement::Return]
1957319602 fn parse_return(&mut self) -> Result<Statement, ParserError> {
19574- match self.maybe_parse(|p| p.parse_expr())? {
19603+ let rs = self.maybe_parse(|p| {
19604+ let expr = p.parse_expr()?;
19605+
19606+ match &expr {
19607+ Expr::Value(_)
19608+ | Expr::Function(_)
19609+ | Expr::UnaryOp { .. }
19610+ | Expr::BinaryOp { .. }
19611+ | Expr::Case { .. }
19612+ | Expr::Cast { .. }
19613+ | Expr::Convert { .. }
19614+ | Expr::Subquery(_) => Ok(expr),
19615+ // todo: how to retstrict to variables?
19616+ Expr::Identifier(id) if id.value.starts_with('@') => Ok(expr),
19617+ _ => parser_err!(
19618+ "Non-returnable expression found following RETURN",
19619+ p.peek_token().span.start
19620+ ),
19621+ }
19622+ })?;
19623+
19624+ match rs {
1957519625 Some(expr) => Ok(Statement::Return(ReturnStatement {
1957619626 value: Some(ReturnStatementValue::Expr(expr)),
1957719627 })),
0 commit comments