sqlc
CLAUDE.md18k starsChanged 6 months agoMITView on GitHub
This document provides essential information for working with the sqlc codebase, including testing, development workflow, and code structure. The sqlc-test-setup tool (cmd/sqlc-test-setup/) automates installing and starting PostgreSQL, MySQL, ClickHouse, SQL Server and Spanner Omni for tests. Both commands are idempotent and safe to re-run, and take the databases to act on as arguments (postgresql, mysql, clickhouse, mssql, spanner); with none named they act on all five. This will: - Configure the apt proxy (if http_proxy is set, e.g. in Claude…
- Deletes or force-pushes
- Commits and pushes
We split this CLAUDE.md into the rules it gives an agent
9 rules. About 0 are common, 2 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 40
Start PostgreSQL and configure password auth (postgres/postgres)
- Very specific: line 41
Start MySQL via mysqld_safe and set root password (mysecretpassword)
- Very specific: line 42
Start a ClickHouse server in the background on localhost, with the default user's password mysecretpassword
- Very specific: line 43
Start SQL Server through systemd, or in the background where there is no systemd, with the sa password Mysecretpassword1!
- Distinctive: line 44
Start a Spanner Omni single server in the background, serving plaintext gRPC on port 15000
- Very specific: line 289
If you see errors about storage.googleapis.com, the Go proxy may be unreachable.
- Distinctive: line 300
Always run tests with the race detector when working on concurrent code:
- Very specific: line 321
Cover new behavior end to end: Add a case under /internal/endtoend/testdata/
- Very specific: line 322
Check for race conditions: Use -race flag when testing concurrent code
≈ “Common” is an estimate: at least 1 in 5 of the 25,680 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Claude Code Development Guide for sqlc
This document provides essential information for working with the sqlc codebase, including testing, development workflow, and code structure.
Quick Start
Prerequisites
- Go 1.26.4+ - Required for building and testing
- Docker & Docker Compose - Required for integration tests with databases (local development)
- Git - For version control
Database Setup with sqlc-test-setup
The sqlc-test-setup tool (cmd/sqlc-test-setup/) automates installing and starting PostgreSQL, MySQL, ClickHouse, SQL Server and Spanner Omni for tests. Both commands are idempotent and safe to re-run, and take the databases to act on as arguments (postgresql, mysql, clickhouse, mssql, spanner); with none named they act on all five.
Install databases
go run ./cmd/sqlc-test-setup installThis will:
- Configure the apt proxy (if
http_proxyis set, e.g. in Claude Code remote environments) - Install PostgreSQL via apt
- Download and install MySQL 26.7 from Oracle's deb bundle
- Download the ClickHouse 25.8 release into the user cache, where goldeneye caches it too
- Install SQL Server 2025 from Microsoft's apt repository and run its setup, accepting the EULA on your behalf (Ubuntu 22.04 and 24.04 only)
- Download the Spanner Omni standalone server release into the user cache (linux/amd64 only)
- Resolve all dependencies automatically
- Skip anything already installed
Start databases
go run ./cmd/sqlc-test-setup startThis will:
- Start PostgreSQL and configure password auth (
postgres/postgres) - Start MySQL via
mysqld_safeand set root password (mysecretpassword) - Start a ClickHouse server in the background on localhost, with the default user's password
mysecretpassword - Start SQL Server through systemd, or in the background where there is no systemd, with the sa password
Mysecretpassword1! - Start a Spanner Omni single server in the background, serving plaintext gRPC on port 15000
- Verify the connections
- Skip steps that are already done (running services, existing config)
Connection URIs after start:
- PostgreSQL:
postgres://postgres:postgres@127.0.0.1:5432/postgres?sslmode=disable - MySQL:
root:mysecretpassword@tcp(127.0.0.1:3306)/mysql - ClickHouse:
clickhouse://default:mysecretpassword@127.0.0.1:9000(CLICKHOUSE_SERVER_URI) - SQL Server:
sqlserver://sa:Mysecretpassword1!@127.0.0.1:1433?encrypt=disable(MSSQL_SERVER_URI) - Spanner Omni:
localhost:15000(SPANNER_SERVER_URI)
The examples' tests for ClickHouse, SQL Server and Spanner read those variables and skip when unset. docker-compose.yml runs the same databases for anyone who prefers containers.
Run tests
# Full test suite (requires databases running)
go test --tags=examples -timeout 20m ./...Running Tests
Basic Unit Tests (No Database Required)
go test ./...Full Test Suite with Docker (Local Development)
docker compose up -d
go test --tags=examples -timeout 20m ./...Full Test Suite without Docker (Remote / CI)
go run ./cmd/sqlc-test-setup install
go run ./cmd/sqlc-test-setup start
go test --tags=examples -timeout 20m ./...Running Specific Tests
# Test a specific package
go test ./internal/config
# Run with verbose output
go test -v ./internal/config
# Run a specific test function
go test -v ./internal/config -run TestConfig
# Run with race detector (recommended for concurrency changes)
go test -race ./internal/configTesting Strategy
Cover new work with end-to-end tests, not unit tests. A change to the compiler, an engine, the analysis core or codegen is exercised by running sqlc the way a user does — a schema, a query file and a committed golden output — so the test says what sqlc produces rather than what an internal function returns. Internal APIs move around; the SQL that goes in and the output that comes out is the contract worth pinning down.
Adding coverage means adding a directory under /internal/endtoend/testdata/,
not a *_test.go next to the code. Reach for a unit test only when the
behavior genuinely cannot be reached through the CLI, and say why in the test.
Some *_test.go files predate this and remain; they are not a precedent for
new ones.
End-to-End Tests
- Location:
/internal/endtoend/ - Requirements:
--tags=examplesflag and running databases - Tests:
TestExamples- Main end-to-end testsTestReplay- Replay testsTestFormat- Code formatting testsTestJsonSchema- JSON schema validationTestExamplesVet- Static analysis tests
A case is a directory holding the inputs and the expected output. exec.json
names the command and its arguments — omit it and the case runs generate,
comparing the generated files against the ones committed alongside; give it
{"command": "analyze", "args": [...]} and the case compares the command's
stdout against stdout.json (or stdout.txt for a command that does not
print JSON). A case that is expected to fail commits its stderr.txt. Regenerate a golden by running the command in its directory and
writing the output back over the committed file.
TestReplay runs the whole corpus once per context. base runs each case as
committed and managed-db reruns it against a live database, so a context can
change the config a case is generated with and the experiments it is generated
under. A case restricts itself to some of them with "contexts": [...] in its
exec.json, and commits per-context expected errors as stderr/<context>.txt.
There is only one set of committed golden files, so every context is expected
to generate identical code.
The core context generates every case through the analysis core
(SQLCEXPERIMENT=coreanalyzer). The two paths still disagree, so it is opt-in
and needs no database:
SQLC_TEST_CORE=1 go test ./internal/endtoend -run 'TestReplay/core'Go aborts a test binary on panic, so a case that panics the core analyzer ends
the run early. Run a subset to get past one (-run 'TestReplay/core/^select').
Dialect Checks
The dialect seeds under /internal/engine/<engine>/dialect/ are generated
from a live database by /internal/goldeneye, a nested module, and its tests
verify the committed files against one byte for byte. The same module checks
the analyze_* cases under /internal/endtoend/testdata/ against what the
database itself reports for them, so a fixture.sql next to a case's schema
gives the queries rows to run against. ClickHouse, DuckDB, MySQL, SQLite,
SQL Server and Spanner have the check today; engines whose database is not
available skip.
cd internal/goldeneye
go run ./cmd/goldeneye install clickhouse # download the pinned clickhouse binary once
go run ./cmd/goldeneye install duckdb # download the current DuckDB 2.0 preview build once
go run ./cmd/goldeneye install sqlite # build the pinned sqlite3 shells once; needs a C compiler
POSTGRESQL_SERVER_URI="postgres://postgres:postgres@127.0.0.1:5432/postgres?sslmode=disable" \
MYSQL_SERVER_URI="root:mysecretpassword@tcp(127.0.0.1:3306)/mysql" \
MSSQL_SERVER_URI="sqlserver://sa:Mysecretpassword1!@127.0.0.1:1433?encrypt=disable" \
SPANNER_SERVER_URI="localhost:15000" go test ./...
go run ./cmd/goldeneye generate postgresql # rewrite the files after a changeThe checks are not part of CI. The gen workflow
(.github/workflows/gen.yml) generates the files on demand and uploads
them as an artifact.
Example Tests
- Location:
/examples/directory, a Go module of its own so the drivers the examples run against are not dependencies of sqlc, and so cgo stays on for the DuckDB driver - Requirements: Tagged with "examples", requires live databases; run
with
cd examples && go test --tags=examples ./... - Databases: PostgreSQL, MySQL, SQLite, ClickHouse, DuckDB, Spanner and SQL Server examples; each skips when its server is not named
Database Services
The docker-compose.yml provides test databases:
- PostgreSQL 16 - Port 5432
- User:
postgres - Password:
mysecretpassword - Database:
postgres
- User:
- MySQL 26.7 - Port 3306
- User:
root - Password:
mysecretpassword - Database:
dinotest
- User:
Makefile Targets
make test # Basic unit tests only
make test-examples # Tests with examples tag
make build-endtoend # Build end-to-end test data
make test-ci # Full CI suite (examples + endtoend + vet)
make vet # Run go vet
make start # Start database containersCI/CD Configuration
GitHub Actions Workflow
- File:
.github/workflows/ci.yml - Go Version: 1.26.4
- Jobs:
buildcross-compiles sqlc with cgo off;testruns sqlc's own tests;examplesruns the examples module against every database;vuln_checkrunsgovulncheck - Database Setup:
sqlc-test-setup(not Docker) installs and starts the databases directly on the runner: PostgreSQL and MySQL fortest, and all five forexamples - Test Command:
gotestsum --junitfile junit.xml -- --tags=examples -timeout 20m ./...intest, andgo test --tags=examples ./...underexamples/inexamples - Additional Checks:
govulncheckfor vulnerability scanning
Development Workflow
Building Development Versions
# Build main sqlc binary for development
go build -o ~/go/bin/sqlc-dev ./cmd/sqlc
# Build JSON plugin (required for some tests)
go build -o ~/go/bin/sqlc-gen-json ./cmd/sqlc-gen-jsonEnvironment Variables for Tests
You can override database connections via environment variables:
POSTGRESQL_SERVER_URI="postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable"
MYSQL_SERVER_URI="root:mysecretpassword@tcp(127.0.0.1:3306)/mysql?multiStatements=true&parseTime=true"Code Structure
Key Directories
/cmd/- Main binaries (sqlc, sqlc-gen-json, sqlc-test-setup)/internal/cmd/- Command implementations (vet, generate, etc.)/internal/engine/- Database engine implementations/postgresql/- PostgreSQL parser and converter/dolphin/- MySQL parser (uses TiDB parser)/sqlite/- SQLite parser/duckdb/- DuckDB 2.0 parser (uses darkwing, the pure Go port of DuckDB's PEG parser)<engine>/dialect/- The engine's type system and standard library, as JSONL read by/internal/core/seed; the generated parts come from/internal/goldeneye
/internal/goldeneye/- Nested module that generates the dialect seeds under/internal/engine/<engine>/dialect/from a live database, checks the committed ones against it, and checks the analyze cases under/internal/endtoend/testdata/against what the database reports, one package per engine; see its README/internal/core/- The analysis core: catalog, analyzer and dialect seeds/internal/compiler/- Query compilation logic/internal/codegen/- Code generation for different languages/internal/config/- Configuration file parsing/internal/endtoend/- End-to-end tests/internal/sqltest/- Test database setup (Docker, native, local detection)/examples/- Example projects for testing
Important Files
/Makefile- Build and test targets/docker-compose.yml- Database services for testing/.github/workflows/ci.yml- CI configuration
Common Issues & Solutions
Network Connectivity Issues
If you see errors about storage.googleapis.com, the Go proxy may be unreachable. Use GOPROXY=direct go mod download to fetch modules directly from source.
Test Timeouts
End-to-end tests can take a while. Use longer timeouts:
go test -timeout 20m --tags=examples ./...Race Conditions
Always run tests with the race detector when working on concurrent code:
go test -race ./...Database Connection Failures
If using Docker:
docker compose ps
docker compose up -dIf using sqlc-test-setup:
go run ./cmd/sqlc-test-setup startTips for Contributors
- Run tests before committing:
go test --tags=examples -timeout 20m ./... - Cover new behavior end to end: Add a case under
/internal/endtoend/testdata/ - Check for race conditions: Use
-raceflag when testing concurrent code - Iterate on one case:
go test ./internal/endtoend -run 'TestReplay/base/<case>' - Read existing cases:
/internal/endtoend/testdata/has one per feature
Git Workflow
Branch Naming
- Feature branches should start with
claude/for Claude Code work - Branch names should be descriptive and end with the session ID
Committing Changes
git add <files>
git commit -m "Brief description of changes"
git push -u origin <branch-name>Rebasing
git checkout main
git pull origin main
git checkout <feature-branch>
git rebase main
git push --force-with-lease origin <feature-branch>Resources
- Main Documentation:
/docs/ - Development Guide:
/docs/guides/development.md - CI Configuration:
/.github/workflows/ci.yml - Docker Compose:
/docker-compose.yml
Trending
Less talk lately.about the whole repository
Who's talking about sqlc-dev/sqlc
- MeeTechnically“Using SQLC on LibSQL Database in Golang Project”YouTube · Oct 27, 2024 · 528 views
- Alex Gubin“Search USDC in Ethereum w/ Golang and TimescaleDB. Part 2”YouTube · Nov 25, 2024 · 98 views
- Dominic St-Pierre“039: Go is now more fun to build web apps”YouTube · Jun 5, 2024 · 78 views
- sqlc-dev/sqlc-gen-typescript“feat: Experimental support for Node.js and `better-sqlite3`”GitHub · Feb 12, 2024 · 7 reactions
- riverqueue/river“Preliminary "foot in the door" SQLite support”GitHub · May 1, 2025 · 5 reactions
The biggest 5 of 60 mentions linking to the repository that our crawl found. Each line is their own headline.
See all 60
Talked about on GitHub, YouTube, Bluesky, the web, Hacker News and Stack Overflow (60 times).
On GitHub · 50
- Feb 12, 2024feat: Experimental support for Node.js and `better-sqlite3` — sqlc-dev/sqlc-gen-typescript7 reactions · 1 comment
- May 1, 2025Preliminary "foot in the door" SQLite support — riverqueue/river5 reactions · 7 comments
- Feb 28, 2026parser: Support spatial types | tidb-test=pr/2693 — pingcap/tidb3 reactions · 83 comments
- Dec 1, 2023Wasm-based codepath to run without cgo — pganalyze/pg_query_go3 reactions · 3 comments
- Nov 3, 2024Generate db documentation from migrations instead of connection to an actual db — k1LoW/tbls2 reactions · 1 comment
45 more on GitHub
- Oct 23, 2026billing: tell customers how to skip card entry on the PAYG checkout — superserve-ai/sandbox1 reaction · 6 comments
- Sep 24, 2026perf(d1): drop inline owner GC and throttle advisory rate writes — openclaw/octopool1 reaction · 2 comments
- Sep 18, 2026fix(api): bump google.golang.org/grpc to v1.83.1 for GO-2026-6348 — mosamlife/wpmgr1 reaction · 3 comments
- Aug 14, 2026feat: support custom OpenAI-compatible endpoints — agentclash/agentclash1 reaction · 1 comment
- Aug 3, 2026Add contact details to teams — coffeyvidzro/dugble1 reaction · 1 comment
- Aug 2, 2026build(deps): update pnpm to v11 — openclaw/wacli1 reaction · 3 comments
- Aug 1, 2026Remove SSO, SCIM, identity policies, and workload authentication — coffeyvidzro/dugble1 reaction · 2 comments
- Jul 28, 2026fix(deps): update cel-go build dependency — openclaw/wacli1 reaction · 1 comment
- Jul 26, 2026Implement webhook SQLC repository — coffeyvidzro/dugble1 reaction · 1 comment
- Jul 23, 2026feat(delibase): add PostgreSQL reliability workers — delinoio/oss1 reaction · 1 comment
- Jul 22, 2026chore: migrate sqlc to go tool and bump Go toolchain to 1.26.5 — openclaw/wacli1 reaction · 3 comments
- May 15, 2026[codex] refactor archive store SQL with sqlc — openclaw/wacrawl1 reaction
- May 15, 2026[codex] Move stable store queries to sqlc — openclaw/gitcrawl1 reaction
- Apr 22, 2026Pin sqlc version in CI to resolve go module issues — arran4/goa4web1 reaction · 2 comments
- Apr 21, 2026Convert SQLite JSON columns to JSONB — riverqueue/river1 reaction · 2 comments
- Apr 20, 2026Upgrade sqlc to 1.31.0 — riverqueue/river1 reaction · 1 comment
- Apr 20, 2026fix(security): bump go.mod to 1.26.2 and add govulncheck CI (APP-2557) — Avido-AI/inngest1 reaction · 2 comments
- Oct 10, 2025Add column metadata API for SQL parser/code generation support — kuklyy/go-duckdb1 reaction
- Sep 24, 2025[bug] golang plugin does not support `tool` section — moonrepo/moon1 reaction · 3 comments
- Jul 5, 2025Add maximum bound for `attempted_by` array — riverqueue/river1 reaction
- Oct 28, 2026Dependency Dashboard — tanzhongyan-org/template-go0 reactions
- Oct 2, 2026build(deps): update module github.com/sqlc-dev/sqlc to v1.31.1 — bangumi/submit-patch0 reactions · 2 comments
- Sep 28, 2026Dependency Dashboard — ripmav/streamcrew0 reactions
- Sep 16, 2026Align sqlc toolchain version to unblock Backend Go CI `verify` — Grimmjow06100/CourseAi0 reactions
- Sep 14, 2026Upstream sqlc updates — mbvlabs/narsilc0 reactions · 3 comments
- Aug 27, 2026Table name in schema is not correct when generate from Postgres — stephenafamo/bob0 reactions
- Aug 8, 2026Dependency Dashboard — hu553in/tempstream0 reactions
- Jul 22, 2026make sqlc-gen does not cover the ada store — rutabageldev/ruby-core0 reactions
- May 24, 2026Dependency Dashboard — ShotaKitazawa/beanmemo0 reactions
- Mar 2, 2026Dependency Dashboard — walnuts1018/prfexample0 reactions
- Feb 22, 2026Dependency Dashboard — fr0stylo/ddash0 reactions
- Feb 14, 2026FOLLOW-UP: Pin sqlc version across the codebase instead of @latest — livetemplate/lvt0 reactions
- Jan 28, 2026Go build info — notopia-uit/notopia0 reactions
- Jan 16, 2026Dependency Dashboard — renovatebot/maintainer-dashboard0 reactions
- Sep 25, 2025Dependency Dashboard — unsafe-risk/zchat20 reactions
- Sep 17, 2025Urlshortener — QMEOWQ/qmeowq.github.io0 reactions
- Sep 11, 2025Dependency Dashboard — kahnwong/sqlite-base0 reactions
- Sep 9, 2025Docker build fails because toolbelt@v0.5.3 requires go >= 1.24.0 — delaneyj/1a5s-datastar0 reactions
- Sep 6, 2025🛠️ CI Refactor suggestion — Abdelrahman-habib/qwin0 reactions
- Aug 1, 2025Dependency Dashboard — kahnwong/qrcode-api0 reactions
- Jul 26, 2025Dependency Dashboard — kahnwong/habit-tracker0 reactions
- Jul 6, 2025Implement Goose database migration with sqlc — truongminhphung/user-api-golang0 reactions
- May 14, 2025Dependency Dashboard — lewtec/rotulador0 reactions
- Jan 7, 2025[Package Request]: sqlc-dev.sqlc — microsoft/winget-pkgs0 reactions · 2 comments
- Aug 16, 2024Dependency Dashboard — bangumi/submit-patch0 reactions
On YouTube · 3
- Oct 27, 2024Using SQLC on LibSQL Database in Golang Project — MeeTechnically528 views · 2 comments
- Nov 25, 2024Search USDC in Ethereum w/ Golang and TimescaleDB. Part 2 — Alex Gubin - Blockchain & Golang98 views · 1 comment
- Jun 5, 2024039: Go is now more fun to build web apps — Dominic St-Pierre78 views
On Bluesky · 3
- Dec 30, 2024Forget LLMs, we need more good-old-fashioned code generation. Especially in science. I should be able to define models, analysis, wet-lab… — @rory.bio2 likes and reposts · 1 reply
- Oct 20, 2024#dev #go #db — @jay4.fun2 likes and reposts
- Apr 16, 20251️⃣ sqlc Write raw SQL and get type-safe Go code automatically. Forget boilerplate—focus on queries and business logic. 👉… — @corentings.dev0 likes and reposts · 1 reply
On the web · 2
- Jul 31, 2023sqlc v1.20.0 released — google.com
- Jan 22, 2021Request for comments: SQL to Go code generator quite ... — google.com
On Hacker News · 1
- Apr 17, 2025Sqlc: Generate type-safe code from SQL5 points
On Stack Overflow · 1
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

