feat(hint): H2 Phase C batch 3 — DML tier-3 hints (ADR-0053)
Per-form hints for querying/changing data: update, delete, show data/table/tables/relationships/indexes, seed, explain, replay (insert was the Phase-B exemplar). hint_ids wired on UPDATE/DELETE/ SHOW/SEED/EXPLAIN/REPLAY; catalogue + keys.rs registered. +2 spot tests (incl. multi-form SHOW disambiguation); 2493 pass / 1 ignored, clippy clean.
This commit is contained in:
+19
@@ -5882,6 +5882,25 @@ mod tests {
|
|||||||
assert!(!output_contains(&app, "Remove a table"));
|
assert!(!output_contains(&app, "Remove a table"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Phase C batch 3: DML hints render (incl. multi-form SHOW) ──
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn f1_on_update_renders_its_hint_block() {
|
||||||
|
let mut app = App::new();
|
||||||
|
type_str(&mut app, "update Customers set email = 'x' ");
|
||||||
|
f1(&mut app);
|
||||||
|
assert!(output_contains(&app, "Change values in the rows"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn f1_disambiguates_show_forms() {
|
||||||
|
let mut app = App::new();
|
||||||
|
type_str(&mut app, "show relationships");
|
||||||
|
f1(&mut app);
|
||||||
|
assert!(output_contains(&app, "List all the relationships"));
|
||||||
|
assert!(!output_contains(&app, "rows stored in a table"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn messages_command_toggles_verbosity_and_reports() {
|
fn messages_command_toggles_verbosity_and_reports() {
|
||||||
let mut app = App::new();
|
let mut app = App::new();
|
||||||
|
|||||||
+12
-6
@@ -1790,7 +1790,13 @@ pub static SHOW: CommandNode = CommandNode {
|
|||||||
shape: SHOW_SHAPE,
|
shape: SHOW_SHAPE,
|
||||||
ast_builder: build_show,
|
ast_builder: build_show,
|
||||||
help_id: Some("data.show"),
|
help_id: Some("data.show"),
|
||||||
hint_ids: &[],
|
hint_ids: &[
|
||||||
|
"show_data",
|
||||||
|
"show_table",
|
||||||
|
"show_tables",
|
||||||
|
"show_relationships",
|
||||||
|
"show_indexes",
|
||||||
|
],
|
||||||
usage_ids: &[
|
usage_ids: &[
|
||||||
"parse.usage.show_data",
|
"parse.usage.show_data",
|
||||||
"parse.usage.show_table",
|
"parse.usage.show_table",
|
||||||
@@ -1806,7 +1812,7 @@ pub static SEED: CommandNode = CommandNode {
|
|||||||
shape: SEED_SHAPE,
|
shape: SEED_SHAPE,
|
||||||
ast_builder: build_seed,
|
ast_builder: build_seed,
|
||||||
help_id: Some("data.seed"),
|
help_id: Some("data.seed"),
|
||||||
hint_ids: &[],
|
hint_ids: &["seed"],
|
||||||
usage_ids: &["parse.usage.seed"],
|
usage_ids: &["parse.usage.seed"],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1824,7 +1830,7 @@ pub static UPDATE: CommandNode = CommandNode {
|
|||||||
shape: UPDATE_SHAPE,
|
shape: UPDATE_SHAPE,
|
||||||
ast_builder: build_update,
|
ast_builder: build_update,
|
||||||
help_id: Some("data.update"),
|
help_id: Some("data.update"),
|
||||||
hint_ids: &[],
|
hint_ids: &["update"],
|
||||||
usage_ids: &["parse.usage.update"],};
|
usage_ids: &["parse.usage.update"],};
|
||||||
|
|
||||||
pub static DELETE: CommandNode = CommandNode {
|
pub static DELETE: CommandNode = CommandNode {
|
||||||
@@ -1832,7 +1838,7 @@ pub static DELETE: CommandNode = CommandNode {
|
|||||||
shape: DELETE_SHAPE,
|
shape: DELETE_SHAPE,
|
||||||
ast_builder: build_delete,
|
ast_builder: build_delete,
|
||||||
help_id: Some("data.delete"),
|
help_id: Some("data.delete"),
|
||||||
hint_ids: &[],
|
hint_ids: &["delete"],
|
||||||
usage_ids: &["parse.usage.delete"],};
|
usage_ids: &["parse.usage.delete"],};
|
||||||
|
|
||||||
pub static REPLAY: CommandNode = CommandNode {
|
pub static REPLAY: CommandNode = CommandNode {
|
||||||
@@ -1840,7 +1846,7 @@ pub static REPLAY: CommandNode = CommandNode {
|
|||||||
shape: REPLAY_PATH,
|
shape: REPLAY_PATH,
|
||||||
ast_builder: build_replay,
|
ast_builder: build_replay,
|
||||||
help_id: Some("data.replay"),
|
help_id: Some("data.replay"),
|
||||||
hint_ids: &[],
|
hint_ids: &["replay"],
|
||||||
usage_ids: &["parse.usage.replay"],};
|
usage_ids: &["parse.usage.replay"],};
|
||||||
|
|
||||||
pub static EXPLAIN: CommandNode = CommandNode {
|
pub static EXPLAIN: CommandNode = CommandNode {
|
||||||
@@ -1848,7 +1854,7 @@ pub static EXPLAIN: CommandNode = CommandNode {
|
|||||||
shape: EXPLAIN_SHAPE,
|
shape: EXPLAIN_SHAPE,
|
||||||
ast_builder: build_explain,
|
ast_builder: build_explain,
|
||||||
help_id: Some("data.explain"),
|
help_id: Some("data.explain"),
|
||||||
hint_ids: &[],
|
hint_ids: &["explain"],
|
||||||
usage_ids: &["parse.usage.explain"],};
|
usage_ids: &["parse.usage.explain"],};
|
||||||
|
|
||||||
/// `explain` over advanced-mode SQL (ADR-0039).
|
/// `explain` over advanced-mode SQL (ADR-0039).
|
||||||
|
|||||||
@@ -306,6 +306,36 @@ pub const KEYS_AND_PLACEHOLDERS: &[(&str, &[&str])] = &[
|
|||||||
("hint.cmd.change_column.what", &[]),
|
("hint.cmd.change_column.what", &[]),
|
||||||
("hint.cmd.change_column.example", &[]),
|
("hint.cmd.change_column.example", &[]),
|
||||||
("hint.cmd.change_column.concept", &[]),
|
("hint.cmd.change_column.concept", &[]),
|
||||||
|
// Phase C batch 3 — DML command hints.
|
||||||
|
("hint.cmd.update.what", &[]),
|
||||||
|
("hint.cmd.update.example", &[]),
|
||||||
|
("hint.cmd.update.concept", &[]),
|
||||||
|
("hint.cmd.delete.what", &[]),
|
||||||
|
("hint.cmd.delete.example", &[]),
|
||||||
|
("hint.cmd.delete.concept", &[]),
|
||||||
|
("hint.cmd.show_data.what", &[]),
|
||||||
|
("hint.cmd.show_data.example", &[]),
|
||||||
|
("hint.cmd.show_data.concept", &[]),
|
||||||
|
("hint.cmd.show_table.what", &[]),
|
||||||
|
("hint.cmd.show_table.example", &[]),
|
||||||
|
("hint.cmd.show_table.concept", &[]),
|
||||||
|
("hint.cmd.show_tables.what", &[]),
|
||||||
|
("hint.cmd.show_tables.example", &[]),
|
||||||
|
("hint.cmd.show_relationships.what", &[]),
|
||||||
|
("hint.cmd.show_relationships.example", &[]),
|
||||||
|
("hint.cmd.show_relationships.concept", &[]),
|
||||||
|
("hint.cmd.show_indexes.what", &[]),
|
||||||
|
("hint.cmd.show_indexes.example", &[]),
|
||||||
|
("hint.cmd.show_indexes.concept", &[]),
|
||||||
|
("hint.cmd.seed.what", &[]),
|
||||||
|
("hint.cmd.seed.example", &[]),
|
||||||
|
("hint.cmd.seed.concept", &[]),
|
||||||
|
("hint.cmd.explain.what", &[]),
|
||||||
|
("hint.cmd.explain.example", &[]),
|
||||||
|
("hint.cmd.explain.concept", &[]),
|
||||||
|
("hint.cmd.replay.what", &[]),
|
||||||
|
("hint.cmd.replay.example", &[]),
|
||||||
|
("hint.cmd.replay.concept", &[]),
|
||||||
(
|
(
|
||||||
"hint.ambient_invalid_ident",
|
"hint.ambient_invalid_ident",
|
||||||
&["kind", "found"],
|
&["kind", "found"],
|
||||||
|
|||||||
@@ -505,6 +505,46 @@ hint:
|
|||||||
what: "Change a column's type, converting the existing values."
|
what: "Change a column's type, converting the existing values."
|
||||||
example: "change column Customers: status (int)"
|
example: "change column Customers: status (int)"
|
||||||
concept: "The database converts each stored value to the new type; if a value can't convert it refuses the change, so you don't silently lose data. Flags let you force or skip the conversion."
|
concept: "The database converts each stored value to the new type; if a value can't convert it refuses the change, so you don't silently lose data. Flags let you force or skip the conversion."
|
||||||
|
# DML — querying and changing data (Phase C batch 3).
|
||||||
|
update:
|
||||||
|
what: "Change values in the rows that match a condition."
|
||||||
|
example: "update Customers set email = 'new@example.io' where id = 1"
|
||||||
|
concept: "The `where` clause picks which rows change, and it's required — pass `--all-rows` to change the whole table on purpose — so you never update more than you meant to."
|
||||||
|
delete:
|
||||||
|
what: "Remove the rows that match a condition."
|
||||||
|
example: "delete from Orders where status = 'cancelled'"
|
||||||
|
concept: "A `where` is required (use `--all-rows` to clear the table on purpose). Rows a relationship points at may be blocked or cascade-deleted, per its `on delete` action."
|
||||||
|
show_data:
|
||||||
|
what: "Show the rows stored in a table."
|
||||||
|
example: "show data Customers"
|
||||||
|
concept: "This reads the data and never changes it. Add a `where` to show only matching rows."
|
||||||
|
show_table:
|
||||||
|
what: "Show a table's structure — its columns, types, keys, and relationships."
|
||||||
|
example: "show table Customers"
|
||||||
|
concept: "Structure, not data: the column definitions and how this table links to others. Use `show data` to see the rows themselves."
|
||||||
|
show_tables:
|
||||||
|
what: "List all the tables in the project."
|
||||||
|
example: "show tables"
|
||||||
|
show_relationships:
|
||||||
|
what: "List all the relationships between tables."
|
||||||
|
example: "show relationships"
|
||||||
|
concept: "Each relationship is a foreign-key link from a child column to a parent's key, with an `on delete` / `on update` rule."
|
||||||
|
show_indexes:
|
||||||
|
what: "List all the indexes in the project."
|
||||||
|
example: "show indexes"
|
||||||
|
concept: "Indexes speed up lookups; this shows which columns each one covers and whether it enforces uniqueness."
|
||||||
|
seed:
|
||||||
|
what: "Fill a table with generated sample rows, or fill one column on existing rows."
|
||||||
|
example: "seed Customers 50"
|
||||||
|
concept: "Seeding invents realistic-looking data so you have something to query. Pin a value with `set col = …`, choose a generator with `as`, or give a numeric range with `between`."
|
||||||
|
explain:
|
||||||
|
what: "Show how the database will run a query — without running it."
|
||||||
|
example: "explain show data Customers where email = 'a@example.io'"
|
||||||
|
concept: "The plan reveals whether the database scans the whole table or jumps straight to rows through an index — the payoff of `add index`. `explain` never executes, so it's safe even on a delete."
|
||||||
|
replay:
|
||||||
|
what: "Re-run the commands recorded in a history file."
|
||||||
|
example: "replay session.log"
|
||||||
|
concept: "Every successful command is journalled, so replaying re-applies them in order to reproduce a project's state — handy for scripting or redoing a sequence."
|
||||||
err:
|
err:
|
||||||
foreign_key:
|
foreign_key:
|
||||||
child_side:
|
child_side:
|
||||||
|
|||||||
Reference in New Issue
Block a user