Error Recovery
When SQL has parse errors, the formatter formats valid parts normally and preserves error spans as original text. No /* ERROR */ markers — broken parts are left untouched.
Valid SELECT with broken WHERE
The SELECT and FROM clauses are valid and get formatted. The WHERE condition has a syntax error and is preserved as-is.
SELECT a, b FROM t WHERE x >
select a, b from t where x
Multiple statements — one broken
Valid statements get formatted normally. The broken statement is partially formatted.
SELECT 1; SELECT a FROM WHERE; SELECT 2
select 1;
select a from where;
select 2
Completely broken SQL
When the entire statement is unparseable, the original text is preserved.
@#$%
@#$%
Broken statement with trailing semicolon followed by more statements
A broken statement followed by a ; terminator and then another statement. The parser
emits the broken portion as an AstParseErrorBase fragment that carries the original
bytes — including any terminators the user typed.
File-mode formatting passes error fragments through verbatim: one ; in the input
yields exactly one ; in the output, two ;; yield two ;;. The normal inter-statement
; separator is suppressed after an error fragment so the fragment's own terminators
are not doubled. Re-parsing the output produces the same fragment shape, which renders
identically — the round-trip is idempotent by construction.
SELECT a, b FROM t WHERE x >;
SELECT 1
select a, b from t where x >;
select 1
Broken statement followed by another broken statement
Both statements have parse errors. The first goes through the partial-format path then
its >; fragment; the second goes through the verbatim hasErrors path. File-mode
formatting remains idempotent across passes.
SELECT a, b FROM t WHERE x >;
SELECT a FROM WHERE
select a, b from t where x >;
select a from where
Single broken statement at EOF
One statement, broken, running to EOF with no terminator. The valid prefix is formatted normally; the broken tail is preserved verbatim. This is the baseline shape of error recovery — one statement in, one statement out.
SELECT a, b FROM t WHERE x >
select a, b from t where x >
Broken statement at EOF with trailing semicolon
One statement, broken, terminated with ; at EOF. The trailing ; is preserved
exactly — the formatter does not drop or duplicate it.
SELECT a, b FROM t WHERE x >;
select a, b from t where x >;
Double semicolon preserved exactly
The user typed ;;, so the output must contain ;; — not more, not fewer. The fragment
text >;; is passed through verbatim, and the inter-statement ; separator is not
auto-inserted after it. One ; in → one out; two in → two out.
SELECT a, b FROM t WHERE x >;;
SELECT 1
select a, b from t where x >;;
select 1
Garbage token between valid statements
A lexically valid but syntactically nonsense token (@#$%) sitting between two valid
statements. The parser emits it as an error fragment; the formatter preserves it
verbatim while still formatting the surrounding statements normally.
SELECT 1;
@#$%
SELECT 2
select 1;
@#$%
select 2
Stray keyword between statements
A bare keyword like FROM on its own line between two valid statements. The parser
treats it as an unparseable fragment and the formatter preserves it while keeping the
surrounding statements idempotent.
SELECT 1;
FROM
SELECT 2
select 1;
FROM
select 2