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:
@@ -332,6 +332,13 @@ pub enum Command {
|
||||
ShowTable {
|
||||
name: String,
|
||||
},
|
||||
/// Re-display a whole schema collection — every table,
|
||||
/// relationship, or index — as a list in the output (V5). The
|
||||
/// read-only "all items" sibling of `ShowTable`; pure display,
|
||||
/// no schema change.
|
||||
ShowList {
|
||||
kind: ShowListKind,
|
||||
},
|
||||
/// Insert a single row. `columns` is `None` for the natural-
|
||||
/// order short form (`insert into T values (...)`); the
|
||||
/// executor fills in the column list by walking the schema.
|
||||
@@ -746,6 +753,36 @@ pub enum IndexSelector {
|
||||
Columns { table: String, columns: Vec<String> },
|
||||
}
|
||||
|
||||
/// Which schema collection a `show <kind>` list command displays (V5).
|
||||
///
|
||||
/// The bare plural forms list every item of the kind across the
|
||||
/// project; the singular `show table <name>` (a separate
|
||||
/// `Command::ShowTable`) shows one. The singular `show
|
||||
/// relationship <name>` / `show index <name>` forms are not yet
|
||||
/// provided — only the list-all forms land here.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ShowListKind {
|
||||
/// `show tables` — every user table (internal `__rdbms_*`
|
||||
/// tables excluded, as in the items panel).
|
||||
Tables,
|
||||
/// `show relationships` — every declared FK relationship.
|
||||
Relationships,
|
||||
/// `show indexes` — every index across all tables.
|
||||
Indexes,
|
||||
}
|
||||
|
||||
impl ShowListKind {
|
||||
/// The full command name for the `name()` / echo surface.
|
||||
#[must_use]
|
||||
pub const fn command_name(self) -> &'static str {
|
||||
match self {
|
||||
Self::Tables => "show tables",
|
||||
Self::Relationships => "show relationships",
|
||||
Self::Indexes => "show indexes",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The action of an advanced-mode `ALTER TABLE` (ADR-0035 §4).
|
||||
///
|
||||
/// Sub-phase 4e carries the column actions; 4f adds `AlterColumnType`;
|
||||
@@ -860,6 +897,7 @@ impl Command {
|
||||
Self::AddConstraint { .. } => "add constraint",
|
||||
Self::DropConstraint { .. } => "drop constraint",
|
||||
Self::ShowTable { .. } => "show table",
|
||||
Self::ShowList { kind } => kind.command_name(),
|
||||
Self::Insert { .. } => "insert into",
|
||||
Self::Update { .. } => "update",
|
||||
Self::Delete { .. } => "delete from",
|
||||
@@ -948,6 +986,10 @@ impl Command {
|
||||
// result renders as a data view, not a structure
|
||||
// view, so an empty target is correct here.
|
||||
Self::Select { .. } => "",
|
||||
// A `show <kind>` list spans every table (or none) —
|
||||
// there is no single structure-target table; it renders
|
||||
// as a list, not a structure view.
|
||||
Self::ShowList { .. } => "",
|
||||
// A SQL `INSERT` carries its parsed target table (for
|
||||
// CSV re-persistence and ok-summary subject).
|
||||
Self::SqlInsert { target_table, .. }
|
||||
|
||||
+38
-5
@@ -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"),
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ pub use action::ReferentialAction;
|
||||
pub use command::{
|
||||
AlterTableAction, AppCommand, ChangeColumnMode, ColumnSpec, Command, CompareOp, CopyScope, Expr,
|
||||
IndexSelector, MessagesValue, ModeValue, Operand, Predicate, RelationshipSelector, RowFilter,
|
||||
SqlForeignKey,
|
||||
ShowListKind, SqlForeignKey,
|
||||
};
|
||||
pub use parser::{ParseError, parse_command};
|
||||
pub use types::Type;
|
||||
|
||||
Reference in New Issue
Block a user