@@ -266,6 +266,22 @@ impl ParserOptions {
266266 self.unescape = unescape;
267267 self
268268 }
269+
270+ /// Set if semicolon statement delimiters are required.
271+ ///
272+ /// If this option is `true`, the following SQL will not parse. If the option is `false`, the SQL will parse.
273+ ///
274+ /// ```sql
275+ /// SELECT 1
276+ /// SELECT 2
277+ /// ```
278+ pub fn with_require_semicolon_stmt_delimiter(
279+ mut self,
280+ require_semicolon_stmt_delimiter: bool,
281+ ) -> Self {
282+ self.require_semicolon_stmt_delimiter = require_semicolon_stmt_delimiter;
283+ self
284+ }
269285}
270286
271287#[derive(Copy, Clone)]
@@ -362,7 +378,11 @@ impl<'a> Parser<'a> {
362378 state: ParserState::Normal,
363379 dialect,
364380 recursion_counter: RecursionCounter::new(DEFAULT_REMAINING_DEPTH),
365- options: ParserOptions::new().with_trailing_commas(dialect.supports_trailing_commas()),
381+ options: ParserOptions::new()
382+ .with_trailing_commas(dialect.supports_trailing_commas())
383+ .with_require_semicolon_stmt_delimiter(
384+ !dialect.supports_statements_without_semicolon_delimiter(),
385+ ),
366386 }
367387 }
368388
@@ -485,10 +505,10 @@ impl<'a> Parser<'a> {
485505 match self.peek_token().token {
486506 Token::EOF => break,
487507
488- // end of statement
489- Token::Word(word ) => {
490- if expecting_statement_delimiter && word.keyword == Keyword::END {
491- break ;
508+ // don't expect a semicolon statement delimiter after a newline when not otherwise required
509+ Token::Whitespace(Whitespace::Newline ) => {
510+ if !self.options.require_semicolon_stmt_delimiter {
511+ expecting_statement_delimiter = false ;
492512 }
493513 }
494514 _ => {}
@@ -500,7 +520,7 @@ impl<'a> Parser<'a> {
500520
501521 let statement = self.parse_statement()?;
502522 stmts.push(statement);
503- expecting_statement_delimiter = true ;
523+ expecting_statement_delimiter = self.options.require_semicolon_stmt_delimiter ;
504524 }
505525 Ok(stmts)
506526 }
@@ -4558,6 +4578,9 @@ impl<'a> Parser<'a> {
45584578 ) -> Result<Vec<Statement>, ParserError> {
45594579 let mut values = vec![];
45604580 loop {
4581+ // ignore empty statements (between successive statement delimiters)
4582+ while self.consume_token(&Token::SemiColon) {}
4583+
45614584 match &self.peek_nth_token_ref(0).token {
45624585 Token::EOF => break,
45634586 Token::Word(w) => {
@@ -4569,7 +4592,13 @@ impl<'a> Parser<'a> {
45694592 }
45704593
45714594 values.push(self.parse_statement()?);
4572- self.expect_token(&Token::SemiColon)?;
4595+
4596+ if self.options.require_semicolon_stmt_delimiter {
4597+ self.expect_token(&Token::SemiColon)?;
4598+ }
4599+
4600+ // ignore empty statements (between successive statement delimiters)
4601+ while self.consume_token(&Token::SemiColon) {}
45734602 }
45744603 Ok(values)
45754604 }
@@ -16464,7 +16493,28 @@ impl<'a> Parser<'a> {
1646416493
1646516494 /// Parse [Statement::Return]
1646616495 fn parse_return(&mut self) -> Result<Statement, ParserError> {
16467- match self.maybe_parse(|p| p.parse_expr())? {
16496+ let rs = self.maybe_parse(|p| {
16497+ let expr = p.parse_expr()?;
16498+
16499+ match &expr {
16500+ Expr::Value(_)
16501+ | Expr::Function(_)
16502+ | Expr::UnaryOp { .. }
16503+ | Expr::BinaryOp { .. }
16504+ | Expr::Case { .. }
16505+ | Expr::Cast { .. }
16506+ | Expr::Convert { .. }
16507+ | Expr::Subquery(_) => Ok(expr),
16508+ // todo: how to retstrict to variables?
16509+ Expr::Identifier(id) if id.value.starts_with('@') => Ok(expr),
16510+ _ => parser_err!(
16511+ "Non-returnable expression found following RETURN",
16512+ p.peek_token().span.start
16513+ ),
16514+ }
16515+ })?;
16516+
16517+ match rs {
1646816518 Some(expr) => Ok(Statement::Return(ReturnStatement {
1646916519 value: Some(ReturnStatementValue::Expr(expr)),
1647016520 })),
0 commit comments