Summary
extractChanges() checks affectedRows (MySQL), then res.count, then Array.isArray → res.length. For a Postgres UPDATE/DELETE via Bun.sql.unsafe (no RETURNING), the result is typically an empty array, so res.length === 0 and the function returns 0 even when rows were affected. That makes ModelQueryBuilder.update()/delete(), destroy(), and BelongsToManyRelationBuilder.detach()/updateExistingPivot() report 0/false despite succeeding.
Status
Suspected — derived from code + Bun result-shape reasoning; not yet reproduced against a live Postgres (no server in the audit sandbox). Needs confirmation of Bun's non-RETURNING command-tag shape.
Location
src/orm.ts:~355 (extractChanges) and ~424.
Suggested fix
Read the Postgres command-tag affected-row count (Bun exposes it on the result object, not as array length) and prefer it over length.
Severity: medium. Found via internal code audit.