Skip to content

feat: generate — :execrows/:execresult verbs + verb robustness - #28

Merged
dyammarcano merged 1 commit into
mainfrom
feat/generate-exec-verbs
Jul 3, 2026
Merged

feat: generate — :execrows/:execresult verbs + verb robustness#28
dyammarcano merged 1 commit into
mainfrom
feat/generate-exec-verbs

Conversation

@dyammarcano

Copy link
Copy Markdown
Contributor

What

Widens sequa generate's query analyzer — the coverage frontier a corpus census identified as highest-leverage.

Census (real annotated queries): the non-standard-verb bucket was the single biggest blocker — :execrows alone is 71 uses in one corpus (~18% of 404 queries), dwarfing outer joins (3), CTEs (4), subqueries (7). So this PR does verbs first.

Changes

  • Recognize any -- name: X :verb header. The regex was hard-coded to :one|:many|:exec, so an unknown verb (e.g. :execrows) failed to match and its SQL was silently merged into the previous query — surfacing the misleading expected exactly one SQL statement against the wrong query. Now every header is recognized and the verb is validated.
  • :execrows(int64, error) via ExecContext + result.RowsAffected().
  • :execresult(sql.Result, error) via ExecContext.
  • Reject pgx-only verbs (:copyfrom, :batchexec/many/one) and :execlastid with actionable errors (requires the pgx driver / use RETURNING with :one) instead of emitting broken code.
  • Param/local collision fix — a parameter bound to a column named result (or err, etc.) is renamed (result2) so the generated body never redeclares its own locals. Also closes the pre-existing latent collision in :one/:many/:exec.
  • Malformed-header handling — a header-shaped typo (-- name : X :exec) fails loudly; a prose comment that merely starts with -- name: stays ordinary SQL.

Verification

  • Golden test unchanged:one/:many/:exec output is byte-identical.
  • New verb_test.go (10 tests): the new verbs, the anti-silent-merge regression, verb rejection, the param-collision fix, and both malformed/prose header cases.
  • Measured on a real 106-migration project: the query corpus now clears the verb wall it previously died on at query Hardening: fix codegen version-0 bug, consolidate duplication, add tests #1, advancing to the next frontier (subqueries).
  • The two defects fixed here (result collision; over/under-broad malformed regex) were caught by an adversarial review pass and are regression-locked; the collision case compiles standalone.

Outer joins, SELECT * across joins, CTEs, and subqueries remain the next designed increments (tracked separately).

Widen the query analyzer, chosen by a leverage census of ~500 real
annotated queries: the non-standard-verb bucket (:execrows, 71 uses in
one corpus) was the single largest blocker, dwarfing outer joins/CTEs.

- Recognize any `-- name: X :verb` header (was hard-coded to
  :one|:many|:exec) so an unknown verb is reported clearly instead of
  silently merging its SQL into the previous query — the root cause of
  the misleading "expected exactly one SQL statement" error.
- Emit :execrows -> (int64, error) via ExecContext + RowsAffected(),
  and :execresult -> (sql.Result, error).
- Reject pgx-only verbs (:copyfrom, :batchexec/many/one) and :execlastid
  with actionable errors instead of broken output.
- Rename parameters that collide with a generated method's locals (e.g.
  a column named `result`) so the output always compiles.
- Malformed `-- name:` headers fail loudly; prose comments that merely
  start with "-- name:" stay ordinary SQL.

Golden output for :one/:many/:exec is byte-identical (regression-locked).
@dyammarcano
dyammarcano merged commit fbd0702 into main Jul 3, 2026
5 checks passed
@dyammarcano
dyammarcano deleted the feat/generate-exec-verbs branch July 3, 2026 17:21
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.

1 participant