GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — core: carry enums, views and missing placeholders through the analysis core by kyleconroy · Pull Request #4614 · sqlc-dev/sqlc

Conversation

@kyleconroy

@kyleconroy kyleconroy commented Sep 9, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Collaborator

Three fixes from a triage of every internal/endtoend replay case that passes as committed but fails under SQLCEXPERIMENT=coreanalyzer. Together they take the core context from 347 failing cases to 281, with no case regressing and the base context still fully green. Each commit stands on its own.

Enums absent from models (50 cases, 45 fixed)

The core catalog created an enum type on CREATE TYPE ... AS ENUM but kept none of its labels, and the dump that hands the catalog to codegen carried relations only. Every enum was missing from models.go, PostgreSQL enum columns were typed any and MySQL ENUM columns string.

  • sql_enum_label stores an enum's labels, modeled on pg_enum.
  • The schema package applies ALTER TYPE ADD VALUE (with BEFORE/AFTER and IF NOT EXISTS), RENAME VALUE, RENAME TO, SET SCHEMA and DROP TYPE.
  • A MySQL ENUM or SET column declares an enum of its own, named <table>_<column> as the legacy catalog names it. It follows the column and the table through renames, is replaced on MODIFY, and goes with a dropped column or table.
  • Type names keep the schema an engine reports on the TypeName itself and drop a spelled-out public., so foo.mood and DROP TYPE public.status resolve the way their column references do.

The five leftovers are blocked by other buckets (varchar typed any, MySQL BOOLEAN, sqlc.embed).

Views absent from models (10 cases, 8 fixed)

The catalog dump listed kind r relations only, so views, materialized views and CREATE TABLE AS had no model, and a query selecting all of one got a row struct of its own. The listing now covers the relations a query selects rows from the same way. The two leftovers are the anonymous-column naming bucket (SELECT 1 as a view) and CREATE SCHEMA.

Placeholders the analyzer walked past (17 cases, 14 fixed)

  • INSERT ... SELECT: the engines report the source query with an empty VALUES list rather than none, so the analyzer took the VALUES branch and walked nothing. A placeholder selected directly now takes the type of the column it lands in.
  • LIMIT on UPDATE, DELETE, and on UNION/INTERSECT/EXCEPT was never looked at.
  • ON DUPLICATE KEY UPDATE assignments bind the way SET does.
  • x IN (SELECT ...) on MySQL arrives wrapped in a sublink, which the IN node now looks through.
  • x COLLATE c: SQLite puts the expression in the node's other field, so the placeholder underneath was neither found nor typed.
  • CALL: the compiler now sends it through the core, CREATE PROCEDURE is recorded with a void pseudo type as its result, and a call types each placeholder from the declared parameter, by position or by name =>. The AST gains IsProcedure, set by both parsers, since a function with only OUT parameters also declares no return type.
  • A placeholder on the left of an IN list takes its type from the members.

The three leftovers are MySQL BOOLEAN and LIMIT parameter naming. I tried naming LIMIT/OFFSET placeholders in the core and backed it out: it changed analyze output for SQLite and ClickHouse, where the database reports no name, so that convention belongs in the compiler bridge rather than the analysis.

Notes for review

  • One judgement call: a MySQL ENUM column is now reported by sqlc analyze with the synthetic <table>_<column> type name rather than enum. That is what codegen needs and what the legacy compiler always did, but it is not what MySQL itself reports. goldeneye has no MySQL analyze check today.
  • No test cases were added; the existing corpus covers the changes. Verified by running TestReplay/base (all green) and SQLC_TEST_CORE=1 TestReplay/core (347 → 281) before and after each commit.
  • internal/core/catalogdb is regenerated from the catalog schema and query changes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XZcKb4GFiZQbeo9oVmyF3m

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
claude added 3 commits September 9, 2026 04:55
@claude
core: carry enum types through the analysis core to codegen
2c11559
The core catalog created an enum type on CREATE TYPE ... AS ENUM but kept
none of its labels, and the dump that hands the catalog to codegen carried
relations only. Under SQLCEXPERIMENT=coreanalyzer every enum was missing
from models.go, PostgreSQL enum columns were typed any and MySQL ENUM
columns string.

