Skip to content

Conversation

@kyleconroy
Copy link
Collaborator

Summary

Adds an optional analyzer.accurate: true mode for PostgreSQL that bypasses the internal catalog and uses only database-backed analysis for more accurate type information.

Key Features

  • Database-only type resolution: Uses PostgreSQL PREPARE statements for all column and parameter type inference
  • Database-backed star expansion: Uses the expander package (from feat(expander): Add star expander for SELECT * and RETURNING * (PostgreSQL, MySQL, SQLite) #4203) with database queries for SELECT * and RETURNING * expansion
  • Schema introspection: Queries pg_catalog to build catalog structures needed for code generation (tables, columns, enums)
  • No internal catalog: Skips building the internal catalog from schema files in accurate mode

Configuration

version: "2"
sql:
  - engine: postgresql
    schema: "schema.sql"
    queries: "queries/"
    database:
      uri: "postgres://localhost/mydb"  # or managed: true
    analyzer:
      accurate: true
    gen:
      go:
        package: "db"
        out: "db"

Requirements

  • Accurate mode requires a database connection (database.uri or database.managed: true)
  • The schema must exist in the database before running sqlc generate
  • Only supported for PostgreSQL engine

Files Changed

File Changes
internal/config/config.go Added Accurate *bool to Analyzer struct
internal/config/v_one.json, v_two.json Added accurate boolean to analyzer schema
internal/engine/postgresql/analyzer/analyze.go Added IntrospectSchema(), EnsurePool(), GetColumnNames() methods
internal/compiler/engine.go Added accurate mode detection and expander setup
internal/compiler/compile.go Skip catalog building, introspect schema after parsing
internal/compiler/parse.go Use expander for star expansion in accurate mode

Test plan

  • All existing tests pass
  • Code compiles without errors
  • Manual testing with local PostgreSQL database

🤖 Generated with Claude Code

Add an optional `analyzer.accurate: true` mode for PostgreSQL that bypasses
the internal catalog and uses only database-backed analysis.

Key features:
- Uses database PREPARE for all type resolution (columns, parameters)
- Uses expander package for SELECT * and RETURNING * expansion
- Queries pg_catalog to build catalog structures for code generation
- Skips internal catalog building from schema files

Configuration:
```yaml
sql:
  - engine: postgresql
    database:
      uri: "postgres://..."  # or managed: true
    analyzer:
      accurate: true
```

This mode requires a database connection and the schema must exist in the
database. It provides more accurate type information for complex queries.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. 🔧 golang labels Dec 1, 2025
@kyleconroy kyleconroy marked this pull request as draft December 1, 2025 04:49
kyleconroy and others added 4 commits December 1, 2025 07:41
Add three end-to-end test cases for the accurate analyzer mode:

1. accurate_star_expansion - Tests SELECT *, INSERT RETURNING *, UPDATE RETURNING *, DELETE RETURNING *
2. accurate_enum - Tests enum type introspection from pg_catalog
3. accurate_cte - Tests CTE (Common Table Expression) with star expansion

All tests use the managed-db context which requires Docker to run
PostgreSQL containers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Update expected output files to match actual sqlc generate output:
- Fix parameter naming (Column1, Column2, dollar_1)
- Fix nullability types (sql.NullString, sql.NullInt32)
- Fix CTE formatting (single line)
- Fix query semicolons

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Tests CTE using VALUES clause with column aliasing to verify
accurate analyzer handles inline table expressions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The VALUES clause was incorrectly formatting multiple rows as a single
row with multiple columns. For example:
  VALUES ('A'), ('B'), ('C')
was being formatted as:
  VALUES ('A', 'B', 'C')

This caused the star expander to think the VALUES table had 3 columns
instead of 1, resulting in incorrect SELECT * expansion.

The fix properly iterates over each row in ValuesLists and wraps each
in parentheses.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files. 🔧 golang

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants