feat(types)!: drop the blob column type (ADR-0005 Amendment 2)
ci / gate (push) Failing after 35s
ci / manifests (push) Successful in 3s
website / deploy (push) Successful in 35s

blob was a dead-end: declarable but never fillable (no literal in either
mode, seed-unsupported), so a blob column could only ever hold NULL. Remove
Type::Blob + Value/CellValue::Blob + the base64 CSV path + the grammar slot
+ completion/render/type-change/seed handling + the binder refusal (whose
message also carried a user-facing "DSL" copy-rule bug). The vocabulary is
now nine types; base64 stays (clipboard OSC-52).

Backward compat is the ADR-0015 migration framework's first real use: a
v1->v2 format bump (CURRENT_SCHEMA_VERSION across serializer/parser/skeleton)
with a migrator that rewrites `type: blob` -> `type: text`, and a forced .db
rebuild from the migrated text when a blob column was actually converted
(the stale .db keeps a STRICT BLOB engine column). Conversion to text is
non-destructive and CSV-free. Covered by a full-stack integration test and a
Tier-4 PTY test that opens a real legacy v1-blob project.

Also sweeps the nine-type vocabulary through CLAUDE.md, requirements.md, the
website (type reference, seed doc, highlight grammar), and the ADR-0030/0033/
0035 cross-references; CHANGELOG Removed entry; handoff-79.

BREAKING CHANGE: the `blob` column type is removed. Existing projects that
declared a blob column are migrated on first open (the column becomes text;
the original project.yaml is kept as a .v1.bak).
This commit is contained in:
claude@clouddev1
2026-06-22 21:25:38 +00:00
parent 1a2002dbf6
commit 6b4c4dcea4
41 changed files with 506 additions and 390 deletions
+1 -7
View File
@@ -263,11 +263,6 @@ const DATETIME_SLOT: Node = Node::TypedValueSlot {
column_name: None,
inner: &TEXT_SLOT_INNER,
};
const BLOB_SLOT: Node = Node::TypedValueSlot {
ty: Type::Blob,
column_name: None,
inner: &TEXT_SLOT_INNER,
};
// shortid columns store base58 text (ADR-0011 fk_target_type
// shortid → text); the slot accepts a quoted-text literal or
// null.
@@ -297,7 +292,6 @@ pub const fn slot_for_type(ty: Type) -> Node {
Type::Text => TEXT_SLOT,
Type::Date => DATE_SLOT,
Type::DateTime => DATETIME_SLOT,
Type::Blob => BLOB_SLOT,
}
}
@@ -310,7 +304,7 @@ const fn slot_inner_for_type(ty: Type) -> &'static Node {
Type::Real => &REAL_SLOT_INNER,
Type::Decimal => &DECIMAL_SLOT_INNER,
Type::Bool => &BOOL_SLOT_INNER,
Type::Text | Type::Date | Type::DateTime | Type::Blob | Type::ShortId => &TEXT_SLOT_INNER,
Type::Text | Type::Date | Type::DateTime | Type::ShortId => &TEXT_SLOT_INNER,
}
}
+2 -3
View File
@@ -567,7 +567,7 @@ mod tests {
fn standard_sql_type_aliases() {
good("table t (a integer, b varchar, c boolean, d timestamp)");
good("table t (e bigint, f smallint, g char, h numeric)");
good("table t (i binary, j varbinary, k float)");
good("table t (k float)");
}
#[test]
@@ -734,7 +734,7 @@ mod builder_tests {
fn standard_sql_aliases_map_to_playground_types() {
let (_, cols, _, _) = sct(
"create table t (a bigint, b varchar, c boolean, d timestamp, \
e numeric, f float, g binary)",
e numeric, f float)",
);
assert_eq!(
cols,
@@ -745,7 +745,6 @@ mod builder_tests {
("d".to_string(), Type::DateTime),
("e".to_string(), Type::Decimal),
("f".to_string(), Type::Real),
("g".to_string(), Type::Blob),
]
);
}