0dc159fd7e
Implement ADR-0025 — indexes as a DSL DDL feature. - Grammar: `add index [as <name>] on <T> (<cols>)`, `drop index <name>` / `drop index on <T> (<cols>)`, plus a `--cascade` flag on `drop column`. - db.rs: index operations over the engine's native index catalog (no metadata table). The rebuild-table primitive now captures and recreates indexes, so `change column` and the relationship operations no longer silently drop them. - `drop column` refuses an indexed column unless `--cascade`, which drops the covering indexes and reports each. - Persistence: additive `indexes:` list in `project.yaml` (version unchanged); round-trips through rebuild/export/import. - Display: an `Indexes:` section in the structure view and a nested tables/indexes items panel (S2). Reconciles requirements.md (C3 index portion, S2 satisfied) and CLAUDE.md. 1038 tests passing (+31), clippy clean.
79 lines
2.7 KiB
Rust
79 lines
2.7 KiB
Rust
//! Matrix coverage for `add index [as <name>] on <T> (<col>, …)`
|
|
//! and `drop index (<name> | on <T> (<col>, …))` (ADR-0025).
|
|
|
|
use crate::typing_surface::*;
|
|
use rdbms_playground::input_render::InputState;
|
|
|
|
#[test]
|
|
fn after_add_offers_index_branch() {
|
|
let schema = schema_multi_table();
|
|
let a = assess_at_end("add ", &schema);
|
|
assert!(matches!(a.state, InputState::IncompleteAtEof));
|
|
assert_candidate_present(&a, &["index"]);
|
|
crate::snap!("after_add_index_branch", a);
|
|
}
|
|
|
|
#[test]
|
|
fn add_index_after_on_offers_table_names() {
|
|
let schema = schema_multi_table();
|
|
let a = assess_at_end("add index on ", &schema);
|
|
assert!(matches!(a.state, InputState::IncompleteAtEof));
|
|
assert_candidate_present(&a, &["Customers", "Orders"]);
|
|
crate::snap!("add_index_after_on", a);
|
|
}
|
|
|
|
#[test]
|
|
fn add_index_open_paren_narrows_to_table_columns() {
|
|
let schema = schema_multi_table();
|
|
let a = assess_at_end("add index on Orders (", &schema);
|
|
assert!(matches!(a.state, InputState::IncompleteAtEof));
|
|
assert_candidate_present(&a, &["OrderId", "CustId", "Total"]);
|
|
assert_no_candidate_named(&a, &["id", "Name"]);
|
|
crate::snap!("add_index_open_paren", a);
|
|
}
|
|
|
|
#[test]
|
|
fn complete_add_index_parses() {
|
|
let schema = schema_multi_table();
|
|
let a = assess_at_end("add index on Orders (CustId)", &schema);
|
|
assert!(matches!(a.state, InputState::Valid));
|
|
assert_eq!(a.parse_result.as_deref(), Ok("AddIndex"));
|
|
crate::snap!("add_index_complete", a);
|
|
}
|
|
|
|
#[test]
|
|
fn complete_add_index_named_parses() {
|
|
let schema = schema_multi_table();
|
|
let a = assess_at_end("add index as ord_cust on Orders (CustId)", &schema);
|
|
assert!(matches!(a.state, InputState::Valid));
|
|
assert_eq!(a.parse_result.as_deref(), Ok("AddIndex"));
|
|
crate::snap!("add_index_named_complete", a);
|
|
}
|
|
|
|
#[test]
|
|
fn after_drop_offers_index_branch() {
|
|
let schema = schema_multi_table();
|
|
let a = assess_at_end("drop ", &schema);
|
|
assert!(matches!(a.state, InputState::IncompleteAtEof));
|
|
assert_candidate_present(&a, &["index"]);
|
|
crate::snap!("drop_index_branch", a);
|
|
}
|
|
|
|
#[test]
|
|
fn complete_drop_index_by_name_parses() {
|
|
let schema = schema_multi_table();
|
|
let a = assess_at_end("drop index some_idx", &schema);
|
|
assert!(matches!(a.state, InputState::Valid));
|
|
assert_eq!(a.parse_result.as_deref(), Ok("DropIndex"));
|
|
crate::snap!("drop_index_named_complete", a);
|
|
}
|
|
|
|
#[test]
|
|
fn complete_drop_index_by_columns_parses() {
|
|
let schema = schema_multi_table();
|
|
let a = assess_at_end("drop index on Orders (CustId)", &schema);
|
|
assert!(matches!(a.state, InputState::Valid));
|
|
assert_eq!(a.parse_result.as_deref(), Ok("DropIndex"));
|
|
crate::snap!("drop_index_columns_complete", a);
|
|
}
|