feat: advanced ALTER COLUMN SET/DROP NOT NULL & DEFAULT, SET DATA TYPE (ADR-0035 Am2)

The standard-first ALTER COLUMN constraint gap-fill advanced mode lacked:

- ALTER COLUMN <c> SET DATA TYPE <ty> — ISO canonical synonym for the
  PostgreSQL TYPE shorthand (same AlterColumnType action + executor).
- SET NOT NULL / DROP NOT NULL — reuse the ADR-0029 do_add_constraint /
  do_drop_constraint executors (dry-run + internal-table guards free).
- SET DEFAULT <expr> / DROP DEFAULT — SET DEFAULT uses a dedicated
  raw-SQL executor (do_set_column_default); sql_expr yields no typed
  Value, so it can't go through do_add_constraint. DROP DEFAULT reuses
  do_drop_constraint.

Grammar: AT_ALTER_COLUMN gains a tail Choice (type / set / drop), reusing
SQL_TYPE and the CREATE TABLE DEFAULT_NODES; builder dispatch routes the
new column-attribute forms; runtime decomposes to the executors.

ADR-0035 Am2 corrected in-place: SET DEFAULT decomposes to
do_set_column_default, not do_add_constraint (Value-based) — found during
build.

Tests (test-first): 6 parse + 7 Tier-3 execution via run_replay. Suite
1962/0/1; clippy clean.
This commit is contained in:
claude@clouddev1
2026-05-27 21:03:14 +00:00
parent 9f15f386d5
commit 338dc8a4cf
7 changed files with 550 additions and 10 deletions
+15 -2
View File
@@ -662,13 +662,26 @@ and the *canonical/echoed* form change. The echo (ADR-0038) emits
Four new `AlterColumnType`-family actions under `ALTER COLUMN <c>`:
| Spelling | Standing | Decomposes to (ADR-0029 executor) |
| Spelling | Standing | Decomposes to |
|---|---|---|
| `SET DEFAULT <expr>` | **ISO-standard** | `do_add_constraint(Default)` |
| `SET DEFAULT <expr>` | **ISO-standard** | `do_set_column_default` (raw-SQL — see note) |
| `DROP DEFAULT` | **ISO-standard** | `do_drop_constraint(Default)` |
| `SET NOT NULL` | **documented extension** | `do_add_constraint(NotNull)` |
| `DROP NOT NULL` | **documented extension** | `do_drop_constraint(NotNull)` |
**Implementation correction (2026-05-27, during build).** The draft said
`SET DEFAULT` decomposes to `do_add_constraint(Default)`. It cannot:
`do_add_constraint`'s `Constraint::Default(Value)` carries a *typed*
`Value` (the simple-mode shape), but advanced `SET DEFAULT <expr>` is
**raw `sql_expr` text** with no AST (it may be `(1 + 1)`, a function
call, …). So `SET DEFAULT` decomposes to a small dedicated executor
**`do_set_column_default(table, column, default_sql)`** that sets the
column's raw `default_sql` and rebuilds — mirroring `do_add_constraint`'s
`Default` branch (the §6 `serial`/`shortid` refusal, no dry-run — a
default never touches existing rows) but accepting raw SQL instead of a
`Value`. `SET NOT NULL` / `DROP NOT NULL` / `DROP DEFAULT` reuse the
ADR-0029 `do_add_constraint` / `do_drop_constraint` executors unchanged.
`SET DEFAULT`/`DROP DEFAULT` are taken directly from the ISO
`<alter column action>` set. **`NOT NULL` toggling has no ISO spelling**
— in the standard `NOT NULL` is a column constraint, not an in-place