| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Add a sqlc.switch(@selector, sqlc.when('key', 'sql'), sqlc.else('sql')) macro that expands at compile time into one static query per branch, named <QueryName><BranchKey>. This implements the sqlc.switch() idea floated in discussions/364 ("generate multiple optimized queries at compile time rather than runtime CASE"). Each branch fragment is spliced into the query in place of the macro call and re-parsed as an ordinary query, so: - the generated SQL is fully static (no runtime CASE, planner uses indexes); - branch fragments are author-written constants, never runtime input, so there is no SQL injection surface; - a bad column reference in a fragment is a normal compile error; - a generated name colliding with another query is caught by the existing duplicate-query-name check. Recognition is AST-based, identical to sqlc.arg/sqlc.slice, so it works wherever those macros parse: WHERE on all engines, ORDER BY on PostgreSQL and MySQL. SQLite drops function calls in ORDER BY (see sqlc-dev#4429), so it errors there instead of emitting the unexpanded call. The macro is rejected in the SELECT projection, where branches could change the result shape. The only change to existing code is a thin wrapper in parseQueries; all macro logic lives in the new internal/compiler/expand_switch.go. Includes unit tests and golden end-to-end tests for PostgreSQL (stdlib + pgx), MySQL, and SQLite, plus a design note in docs/proposals/sqlc-switch.md.
Allow several sqlc.switch() calls in one query as long as they declare the same keys (e.g. the same sort applied in a CTE pre-sort and the final ORDER BY). Expansion stays linear in the number of keys — one function per key, each call contributing its own fragment — not the cross product. Branches expanded from a sqlc.switch() now share a single Params and Row struct named after the original query, instead of an identical copy per branch. All branches have the same parameters and result columns (only the spliced fragment differs), so the per-branch structs were byte-identical. A new SwitchGroup field links the branches from compiler metadata through to the Go generator, which emits the shared struct once and points every branch at it.
VariableForField used EmitStruct() to decide between arg.Field and an inlined bare name. A value whose struct is DefinedElsewhere (a shared sqlc.switch Params struct) still takes a single struct arg, so it must use arg.Field. Switch to v.Emit to match Pairs().
SQLite ORDER BY clauses were parsed but not propagated into SelectStmt.SortClause during AST conversion. This caused ORDER BY expressions, including sqlc.switch(...) and function calls such as upper(name), to be invisible to later AST visitors and macro recognition passes. Co-authored-by: OpenAI Codex <codex@openai.com>
…support fix(sqlite): populate SelectStmt.SortClause during AST conversion
… validation Populating SelectStmt.SortClause for SQLite (006f4e8) made the strict_order_by validation apply to SQLite queries for the first time. That broke queries ordering by rowid, _rowid_, or oid, which exist on most SQLite tables but never appear in the declared schema. Skip validation for those implicit names on the sqlite engine only; typos in regular column names still fail. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…bumps) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| Back | FazBrowse Home | New Git URL |
Summary
Implements sqlc.switch — compile-time expansion of dynamic ORDER BY/WHERE branches into one static, fully-validated query per branch.
Follows up on the proposal posted in #364 (comment), opened after @StevenACoffman indicated a PR would be welcome at this point.
expands at sqlc generate time into ListAuthorsNameAsc, ListAuthorsRecent, and ListAuthorsElse — each a plain static query. No runtime CASE (planner/index friendly), no string interpolation (no injection surface), and every branch is re-parsed and validated against the catalog like any ordinary query.
Design
Full design note: docs/proposals/sqlc-switch.md.
Commits
Testing
Disclosure
The initial implementation was AI-generated as a proof of concept to explore the design space; it has since been manually reviewed and tested (unit tests, golden tests across all three engines, and real use in a production project). Details in the discussion post.
Open questions
Carrying over from the discussion, happy to adjust any of these:
🤖 Generated with Claude Code