feat: ADR-0035 4c — DROP TABLE [IF EXISTS]

Add advanced-mode SQL `DROP TABLE [IF EXISTS] <name>` -> SqlDropTable,
executing through the existing do_drop_table (cascade / inbound-
relationship refusal / metadata cleanup) — full parity with the simple
`drop table`. The only new behaviour is `IF EXISTS` as a
no-op-with-note: a new DropOutcome::Skipped mirroring
CreateOutcome::Skipped (journalled, no snapshot), rendered via a new
ddl.drop_skipped_absent note + DslDropSkipped event.

- Grammar: SQL_DROP_TABLE node (entry `drop`, shape `table [if exists]
  <name> [;]`), registered Advanced. SQL-first dispatch: `drop table T`
  -> SqlDropTable in advanced; `drop column`/`relationship`/`index`/
  `constraint` fall back to the simple `drop` node (and still execute).
- Worker: Request::SqlDropTable + db.sql_drop_table; the if-exists-and-
  absent arm journals + replies Skipped without a snapshot, else
  snapshot_then(do_drop_table) -> Dropped.
- Completion: advanced `drop ` now surfaces the SQL `table` (the
  shared-entry-word behaviour from `create`); test split into simple
  (full DSL list) + advanced (SQL surface).

Known shared-entry-word completion unevenness (advanced `drop ` offers
only `table`; partial `drop rel` returns an empty list) deferred to 4i
(merge candidate sets for shared entry words) along with a flagged user
request to visually distinguish simple- vs advanced-mode completions in
the hint UI — tracked in ADR §13 4i (d)/(e), the 4c plan, and the
completion test. The DSL drops still parse + execute via fallback.

10 new tests (parse/builder + Tier-3: drop existing + one-undo-step +
restore, IF EXISTS skip + journal, plain-absent error, inbound refusal).
Docs: ADR-0035 Status/§13, README, requirements.md Q1.

Tests: 1805 passing, 0 failing, 1 ignored. Clippy clean.
This commit is contained in:
claude@clouddev1
2026-05-25 16:31:41 +00:00
parent 76d60591bf
commit e52e90c45b
16 changed files with 597 additions and 19 deletions
+6
View File
@@ -263,6 +263,8 @@ help:
sql_create_table: |-
create table [if not exists] <T> (<col> <type> [not null] [unique] [primary key], ...
[, primary key (<col>, ...)]) — create a table (advanced SQL)
sql_drop_table: |-
drop table [if exists] <T> — remove a table (advanced SQL)
drop: |-
drop table <T> — remove a table
drop column [from] [table] <T>: <col> [--cascade] — remove a column
@@ -377,6 +379,9 @@ ddl:
# present: a no-op that succeeds with this note instead of an
# "already exists" error.
create_skipped_exists: "table '{name}' already exists — skipped (no changes made)"
# `drop table if exists <T>` where the table is absent: a no-op that
# succeeds with this note instead of a "doesn't exist" error.
drop_skipped_absent: "table '{name}' doesn't exist — skipped (no changes made)"
parse:
# Wrapper around chumsky's structural error message. The
@@ -446,6 +451,7 @@ parse:
usage:
create_table: "create table <Name> with pk [<col>(<type>)[, ...]]"
sql_create_table: "create table [if not exists] <Name> (<col> <type> [not null] [unique] [primary key], ... [, primary key (<col>, ...)])"
sql_drop_table: "drop table [if exists] <Name>"
drop_table: "drop table <Name>"
drop_column: "drop column [from] [table] <Table>: <Name>"
drop_relationship: |-