The catalog now stores enum labels (sql_enum_label, modeled on pg_enum)
and the schema package applies the statements that change them: ALTER TYPE
ADD VALUE (with BEFORE/AFTER and IF NOT EXISTS), RENAME VALUE, RENAME TO,
SET SCHEMA, and DROP TYPE. A MySQL ENUM or SET column declares an enum of
its own, named <table>_<column> as the legacy catalog names it; it follows
the column and the table through renames, is replaced on MODIFY, and goes
with a dropped column or table. The dump adds each enum to its schema so
codegen builds the same Go types either way a query set was analyzed.

Type names now keep the schema an engine reports on the TypeName itself
and drop a spelled-out "public.", so foo.mood and public.status resolve
the way their column references do.

In the core replay context 46 more cases pass, with no case regressing.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01XZcKb4GFiZQbeo9oVmyF3m
@claude
core: hand views to codegen along with tables
94fb2a5
The dump that carries the core catalog to codegen listed tables only, so
under SQLCEXPERIMENT=coreanalyzer a view, a materialized view or a table
created from a query had no model in models.go, and a query selecting all
of one got a row struct of its own instead of the view's model.

The listing now covers the relations a query selects rows from the same
way, which is what codegen builds a model for.

In the core replay context 8 more cases pass, with no case regressing.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01XZcKb4GFiZQbeo9oVmyF3m
@claude
core: report the placeholders the analyzer used to walk past
8a6f99d
Under SQLCEXPERIMENT=coreanalyzer several statement shapes lost their
parameters, so the generated function took fewer arguments than the query
has placeholders:

- INSERT ... SELECT: the engines report the source query with an empty
  VALUES list rather than none, so the analyzer took the VALUES branch and
  walked nothing. The query is analyzed now, and a placeholder selected
  directly stands in for the column it lands in.
- UPDATE ... LIMIT and DELETE ... LIMIT, and LIMIT/OFFSET on a UNION,
  INTERSECT or EXCEPT, were never looked at.
- ON DUPLICATE KEY UPDATE assignments were never looked at; they bind the
  way SET does.
- x IN (SELECT ...) on MySQL arrives wrapped in a sublink, which the IN
  node did not look through.
- x COLLATE c: SQLite puts the expression in the node's other field and
  the collation's name where PostgreSQL puts the expression, so the
  placeholder underneath was neither found nor typed.
- CALL: the compiler only sent SELECT, INSERT, UPDATE and DELETE through
  the core, and the schema package skipped CREATE PROCEDURE. A procedure is
  recorded now, with a void pseudo type as its result, and a CALL types
  each placeholder from the procedure's declared parameter, by position or
  by name, and names it after the parameter. The AST gains IsProcedure,
  which both parsers set, since a function with only OUT parameters also
  declares no return type.

A placeholder on the left of an IN list takes its type from the members,
the way the other operand of a comparison would.

In the core replay context 12 more cases pass, with no case regressing.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01XZcKb4GFiZQbeo9oVmyF3m
@kyleconroy
kyleconroy force-pushed the claude/magical-lamport-ckjxj8 branch from 6c75a73 to 8a6f99d Compare September 9, 2026 06:14
@kyleconroy kyleconroy changed the title core: carry enums, unsigned, views and missing placeholders through the analysis core core: carry enums, views and missing placeholders through the analysis core Sep 9, 2026
@manuelschoene manuelschoene mentioned this pull request Nov 11, 2026
fix(sqlite): Extract columns from CREATE TABLE ... AS statement #4684
Open
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@kyleconroy @claude
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.