Skip to content

Options: model/table/db_type overrides, rename, global options, unknown-option errors, engine check, comments - #44

Merged
doron050 merged 1 commit into
devin/1793571509-unsupported-featuresfrom
devin/1793571817-config-options
Nov 3, 2026
Merged

doron050 merged 1 commit into
devin/1793571509-unsupported-featuresfrom
devin/1793571817-config-options

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes the configuration and option gaps from the feature-gap analysis (section 1c). Stacked on #43, which is stacked on #42; retarget to main once those are merged.

  • Overrides now apply to models. Before, overrides: only affected query rows and parameters, so Author#bio kept the database type while GetAuthorRow#bio used the override. *:<column> now also applies to models. Two new forms work like sqlc's Go overrides:
    • column: "<table>.<column>" (or "<schema>.<table>.<column>"): the table's model plus every query column that sqlc reports as coming from that table.
    • db_type: "uuid": every column or parameter of that database type.
    • Order of precedence: Query:col > table.col > *:col > db_type.
  • rename: {authors: Writer, bio: biography}. A table name (or schema.table) sets the model class name. A column name sets the attribute name in rows and models; the value is still read by the original column name. Class names are validated.
  • exactTableNames (the equivalent of emit_exact_table_names): authors gives Authors instead of Author.
  • Global options: GenerateRequest.global_options (field 6, the plugin's entry in the top-level options: of sqlc.yaml) used to be ignored. It is now merged under the codegen options: the codegen options win, and the overrides of both apply.
  • Unknown options are rejected instead of silently ignored, with a hint for near misses: unknown plugin options: generate_types (did you mean generateTypes?).
  • Engine check: GenerateRequest.settings (version, engine) is now decoded. A driver used with another engine (e.g. driver: pg with engine: mysql) is an error.
  • Comments: table and enum comments become doc comments of the models (.rb + .rbs), and column comments become comments in the RBS. The PG example gains COMMENT ON statements to show this.

Breaking: configs with misspelled or unsupported option keys now fail. Models change type when an existing *:<column> override matches one of their columns.

The fixtures are recaptured; they now include settings.

Checklist

  • examples/ is regenerated (rake sqlc_generate_process) and committed
  • Tests added or updated (rake test, and rake end2end_* when the generated code changes)
  • The generated code stays RuboCop-clean (rake rubocop) and Steep-clean (rake steep)
  • Labelled (feature, bug, breaking, documentation) so the release notes are grouped correctly

Tested locally: rake test, rake rubocop steep, rake end2end_pg (postgres:16).

…mes, global options, unknown-option errors, engine check, schema comments

Co-Authored-By: Doron Eli Rachman <doron050@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration devin-ai-integration Bot added the enhancement New feature or request label Nov 1, 2026
@doron050
doron050 merged commit 277ee94 into devin/1793571509-unsupported-features Nov 3, 2026
doron050 added a commit that referenced this pull request Nov 3, 2026
…te affinity (#43)

## Summary
Adds the sqlc features from the feature-gap analysis (section 1b) that
used to make generation fail with an error. It also contains the section
1c options work from #44, which was merged into this branch.

- **`:execresult`**: returns `ExecResult` (`rows_affected`,
`last_insert_id`). This is a `Data` class (a `Struct` below Ruby 3.2)
nested in the query class. pg: `result.cmd_tuples` with `nil` last id
(use `RETURNING`). mysql2: `stmt.affected_rows` / `client.last_id`.
sqlite3: `client.changes` / `client.last_insert_row_id`.
- **`:batchexec` / `:batchone` / `:batchmany`**: take an `Array` of
`<Query>Args` (the same kind of `Data` class `:copyfrom` uses) and run
the prepared statement once per element on one connection. They return
`nil` / `Array[Row?]` / `Array[Array[Row]]`. Available on all three
drivers. This is sequential execution, not libpq pipeline mode.
- **Unknown types no longer abort generation**: a query column or
parameter whose type the plugin doesn't map (e.g. `now()`, `unnest`,
`any`, domains) is typed `untyped`. Models already did this.
- **More PostgreSQL types**: `timetz`, `tsvector` / `tsquery`, `hstore`,
`ltree` / `lquery` / `ltxtquery`, geometric types, ranges and
multiranges, `reg*`, `pg_lsn`, ... map to `String`, and `oid` maps to
`Integer`. These are the classes the pg gem returns; I checked each one
against postgres:16. Pseudo-types (`any`, `anyelement`, `record`,
`void`, ...) map to `untyped`.
- **Composite types**: `Schema.composite_types` (protobuf field 5) is
now decoded. Composite columns are `String` (the record text, e.g.
`"(3,4)"`).
- **SQLite declared types**: `VARCHAR(255)`, `DECIMAL(10, 5)`, `UNSIGNED
BIG INT`, `NATIVE CHARACTER(70)` are normalized. Types that no mapping
matches follow SQLite's type-affinity rules, through a new driver hook
`affinity_type`.
- **Options (from #44)**: model/table/`db_type` overrides, `rename`,
`exactTableNames`, global options, errors for unknown options,
engine/driver check, schema/table/column/enum comments as doc comments.
**Breaking**: configs with misspelled option names now fail.

Domains stay `untyped`: sqlc sends only the domain name, not its base
type.

The examples gain `postgres_special_types` (incl. a composite type and a
domain), SQLite `declared_types`, and `:execresult` / `:batch*` queries
for all three engines. The fixtures are recaptured, and
`steep_expectations.yml` is refreshed (line shifts only).

## Checklist
- [x] `examples/` is regenerated (`rake sqlc_generate_process`) and
committed
- [x] Tests added or updated (`rake test`, and `rake end2end_*` when the
generated code changes)
- [x] The generated code stays RuboCop-clean (`rake rubocop`) and
Steep-clean (`rake steep`)
- [x] Labelled (`feature`, `bug`, `breaking`, `documentation`) so the
release notes are grouped correctly

Tested locally: `rake test`, `rake rubocop steep`, `rake end2end_pg`
(postgres:16), `rake end2end_mysql2` (mysql:8.3), `rake
end2end_sqlite3`.

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Doron Eli Rachman <doron050@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant