Commit de96cf4
fix(driver-memory): bulkUpdate's touched-row set must agree with its own id resolution (#13917)
* fix(driver-memory): bulkUpdate's touched-row set must agree with its own id resolution
`bulkUpdate` resolved each id with a loose `==` (matching `update`, one
method up) but built its untouched-row set `settled` from the CALLER's ids
with a strict `Set.has`. `IDataDriver.bulkUpdate` declares
`id: string | number`, so a caller may name a stored `1` as `'1'` — and then
the two lookups disagreed: `findIndex` resolved the row and updated it, while
`settled` still carried that row's PRE-image. The row was represented twice
in the projected set handed to `assertUnique` — once with the value it was
vacating, once with the value it was taking — so a batch that merely HANDS a
unique value from one row to another was refused with a false
`UNIQUE_VIOLATION` / 409. `exceptId` does not help, since it only excludes
the row currently being checked, never a sibling row of the same batch.
Resolve every id to its table index first, then derive the touched set from
the RESOLVED rows' own ids. Both lookups now read the same stored value and
cannot drift apart — the property `updateMany` gets for free by drawing its
`targetIds` from table rows. The loose resolution is deliberately preserved:
narrowing it to `===` would silently change which ids resolve at all, well
beyond this defect.
`bulkDelete` needs no change, and this is checked rather than assumed: it has
exactly ONE id comparison, and dedups on the RESOLVED table index rather than
on caller input, so a mixed-type or repeated id collapses to one index by
construction. Keying that set on caller ids instead would splice one index
twice and take a neighbouring row with it — pinned by test.
Regression test uses mixed id types, alongside a positive control with
consistent id types so it cannot pass vacuously.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3jdziLbAPGeceVNmSox5L
* docs(driver-memory): cite the issue this fix closes, not the PR that introduced the defect
Neighbouring comments in this file cite the ISSUE (`[#13435]`, `[#13197]`,
`[#13340]`); this one cited #13875, which is the PR that introduced the
defect. Comment text only — no behaviour change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3jdziLbAPGeceVNmSox5L
* test(driver-memory): cite the issue the new block pins, matching the rest of the file
Comment and describe-title text only — no assertion changes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F3jdziLbAPGeceVNmSox5L
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent cce0aa9 commit de96cf4
3 files changed
Lines changed: 157 additions & 3 deletions
File tree
- .changeset
- packages/drivers/driver-memory/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 | + | |
Lines changed: 106 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
328 | 328 | | |
329 | 329 | | |
330 | 330 | | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
907 | 907 | | |
908 | 908 | | |
909 | 909 | | |
910 | | - | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
| 916 | + | |
| 917 | + | |
| 918 | + | |
| 919 | + | |
| 920 | + | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
911 | 927 | | |
912 | 928 | | |
913 | 929 | | |
914 | 930 | | |
915 | 931 | | |
916 | | - | |
917 | | - | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
918 | 937 | | |
919 | 938 | | |
920 | 939 | | |
| |||
0 commit comments