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
+11
View File
@@ -160,6 +160,15 @@ pub enum Command {
DropTable {
name: String,
},
/// Advanced-mode SQL `DROP TABLE [IF EXISTS] <name>` (ADR-0035 §4,
/// sub-phase 4c). Executes through the same `do_drop_table`
/// machinery as [`Self::DropTable`] (cascade / inbound-relationship
/// refusal / metadata cleanup); `if_exists` turns an absent table
/// into a no-op-with-note rather than an error.
SqlDropTable {
name: String,
if_exists: bool,
},
/// Advanced-mode SQL `CREATE TABLE` (ADR-0035 §1, sub-phase 4a).
/// Its own command, but executed **structurally** through the
/// same `do_create_table` machinery as [`Self::CreateTable`] —
@@ -692,6 +701,7 @@ impl Command {
Self::CreateTable { .. } => "create table",
Self::SqlCreateTable { .. } => "create table",
Self::DropTable { .. } => "drop table",
Self::SqlDropTable { .. } => "drop table",
Self::AddColumn { .. } => "add column",
Self::DropColumn { .. } => "drop column",
Self::RenameColumn { .. } => "rename column",
@@ -741,6 +751,7 @@ impl Command {
Self::CreateTable { name, .. }
| Self::SqlCreateTable { name, .. }
| Self::DropTable { name }
| Self::SqlDropTable { name, .. }
| Self::ShowTable { name }
| Self::ShowData { name, .. } => name,
Self::AddColumn { table, .. }