Skip to content

Commit d715a2e

Browse files
authored
parser: improve error recovery for misplaced join clauses (#1065)
1 parent 98fe985 commit d715a2e

3 files changed

Lines changed: 76 additions & 11 deletions

File tree

β€Žcrates/squawk_parser/src/grammar.rsβ€Ž

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2752,6 +2752,7 @@ fn select(p: &mut Parser, m: Option<Marker>, r: &SelectRestrictions) -> Option<C
27522752
}
27532753
opt_from_clause(p);
27542754
opt_where_clause(p);
2755+
opt_misplaced_joins(p);
27552756
opt_group_by_clause(p);
27562757
opt_having_clause(p);
27572758
opt_window_clause(p);
@@ -3465,6 +3466,16 @@ fn join(p: &mut Parser<'_>) {
34653466
m.complete(p, JOIN);
34663467
}
34673468

3469+
// Improve error recovery for wrong joins
3470+
fn opt_misplaced_joins(p: &mut Parser<'_>) {
3471+
while p.at_ts(JOIN_FIRST) {
3472+
let m = p.start();
3473+
p.error("JOINs must appear before WHERE");
3474+
join(p);
3475+
m.complete(p, ERROR);
3476+
}
3477+
}
3478+
34683479
fn on_clause(p: &mut Parser<'_>) {
34693480
assert!(p.at(ON_KW));
34703481
let m = p.start();

β€Žcrates/squawk_parser/tests/data/err/select.sqlβ€Ž

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ select having or c != 'b';
9090
select from t join u on and true;
9191
select from t join u on or true;
9292

93+
-- join after the where
94+
select * from t
95+
where x > 1
96+
join k on true;
97+
9398
-- select end
9499
select
95100
end;

β€Žcrates/squawk_parser/tests/snapshots/tests__select_err.snapβ€Ž

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,51 @@ SOURCE_FILE
938938
TRUE_KW "true"
939939
SEMICOLON ";"
940940
WHITESPACE "\n\n"
941+
COMMENT "-- join after the where"
942+
WHITESPACE "\n"
943+
SELECT
944+
SELECT_CLAUSE
945+
SELECT_KW "select"
946+
WHITESPACE " "
947+
TARGET_LIST
948+
TARGET
949+
STAR "*"
950+
WHITESPACE " "
951+
FROM_CLAUSE
952+
FROM_KW "from"
953+
WHITESPACE " "
954+
FROM_ITEM
955+
NAME_REF
956+
IDENT "t"
957+
WHITESPACE "\n"
958+
WHERE_CLAUSE
959+
WHERE_KW "where"
960+
WHITESPACE " "
961+
BIN_EXPR
962+
NAME_REF
963+
IDENT "x"
964+
WHITESPACE " "
965+
R_ANGLE ">"
966+
WHITESPACE " "
967+
LITERAL
968+
INT_NUMBER "1"
969+
WHITESPACE "\n"
970+
ERROR
971+
JOIN
972+
JOIN_INNER
973+
JOIN_KW "join"
974+
WHITESPACE " "
975+
FROM_ITEM
976+
NAME_REF
977+
IDENT "k"
978+
WHITESPACE " "
979+
ON_CLAUSE
980+
ON_KW "on"
981+
WHITESPACE " "
982+
LITERAL
983+
TRUE_KW "true"
984+
SEMICOLON ";"
985+
WHITESPACE "\n\n"
941986
COMMENT "-- select end"
942987
WHITESPACE "\n"
943988
SELECT
@@ -1176,31 +1221,35 @@ error[syntax-error]: expected expression but got OR_KW
11761221
β•­β–Έ
11771222
91 β”‚ select from t join u on or true;
11781223
β•°β•΄ ━
1179-
error[syntax-error]: expected SEMICOLON
1224+
error[syntax-error]: JOINs must appear before WHERE
11801225
β•­β–Έ
1181-
94 β”‚ select
1182-
β”‚ ┏━━━━━━━┛
1183-
95 β”‚ ┃ end;
1184-
╰╴┗━┛
1226+
96 β”‚ join k on true;
1227+
╰╴━
11851228
error[syntax-error]: expected SEMICOLON
11861229
β•­β–Έ
1187-
98 β”‚ select
1230+
99 β”‚ select
11881231
β”‚ ┏━━━━━━━┛
1189-
99 β”‚ ┃ analyze;
1232+
100β”‚ ┃ end;
11901233
╰╴┗━┛
11911234
error[syntax-error]: expected SEMICOLON
11921235
β•­β–Έ
1193-
101 β”‚ select
1236+
103 β”‚ select
11941237
β”‚ ┏━━━━━━━┛
1195-
102 β”‚ ┃ analyse;
1238+
104 β”‚ ┃ analyze;
11961239
╰╴┗━┛
11971240
error[syntax-error]: expected SEMICOLON
11981241
β•­β–Έ
11991242
106 β”‚ select
12001243
β”‚ ┏━━━━━━━┛
1201-
107 β”‚ ┃ with t as (select 1)
1244+
107 β”‚ ┃ analyse;
1245+
╰╴┗━┛
1246+
error[syntax-error]: expected SEMICOLON
1247+
β•­β–Έ
1248+
111 β”‚ select
1249+
β”‚ ┏━━━━━━━┛
1250+
112 β”‚ ┃ with t as (select 1)
12021251
╰╴┗━┛
12031252
error[syntax-error]: unexpected trailing comma
12041253
β•­β–Έ
1205-
111 β”‚ select 1,
1254+
116 β”‚ select 1,
12061255
β•°β•΄ ━

0 commit comments

Comments
Β (0)