feat(types)!: drop the blob column type (ADR-0005 Amendment 2)
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:
+11
-14
@@ -208,13 +208,12 @@ fn e2e_insert_select_cross_table_copies_rows_and_persists_both() {
|
||||
// ===============================================================
|
||||
|
||||
#[test]
|
||||
fn e2e_multirow_insert_all_ten_types_roundtrips_and_returning_recovers_each_type() {
|
||||
fn e2e_multirow_insert_all_nine_types_roundtrips_and_returning_recovers_each_type() {
|
||||
let (project, db, _dir) = open_project_db();
|
||||
let rt = rt();
|
||||
// serial PK + shortid auto-fill; the other eight columns are
|
||||
// user-supplied. `blob` has no value-literal grammar yet
|
||||
// (see src/dsl/value.rs), so it is inserted NULL — its *type*
|
||||
// still round-trips through the RETURNING column-origin path.
|
||||
// serial PK + shortid auto-fill; the other seven columns are
|
||||
// user-supplied. Their *types* round-trip through the RETURNING
|
||||
// column-origin path.
|
||||
create_cols(
|
||||
&db,
|
||||
&rt,
|
||||
@@ -228,7 +227,6 @@ fn e2e_multirow_insert_all_ten_types_roundtrips_and_returning_recovers_each_type
|
||||
("flag", Type::Bool),
|
||||
("d", Type::Date),
|
||||
("ts", Type::DateTime),
|
||||
("bl", Type::Blob),
|
||||
("sid", Type::ShortId),
|
||||
],
|
||||
&["ser"],
|
||||
@@ -237,17 +235,17 @@ fn e2e_multirow_insert_all_ten_types_roundtrips_and_returning_recovers_each_type
|
||||
let result = run_insert(
|
||||
&db,
|
||||
&rt,
|
||||
"insert into allten (txt, i, r, dec, flag, d, ts, bl) values \
|
||||
('hi', 42, 1.5, 9.50, true, '2026-05-23', '2026-05-23 10:00:00', null), \
|
||||
('yo', 7, 2.5, 3.25, false, '2025-01-01', '2025-01-01 00:00:00', null) \
|
||||
returning ser, txt, i, r, dec, flag, d, ts, bl, sid",
|
||||
"insert into allten (txt, i, r, dec, flag, d, ts) values \
|
||||
('hi', 42, 1.5, 9.50, true, '2026-05-23', '2026-05-23 10:00:00'), \
|
||||
('yo', 7, 2.5, 3.25, false, '2025-01-01', '2025-01-01 00:00:00') \
|
||||
returning ser, txt, i, r, dec, flag, d, ts, sid",
|
||||
)
|
||||
.expect("multi-row INSERT … RETURNING runs");
|
||||
|
||||
assert_eq!(result.rows_affected, 2, "two rows inserted");
|
||||
assert_eq!(result.data.rows.len(), 2, "RETURNING yields both rows");
|
||||
|
||||
// Every one of the ten playground types is recovered via the
|
||||
// Every one of the nine playground types is recovered via the
|
||||
// RETURNING column-origin path (matrix R5).
|
||||
assert_eq!(
|
||||
result.data.column_types,
|
||||
@@ -260,10 +258,9 @@ fn e2e_multirow_insert_all_ten_types_roundtrips_and_returning_recovers_each_type
|
||||
Some(Type::Bool),
|
||||
Some(Type::Date),
|
||||
Some(Type::DateTime),
|
||||
Some(Type::Blob),
|
||||
Some(Type::ShortId),
|
||||
],
|
||||
"RETURNING recovers each of the ten playground types; got {:?}",
|
||||
"RETURNING recovers each of the nine playground types; got {:?}",
|
||||
result.data.column_types,
|
||||
);
|
||||
|
||||
@@ -281,7 +278,7 @@ fn e2e_multirow_insert_all_ten_types_roundtrips_and_returning_recovers_each_type
|
||||
"dates round-trip: {csv:?}"
|
||||
);
|
||||
|
||||
let sids: Vec<&str> = rows.iter().filter_map(|r| r[9].as_deref()).collect();
|
||||
let sids: Vec<&str> = rows.iter().filter_map(|r| r[8].as_deref()).collect();
|
||||
assert_eq!(sids.len(), 2, "both shortids present");
|
||||
assert!(
|
||||
sids.iter().all(|s| !s.is_empty()),
|
||||
|
||||
Reference in New Issue
Block a user