@@ -271,6 +271,22 @@ impl ParserOptions {
271271 self.unescape = unescape;
272272 self
273273 }
274+
275+ /// Set if semicolon statement delimiters are required.
276+ ///
277+ /// If this option is `true`, the following SQL will not parse. If the option is `false`, the SQL will parse.
278+ ///
279+ /// ```sql
280+ /// SELECT 1
281+ /// SELECT 2
282+ /// ```
283+ pub fn with_require_semicolon_stmt_delimiter(
284+ mut self,
285+ require_semicolon_stmt_delimiter: bool,
286+ ) -> Self {
287+ self.require_semicolon_stmt_delimiter = require_semicolon_stmt_delimiter;
288+ self
289+ }
274290}
275291
276292#[derive(Copy, Clone)]
@@ -367,7 +383,11 @@ impl<'a> Parser<'a> {
367383 state: ParserState::Normal,
368384 dialect,
369385 recursion_counter: RecursionCounter::new(DEFAULT_REMAINING_DEPTH),
370- options: ParserOptions::new().with_trailing_commas(dialect.supports_trailing_commas()),
386+ options: ParserOptions::new()
387+ .with_trailing_commas(dialect.supports_trailing_commas())
388+ .with_require_semicolon_stmt_delimiter(
389+ !dialect.supports_statements_without_semicolon_delimiter(),
390+ ),
371391 }
372392 }
373393
@@ -490,10 +510,10 @@ impl<'a> Parser<'a> {
490510 match self.peek_token().token {
491511 Token::EOF => break,
492512
493- // end of statement
494- Token::Word(word ) => {
495- if expecting_statement_delimiter && word.keyword == Keyword::END {
496- break ;
513+ // don't expect a semicolon statement delimiter after a newline when not otherwise required
514+ Token::Whitespace(Whitespace::Newline ) => {
515+ if !self.options.require_semicolon_stmt_delimiter {
516+ expecting_statement_delimiter = false ;
497517 }
498518 }
499519 _ => {}
@@ -505,7 +525,7 @@ impl<'a> Parser<'a> {
505525
506526 let statement = self.parse_statement()?;
507527 stmts.push(statement);
508- expecting_statement_delimiter = true ;
528+ expecting_statement_delimiter = self.options.require_semicolon_stmt_delimiter ;
509529 }
510530 Ok(stmts)
511531 }
@@ -4632,6 +4652,9 @@ impl<'a> Parser<'a> {
46324652 ) -> Result<Vec<Statement>, ParserError> {
46334653 let mut values = vec![];
46344654 loop {
4655+ // ignore empty statements (between successive statement delimiters)
4656+ while self.consume_token(&Token::SemiColon) {}
4657+
46354658 match &self.peek_nth_token_ref(0).token {
46364659 Token::EOF => break,
46374660 Token::Word(w) => {
@@ -4643,7 +4666,13 @@ impl<'a> Parser<'a> {
46434666 }
46444667
46454668 values.push(self.parse_statement()?);
4646- self.expect_token(&Token::SemiColon)?;
4669+
4670+ if self.options.require_semicolon_stmt_delimiter {
4671+ self.expect_token(&Token::SemiColon)?;
4672+ }
4673+
4674+ // ignore empty statements (between successive statement delimiters)
4675+ while self.consume_token(&Token::SemiColon) {}
46474676 }
46484677 Ok(values)
46494678 }
@@ -17271,7 +17300,28 @@ impl<'a> Parser<'a> {
1727117300
1727217301 /// Parse [Statement::Return]
1727317302 fn parse_return(&mut self) -> Result<Statement, ParserError> {
17274- match self.maybe_parse(|p| p.parse_expr())? {
17303+ let rs = self.maybe_parse(|p| {
17304+ let expr = p.parse_expr()?;
17305+
17306+ match &expr {
17307+ Expr::Value(_)
17308+ | Expr::Function(_)
17309+ | Expr::UnaryOp { .. }
17310+ | Expr::BinaryOp { .. }
17311+ | Expr::Case { .. }
17312+ | Expr::Cast { .. }
17313+ | Expr::Convert { .. }
17314+ | Expr::Subquery(_) => Ok(expr),
17315+ // todo: how to retstrict to variables?
17316+ Expr::Identifier(id) if id.value.starts_with('@') => Ok(expr),
17317+ _ => parser_err!(
17318+ "Non-returnable expression found following RETURN",
17319+ p.peek_token().span.start
17320+ ),
17321+ }
17322+ })?;
17323+
17324+ match rs {
1727517325 Some(expr) => Ok(Statement::Return(ReturnStatement {
1727617326 value: Some(ReturnStatementValue::Expr(expr)),
1727717327 })),
0 commit comments