create table: column constraints — NOT NULL / UNIQUE / DEFAULT grammar (ADR-0029)
`create table … with pk` now parses the column-constraint suffix; combined with the commit-1 db layer, a constrained table works end to end. - A shared constraint-suffix grammar fragment — `not null`, `unique`, `default <literal>` — sits after each column's `(type)` group; `build_create_table` walks the matched path per column and folds the constraints into `ColumnSpec`. - §9 redundancy check: every `with pk` column is a primary-key column, so `not null` (any) and `unique` (single-column PK) are rejected with a friendly error (`parse.custom.constraint_redundant_on_pk`). - `project.yaml` round-trip: `ColumnSchema` gains `not_null` / `default`; the YAML reader/writer and `build_read_schema` carry them, so `rebuild` / `export` / `import` preserve constraints. - ADR-0029 §2.1's example corrected — `create table` columns are all PK columns, so its suffix is for `default` / `check`; `docs/simple-mode-limitations.md` records that non-PK columns at create time need advanced mode. CHECK is deferred to the next commit. 1184 tests pass (+7); clippy clean.
This commit is contained in:
@@ -1610,6 +1610,8 @@ fn read_schema_snapshot(conn: &Connection) -> Result<SchemaSnapshot, DbError> {
|
||||
.map(|c| ColumnSchema {
|
||||
name: c.name.clone(),
|
||||
unique: c.unique,
|
||||
not_null: c.notnull,
|
||||
default: c.default_sql.clone(),
|
||||
// user_type is always populated for tables we
|
||||
// created; the fallback is defensive.
|
||||
user_type: c.user_type.unwrap_or(Type::Text),
|
||||
@@ -1703,6 +1705,8 @@ fn read_table_snapshot(
|
||||
name: c.name.clone(),
|
||||
user_type: c.user_type.unwrap_or(Type::Text),
|
||||
unique: c.unique,
|
||||
not_null: c.notnull,
|
||||
default: c.default_sql.clone(),
|
||||
})
|
||||
.collect();
|
||||
let column_idents: Vec<String> = read
|
||||
@@ -5361,10 +5365,10 @@ fn build_read_schema(table: &TableSchema, relationships: &[RelationshipSchema])
|
||||
.map(|c| ReadColumn {
|
||||
name: c.name.clone(),
|
||||
sqlite_type: c.user_type.sqlite_strict_type().to_string(),
|
||||
notnull: false,
|
||||
notnull: c.not_null,
|
||||
primary_key: table.primary_key.contains(&c.name),
|
||||
unique: c.unique,
|
||||
default_sql: None,
|
||||
default_sql: c.default.clone(),
|
||||
user_type: Some(c.user_type),
|
||||
})
|
||||
.collect();
|
||||
|
||||
Reference in New Issue
Block a user