Skip to content

endtoend: run sqlc fmt over the sqlite testdata queries - #4582

Merged
kyleconroy merged 2 commits into
mainfrom
claude/sqlc-fmt-sqlite-testdata-pw47ve
Aug 27, 2026
Merged

endtoend: run sqlc fmt over the sqlite testdata queries#4582
kyleconroy merged 2 commits into
mainfrom
claude/sqlc-fmt-sqlite-testdata-pw47ve

Conversation

@kyleconroy

@kyleconroy kyleconroy commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

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, so go/ files change alongside the queries). 97 files changed across 50 cases; a second fmt pass over the result is a no-op.

Not formatted, by design:

  • testdata/fmt/sqlite — the formatter's own fixture; its input must stay unformatted.
  • Nine files that only parse after the compiler's preprocessing (sqlc.arg/narg/slice/embed, CASE with @named params): 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.
  • Statements the AST cannot yet render faithfully (constraints beyond plain NOT NULL/PRIMARY KEY, table options, TEMP, AS SELECT) fall back verbatim via the Incomplete guard.

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=examples suite (managed-db context included) passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_018MTvpHqNMadH12pTtsgUq2

@kyleconroy
kyleconroy force-pushed the claude/sqlc-fmt-sqlite-testdata-pw47ve branch 4 times, most recently from 6a39022 to 1154d94 Compare August 26, 2026 21:46
Base automatically changed from claude/sqlc-fmt-formatting-pw47ve to main August 27, 2026 05:01
@kyleconroy
kyleconroy force-pushed the claude/sqlc-fmt-sqlite-testdata-pw47ve branch 8 times, most recently from a3b2a8a to 3516d68 Compare August 27, 2026 17:39
claude added 2 commits August 27, 2026 17:54
…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
kyleconroy force-pushed the claude/sqlc-fmt-sqlite-testdata-pw47ve branch from 3516d68 to 465f4a9 Compare August 27, 2026 17:57
@kyleconroy
kyleconroy merged commit 2249e14 into main Aug 27, 2026
12 checks passed
@kyleconroy
kyleconroy deleted the claude/sqlc-fmt-sqlite-testdata-pw47ve branch August 27, 2026 18:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants