docs(adr): design the DSL→SQL teaching echo (ADR-0038) + dependencies
Realises ADR-0030 §10 (the DSL→SQL teaching bridge) as a /runda'd design
set, before implementation:
- ADR-0037 (new): execution-time mode side-channel — SubmissionMode
{Simple, Advanced, AdvancedOneShot} threaded Action→worker, output-only;
redeems ADR-0033 Amendment 3's deferred follow-up. Replay stays silent.
- ADR-0038 (new): the teaching echo + full catalogue (Buckets A/B/C),
the copy-paste round-trip contract, the three-category framework, and
the Value→SQL-literal renderer. DDL + show-data centric (overlapping
DML is SQL-first, so already SQL). Build-order deps recorded.
- ADR-0035 Amendment 2: standard-first dialect stance + ALTER COLUMN
SET/DROP NOT NULL, SET/DROP DEFAULT, ISO SET DATA TYPE gap-fill.
- ADR-0033 Amendment 4: reclassifies the `update … --all-rows`
non-fall-back as a bug; it now falls back to the DSL Update and echoes
(keyed on adjacent `--`; spaced arithmetic preserved).
- ADR-0039 (new): EXPLAIN over advanced SQL — decision recorded, build
deferred; supersedes ADR-0030 §13 OOS-2.
- ADR-0000: out-of-scope discipline (deferred vs rejected). README index
updated for all of the above.
Reconcile CLAUDE.md: simple-mode column ops are implemented, not pending
(requirements.md C2/B2 already [x]).
This commit is contained in:
@@ -616,6 +616,117 @@ Single-column UNIQUE column drops are a **parallel** gap (different
|
||||
mechanism — ADR-0029 column-level `drop constraint`) and are **out of
|
||||
scope** here.
|
||||
|
||||
## Amendment 2 — Standard-first dialect + `ALTER COLUMN` constraint gap-fill (2026-05-27)
|
||||
|
||||
Designing the **DSL → SQL teaching echo** (ADR-0030 §10, specified in
|
||||
ADR-0038) surfaced two related things about this ADR's surface. First, a
|
||||
**dialect drift**: ADR-0030 frames advanced mode as "the **standard-SQL**
|
||||
surface," but §4f shipped the type-change verb as bare
|
||||
`ALTER COLUMN … TYPE` — the **PostgreSQL shorthand** — and explicitly
|
||||
declined the ISO `SET DATA TYPE` synonym (§4f, line "no `SET DATA TYPE`
|
||||
synonym"). Second, **gaps**: advanced mode has no way to toggle `NOT NULL`
|
||||
or `DEFAULT` on an existing column, though simple mode does
|
||||
(ADR-0029 `add`/`drop constraint`), and the rebuild primitive that would
|
||||
back them is already in place (it backs §4f type-change and §4g
|
||||
constraint-add). This amendment records a **dialect stance** and **fills
|
||||
the clean gaps** so the echo can emit portable SQL that is also runnable
|
||||
in advanced mode. Recorded with explicit user approval (2026-05-27).
|
||||
|
||||
### The dialect stance — standard-first (refines ADR-0030)
|
||||
|
||||
Where ISO SQL provides a spelling, the **authored grammar's canonical
|
||||
form is the ISO one**, and the **echo emits the ISO form**. A widely-
|
||||
recognised vendor shorthand *may* be **accepted** as a synonym (so a
|
||||
learner who knows it is not punished), but it is never the canonical or
|
||||
emitted form. Where ISO provides **no** spelling for an operation the
|
||||
playground teaches, **one** widely-recognised vendor spelling is adopted
|
||||
as a **deliberate, documented extension** — not silently. This realigns
|
||||
the surface with ADR-0030's stated posture and makes the divergence a
|
||||
conscious, recorded choice rather than drift.
|
||||
|
||||
The stance applies to the whole advanced surface going forward; this
|
||||
amendment exercises it on the `ALTER COLUMN` family.
|
||||
|
||||
### Type change: ISO `SET DATA TYPE` canonical, `TYPE` retained as a synonym
|
||||
|
||||
Reverses §4f's "no `SET DATA TYPE` synonym." The grammar now accepts
|
||||
**both** `ALTER COLUMN <c> SET DATA TYPE <type>` (ISO; canonical) and
|
||||
`ALTER COLUMN <c> TYPE <type>` (PostgreSQL; accepted synonym, no
|
||||
breakage for already-shipped usage). Both decompose to the same §4f
|
||||
`AlterColumnType` action and the same `ChangeColumnMode::ForceConversion`
|
||||
executor — semantics are **unchanged**; only the accepted spelling set
|
||||
and the *canonical/echoed* form change. The echo (ADR-0038) emits
|
||||
`SET DATA TYPE`.
|
||||
|
||||
### New: `SET/DROP DEFAULT` (ISO) and `SET/DROP NOT NULL` (the one extension)
|
||||
|
||||
Four new `AlterColumnType`-family actions under `ALTER COLUMN <c>`:
|
||||
|
||||
| Spelling | Standing | Decomposes to (ADR-0029 executor) |
|
||||
|---|---|---|
|
||||
| `SET DEFAULT <expr>` | **ISO-standard** | `do_add_constraint(Default)` |
|
||||
| `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)` |
|
||||
|
||||
`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
|
||||
`ALTER COLUMN` verb, and the vendors diverge (PostgreSQL
|
||||
`SET/DROP NOT NULL`; SQL Server `ALTER COLUMN <c> <type> NOT NULL`;
|
||||
MySQL `MODIFY`; Oracle `MODIFY`). Per the stance, **one** spelling is
|
||||
adopted as a deliberate extension: **PostgreSQL's `SET/DROP NOT NULL`**,
|
||||
chosen because it is the only form that is type-independent (it does not
|
||||
force the user to restate the column type), reads as plain English, and
|
||||
composes uniformly with the ISO `SET/DROP DEFAULT` it sits beside.
|
||||
|
||||
`SET DEFAULT`'s value slot reuses the §4a.2 / §4e **raw `sql_expr`**
|
||||
default mechanism (`default_sql`), so a default may be any expression
|
||||
the create-table `DEFAULT` accepts — one syntax, not a third
|
||||
(ADR-0030 §11).
|
||||
|
||||
### Execution — rebuild-backed, no new low-level op
|
||||
|
||||
Each new action **runtime-decomposes to an existing ADR-0029 executor**
|
||||
(`do_add_constraint` / `do_drop_constraint`), exactly as §4e/§4f
|
||||
decompose their actions — the populated-column **pre-flight dry-run
|
||||
guard** (ADR-0029 §5) and the internal-`__rdbms_*` guard come for free.
|
||||
No new worker layer. The grammar discriminates the `ALTER COLUMN <c> …`
|
||||
tail by its leading keyword: `type` / `set data type` (type change),
|
||||
`set not null` / `drop not null`, `set default` / `drop default` — the
|
||||
`set`/`drop` lead is new alongside §4f's `type` lead.
|
||||
|
||||
### Parity reached, and the one residual gap
|
||||
|
||||
This brings advanced mode to **constraint-modification parity with
|
||||
simple mode (ADR-0029) for `NOT NULL` and `DEFAULT`** — add and drop,
|
||||
both directions. It closes the simple↔advanced asymmetry the echo design
|
||||
flagged for those ops.
|
||||
|
||||
**Residual gap (deliberately not closed here):** dropping a
|
||||
**column-level `UNIQUE` or `CHECK`** (the single-column, *anonymous*
|
||||
constraints simple mode adds via ADR-0029 `add constraint unique/check`).
|
||||
`DROP CONSTRAINT <name>` (§4g) + the derived composite-UNIQUE name
|
||||
(Amendment 1) resolve *table-level* / *named* constraints; a single-
|
||||
column column-level `UNIQUE` lives as the column's `unique` flag and a
|
||||
column-level `CHECK` is likewise anonymous, so neither has a portable
|
||||
name to address. This is the same class Amendment 1 called a "parallel
|
||||
gap … out of scope." Consequently ADR-0038's catalogue marks
|
||||
`drop constraint unique/check from T.col` as **no headline echo** (a
|
||||
residual gap), rather than inventing a name or a recipe. Flagged for the
|
||||
user; closing it (e.g. extending the derived-name approach to single-
|
||||
column UNIQUE) would be its own small follow-up.
|
||||
|
||||
### Engine neutrality holds (the rebuild stays hidden)
|
||||
|
||||
The chosen spellings are **portable SQL**, not engine features. The fact
|
||||
that *this* engine satisfies `SET NOT NULL` / `SET DATA TYPE` via a table
|
||||
rebuild (because it lacks in-place `ALTER`) is a **Category-1 engine
|
||||
implementation detail** (ADR-0038's taxonomy) and stays **invisible** —
|
||||
no recipe, no rebuild steps surfaced — exactly as §9 and ADR-0030 §7
|
||||
require. A learner sees the standard statement; the engine's means of
|
||||
honouring it is not the lesson.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Advanced mode reaches DDL parity with simple mode and adds
|
||||
|
||||
Reference in New Issue
Block a user