Commit 7d1ff75
* fix(driver-sql): re-seed a stale autonumber counter instead of burning a number per failed create (#5495)
The counter bootstraps from the data-table MAX exactly once, in
`getNextSequenceValue`'s `if (!existing)` branch; afterwards the data table is
never consulted again. Any row landing by a path that bypasses
`fillAutoNumberFields` — an `isSystem` seed replay, a `preserveAudit` import,
or direct SQL — never raises the sequence, so once it sits below MAX it is
permanently behind and every create collides, burns a number and fails the
request until it has ground past the seeded range one 409 at a time.
Measured on main @ 86e6f6c with the counter seeded at 10 and rows 11-39 landed
by a bypass path: 29 caller-visible 409s before a create succeeded at
CASE-00040 on attempt 30. Now: CASE-00040 on the caller's first attempt.
`create()` re-seeds from MAX and retries (bounded) only when it can prove the
collision was that counter's. The proof cannot be the conflicting column:
`uniqueViolationColumn()` refuses composites, and ADR-0120 D3 makes the
tenanted index an expression composite on which SQLite names only the index —
so on this path the column is never determinable. All three of that export's
states are handled explicitly; the indeterminate one is decided from the data
(does the generated value already exist in this tenant partition?), never by a
hand-written dialect word-list.
Retry is confined to the no-caller-transaction case: inside a caller's
transaction the sequence UPDATE rolls back with the INSERT, so nothing is
burned, and on Postgres the transaction is aborted anyway.
The "gaps are tolerated by design" docstring is reconciled with the change
rather than left to contradict it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015XLbsWE5G58ybd1Leq6bNg
* test(driver-sql): pin the three-state collision routing on Postgres and MySQL shapes (#5495)
The SQLite tests cover the path end to end, but SQLite is the one dialect
where the decision is easy. Postgres names a column in its DETAIL line
(state 1/2) or a composite (state 3); MySQL names only an index and so can
only ever reach state 3 — which means on MySQL the data probe is not a
fallback, it is the whole mechanism.
This package's unit suite boots SQLite only, so the shapes are injected
rather than driven through live servers — same method and same reason as
sql-driver-unique-violation-predicate.test.ts. The state-2 case asserts the
part that matters most: a named column that is not ours ends the matter
WITHOUT probing, even when the probe would have said yes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015XLbsWE5G58ybd1Leq6bNg
---------
Co-authored-by: os-dev <steve@objectstack.ai>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
1 parent 68feaad commit 7d1ff75
5 files changed
Lines changed: 815 additions & 14 deletions
File tree
- .changeset
- packages/drivers
- driver-sqlite-wasm/src
- driver-sql/src
- driver-turso/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 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
0 commit comments