Skip to content

[finding] An UNDECLARED signature/qrcode column on a pre-existing table stays varchar(255) and no drift op reports it — the #11875 repair reaches new tables only #12121

Description

@os-warren

Filed by the domain:engine PM seat while reviewing PR #12119 (#11875). ⛔ Not a defect in that PR, and not a reason to hold it#12119 strictly improves the situation and declares this boundary honestly in its own changeset. Recorded so the remaining half is not rediscovered as a surprise.

What #11875 fixes, and where it stops

After #12119, signature / qrcode are in the TEXT family, so a newly created column holds a data URI correctly. The changeset states the boundary in as many words:

Nothing about existing tables changes — createColumn runs on CREATE TABLE and ALTER TABLE ADD COLUMN, so the column it sizes is always empty; a pre-existing signature / qrcode column stays varchar(255) until an operator migrates it, and the additive sync never rewrites a column's type on its own.

That is correct and is standard additive-sync behaviour. The part not stated is what the drift reporter does about it.

The measurement

packages/drivers/driver-sql/src/schema-drift.ts, the varchar differ. declaredMaxLength !== undefined is a required condition of the whole branch:

constdeclaredMaxLength=typeoffield.maxLength==='number'&&Number.isInteger(field.maxLength)&&field.maxLength>0
? field.maxLength
: undefined;if(enforcesVarcharLength(dialect)&&!declaresJsonColumn&&declaredMaxLength!==undefined&&// <-- the gateisCharacterColumn(col.type)&&typeofcol.maxLength==='number'&&declaredMaxLength!==col.maxLength){widen_varchar/narrow_varchar}

⇒ Split by whether the author declared a bound, on a pre-existing table:

declarationphysical columndrift saysoutcome
Field.signature({ maxLength: 4096 })varchar(255)widen_varchar, severity warning, category safe"metadata allows 4096 chars but the column caps at 255 — widen via os migrate"✅ reported, remedy exists
Field.signature()no boundvarchar(255)nothing — no number on the declared side to compare⛔ silent

The second row is the common case (the card's own motivating example is field-zoo writing a data-URI PNG into a plain signature), and it is the same declared ≠ enforced shape the whole #11374 / #11431 / #11875 family exists to close — arriving one door further along, at the migration seam rather than the authoring or write seam.

Scope of harm: an existing deployment upgrading to the release carrying #11875 sees no change and no diagnostic for these columns. A 1000-character data URI is still refused by the server (22001 / ER_DATA_TOO_LONG) exactly as the card measured, and nothing anywhere says why the fix did not reach them.

Not claimed

Refs

#11875 (the ruling) · PR #12119 · #11794 (the invariant) · #11374 / #11431 (the family) · #11722 (a neighbouring applyMigrationEntries reporting gap, currently in flight)

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions