From 2707b6d5723b5b64522a1d9d5fa0244487e1918a Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Sat, 10 Jan 2026 20:17:26 -0700 Subject: [PATCH] parser: improve error handling for unfinished select stmt --- crates/squawk_parser/src/grammar.rs | 11 +- .../squawk_parser/tests/data/err/select.sql | 27 +++- .../tests/snapshots/tests__select_err.snap | 149 +++++++++++++++++- 3 files changed, 182 insertions(+), 5 deletions(-) diff --git a/crates/squawk_parser/src/grammar.rs b/crates/squawk_parser/src/grammar.rs index 2369022e..da63d143 100644 --- a/crates/squawk_parser/src/grammar.rs +++ b/crates/squawk_parser/src/grammar.rs @@ -4878,8 +4878,17 @@ const TARGET_FOLLOW: TokenSet = TokenSet::new(&[ R_BRACK, RETURNING_KW, SEMICOLON, - CREATE_KW, EOF, + // start of another stmt that is also a reserved keyword, aka it can't be a + // unquoted column name + CREATE_KW, + DO_KW, + CREATE_KW, + GRANT_KW, + END_KW, + ANALYZE_KW, + ANALYSE_KW, + WITH_KW, ]) .union(COMPOUND_SELECT_FIRST); diff --git a/crates/squawk_parser/tests/data/err/select.sql b/crates/squawk_parser/tests/data/err/select.sql index a5ec1574..f2f0e5e4 100644 --- a/crates/squawk_parser/tests/data/err/select.sql +++ b/crates/squawk_parser/tests/data/err/select.sql @@ -66,8 +66,33 @@ select case when 1 then 2 else end; -- select without semi and trailing create table select - create table users (); + +-- select do +select +do 'begin null; end'; + +-- select grant +select +grant select on t to u; + +-- select end +select +end; + +-- select analyze/analyse +select +analyze; + +select +analyse; + +-- select with + +select +with t as (select 1) +select * from t; + -- trailing comma at EOF select 1, diff --git a/crates/squawk_parser/tests/snapshots/tests__select_err.snap b/crates/squawk_parser/tests/snapshots/tests__select_err.snap index 724bca13..5c242257 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_err.snap @@ -690,7 +690,7 @@ SOURCE_FILE SELECT SELECT_CLAUSE SELECT_KW "select" - WHITESPACE "\n\n" + WHITESPACE "\n" CREATE_TABLE CREATE_KW "create" WHITESPACE " " @@ -705,6 +705,117 @@ SOURCE_FILE L_PAREN "(" R_PAREN ")" SEMICOLON ";" + WHITESPACE "\n\n\n" + COMMENT "-- select do" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " \n" + DO + DO_KW "do" + WHITESPACE " " + LITERAL + STRING "'begin null; end'" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select grant" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " \n" + GRANT + GRANT_KW "grant" + WHITESPACE " " + REVOKE_COMMAND_LIST + REVOKE_COMMAND + SELECT_KW "select" + WHITESPACE " " + ON_KW "on" + WHITESPACE " " + PATH + PATH_SEGMENT + NAME_REF + IDENT "t" + WHITESPACE " " + TO_KW "to" + WHITESPACE " " + ROLE_LIST + ROLE + NAME_REF + IDENT "u" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select end" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE "\n" + COMMIT + END_KW "end" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select analyze/analyse" + WHITESPACE "\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE "\n" + ANALYZE + ANALYZE_KW "analyze" + SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE "\n" + ANALYZE + ANALYSE_KW "analyse" + SEMICOLON ";" + WHITESPACE "\n\n" + COMMENT "-- select with" + WHITESPACE "\n\n" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE "\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " " + WITH_TABLE + NAME + IDENT "t" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + STAR "*" + WHITESPACE " " + FROM_CLAUSE + FROM_KW "from" + WHITESPACE " " + FROM_ITEM + NAME_REF + IDENT "t" + SEMICOLON ";" WHITESPACE "\n\n" COMMENT "-- trailing comma at EOF" WHITESPACE "\n" @@ -836,9 +947,41 @@ error[syntax-error]: expected SEMICOLON ╭▸ 68 │ select │ ┏━━━━━━━┛ -69 │ ┃ +69 │ ┃ create table users (); + ╰╴┗━┛ +error[syntax-error]: expected SEMICOLON + ╭▸ +73 │ select + ╰╴ ━ +error[syntax-error]: expected SEMICOLON + ╭▸ +77 │ select + ╰╴ ━ +error[syntax-error]: expected SEMICOLON + ╭▸ +81 │ select + │ ┏━━━━━━━┛ +82 │ ┃ end; + ╰╴┗━┛ +error[syntax-error]: expected SEMICOLON + ╭▸ +85 │ select + │ ┏━━━━━━━┛ +86 │ ┃ analyze; + ╰╴┗━┛ +error[syntax-error]: expected SEMICOLON + ╭▸ +88 │ select + │ ┏━━━━━━━┛ +89 │ ┃ analyse; + ╰╴┗━┛ +error[syntax-error]: expected SEMICOLON + ╭▸ +93 │ select + │ ┏━━━━━━━┛ +94 │ ┃ with t as (select 1) ╰╴┗━┛ error[syntax-error]: unexpected trailing comma ╭▸ -73 │ select 1, +98 │ select 1, ╰╴ ━