From f160d89a6d084355fe7453c1d746e0e9273a78ef Mon Sep 17 00:00:00 2001 From: Steve Dignam Date: Fri, 10 Oct 2025 10:56:06 -0400 Subject: [PATCH] parser: improve error recovery for CTE --- crates/squawk_parser/src/grammar.rs | 6 ++- .../tests/data/err/select_cte.sql | 9 ++++ .../snapshots/tests__select_cte_err.snap | 54 +++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/crates/squawk_parser/src/grammar.rs b/crates/squawk_parser/src/grammar.rs index 9ed387ed..f26e7a02 100644 --- a/crates/squawk_parser/src/grammar.rs +++ b/crates/squawk_parser/src/grammar.rs @@ -2511,7 +2511,11 @@ fn with_query_clause(p: &mut Parser<'_>) -> Option { break; } if !p.eat(COMMA) { - break; + if p.at(IDENT) { + p.error("missing comma"); + } else { + break; + } } } Some(m.complete(p, WITH_CLAUSE)) diff --git a/crates/squawk_parser/tests/data/err/select_cte.sql b/crates/squawk_parser/tests/data/err/select_cte.sql index 1def4524..026d53c5 100644 --- a/crates/squawk_parser/tests/data/err/select_cte.sql +++ b/crates/squawk_parser/tests/data/err/select_cte.sql @@ -12,3 +12,12 @@ select * from t order by ordercol; with t as (select 1) search depth first by a, b c set ordercol select * from t order by ordercol; + +with + a as ( + select 1 + ) -- <-- missing a comma + b as ( + select 3 + ) +select 2; diff --git a/crates/squawk_parser/tests/snapshots/tests__select_cte_err.snap b/crates/squawk_parser/tests/snapshots/tests__select_cte_err.snap index 67f31416..fad12299 100644 --- a/crates/squawk_parser/tests/snapshots/tests__select_cte_err.snap +++ b/crates/squawk_parser/tests/snapshots/tests__select_cte_err.snap @@ -184,8 +184,62 @@ SOURCE_FILE NAME_REF IDENT "ordercol" SEMICOLON ";" + WHITESPACE "\n\n" + SELECT + WITH_CLAUSE + WITH_KW "with" + WHITESPACE " \n " + WITH_TABLE + NAME + IDENT "a" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "1" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE " " + COMMENT "-- <-- missing a comma" + WHITESPACE "\n " + WITH_TABLE + NAME + IDENT "b" + WHITESPACE " " + AS_KW "as" + WHITESPACE " " + L_PAREN "(" + WHITESPACE "\n " + SELECT + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "3" + WHITESPACE "\n " + R_PAREN ")" + WHITESPACE "\n" + SELECT_CLAUSE + SELECT_KW "select" + WHITESPACE " " + TARGET_LIST + TARGET + LITERAL + INT_NUMBER "2" + SEMICOLON ";" WHITESPACE "\n" --- ERROR@24: unexpected comma ERROR@140: unexpected comma, expected a column name ERROR@270: expected COMMA +ERROR@357: missing comma