Skip to content

Commit ab798b0

Browse files
authored
parser: handle missing exprs in case expr (#749)
1 parent 4ca2bdd commit ab798b0

File tree

3 files changed

+100
-10
lines changed

3 files changed

+100
-10
lines changed

crates/squawk_parser/src/grammar.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ const EXPR_RECOVERY_SET: TokenSet = TokenSet::new(&[
2020
// which should be written as:
2121
// select 1; select 2;
2222
SELECT_KW,
23+
// select case when x then y else end;
24+
// ^ missing expr
25+
END_KW,
26+
// select case when x then else z end;
27+
// ^ missing expr
28+
ELSE_KW, // select case when then y end;
29+
// ^ missing expr
30+
THEN_KW,
2331
]);
2432

2533
fn literal(p: &mut Parser<'_>) -> Option<CompletedMarker> {
@@ -208,8 +216,8 @@ fn opt_else_clause(p: &mut Parser<'_>) {
208216
return;
209217
}
210218
let m = p.start();
211-
if p.eat(ELSE_KW) && expr(p).is_none() {
212-
p.error("expected an expression");
219+
if p.eat(ELSE_KW) {
220+
expr(p);
213221
}
214222
m.complete(p, ELSE_CLAUSE);
215223
}
@@ -219,13 +227,9 @@ fn opt_else_clause(p: &mut Parser<'_>) {
219227
fn when_clause(p: &mut Parser<'_>) -> CompletedMarker {
220228
let m = p.start();
221229
p.expect(WHEN_KW);
222-
if expr(p).is_none() {
223-
p.error("expected an expression");
224-
}
230+
expr(p);
225231
p.expect(THEN_KW);
226-
if expr(p).is_none() {
227-
p.error("expected an expression");
228-
}
232+
expr(p);
229233
m.complete(p, WHEN_CLAUSE)
230234
}
231235

@@ -2334,7 +2338,6 @@ fn postfix_dot_expr(
23342338
})
23352339
}
23362340

2337-
#[must_use]
23382341
fn expr(p: &mut Parser) -> Option<CompletedMarker> {
23392342
expr_bp(p, 1, &Restrictions::default())
23402343
}

crates/squawk_parser/tests/data/err/select.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,14 @@ select select;
5555
-- extra comma
5656
select a, from t;
5757

58+
-- case missing then expr
59+
select case when 1 then end;
60+
61+
-- case missing when expr
62+
select case when then x end;
63+
64+
-- case missing else expr
65+
select case when 1 then 2 else end;
66+
5867
-- trailing comma at EOF
5968
select 1,

crates/squawk_parser/tests/snapshots/tests__select_err.snap

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,81 @@ SOURCE_FILE
610610
IDENT "t"
611611
SEMICOLON ";"
612612
WHITESPACE "\n\n"
613+
COMMENT "-- case missing then expr"
614+
WHITESPACE "\n"
615+
SELECT
616+
SELECT_CLAUSE
617+
SELECT_KW "select"
618+
WHITESPACE " "
619+
TARGET_LIST
620+
TARGET
621+
CASE_EXPR
622+
CASE_KW "case"
623+
WHITESPACE " "
624+
WHEN_CLAUSE_LIST
625+
WHEN_CLAUSE
626+
WHEN_KW "when"
627+
WHITESPACE " "
628+
LITERAL
629+
INT_NUMBER "1"
630+
WHITESPACE " "
631+
THEN_KW "then"
632+
WHITESPACE " "
633+
END_KW "end"
634+
SEMICOLON ";"
635+
WHITESPACE "\n\n"
636+
COMMENT "-- case missing when expr"
637+
WHITESPACE "\n"
638+
SELECT
639+
SELECT_CLAUSE
640+
SELECT_KW "select"
641+
WHITESPACE " "
642+
TARGET_LIST
643+
TARGET
644+
CASE_EXPR
645+
CASE_KW "case"
646+
WHITESPACE " "
647+
WHEN_CLAUSE_LIST
648+
WHEN_CLAUSE
649+
WHEN_KW "when"
650+
WHITESPACE " "
651+
THEN_KW "then"
652+
WHITESPACE " "
653+
NAME_REF
654+
IDENT "x"
655+
WHITESPACE " "
656+
END_KW "end"
657+
SEMICOLON ";"
658+
WHITESPACE "\n\n"
659+
COMMENT "-- case missing else expr"
660+
WHITESPACE "\n"
661+
SELECT
662+
SELECT_CLAUSE
663+
SELECT_KW "select"
664+
WHITESPACE " "
665+
TARGET_LIST
666+
TARGET
667+
CASE_EXPR
668+
CASE_KW "case"
669+
WHITESPACE " "
670+
WHEN_CLAUSE_LIST
671+
WHEN_CLAUSE
672+
WHEN_KW "when"
673+
WHITESPACE " "
674+
LITERAL
675+
INT_NUMBER "1"
676+
WHITESPACE " "
677+
THEN_KW "then"
678+
WHITESPACE " "
679+
LITERAL
680+
INT_NUMBER "2"
681+
WHITESPACE " "
682+
ELSE_CLAUSE
683+
ELSE_KW "else"
684+
WHITESPACE " "
685+
END_KW "end"
686+
SEMICOLON ";"
687+
WHITESPACE "\n\n"
613688
COMMENT "-- trailing comma at EOF"
614689
WHITESPACE "\n"
615690
SELECT
@@ -649,4 +724,7 @@ ERROR@1047: unexpected comma
649724
ERROR@1079: unexpected trailing comma
650725
ERROR@1203: expected SEMICOLON
651726
ERROR@1236: unexpected trailing comma
652-
ERROR@1280: unexpected trailing comma
727+
ERROR@1296: expected an expression, found END_KW
728+
ERROR@1345: expected an expression, found THEN_KW
729+
ERROR@1415: expected an expression, found END_KW
730+
ERROR@1455: unexpected trailing comma

0 commit comments

Comments
 (0)