feat: support explain over advanced-mode SQL queries
explain now wraps the advanced SQL commands — select, with (CTE), insert, update, delete — in addition to the DSL show data/update/ delete it already covered, rendering through the same plan tree (ADR-0039, closing the ADR-0030 OOS-2 gap). Implemented as a second Advanced `explain` CommandNode under the shared entry word, reusing the established shared-word dispatch (SQL-first, DSL-fallback) rather than new grammar machinery. build_explain_sql slices the inner SQL off the source and reuses the existing SQL builders; do_explain_plan runs EXPLAIN QUERY PLAN over the carried text verbatim (never executes, so safe for destructive verbs). Advanced explain update/delete now route through SQL with an identical plan; DSL-explain tests pinned to simple mode. Help and usage text now list the advanced explain forms.
This commit is contained in:
@@ -634,6 +634,13 @@ pub static REGISTRY: &[(&CommandNode, CommandCategory)] = &[
|
||||
(&data::SQL_INSERT, CommandCategory::Advanced),
|
||||
(&data::SQL_UPDATE, CommandCategory::Advanced),
|
||||
(&data::SQL_DELETE, CommandCategory::Advanced),
|
||||
// Shared entry word `explain` (ADR-0039): the `Simple` DSL
|
||||
// `data::EXPLAIN` (above) wraps `show data` / `update` / `delete`;
|
||||
// this `Advanced` node wraps the SQL `select` / `with` / `insert`
|
||||
// / `update` / `delete`. SQL-first / DSL-fallback in advanced mode
|
||||
// (so `explain show data …` and DSL-only `--all-rows` still reach
|
||||
// the DSL node); DSL-only in simple mode.
|
||||
(&data::EXPLAIN_SQL, CommandCategory::Advanced),
|
||||
// Shared entry word `create` (ADR-0035 §2): the simple
|
||||
// `ddl::CREATE` (above) and these advanced SQL nodes. The
|
||||
// dispatcher tries the advanced candidates first in advanced mode
|
||||
@@ -782,4 +789,22 @@ mod usage_key_tests {
|
||||
Some("parse.usage.create_table"),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_two_registered_commands_share_a_help_id() {
|
||||
// `note_help` emits one help block per `help_id: Some(_)`
|
||||
// with no dedup, so a duplicate help_id prints the same
|
||||
// command twice in `help`. Shared-entry-word `Advanced`
|
||||
// nodes (SQL_INSERT, …, EXPLAIN_SQL) therefore carry
|
||||
// `help_id: None` and defer to their `Simple` sibling.
|
||||
let mut seen = std::collections::HashSet::new();
|
||||
for (command, _category) in super::REGISTRY {
|
||||
if let Some(id) = command.help_id {
|
||||
assert!(
|
||||
seen.insert(id),
|
||||
"duplicate help_id `{id}` in REGISTRY would print twice in `help`",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user