diff --git a/crates/squawk_parser/src/grammar.rs b/crates/squawk_parser/src/grammar.rs index db9450a6..4b08dfb6 100644 --- a/crates/squawk_parser/src/grammar.rs +++ b/crates/squawk_parser/src/grammar.rs @@ -2752,6 +2752,7 @@ fn select(p: &mut Parser, m: Option, r: &SelectRestrictions) -> Option) { m.complete(p, JOIN); } +// Improve error recovery for wrong joins +fn opt_misplaced_joins(p: &mut Parser<'_>) { + while p.at_ts(JOIN_FIRST) { + let m = p.start(); + p.error("JOINs must appear before WHERE"); + join(p); + m.complete(p, ERROR); + } +} + fn on_clause(p: &mut Parser<'_>) { assert!(p.at(ON_KW)); let m = p.start(); diff --git a/crates/squawk_parser/tests/data/err/select.sql b/crates/squawk_parser/tests/data/err/select.sql index 98a718d9..9ff57219 100644 --- a/crates/squawk_parser/tests/data/err/select.sql +++ b/crates/squawk_parser/tests/data/err/select.sql @@ -90,6 +90,11 @@ select having or c != 'b'; select from t join u on and true; select from t join u on or true; +-- join after the where +select * from t +where x > 1 +join k on true; + -- select end select end; diff --git a/crates/squawk_parser/tests/snapshots/tests__select_err.snap b/crates/squawk_parser/tests/snapshots/tests__select_err.snap index efa8364a..36405595 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_err.snap @@ -938,6 +938,51 @@ SOURCE_FILE TRUE_KW "true" SEMICOLON ";" WHITESPACE "\n\n" + COMMENT "-- join after the where" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + FROM_ITEM + NAME_REF + IDENT "t" + WHITESPACE "\n" + WHERE_CLAUSE + WHERE_KW "where" + WHITESPACE " " + BIN_EXPR + NAME_REF + IDENT "x" + WHITESPACE " " + R_ANGLE ">" + WHITESPACE " " + LITERAL + INT_NUMBER "1" + WHITESPACE "\n" + ERROR + JOIN + JOIN_INNER + JOIN_KW "join" + WHITESPACE " " + FROM_ITEM + NAME_REF + IDENT "k" + WHITESPACE " " + ON_CLAUSE + ON_KW "on" + WHITESPACE " " + LITERAL + TRUE_KW "true" + SEMICOLON ";" + WHITESPACE "\n\n" COMMENT "-- select end" WHITESPACE "\n" SELECT @@ -1176,31 +1221,35 @@ error[syntax-error]: expected expression but got OR_KW ╭▸ 91 │ select from t join u on or true; ╰╴ ━ -error[syntax-error]: expected SEMICOLON +error[syntax-error]: JOINs must appear before WHERE ╭▸ -94 │ select - │ ┏━━━━━━━┛ -95 │ ┃ end; - ╰╴┗━┛ +96 │ join k on true; + ╰╴━ error[syntax-error]: expected SEMICOLON ╭▸ -98 │ select +99 │ select │ ┏━━━━━━━┛ -99 │ ┃ analyze; +100│ ┃ end; ╰╴┗━┛ error[syntax-error]: expected SEMICOLON ╭▸ -101 │ select +103 │ select │ ┏━━━━━━━┛ -102 │ ┃ analyse; +104 │ ┃ analyze; ╰╴┗━┛ error[syntax-error]: expected SEMICOLON ╭▸ 106 │ select │ ┏━━━━━━━┛ -107 │ ┃ with t as (select 1) +107 │ ┃ analyse; + ╰╴┗━┛ +error[syntax-error]: expected SEMICOLON + ╭▸ +111 │ select + │ ┏━━━━━━━┛ +112 │ ┃ with t as (select 1) ╰╴┗━┛ error[syntax-error]: unexpected trailing comma ╭▸ -111 │ select 1, +116 │ select 1, ╰╴ ━