feat: emit the schema in the generated module - #22
Conversation
…e generated module The generated module now carries a `Tables` registry alongside `Queries`: every table and view with its columns (resolved through the same type/override pipeline as the query results) and its index and constraint names as literal unions. Merged into the package's `DatabaseTables` global; `--no-schema` (or `schema: false`) opts out.
A result field that traces to a base column is now emitted as `IUsersColumns['email']` rather than a repeated `string`, so the column it came from is visible on hover and in tsc errors. The nullability step already resolved each field to its source column; it just discarded it. Nullability is composed per query — `| null` for outer-join widening, `NonNullable<…>` for a `@notNull` pragma — since it isn't a property of the column alone. Expressions, per-query `@type` and `--no-schema` stay inline.
A GENERATED ... VIRTUAL column reaches the plan as its generating expression, so it has no column provenance and its COMMENT ON COLUMN override was matched by name across every relation in scope — ambiguous, and silently dropped, as soon as two joined tables commented the same name (#23). Postgres qualifies an expression's inputs exactly when more than one relation is in scope, so the alias it names resolves the owning relation and the override lands. Outer-join widening now applies to comment-sourced nullability too, so resolving more comments can't make an outer-joined column confidently non-null.
|
Fixes #23 — pushed in 1e92cb2. Reproduced it exactly against PGlite 0.5.4 (PG 18.3). The plan output is the key detail:
Postgres qualifies an expression's inputs exactly when more than one relation is in scope — which is exactly when Expression provenance now carries the relation its inputs resolve to (only when they all agree on one), and One thing the fix needed beyond the issue: resolving more comments in join queries would otherwise make an outer-joined column confidently non-null, since the comment branch ignored outer-join widening. Expression provenance now carries Covered in the What I did not do: promote these expressions to full column provenance. |
Cut the pitch-toned prose down to what a user needs: how to read the types, that view columns are nullable, and how to turn the block off.
The generator already reads the whole schema to type queries — this exposes it, and makes it the source the query types point at.
queries.gen.d.tsnow carries aTablesregistry alongsideQueries: every table and view with its columns, index names and constraint names.Result fields that trace back to a base column now reference it rather than repeating its type, so the origin is visible on hover and in
tscerrors:The nullability pass already resolved each field to its source column (that's how it finds the catalog entry); it just discarded it. Nullability is still composed per query —
| nullfor outer-join widening,NonNullable<…>for a@notNullpragma — because it isn't a property of the column alone. Expressions, per-query@type, and untraceable columns keep their type inline.On by default;
--no-schema/schema: falseopts out and restores byte-identical pre-PR output. Views are included but their columns are all nullable (neither engine tracksNOT NULLthrough a view definition); SQLite lists only explicitly named constraints, since it catalogues none.Fixes #23.