feat: V5 show tables / relationships / indexes list commands

Add the list-all show family as one Command::ShowList { kind }
variant. A read-only worker show_list formats count-headed lists
(reusing do_list_tables / read_all_relationships /
read_table_indexes, so it never drifts from the items panel);
internal __rdbms_* tables excluded. Help + parse-usage entries
added; 10 integration tests in tests/it/show_list.rs.

Mark V5 [x]. Split the singular show relationship/index <name>
detail forms (the [<name>] half) into a new tracked V5a [ ] item
rather than leaving them as an untracked footnote.
This commit is contained in:
claude@clouddev1
2026-06-07 13:20:52 +00:00
parent 28e75961aa
commit 8dec784080
15 changed files with 555 additions and 27 deletions
+38 -5
View File
@@ -24,7 +24,7 @@
//! later swap that capture for the same typed slots used here, adding
//! live hints/highlighting.
use crate::dsl::command::{Command, Expr, RowFilter};
use crate::dsl::command::{Command, Expr, RowFilter, ShowListKind};
use crate::dsl::grammar::{
CommandNode, IdentSource, Node, NumberValidator, ValidationError, Word, expr,
shared::{
@@ -99,7 +99,21 @@ const SHOW_TABLE_NODES: &[Node] = &[
];
const SHOW_TABLE: Node = Node::Seq(SHOW_TABLE_NODES);
const SHOW_CHOICES: &[Node] = &[SHOW_DATA, SHOW_TABLE];
// `show tables` / `show relationships` / `show indexes` — the
// list-all forms (V5). Each is a single keyword with no argument;
// the executor lists every item of the kind. Distinct keyword
// tokens (`tables` ≠ `table`), so Choice ordering is irrelevant.
const SHOW_TABLES: Node = Node::Word(Word::keyword("tables"));
const SHOW_RELATIONSHIPS: Node = Node::Word(Word::keyword("relationships"));
const SHOW_INDEXES: Node = Node::Word(Word::keyword("indexes"));
const SHOW_CHOICES: &[Node] = &[
SHOW_DATA,
SHOW_TABLE,
SHOW_TABLES,
SHOW_RELATIONSHIPS,
SHOW_INDEXES,
];
const SHOW_SHAPE: Node = Node::Choice(SHOW_CHOICES);
// =================================================================
@@ -552,10 +566,23 @@ fn build_show(path: &MatchedPath, _source: &str) -> Result<Command, ValidationEr
_ => None,
})
.nth(1);
let name = require_ident(path, "table_name")?;
match sub {
Some("data") => build_show_data(path, _source),
Some("table") => Ok(Command::ShowTable { name }),
// `name` is resolved only for the forms that carry one; the
// list-all forms (`tables` / `relationships` / `indexes`)
// have no table argument.
Some("table") => Ok(Command::ShowTable {
name: require_ident(path, "table_name")?,
}),
Some("tables") => Ok(Command::ShowList {
kind: ShowListKind::Tables,
}),
Some("relationships") => Ok(Command::ShowList {
kind: ShowListKind::Relationships,
}),
Some("indexes") => Ok(Command::ShowList {
kind: ShowListKind::Indexes,
}),
_ => Err(ValidationError {
message_key: "parse.error_wrapper",
args: vec![("detail", "unknown show subcommand".to_string())],
@@ -1362,7 +1389,13 @@ pub static SHOW: CommandNode = CommandNode {
shape: SHOW_SHAPE,
ast_builder: build_show,
help_id: Some("data.show"),
usage_ids: &["parse.usage.show_data", "parse.usage.show_table"],};
usage_ids: &[
"parse.usage.show_data",
"parse.usage.show_table",
"parse.usage.show_tables",
"parse.usage.show_relationships",
"parse.usage.show_indexes",
],};
pub static INSERT: CommandNode = CommandNode {
entry: Word::keyword("insert"),