diff --git a/src/app.rs b/src/app.rs index b015b0e..fd296cf 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1108,7 +1108,7 @@ impl App { "DSL data commands (in simple mode):", " create table with pk [:...]", " drop table ", - " add column [to table] : ()", + " add column [to] [table] : ()", " add 1:n relationship [as ] from

. to .", " [on delete ] [on update ] [--create-fk]", " drop relationship ", diff --git a/src/dsl/parser.rs b/src/dsl/parser.rs index 8f13482..bbba41d 100644 --- a/src/dsl/parser.rs +++ b/src/dsl/parser.rs @@ -129,14 +129,19 @@ fn command_parser<'a>() .ignore_then(identifier()) .map(|name| Command::DropTable { name }); - // `to table` is optional — both `add column to table T: c (text)` - // and `add column T: c (text)` parse identically. - let to_table_optional = keyword_ci("to") - .ignore_then(keyword_ci("table")) - .or_not(); + // Both `to` and `table` are independently optional — + // `add column to table T: c (text)`, + // `add column to T: c (text)`, + // `add column table T: c (text)`, + // 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") .ignore_then(keyword_ci("column")) - .ignore_then(to_table_optional) + .ignore_then(optional_to) + .ignore_then(optional_table) .ignore_then(identifier()) .then_ignore(just(':').padded()) .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] fn add_column_tolerates_whitespace_around_punctuation() { assert_eq!(