ADR-0017 implementation: per-cell type-change with override flags
Replaces the placeholder "trust STRICT" body of do_change_column_type
with the per-cell transformer matrix from ADR-0017. Adds:
- src/type_change.rs: CellOutcome { Clean / Lossy / Incompatible }
+ transform_cell + static_refusal covering every matrix pair
from §3 (54 unit tests).
- --force-conversion and --dont-convert flags on `change column`
(mutually exclusive at parse time per §5).
- Refined PK rule (§4.1): refused only when the column has an
inbound FK and fk_target_type would change. Outbound-FK columns
still refused outright (§4.2). PK / shortid uniqueness checked
post-transformation (§4.3).
- Bordered diagnostic tables (lossy / incompatible / collision)
via the pretty-table renderer (§7) — uses ADR-0016's primitives.
- [client-side] success note (§6) when any cell was rewritten.
- Friendly wrapper for engine-level errors under --dont-convert
so no engine vocabulary leaks (ADR-0002 user-facing posture).
ADR-0017 §3 + §7 amended in place (with user sign-off): serial->int
added explicitly to the always-clean matrix, and diagnostic rows
identify themselves by PK value(s) rather than positional indices
(SQLite returns rows unordered without ORDER BY, so positional
"row 5" is unaddressable).
Tests: 449 -> 517 (+68). Clippy clean with nursery lints.
This commit is contained in:
+22
-5
@@ -63,15 +63,17 @@ pub enum Command {
|
||||
},
|
||||
/// Change a column's type. Implemented via the
|
||||
/// rebuild-table primitive (ADR-0013) since SQLite's
|
||||
/// ALTER TABLE does not support type changes. Refused
|
||||
/// for PK columns and for columns involved in a declared
|
||||
/// relationship — those would require cascading FK
|
||||
/// type updates the v1 surface deliberately doesn't
|
||||
/// expose.
|
||||
/// ALTER TABLE does not support type changes.
|
||||
///
|
||||
/// Per ADR-0017 the actual conversion model is a per-cell
|
||||
/// dry-run against a curated transformer matrix; the two
|
||||
/// optional flags carried in `mode` let the user opt into
|
||||
/// lossy conversions or skip the client-side layer entirely.
|
||||
ChangeColumnType {
|
||||
table: String,
|
||||
column: String,
|
||||
ty: Type,
|
||||
mode: ChangeColumnMode,
|
||||
},
|
||||
/// Establish a 1:n relationship: parent_table.parent_column
|
||||
/// is the primary-key side; child_table.child_column is the
|
||||
@@ -125,6 +127,21 @@ pub enum Command {
|
||||
},
|
||||
}
|
||||
|
||||
/// Conversion mode for `change column …` (ADR-0017 §5).
|
||||
///
|
||||
/// `Default` runs the per-cell dry-run and refuses on lossy or
|
||||
/// incompatible cells. `ForceConversion` accepts lossy cells but
|
||||
/// still refuses incompatibles. `DontConvert` skips the entire
|
||||
/// client-side layer and lets the database's STRICT typing
|
||||
/// decide. `ForceConversion` and `DontConvert` are mutually
|
||||
/// exclusive at the grammar level.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ChangeColumnMode {
|
||||
Default,
|
||||
ForceConversion,
|
||||
DontConvert,
|
||||
}
|
||||
|
||||
/// How an UPDATE / DELETE selects which rows to operate on.
|
||||
/// `Where` is the default safe form. `AllRows` is the explicit
|
||||
/// `--all-rows` flag opt-in for unfiltered operations.
|
||||
|
||||
Reference in New Issue
Block a user