Grammar: with-pk column specs use name(type), matching add column

`create table … with pk` parsed column types as `name:type`,
while `add column` uses `name(type)`. Unify on the parens
form so column-type syntax is consistent across the DSL:

    create table T with pk id(serial), name(text)

Only `COL_SPEC` changes (`:` → `( … )`); `build_create_table`
reads columns by role, so it is unaffected. The `:` that
separates table from column in `add column` / `drop column`
is unchanged. Sweeps the test suite, the typing-surface
matrix (two `after_colon` cells renamed to `after_paren`,
4 snapshots regenerated), the friendly catalog's usage
templates, ADR-0009's example, and requirements.md.

1039 passing / 0 failing / 1 ignored; clippy clean.
This commit is contained in:
claude@clouddev1
2026-05-18 21:51:52 +00:00
parent 9aa7e2ede0
commit d9a98bbd49
20 changed files with 68 additions and 67 deletions
+9 -9
View File
@@ -95,7 +95,7 @@ fn replay_three_lines_dispatches_three_commands() {
write_script(
project.path(),
"seed.commands",
"create table T with pk id:int\n\
"create table T with pk id(int)\n\
add column T: name (text)\n\
insert into T (1, 'Alice')\n",
);
@@ -122,7 +122,7 @@ fn replay_skips_blank_lines_and_comments() {
"seed.commands",
"# this is a comment\n\
\n\
create table T with pk id:int\n\
create table T with pk id(int)\n\
\n\
# another comment\n\
# comment with leading whitespace\n\
@@ -192,7 +192,7 @@ fn replay_aborts_on_first_parse_failure_and_reports_line() {
"bad.commands",
// Line 1: ok. Line 2: ok. Line 3: parse error
// (`broken keyword X` — not a recognised command).
"create table T with pk id:int\n\
"create table T with pk id(int)\n\
add column T: name (text)\n\
this is not a command\n\
insert into T (1, 'should not happen')\n",
@@ -248,7 +248,7 @@ fn replay_rejects_typed_slot_violation_at_parse_time() {
write_script(
project.path(),
"typed.commands",
"create table T with pk id:int\n\
"create table T with pk id(int)\n\
add column T: count (int)\n\
insert into T values (1, 'not a number')\n",
);
@@ -285,7 +285,7 @@ fn replay_aborts_on_first_runtime_failure_and_reports_line() {
"bad.commands",
// Line 2 references a table that doesn't exist; the
// engine refuses, replay stops and reports line 2.
"create table T with pk id:int\n\
"create table T with pk id(int)\n\
add column NotATable: x (text)\n\
insert into T (1)\n",
);
@@ -300,11 +300,11 @@ fn replay_aborts_on_first_runtime_failure_and_reports_line() {
fn replay_refuses_nested_replay() {
let data = tempdir();
let (project, db) = open_project_db(data.path());
write_script(project.path(), "inner.commands", "create table T with pk id:int\n");
write_script(project.path(), "inner.commands", "create table T with pk id(int)\n");
write_script(
project.path(),
"outer.commands",
"create table U with pk id:int\nreplay inner.commands\n",
"create table U with pk id(int)\nreplay inner.commands\n",
);
let events = rt().block_on(async {
@@ -332,7 +332,7 @@ fn replay_history_log_records_subcommands_only() {
write_script(
project.path(),
"seed.commands",
"create table T with pk id:int\nadd column T: name (text)\n",
"create table T with pk id(int)\nadd column T: name (text)\n",
);
let events = rt().block_on(async {
@@ -344,7 +344,7 @@ fn replay_history_log_records_subcommands_only() {
.expect("history.log exists");
// Per-command entries landed.
assert!(
history.lines().any(|l| l.contains("create table T with pk id:int")),
history.lines().any(|l| l.contains("create table T with pk id(int)")),
"history.log missing create line:\n{history}"
);
assert!(