feat: ADR-0035 4g — ALTER TABLE add/drop constraint + add FK

ALTER TABLE <T> ADD [CONSTRAINT <name>] (CHECK | UNIQUE | FOREIGN KEY)
and DROP CONSTRAINT <name>. ADD = table-CHECK + composite UNIQUE + FK
(ADD PRIMARY KEY and a named UNIQUE refused — composite UNIQUE is
anonymous in our model). Each ADD reuses a low-level path with a dry-run
guard (table-CHECK/UNIQUE rebuild; FK -> add_relationship, bare
REFERENCES -> parent single PK). DROP CONSTRAINT resolves the name to a
named table-CHECK then a child-side FK, else refuses. One undo step each.

Named table-CHECKs round-trip: a nullable `name` column on
__rdbms_playground_table_checks (rebuild-only arrival; a named add on a
pre-4g project is refused with a "rebuild first" hint) plus a project.yaml
check_constraints {expr, name} extension (bare-string form still reads).
The internal-__rdbms_* guard was folded into do_add_constraint /
do_add_relationship, completing that guard class.

Grammar: the action Choice keeps one branch per verb (add/drop/rename/
alter) with an inner Choice fanning out on the distinct second keyword,
since the walker's Choice does not backtrack between same-led branches.

Tests: 7 Tier-1 parse + 2 yaml round-trip + 1 internal-guard + 9 Tier-3
e2e. Help/usage refreshed; ADR-0035 §13 4g + README + requirements.md in
lockstep.
This commit is contained in:
claude@clouddev1
2026-05-25 22:07:50 +00:00
parent 5b76315d1e
commit 6ff97f6e20
16 changed files with 1747 additions and 84 deletions
+11 -3
View File
@@ -238,9 +238,17 @@ handoff-14 cleanup; 449 after B2/C2.)
runtime-decomposed to `change_column_type` with `ForceConversion`, the
§7 advanced policy: lossy converts with a note, incompatible + static
refusals (`↔ blob`, non-`int → serial`) refuse, `int → serial` allowed;
the internal-`__rdbms_*` guard folded into `do_change_column_type`)).
Remaining DDL — `ALTER TABLE` add-drop-constraint / add-FK / `RENAME TO`
(4g4h) — is phased per ADR-0035 §13.)*
the internal-`__rdbms_*` guard folded into `do_change_column_type`),
then `ALTER TABLE` add/drop constraint + add FK (4g — `ADD [CONSTRAINT
<name>] (CHECK | UNIQUE | FOREIGN KEY)` + `DROP CONSTRAINT <name>`;
ADD = CHECK + composite UNIQUE + FK (PRIMARY KEY + named UNIQUE
refused); table-CHECK/UNIQUE rebuild with a dry-run guard, FK reuses
`add_relationship`; named table-CHECKs round-trip via a rebuild-only
`name` column on `__rdbms_playground_table_checks` + a `project.yaml`
`check_constraints` `{expr, name}` extension; the internal-table guard
completed across `do_add_constraint`/`do_add_relationship`)).
Remaining DDL — `ALTER TABLE … RENAME TO` (4h) — is phased per
ADR-0035 §13.)*
- [ ] **Q2** Non-standard syntax rejected with a clear message
pointing at the supported subset.
*(Design done — ADR-0030 §8: out-of-subset statements are