Skip to content

Add analyze command for static query analysis#4476

Open
kyleconroy wants to merge 2 commits into
mainfrom
claude/analyze-command-8uWVs
Open

Add analyze command for static query analysis#4476
kyleconroy wants to merge 2 commits into
mainfrom
claude/analyze-command-8uWVs

Conversation

@kyleconroy

Copy link
Copy Markdown
Collaborator

Summary

Adds a new sqlc analyze command that analyzes a query against a schema and outputs the inferred result columns and parameters as JSON.

Like sqlc parse, it's a standalone command — no configuration file required and no database connection. It drives sqlc's native static analysis (the catalog-based compiler) to infer types directly from the provided schema, supporting the postgresql, mysql, and sqlite dialects.

sqlc analyze --dialect postgresql --schema schema.sql query.sql
  • --dialect / -dpostgresql, mysql, or sqlite (required)
  • --schema / -s — path to the schema file (required)
  • query file — positional argument, or piped via stdin

Example

Given schema.sql:

CREATE TABLE authors (
  id   BIGSERIAL PRIMARY KEY,
  name text      NOT NULL,
  bio  text
);

and the query -- name: GetAuthor :one / SELECT id, name FROM authors WHERE id = $1;:

[
  {
    "name": "GetAuthor",
    "cmd": ":one",
    "columns": [
      { "name": "id",   "data_type": "bigserial", "not_null": true, "is_array": false, "table": "authors" },
      { "name": "name", "data_type": "text",      "not_null": true, "is_array": false, "table": "authors" }
    ],
    "params": [
      { "number": 1, "column": { "name": "id", "data_type": "bigserial", "not_null": true, "is_array": false, "table": "authors" } }
    ]
  }
]

Output format alignment

This also aligns sqlc parse and sqlc analyze on a single-document JSON output. parse previously emitted one JSON object per statement (newline-delimited), which is not parseable as a single document; it now emits a single JSON array of statements, matching the array analyze produces.

Note: changing parse's output is a behavior change to an existing command, but it has no tests or golden files, and the previous newline-delimited form was not valid as a single JSON document.

Implementation

  • internal/cmd/analyze.go (new) — the command, with small serializable output structs (analyzedQuery / analyzedColumn / analyzedParam) so internal AST types aren't dumped raw. Schema/query parse errors are unwrapped from multierr.Error and reported with file:line:col locations. Stdin (when no file arg is given) is written to a temp file so the compiler can read it, mirroring parse.
  • internal/cmd/parse.go — emit a single JSON array of statements.
  • internal/cmd/cmd.go — register analyzeCmd and its --dialect / --schema flags.

Testing

Manually verified across all three engines and the error/stdin paths:

  • PostgreSQL — SELECT * expansion, RETURNING *, params, and nullability resolved from the schema
  • SQLite — column types and NOT NULL inferred correctly
  • stdin — query piped in works; empty input gives a clear error
  • errors — unknown column reported as bad.sql:2:8: column "nonexistent" does not exist (exit 1); missing --dialect gives a clear message
  • parse output now loads as a single JSON array

go build ./... and go vet ./internal/cmd/ are clean.

https://claude.ai/code/session_01Wyz9n2TDrUMXT2LMk7qjgV


Generated by Claude Code

claude added 2 commits June 8, 2026 16:22
Add a new `sqlc analyze` command that analyzes a query file against a
schema file and outputs the inferred result columns and parameters as
JSON.

Unlike `sqlc generate`, this command does not require a configuration
file and does not connect to a database. It drives sqlc's native static
analysis (the catalog-based compiler) to infer types directly from the
provided schema, supporting the postgresql, mysql, and sqlite dialects.

Usage:
  sqlc analyze --dialect postgresql --schema schema.sql query.sql
Add stdin support to `sqlc analyze`: when no query file argument is
given, the query is read from stdin (written to a temporary file so the
compiler can read it), mirroring `sqlc parse`.

Align the two commands on a single-document JSON output. `parse`
previously emitted one JSON object per statement (newline-delimited),
which is not parseable as a single document; it now emits a single JSON
array of statements, matching the array `analyze` already produces.
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