grammar+db: 3b — SQL INSERT grammar + minimal execution (ADR-0033 §1)
SQL_INSERT_SHAPE (INTO <table> [(cols)] VALUES tuple(s)) with __rdbms_*
target rejection; Command::SqlInsert{sql,target_table}; Request::RunSqlInsert
+ do_sql_insert worker (tx-guarded: execute, then finalize_persistence for
CSV + history before commit, so failures roll back and don't re-persist).
Auto-show is best-effort via last_insert_rowid range.
Isolated behind a dev `sqlinsert` entry word (Advanced) so the SQL path is
testable without making `insert` a shared word yet (that's 3j, after 3d
auto-fill parity). Command::SqlInsert carries only sql+target_table; the
plan's listed_columns/returning land in 3d/3g where they're read.
6 grammar accept/reject tests + 8 integration tests (single/multi-row,
column-list, full-arity, history, rollback-on-failure, multi-row atomicity,
parse-path reconstruction, internal-table rejection). 1452 baseline green.
This commit is contained in:
@@ -292,6 +292,18 @@ pub enum Command {
|
||||
Select {
|
||||
sql: String,
|
||||
},
|
||||
/// Run a validated SQL `INSERT` (ADR-0033 §1, sub-phase 3b).
|
||||
/// Advanced mode only. Grammar-as-text (ADR-0030 §4): `sql` is
|
||||
/// the validated statement the worker executes verbatim;
|
||||
/// `target_table` is extracted from the parse so the worker can
|
||||
/// re-persist that table's CSV after a successful insert
|
||||
/// (ADR-0030 §11) without re-parsing the SQL. `listed_columns`
|
||||
/// (3d, `shortid` auto-fill) and `returning` (3g) are added by
|
||||
/// the sub-phases that read them.
|
||||
SqlInsert {
|
||||
sql: String,
|
||||
target_table: String,
|
||||
},
|
||||
/// App-lifecycle command (per ADR-0003). These work in both
|
||||
/// simple and advanced modes; the dispatcher branches on the
|
||||
/// `Command::App(...)` variant before mode-specific routing.
|
||||
@@ -587,6 +599,7 @@ impl Command {
|
||||
Self::Replay { .. } => "replay",
|
||||
Self::Explain { .. } => "explain",
|
||||
Self::Select { .. } => "select",
|
||||
Self::SqlInsert { .. } => "insert into",
|
||||
Self::App(app) => match app {
|
||||
AppCommand::Quit => "quit",
|
||||
AppCommand::Help => "help",
|
||||
@@ -654,6 +667,9 @@ impl Command {
|
||||
// result renders as a data view, not a structure
|
||||
// view, so an empty target is correct here.
|
||||
Self::Select { .. } => "",
|
||||
// A SQL `INSERT` carries its parsed target table (for
|
||||
// CSV re-persistence and ok-summary subject).
|
||||
Self::SqlInsert { target_table, .. } => target_table,
|
||||
// App commands aren't tied to schema entities — the
|
||||
// verb is the most identifying thing. The
|
||||
// display_subject override below provides a richer
|
||||
|
||||
Reference in New Issue
Block a user