bbc2e34b33
Advanced-only `alter` entry word; ALTER TABLE <T> ADD COLUMN <col> <type> [constraints] | DROP COLUMN <col> | RENAME COLUMN <old> TO <new> -> SqlAlterTable, runtime-decomposed to the existing column executors (do_add_column / do_drop_column / do_rename_column) — one undo step each, no new worker layer. The COLUMN keyword is required (reserves bare RENAME TO for 4h, ADD CONSTRAINT for 4g). - ADD COLUMN takes NOT NULL / UNIQUE / DEFAULT / CHECK (no PK / inline REFERENCES). do_add_column extended to consume the SQL raw-text default_sql / check_sql (sql_expr is validate-only, the 4a.2 mechanism), reaching parity with CREATE TABLE's column constraints. - Drop/rename column refuse a column any CHECK references — table-level AND column-level (incl. a column's own self-check on rename) — the 4a.3 deferral, detected up-front by tokenizing the raw CHECK text (skipping string literals). In the shared executors, so it guards both the simple and SQL surfaces and fixes a latent rename-drift bug that desynced the stored CHECK text and broke rebuild. - SQL DROP COLUMN refuses an index-covered column (no --cascade SQL spelling — matches SQLite + the simple default). - The column executors and do_add_index gained an internal-__rdbms_* guard (refuse as "no such table"), closing a pre-existing exposure on both surfaces. (do_change_column_type / do_add_constraint / do_add_relationship are a tracked follow-up.) - `alter` is advanced-only; AlterTableAction::AddColumn is boxed (clippy::large_enum_variant). Docs: ADR-0035 status + §13 4e; ADR README; requirements.md Q1. Plan: docs/plans/20260525-adr-0035-sql-ddl-4e.md. Tests: 1854 passing / 0 failing / 0 skipped / 1 ignored; clippy clean.
58 lines
1.9 KiB
Rust
58 lines
1.9 KiB
Rust
//! The Playground DSL.
|
|
//!
|
|
//! The DSL is the simplified, beginner-friendly command surface
|
|
//! described in ADR-0003. This module owns its grammar
|
|
//! (`parser`), its abstract syntax tree (`command`), and the
|
|
//! user-facing type vocabulary (`types`).
|
|
//!
|
|
//! Raw SQL handling for advanced mode is intentionally *not* in
|
|
//! this module — that path uses `sqlparser-rs` and lives
|
|
//! elsewhere when it lands.
|
|
|
|
pub mod action;
|
|
pub mod command;
|
|
pub mod grammar;
|
|
pub mod parser;
|
|
pub mod shortid;
|
|
pub mod types;
|
|
pub mod value;
|
|
pub mod walker;
|
|
|
|
pub use action::ReferentialAction;
|
|
pub use command::{
|
|
AlterTableAction, AppCommand, ChangeColumnMode, ColumnSpec, Command, CompareOp, Expr,
|
|
IndexSelector, MessagesValue, ModeValue, Operand, Predicate, RelationshipSelector, RowFilter,
|
|
SqlForeignKey,
|
|
};
|
|
pub use parser::{ParseError, parse_command};
|
|
pub use types::Type;
|
|
pub use value::Value;
|
|
|
|
/// Prefix every echoed DSL command carries in the output
|
|
/// panel — i.e. `[simple] running: <input>` reads as
|
|
/// `[simple]` (tag) + `running: ` (this constant) + the
|
|
/// user's input.
|
|
///
|
|
/// The catalog template `dsl.running` is contracted to equal
|
|
/// `format!("{ECHO_PREFIX}{{input}}")`. The constant lives
|
|
/// in code because the echo-line renderer (ADR-0022 §5)
|
|
/// peels this prefix off and re-tokenises the rest for
|
|
/// highlighting; a unit test (`echo_prefix_matches_catalog_template`)
|
|
/// pins the binding.
|
|
pub const ECHO_PREFIX: &str = "running: ";
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::ECHO_PREFIX;
|
|
|
|
#[test]
|
|
fn echo_prefix_matches_catalog_template() {
|
|
// The catalog template `dsl.running` must produce
|
|
// `<ECHO_PREFIX><input>` so the echo-line renderer can
|
|
// peel the prefix and re-tokenise the rest. A
|
|
// translator changing the prefix breaks this test.
|
|
let rendered = crate::t!("dsl.running", input = "");
|
|
assert_eq!(rendered, ECHO_PREFIX);
|
|
}
|
|
}
|