Repository navigation
Commit c8806ae
fix(driver-sql): refuse an unbacked upsert conflict target on MySQL before compiling (#8761)
* fix(driver-sql): refuse an unbacked upsert conflict target on MySQL before compiling (#8621)
SQLite and Postgres already refuse a `conflictKeys` upsert whose target no
PRIMARY KEY or UNIQUE index backs: the server cannot infer an arbiter index and
raises, and `isUnbackedConflictTargetError` turns that into a VALIDATION_ERROR /
400. On MySQL the same call resolved. knex compiles `onConflict(...).merge(...)`
to `ON DUPLICATE KEY UPDATE`, which takes no conflict target at all, so the
named keys are dropped before the statement leaves the process and the server is
never asked to find an index for them. The reactive catch has nothing to catch.
Measured on live MySQL 8.0.46 (`email` unnamed by any index, `tax_id` carrying
the only unique key): the call merged on `tax_id`, across two different `email`
values, and separately left two rows sharing the `email` the caller had asked to
merge on. A wrong write, with no error.
`upsert` now consults the table's physical PRIMARY KEY and UNIQUE indexes before
compiling on MySQL and refuses with the wording, `code` and `status` the other
two dialects already answer (#5240 -- one condition, one wording). It runs on
MySQL alone by design: SQLite and Postgres refuse this from the server, with the
server's own sentence attached as `cause`, and no pre-flight can reconstruct
that. Only what can be PROVEN unbacked is refused -- a failed introspection, a
table reporting no keys at all, and a possibly stale cache all proceed, the last
after a fresh re-read.
Not closed by this change, and filed as #8755: `ON DUPLICATE KEY UPDATE` carries
no target even when the named one IS backed, so a second unique index can still
absorb the conflict on MySQL.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeQRiAa7vYRVX5Fog7Zby8
* docs(changeset): driver-sql minor — MySQL upsert accept-set narrowing (#8621)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XeQRiAa7vYRVX5Fog7Zby8
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent e783e16 commit c8806ae
3 files changed
Lines changed: 538 additions & 81 deletions
File tree
- .changeset
- packages/drivers/driver-sql/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
0 commit comments