feat: ADR-0035 4h — ALTER TABLE … RENAME TO

The one genuinely new low-level op in Phase 4: a native engine RENAME TO
plus one-transaction reconciliation (commit-db-last) of everything the
engine does not track —

- every metadata row naming the table: __rdbms_playground_columns, both
  ends of __rdbms_playground_relationships (FK parent, child, and
  self-referential), and __rdbms_playground_table_checks;
- the CSV file, via the existing persistence rewrite+delete path
  (rewritten_tables=[new], deleted_tables=[old]) — no new method;
- CHECK text that qualifies a column with the old table name
  (T.age → U.age, column- and table-level): the engine rewrites the live
  CHECK but the stored text would drift and break a fresh rebuild (a
  planning-/runda finding); rewrite_check_table_qualifier keeps them in
  step. Bounded — a CHECK references only its own table.

Grammar: a fifth AlterTableAction (RenameTable { new }), added by
splitting the `rename` verb into one branch with an inner Choice on a
distinct second keyword (column vs to); the new-name slot mirrors the
CREATE TABLE name slot (NewName + reject_internal_table validator).

Refusals are engine-neutral and case-insensitive (the engine matches
names that way): same-name, case-only, existing-target, __rdbms_*, and
non-existent source. Auto-named indexes and relationships keep their
stale names (only table-name columns update — §6 scope). One undo step;
advanced-mode only; closes the rename half of C1.

Tests: 8 Tier-3 e2e + rewrite-helper unit tests + parse-dispatch tests.
Full suite 1903 passing / 0 failing / 1 ignored; clippy clean.
This commit is contained in:
claude@clouddev1
2026-05-26 08:38:39 +00:00
parent 6112859660
commit f7e77a86f8
12 changed files with 1379 additions and 15 deletions
+40 -7
View File
@@ -4,15 +4,17 @@
Accepted. Design agreed with the user (2026-05-24); the approach is
**validated end-to-end by sub-phases 4a / 4a.2 / 4a.3 / 4b / 4c / 4d /
4e / 4f / 4g** (`CREATE TABLE` with column- and table-level constraints
and foreign keys, `DROP TABLE [IF EXISTS]`, `CREATE [UNIQUE] INDEX` /
`DROP INDEX [IF EXISTS]`, `ALTER TABLE` add/drop/rename column,
`ALTER TABLE … ALTER COLUMN TYPE`, and `ALTER TABLE` add/drop constraint
+ add foreign key, implemented 2026-05-25 — plans
4e / 4f / 4g / 4h** (`CREATE TABLE` with column- and table-level
constraints and foreign keys, `DROP TABLE [IF EXISTS]`,
`CREATE [UNIQUE] INDEX` / `DROP INDEX [IF EXISTS]`, `ALTER TABLE`
add/drop/rename column, `ALTER TABLE … ALTER COLUMN TYPE`, `ALTER TABLE`
add/drop constraint + add foreign key, and `ALTER TABLE … RENAME TO`,
implemented 2026-05-25/26 — plans
`docs/plans/20260524-adr-0035-sql-ddl-4a.md`, `…-4a2.md`, `…-4a3.md`,
`docs/plans/20260525-adr-0035-sql-ddl-4b.md`, `…-4c.md`, `…-4d.md`,
`…-4e.md`, `…-4f.md`, `…-4g.md`), so the decision is accepted while the
remaining sub-phases (**4h4i**, §13) continue. This is **Phase 4** of the ADR-0030 roadmap (the
`…-4e.md`, `…-4f.md`, `…-4g.md`,
`docs/plans/20260526-adr-0035-sql-ddl-4h.md`), so the decision is accepted
while the remaining sub-phase (**4i**, §13) continues. This is **Phase 4** of the ADR-0030 roadmap (the
advanced-mode SQL surface), the peer of ADR-0031 (expression grammar),
ADR-0032 (`SELECT`), and ADR-0033 (DML). It **clarifies ADR-0030 §4**
on how DDL is represented and executed.
@@ -482,6 +484,37 @@ ADR-0033's structure:
into `do_add_constraint` / `do_add_relationship`, completing the
4d/4e/4f guard class. One undo step per statement.
- **4h — `ALTER TABLE … RENAME TO`** (the §6 new low-level op).
*(Implemented 2026-05-26 — plan
`docs/plans/20260526-adr-0035-sql-ddl-4h.md`.)* The one genuinely new
low-level executor in Phase 4 (`do_rename_table`): a native engine
`RENAME TO` (structure-preserving — no rebuild) plus reconciliation, in
one transaction (commit-db-last), of everything the engine does not
track — every metadata row that names the table
(`__rdbms_playground_columns`, **both ends** of
`__rdbms_playground_relationships`, `__rdbms_playground_table_checks`),
the CSV file (via the existing persistence rewrite+delete path:
`rewritten_tables = [new]`, `deleted_tables = [old]` — no new
persistence method), and **CHECK text that qualifies a column with the
old table name** (`T.age` → `U.age`, both column- and table-level — a
planning-`/runda` finding: the engine rewrites the *live* CHECK but the
*stored* text would drift and break a fresh rebuild;
`rewrite_check_table_qualifier` keeps them in step; bounded because a
CHECK references only its own table). Grammar: a fifth action,
`AlterTableAction::RenameTable { new }`, added by splitting the `rename`
verb into one branch with an inner `Choice` on a distinct second keyword
(`column` → rename-column, `to` → rename-table — the §6.1 trap-safe
pattern); the new-name slot mirrors the `CREATE TABLE` name slot
(`IdentSource::NewName` + the `reject_internal_table` parse validator).
**Refusals (user-confirmed 2026-05-26):** rename to the same name, to an
existing other table, to an `__rdbms_*` name, or of a non-existent
table. Collision checks are **case-insensitive** (the engine matches
names that way), with an engine-neutral pre-check so a case-only rename
or a case-insensitive clash never surfaces the raw engine error
(a finished-slice `/runda` finding). **Auto-named indexes *and*
relationships keep their stale names** (only the table-name *columns*
update; ADR-0035 §6 scope — user-confirmed; documented collision
caveat). One undo step (the whole-project snapshot). Advanced-mode only;
closes the rename half of `C1`.
- **4i — Verification sweep.** Typing-surface + matrix coverage,
engine-neutral error pass, undo-parity check (one step per
statement), `help`/usage for the new forms. **Carried in from earlier
+1 -1
View File
File diff suppressed because one or more lines are too long