endtoend: run sqlc fmt over the sqlite testdata queries - #4582
Merged
Conversation
kyleconroy
force-pushed
the
claude/sqlc-fmt-sqlite-testdata-pw47ve
branch
4 times, most recently
from
August 26, 2026 21:46
6a39022 to
1154d94
Compare
kyleconroy
force-pushed
the
claude/sqlc-fmt-sqlite-testdata-pw47ve
branch
8 times, most recently
from
August 27, 2026 17:39
a3b2a8a to
3516d68
Compare
…ase coalesce SQLite gives several constructs more than one spelling, and the formatter was silently picking one: != printed as <> and == as =, a comma-separated FROM item printed as JOIN, a bare JOIN with no ON printed as CROSS JOIN — a planner hint in SQLite the author did not write — and a numbered parameter printed as a bare ?, which is worse than a spelling change: reordered ?N parameters bind by their numbers, so VALUES (?2, ?1) rewritten to (?, ?) swaps its arguments. Operators keep pg_query's shape: A_Expr.Name is the operator as the engine's parser saw it, and since meyer's tree keeps only the operator kind, the sqlite converter reads the author's spelling back out of the source between the operands. The compiler already recognizes every spelling, as it must for MySQL, whose canonical != flows through the same lists. Joins that SQLite treats distinctly become distinct: JoinType gains JoinTypeCross (the planner hint) and JoinTypeComma (its own syntax) beyond the libpg_query set, the sqlite converter maps to them, and the printer spells each as itself — which retires the printer's guess that an inner join with no condition must be a CROSS JOIN. PostgreSQL, whose grammar really does mean CROSS JOIN by that shape (a bare JOIN without ON is a syntax error there), now says so in its converter. Redundant spellings still normalize: INNER JOIN prints as JOIN and LEFT OUTER JOIN as LEFT JOIN, which mean exactly the same thing. Parameters use the numbering the node already records: Dialect.Param gains a numbered flag, ParamRef passes its Dollar field, and sqlite prints ?N for a numbered parameter and ? for a bare one. Compound selects gain the seam boundary the clauses already had: an author who broke the line around UNION, INTERSECT or EXCEPT keeps the operator on its own line, and a one-line compound stays on one line. Statements sqlc has no node for (PRAGMA and friends) stay in the file: ParseFile kept them out of its statement list, so the formatter never saw their extents — it deleted the statements and pulled the name annotations of their neighbours inside the preceding query. They now stay in the list as TODOs, which render as nothing and fall back verbatim; Parse filters them for the compiler, whose skip behavior is unchanged. The file-level belt also refuses any result that changes the file's statement count, so nothing of this class can slip through again. The ON CONFLICT DO UPDATE SET list also gains the boundaries the UPDATE statement's own SET list has: an author who broke the assignments keeps one per line, with the conflict clause's WHERE at clause level, and a one-line upsert stays on one line. COALESCE also drops to lower case: it printed upper-case only because sqlc special-cases it into a dedicated node for nullability inference whose Format hardcoded the spelling, while every other function call prints through FuncCall with its identifier folded lower. The fmt endtoend case pins all of it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018MTvpHqNMadH12pTtsgUq2
Format every sqlite query file in the end-to-end corpus with the new formatter and regenerate the affected goldens (the generated code embeds the query text). The fmt case's own input stays unformatted — it is the formatter's fixture — and nine files are left as written because they only parse after the compiler's preprocessing (sqlc.arg/narg/slice/ embed, @nAmed parameters). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018MTvpHqNMadH12pTtsgUq2
kyleconroy
force-pushed
the
claude/sqlc-fmt-sqlite-testdata-pw47ve
branch
from
August 27, 2026 17:57
3516d68 to
465f4a9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Runs
sqlc fmt(merged in #4580) over every sqlite query file in the end-to-end corpus and regenerates the affected goldens (the generated code embeds the query text, sogo/files change alongside the queries). 97 files changed across 50 cases; a secondfmtpass over the result is a no-op.Not formatted, by design:
testdata/fmt/sqlite— the formatter's own fixture; its input must stay unformatted.sqlc.arg/narg/slice/embed,CASEwith@namedparams):case_named_params,cast_param,named_param,sqlc_arg,sqlc_arg_invalid,sqlc_embed,sqlc_narg,sqlc_slice,sqlc_slice_prepared. fmt reports these on stderr and leaves them as written.NOT NULL/PRIMARY KEY, table options,TEMP,AS SELECT) fall back verbatim via theIncompleteguard.Dogfooding the corpus during development caught several real formatter bugs, all fixed in #4580 before it merged: dropped identifier quotes, rewritten named-parameter sigils, lost authored line breaks around CREATE TABLE column lists, CTE bodies and INSERT's break before
VALUES, squashed two-word type names, and DDL reprints that destroyed constraints.The full
--tags=examplessuite (managed-db context included) passes.🤖 Generated with Claude Code
https://claude.ai/code/session_018MTvpHqNMadH12pTtsgUq2