parser: make to and table independently optional in add column
Previously the grammar accepted only `to table` together or neither. The user-stated convention is that bare table identifiers are accepted in unambiguous positions (matching how `add 1:n relationship from <T>.<col> to <T>.<col>` takes bare table names). Both `to` and `table` are now or_not'd independently, so all four combinations parse identically. Updates the in-app `help` listing to advertise the new shape: `add column [to] [table] <T>: <col> (<type>)`. 3 new parser tests cover the variants.
This commit is contained in:
+1
-1
@@ -1108,7 +1108,7 @@ impl App {
|
|||||||
"DSL data commands (in simple mode):",
|
"DSL data commands (in simple mode):",
|
||||||
" create table <T> with pk [<col>:<type>...]",
|
" create table <T> with pk [<col>:<type>...]",
|
||||||
" drop table <T>",
|
" drop table <T>",
|
||||||
" add column [to table] <T>: <col> (<type>)",
|
" add column [to] [table] <T>: <col> (<type>)",
|
||||||
" add 1:n relationship [as <name>] from <P>.<col> to <C>.<col>",
|
" add 1:n relationship [as <name>] from <P>.<col> to <C>.<col>",
|
||||||
" [on delete <action>] [on update <action>] [--create-fk]",
|
" [on delete <action>] [on update <action>] [--create-fk]",
|
||||||
" drop relationship <name>",
|
" drop relationship <name>",
|
||||||
|
|||||||
+51
-6
@@ -129,14 +129,19 @@ fn command_parser<'a>()
|
|||||||
.ignore_then(identifier())
|
.ignore_then(identifier())
|
||||||
.map(|name| Command::DropTable { name });
|
.map(|name| Command::DropTable { name });
|
||||||
|
|
||||||
// `to table` is optional — both `add column to table T: c (text)`
|
// Both `to` and `table` are independently optional —
|
||||||
// and `add column T: c (text)` parse identically.
|
// `add column to table T: c (text)`,
|
||||||
let to_table_optional = keyword_ci("to")
|
// `add column to T: c (text)`,
|
||||||
.ignore_then(keyword_ci("table"))
|
// `add column table T: c (text)`,
|
||||||
.or_not();
|
// and `add column T: c (text)` all parse identically.
|
||||||
|
// Matches the convention elsewhere in the DSL where bare
|
||||||
|
// identifiers are accepted in unambiguous positions.
|
||||||
|
let optional_to = keyword_ci("to").or_not();
|
||||||
|
let optional_table = keyword_ci("table").or_not();
|
||||||
let add_column = keyword_ci("add")
|
let add_column = keyword_ci("add")
|
||||||
.ignore_then(keyword_ci("column"))
|
.ignore_then(keyword_ci("column"))
|
||||||
.ignore_then(to_table_optional)
|
.ignore_then(optional_to)
|
||||||
|
.ignore_then(optional_table)
|
||||||
.ignore_then(identifier())
|
.ignore_then(identifier())
|
||||||
.then_ignore(just(':').padded())
|
.then_ignore(just(':').padded())
|
||||||
.then(identifier())
|
.then(identifier())
|
||||||
@@ -764,6 +769,46 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_column_accepts_bare_table_name() {
|
||||||
|
// `to table` are both optional; bare table identifier
|
||||||
|
// is accepted in this unambiguous position.
|
||||||
|
assert_eq!(
|
||||||
|
ok("add column Customers: Name (text)"),
|
||||||
|
Command::AddColumn {
|
||||||
|
table: "Customers".to_string(),
|
||||||
|
column: "Name".to_string(),
|
||||||
|
ty: Type::Text,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_column_accepts_to_alone() {
|
||||||
|
// `to` without `table`.
|
||||||
|
assert_eq!(
|
||||||
|
ok("add column to Customers: Name (text)"),
|
||||||
|
Command::AddColumn {
|
||||||
|
table: "Customers".to_string(),
|
||||||
|
column: "Name".to_string(),
|
||||||
|
ty: Type::Text,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_column_accepts_table_alone() {
|
||||||
|
// `table` without `to`.
|
||||||
|
assert_eq!(
|
||||||
|
ok("add column table Customers: Name (text)"),
|
||||||
|
Command::AddColumn {
|
||||||
|
table: "Customers".to_string(),
|
||||||
|
column: "Name".to_string(),
|
||||||
|
ty: Type::Text,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_column_tolerates_whitespace_around_punctuation() {
|
fn add_column_tolerates_whitespace_around_punctuation() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
Reference in New Issue
Block a user