@@ -265,6 +265,22 @@ impl ParserOptions {
265
265
self.unescape = unescape;
266
266
self
267
267
}
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
+ }
268
284
}
269
285
270
286
#[derive(Copy, Clone)]
@@ -355,7 +371,11 @@ impl<'a> Parser<'a> {
355
371
state: ParserState::Normal,
356
372
dialect,
357
373
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
+ ),
359
379
}
360
380
}
361
381
@@ -478,10 +498,10 @@ impl<'a> Parser<'a> {
478
498
match self.peek_token().token {
479
499
Token::EOF => break,
480
500
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 ;
485
505
}
486
506
}
487
507
_ => {}
@@ -493,7 +513,7 @@ impl<'a> Parser<'a> {
493
513
494
514
let statement = self.parse_statement()?;
495
515
stmts.push(statement);
496
- expecting_statement_delimiter = true ;
516
+ expecting_statement_delimiter = self.options.require_semicolon_stmt_delimiter ;
497
517
}
498
518
Ok(stmts)
499
519
}
@@ -4533,6 +4553,9 @@ impl<'a> Parser<'a> {
4533
4553
) -> Result<Vec<Statement>, ParserError> {
4534
4554
let mut values = vec![];
4535
4555
loop {
4556
+ // ignore empty statements (between successive statement delimiters)
4557
+ while self.consume_token(&Token::SemiColon) {}
4558
+
4536
4559
match &self.peek_nth_token_ref(0).token {
4537
4560
Token::EOF => break,
4538
4561
Token::Word(w) => {
@@ -4544,7 +4567,13 @@ impl<'a> Parser<'a> {
4544
4567
}
4545
4568
4546
4569
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) {}
4548
4577
}
4549
4578
Ok(values)
4550
4579
}
@@ -16370,7 +16399,28 @@ impl<'a> Parser<'a> {
16370
16399
16371
16400
/// Parse [Statement::Return]
16372
16401
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 {
16374
16424
Some(expr) => Ok(Statement::Return(ReturnStatement {
16375
16425
value: Some(ReturnStatementValue::Expr(expr)),
16376
16426
})),
0 commit comments