db: column-constraint infrastructure — NOT NULL / UNIQUE / DEFAULT (ADR-0029)
The database layer now honours the ColumnSpec constraint fields end to end, ahead of the grammar that lets users type them. - `do_create_table` emits ` NOT NULL` / ` UNIQUE` / ` DEFAULT <literal>` per column via the new `column_constraints_sql` helper (the default literal bound against the column's type). - `ReadColumn` gains `default_sql`, read from `pragma_table_info.dflt_value`; `schema_to_ddl` emits it, so the rebuild-table primitive preserves DEFAULT — it already preserved NOT NULL / UNIQUE. - `ColumnDescription` gains `unique` / `default`; `do_describe_table` now sources columns from `read_schema` (one source of per-column truth) and `constraints_display` lists PK / NOT NULL / UNIQUE / DEFAULT. No user-facing change yet — no grammar produces constrained columns. Tests exercise creation, enforcement, describe, and rebuild-preservation programmatically. 1177 tests pass (+5); clippy clean.
This commit is contained in:
+15
-3
@@ -354,12 +354,20 @@ fn type_display(c: &ColumnDescription) -> String {
|
||||
}
|
||||
|
||||
fn constraints_display(c: &ColumnDescription) -> String {
|
||||
let mut parts: Vec<&str> = Vec::new();
|
||||
let mut parts: Vec<String> = Vec::new();
|
||||
if c.primary_key {
|
||||
parts.push("PK");
|
||||
parts.push("PK".to_string());
|
||||
}
|
||||
if c.notnull {
|
||||
parts.push("NOT NULL");
|
||||
parts.push("NOT NULL".to_string());
|
||||
}
|
||||
// ADR-0029: a PK column's implicit uniqueness is already
|
||||
// conveyed by `PK`; `unique` is only set for non-PK columns.
|
||||
if c.unique {
|
||||
parts.push("UNIQUE".to_string());
|
||||
}
|
||||
if let Some(default) = &c.default {
|
||||
parts.push(format!("DEFAULT {default}"));
|
||||
}
|
||||
parts.join(", ")
|
||||
}
|
||||
@@ -511,6 +519,8 @@ mod tests {
|
||||
},
|
||||
notnull,
|
||||
primary_key: pk,
|
||||
unique: false,
|
||||
default: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -978,6 +988,8 @@ mod tests {
|
||||
sqlite_type: "INTEGER".to_string(),
|
||||
notnull: false,
|
||||
primary_key: false,
|
||||
unique: false,
|
||||
default: None,
|
||||
}],
|
||||
outbound_relationships: Vec::new(),
|
||||
inbound_relationships: Vec::new(),
|
||||
|
||||
Reference in New Issue
Block a user