@quereus/store 4.5.0 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +34 -6
  2. package/dist/src/common/encoding.d.ts +4 -3
  3. package/dist/src/common/encoding.d.ts.map +1 -1
  4. package/dist/src/common/encoding.js +17 -13
  5. package/dist/src/common/encoding.js.map +1 -1
  6. package/dist/src/common/events.d.ts +31 -25
  7. package/dist/src/common/events.d.ts.map +1 -1
  8. package/dist/src/common/events.js +38 -39
  9. package/dist/src/common/events.js.map +1 -1
  10. package/dist/src/common/implicit-unique-index.d.ts +80 -0
  11. package/dist/src/common/implicit-unique-index.d.ts.map +1 -0
  12. package/dist/src/common/implicit-unique-index.js +148 -0
  13. package/dist/src/common/implicit-unique-index.js.map +1 -0
  14. package/dist/src/common/index.d.ts +7 -3
  15. package/dist/src/common/index.d.ts.map +1 -1
  16. package/dist/src/common/index.js +5 -2
  17. package/dist/src/common/index.js.map +1 -1
  18. package/dist/src/common/json-key.d.ts +30 -2
  19. package/dist/src/common/json-key.d.ts.map +1 -1
  20. package/dist/src/common/json-key.js +49 -2
  21. package/dist/src/common/json-key.js.map +1 -1
  22. package/dist/src/common/key-builder.d.ts +40 -20
  23. package/dist/src/common/key-builder.d.ts.map +1 -1
  24. package/dist/src/common/key-builder.js +31 -23
  25. package/dist/src/common/key-builder.js.map +1 -1
  26. package/dist/src/common/kv-store.d.ts +10 -0
  27. package/dist/src/common/kv-store.d.ts.map +1 -1
  28. package/dist/src/common/pk-key-resolution.d.ts +348 -0
  29. package/dist/src/common/pk-key-resolution.d.ts.map +1 -0
  30. package/dist/src/common/pk-key-resolution.js +481 -0
  31. package/dist/src/common/pk-key-resolution.js.map +1 -0
  32. package/dist/src/common/store-module-access-plan.d.ts +32 -0
  33. package/dist/src/common/store-module-access-plan.d.ts.map +1 -0
  34. package/dist/src/common/store-module-access-plan.js +428 -0
  35. package/dist/src/common/store-module-access-plan.js.map +1 -0
  36. package/dist/src/common/store-module-alter-column.d.ts +23 -0
  37. package/dist/src/common/store-module-alter-column.d.ts.map +1 -0
  38. package/dist/src/common/store-module-alter-column.js +389 -0
  39. package/dist/src/common/store-module-alter-column.js.map +1 -0
  40. package/dist/src/common/store-module-alter.d.ts +55 -0
  41. package/dist/src/common/store-module-alter.d.ts.map +1 -0
  42. package/dist/src/common/store-module-alter.js +504 -0
  43. package/dist/src/common/store-module-alter.js.map +1 -0
  44. package/dist/src/common/store-module-base.d.ts +268 -0
  45. package/dist/src/common/store-module-base.d.ts.map +1 -0
  46. package/dist/src/common/store-module-base.js +362 -0
  47. package/dist/src/common/store-module-base.js.map +1 -0
  48. package/dist/src/common/store-module-catalog.d.ts +269 -0
  49. package/dist/src/common/store-module-catalog.d.ts.map +1 -0
  50. package/dist/src/common/store-module-catalog.js +462 -0
  51. package/dist/src/common/store-module-catalog.js.map +1 -0
  52. package/dist/src/common/store-module-index-build.d.ts +88 -0
  53. package/dist/src/common/store-module-index-build.d.ts.map +1 -0
  54. package/dist/src/common/store-module-index-build.js +280 -0
  55. package/dist/src/common/store-module-index-build.js.map +1 -0
  56. package/dist/src/common/store-module-index.d.ts +116 -0
  57. package/dist/src/common/store-module-index.d.ts.map +1 -0
  58. package/dist/src/common/store-module-index.js +373 -0
  59. package/dist/src/common/store-module-index.js.map +1 -0
  60. package/dist/src/common/store-module-rename.d.ts +49 -0
  61. package/dist/src/common/store-module-rename.d.ts.map +1 -0
  62. package/dist/src/common/store-module-rename.js +268 -0
  63. package/dist/src/common/store-module-rename.js.map +1 -0
  64. package/dist/src/common/store-module-schema-rewrite.d.ts +57 -0
  65. package/dist/src/common/store-module-schema-rewrite.d.ts.map +1 -0
  66. package/dist/src/common/store-module-schema-rewrite.js +140 -0
  67. package/dist/src/common/store-module-schema-rewrite.js.map +1 -0
  68. package/dist/src/common/store-module-schema-sync.d.ts +232 -0
  69. package/dist/src/common/store-module-schema-sync.d.ts.map +1 -0
  70. package/dist/src/common/store-module-schema-sync.js +529 -0
  71. package/dist/src/common/store-module-schema-sync.js.map +1 -0
  72. package/dist/src/common/store-module.d.ts +43 -909
  73. package/dist/src/common/store-module.d.ts.map +1 -1
  74. package/dist/src/common/store-module.js +184 -3276
  75. package/dist/src/common/store-module.js.map +1 -1
  76. package/dist/src/common/store-table-base.d.ts +539 -0
  77. package/dist/src/common/store-table-base.d.ts.map +1 -0
  78. package/dist/src/common/store-table-base.js +900 -0
  79. package/dist/src/common/store-table-base.js.map +1 -0
  80. package/dist/src/common/store-table-constraints.d.ts +237 -0
  81. package/dist/src/common/store-table-constraints.d.ts.map +1 -0
  82. package/dist/src/common/store-table-constraints.js +624 -0
  83. package/dist/src/common/store-table-constraints.js.map +1 -0
  84. package/dist/src/common/store-table-scan.d.ts +452 -0
  85. package/dist/src/common/store-table-scan.d.ts.map +1 -0
  86. package/dist/src/common/store-table-scan.js +901 -0
  87. package/dist/src/common/store-table-scan.js.map +1 -0
  88. package/dist/src/common/store-table.d.ts +71 -1144
  89. package/dist/src/common/store-table.d.ts.map +1 -1
  90. package/dist/src/common/store-table.js +168 -2385
  91. package/dist/src/common/store-table.js.map +1 -1
  92. package/dist/src/testing/index.d.ts +12 -0
  93. package/dist/src/testing/index.d.ts.map +1 -0
  94. package/dist/src/testing/index.js +12 -0
  95. package/dist/src/testing/index.js.map +1 -0
  96. package/dist/src/testing/kv-assert.d.ts +19 -0
  97. package/dist/src/testing/kv-assert.d.ts.map +1 -0
  98. package/dist/src/testing/kv-assert.js +25 -0
  99. package/dist/src/testing/kv-assert.js.map +1 -0
  100. package/dist/src/testing/kv-conformance.d.ts.map +1 -1
  101. package/dist/src/testing/kv-conformance.js +1 -15
  102. package/dist/src/testing/kv-conformance.js.map +1 -1
  103. package/dist/src/testing/kv-provider-conformance.d.ts +54 -0
  104. package/dist/src/testing/kv-provider-conformance.d.ts.map +1 -0
  105. package/dist/src/testing/kv-provider-conformance.js +183 -0
  106. package/dist/src/testing/kv-provider-conformance.js.map +1 -0
  107. package/package.json +8 -8
@@ -0,0 +1,624 @@
1
+ /**
2
+ * Secondary-index maintenance and UNIQUE enforcement for the KVStore-backed
3
+ * virtual table — the two halves of keeping a table's indexes and uniqueness
4
+ * invariants true across a write. Index upkeep is how UNIQUE is enforced (a
5
+ * conflict is answered by a seek when an index soundly covers the constraint's
6
+ * enforcement collations, and by a data-store scan otherwise), and a REPLACE
7
+ * eviction needs both.
8
+ *
9
+ * Third layer of the store-table chain:
10
+ * StoreTableBase -> StoreTableScan -> StoreTableConstraints -> StoreTable
11
+ */
12
+ import { ConflictResolution, compareSqlValues, resolveUniqueEnforcementCollations, uniqueEnforcementComparators, compilePredicate, maintainedTableUniqueViolationError, uniqueEnforcementCollations, } from '@quereus/quereus';
13
+ import { bytesToHex } from './bytes.js';
14
+ import { buildIndexKey, buildIndexPrefixBounds, buildFullScanBounds, } from './key-builder.js';
15
+ import { deserializeRow, } from './serialization.js';
16
+ import { columnCanHoldText, resolveIndexKeyCollations, resolveIndexKeyTransforms } from './pk-key-resolution.js';
17
+ import { implicitUniqueIndexName } from './implicit-unique-index.js';
18
+ import { StoreTableScan } from './store-table-scan.js';
19
+ /**
20
+ * Returned by {@link StoreTableConstraints.findUniqueConflictViaIndex} when the index
21
+ * cannot soundly answer the check and the caller must fall back to the full
22
+ * data-store scan. Distinct from `null`, which means "the index answered: no
23
+ * conflict".
24
+ */
25
+ const INDEX_UNUSABLE = Symbol('store.uniqueIndexUnusable');
26
+ /**
27
+ * Index-maintenance and UNIQUE-enforcement layer of the generic KVStore-backed
28
+ * virtual table.
29
+ *
30
+ * Conflict detection compares under the constraint's ENFORCEMENT collations,
31
+ * which need not match the collations the index keys under — every index-seek
32
+ * shortcut here is gated on that agreement and falls back to the data-store scan
33
+ * when it cannot be shown.
34
+ */
35
+ export class StoreTableConstraints extends StoreTableScan {
36
+ // Lazy cache of compiled partial-UNIQUE predicates. Keyed on the
37
+ // UniqueConstraintSchema object identity — UC schemas are frozen and a
38
+ // new constraint object after CREATE/DROP INDEX produces a fresh compile;
39
+ // the WeakMap lets the GC reclaim entries for retired constraints.
40
+ predicateCache = new WeakMap();
41
+ // Lazy cache of compiled partial-index predicates, keyed on the IndexSchema
42
+ // object identity (frozen; a CREATE/DROP INDEX or reopen produces a fresh
43
+ // object, so the WeakMap reclaims retired entries). Mirrors predicateCache but
44
+ // for secondary-index maintenance rather than UNIQUE enforcement.
45
+ indexPredicateCache = new WeakMap();
46
+ /**
47
+ * Update secondary indexes after a row change.
48
+ *
49
+ * For PK-change UPDATE, `oldPk` (where the existing entry lives) and `newPk`
50
+ * (where the relocated entry will live) differ; using a single pk for both
51
+ * sides leaks the old entry. Other paths pass the same pk for both.
52
+ */
53
+ async updateSecondaryIndexes(inTransaction, oldRow, newRow, oldPk, newPk = oldPk) {
54
+ // Maintain the MATERIALIZED index set: the hidden `_uc_*` per-UNIQUE index must be
55
+ // kept in step with DML so the enforcement seek finds every live row.
56
+ const indexes = this.materializedSchema.indexes || [];
57
+ for (const index of indexes) {
58
+ const indexStore = await this.ensureIndexStore(index.name);
59
+ const indexCols = index.columns.map(c => c.index);
60
+ const indexDirections = index.columns.map(c => !!c.desc);
61
+ // Canonicalize semantic-ordering index members ('PT1H'/'PT60M' → one key) so a
62
+ // UNIQUE enforcement seek and delete-then-insert maintenance address one entry.
63
+ const indexTransforms = resolveIndexKeyTransforms(index, this.tableSchema.columns);
64
+ // Each index column keys under its OWN collation (index COLLATE ?? table column
65
+ // collation ?? BINARY) — the same resolution `buildIndexEntries` uses for the
66
+ // build/rebuild path; the two MUST agree or a maintenance delete misses the
67
+ // entry the build wrote and the index silently rots.
68
+ const indexCollations = resolveIndexKeyCollations(index, this.tableSchema.columns);
69
+ // Partial index: only rows the predicate unambiguously accepts are
70
+ // indexed (mirrors buildIndexEntries' build-time filtering). Guarding both
71
+ // halves keeps a row that transitions across the predicate scope on UPDATE
72
+ // correct — an in-scope→out-of-scope edit removes the old entry and adds
73
+ // none; the reverse adds without a stale delete. A full index (no
74
+ // predicate) always maintains its entry.
75
+ const predicate = this.compileIndexFor(index);
76
+ // Remove old index entry (only if the old row was within scope).
77
+ if (oldRow && (!predicate || predicate.evaluate(oldRow) === true)) {
78
+ const oldIndexValues = indexCols.map(i => oldRow[i]);
79
+ const oldIndexKey = buildIndexKey({ values: oldIndexValues, directions: indexDirections, collations: indexCollations, transforms: indexTransforms }, { values: oldPk, directions: this.pkDirections, collations: this.pkKeyCollations, transforms: this.pkKeyTransforms }, this.encodeOptions);
80
+ if (inTransaction && this.coordinator) {
81
+ this.coordinator.delete(oldIndexKey, indexStore);
82
+ }
83
+ else {
84
+ await indexStore.delete(oldIndexKey);
85
+ }
86
+ }
87
+ // Add new index entry (only if the new row is within scope).
88
+ if (newRow && (!predicate || predicate.evaluate(newRow) === true)) {
89
+ const newIndexValues = indexCols.map(i => newRow[i]);
90
+ const newIndexKey = buildIndexKey({ values: newIndexValues, directions: indexDirections, collations: indexCollations, transforms: indexTransforms }, { values: newPk, directions: this.pkDirections, collations: this.pkKeyCollations, transforms: this.pkKeyTransforms }, this.encodeOptions);
91
+ // Index value = the row's encoded DATA key. The index-entry key can
92
+ // locate a row's byte window, but its PK suffix is not losslessly
93
+ // recoverable to SqlValues (a NOCASE/RTRIM PK column encodes lossily)
94
+ // and its length varies per entry in a range scan — so a scan resolves
95
+ // each entry back to its base row via this stored data key
96
+ // (`scanIndex` → `readEffectiveRowByKey(entry.value)`), never by
97
+ // decoding the suffix. `newPk` is the PK the entry is keyed under, so
98
+ // its data key byte-matches the data store's key for this row.
99
+ const dataKeyValue = this.encodeDataKey(newPk);
100
+ if (inTransaction && this.coordinator) {
101
+ this.coordinator.put(newIndexKey, dataKeyValue, indexStore);
102
+ }
103
+ else {
104
+ await indexStore.put(newIndexKey, dataKeyValue);
105
+ }
106
+ }
107
+ }
108
+ }
109
+ /**
110
+ * Returns the compiled predicate for a partial-UNIQUE constraint, or undefined
111
+ * when the constraint covers the full table. Compilation is memoized per
112
+ * UniqueConstraintSchema instance so the hot UNIQUE-check path doesn't recompile.
113
+ */
114
+ compileFor(uc) {
115
+ if (!uc.predicate)
116
+ return undefined;
117
+ let compiled = this.predicateCache.get(uc);
118
+ if (!compiled) {
119
+ compiled = compilePredicate(uc.predicate, this.tableSchema.columns, this.tableSchema.name);
120
+ this.predicateCache.set(uc, compiled);
121
+ }
122
+ return compiled;
123
+ }
124
+ /**
125
+ * Returns the compiled predicate for a partial secondary index, or undefined
126
+ * for a full index. Compilation is memoized per IndexSchema instance so the hot
127
+ * DML index-maintenance path doesn't recompile.
128
+ */
129
+ compileIndexFor(index) {
130
+ if (!index.predicate)
131
+ return undefined;
132
+ let compiled = this.indexPredicateCache.get(index);
133
+ if (!compiled) {
134
+ compiled = compilePredicate(index.predicate, this.tableSchema.columns, this.tableSchema.name);
135
+ this.indexPredicateCache.set(index, compiled);
136
+ }
137
+ return compiled;
138
+ }
139
+ /**
140
+ * Check if two PK arrays name the same row. A semantic-ordering member compares
141
+ * through its type's `compare` (see {@link resolvePkSemanticEquality}) so
142
+ * differently-spelled equal values ('PT1H' / 'PT60M') answer "same row",
143
+ * agreeing with the physical key identity {@link encodeDataKey} produces; every
144
+ * other member keeps the original strict `!==`.
145
+ */
146
+ keysEqual(a, b) {
147
+ if (a.length !== b.length)
148
+ return false;
149
+ for (let i = 0; i < a.length; i++) {
150
+ const semantic = this.pkSemanticEquality[i];
151
+ if (semantic ? semantic(a[i], b[i]) !== 0 : a[i] !== b[i])
152
+ return false;
153
+ }
154
+ return true;
155
+ }
156
+ /**
157
+ * Per-constrained-column comparison functions for one UNIQUE constraint: the
158
+ * type's `compare` for a semantic-ordering column (so 'PT1H' conflicts with
159
+ * 'PT60M', matching the memory backend's typed BTree), else the enforcement
160
+ * collation the caller resolved (`resolveUniqueEnforcementCollations`) through
161
+ * `compareSqlValuesFast` — the exact comparison every finder used before.
162
+ *
163
+ * Thin wrapper over the engine's `uniqueEnforcementComparators`, which memory
164
+ * and the isolation overlay share so the three backends cannot drift.
165
+ */
166
+ uniqueColumnComparators(uc, collations) {
167
+ return uniqueEnforcementComparators(this.tableSchema.columns, uc.columns, collations);
168
+ }
169
+ /**
170
+ * Returns true if any column covered by a UNIQUE constraint differs between
171
+ * oldRow and newRow, or — for partial UNIQUE — any column referenced by the
172
+ * partial predicate differs (which can transition the row across the
173
+ * predicate scope and re-trigger the uniqueness check).
174
+ */
175
+ uniqueColumnsChanged(oldRow, newRow) {
176
+ const ucs = this.tableSchema?.uniqueConstraints;
177
+ if (!ucs || ucs.length === 0)
178
+ return false;
179
+ for (const uc of ucs) {
180
+ for (const colIdx of uc.columns) {
181
+ if (compareSqlValues(oldRow[colIdx], newRow[colIdx]) !== 0)
182
+ return true;
183
+ }
184
+ if (uc.predicate) {
185
+ const compiled = this.compileFor(uc);
186
+ if (compiled) {
187
+ for (const colIdx of compiled.referencedColumns) {
188
+ if (compareSqlValues(oldRow[colIdx], newRow[colIdx]) !== 0)
189
+ return true;
190
+ }
191
+ }
192
+ }
193
+ }
194
+ return false;
195
+ }
196
+ /**
197
+ * Enforce table-level UNIQUE constraints against the prospective newRow.
198
+ * Honors `onConflict`: IGNORE returns an ok-with-undefined-row; REPLACE
199
+ * deletes the conflicting row(s) and continues; otherwise returns a
200
+ * constraint result. Returns null when all constraints pass.
201
+ *
202
+ * Rows whose PK is in `selfPks` are skipped (the row being inserted/updated).
203
+ * NULL in any covered column skips that constraint (multiple NULLs are allowed
204
+ * per SQL standard).
205
+ *
206
+ * Reads through the transaction coordinator's pending writes when active so
207
+ * intra-transaction duplicates are detected.
208
+ *
209
+ * REPLACE evictions (rows at OTHER PKs) are deleted from storage and pushed onto
210
+ * `evicted` so the DML executor runs the full delete pipeline for each
211
+ * (change-tracking, row-time MV maintenance, FK cascade, auto-events).
212
+ */
213
+ async checkUniqueConstraints(inTransaction, newRow, selfPks, onConflict, evicted) {
214
+ const schema = this.tableSchema;
215
+ const uniqueConstraints = schema.uniqueConstraints;
216
+ if (!uniqueConstraints || uniqueConstraints.length === 0)
217
+ return null;
218
+ for (const uc of uniqueConstraints) {
219
+ if (uc.columns.some(idx => newRow[idx] === null))
220
+ continue;
221
+ // Partial UNIQUE: a row whose predicate is not unambiguously TRUE is
222
+ // outside the index's scope and contributes nothing to uniqueness.
223
+ const predicate = this.compileFor(uc);
224
+ if (predicate && predicate.evaluate(newRow) !== true)
225
+ continue;
226
+ const conflict = await this.findUniqueConflictFor(uc, predicate, newRow, selfPks);
227
+ if (!conflict)
228
+ continue;
229
+ // Resolve action per-constraint: statement OR > per-UC default > ABORT.
230
+ const effective = onConflict ?? uc.defaultConflict ?? ConflictResolution.ABORT;
231
+ if (effective === ConflictResolution.IGNORE) {
232
+ return { status: 'ok', row: undefined };
233
+ }
234
+ if (effective === ConflictResolution.REPLACE) {
235
+ await this.deleteRowAt(inTransaction, conflict.pk, conflict.row);
236
+ // Report the eviction so the executor runs its full delete pipeline —
237
+ // including the row-time covering-structure maintenance that drops the
238
+ // evicted source row's backing entry within this statement (else a later
239
+ // same-UC row sees a phantom). The executor processes the eviction before
240
+ // the writing row's own bookkeeping, so the backing delete still lands
241
+ // mid-statement.
242
+ evicted.push(conflict.row);
243
+ continue;
244
+ }
245
+ const colNames = uc.columns.map(i => schema.columns[i].name).join(', ');
246
+ return {
247
+ status: 'constraint',
248
+ constraint: 'unique',
249
+ message: `UNIQUE constraint failed: ${schema.name} (${colNames})`,
250
+ existingRow: conflict.row,
251
+ };
252
+ }
253
+ return null;
254
+ }
255
+ /**
256
+ * Route one UNIQUE constraint's conflict search to the cheapest SOUND finder,
257
+ * in descending preference:
258
+ *
259
+ * 1. A linked row-time covering MV — its backing table (hosted by any
260
+ * backing-host-capable module — memory by default, this store module under
261
+ * `using store` — queried through the db with reads-own-writes) answers the
262
+ * uniqueness question, mirroring the memory enforcement path.
263
+ * 2. A physical secondary index realizing the constraint — one prefix seek
264
+ * instead of a full table scan (see {@link findIndexForUniqueConstraint}).
265
+ * 3. The full data-store scan ({@link findUniqueConflict}) — always correct,
266
+ * O(rows) per checked row.
267
+ *
268
+ * Every finder returns the SAME `{pk, row}` shape, so the caller's conflict
269
+ * action (ABORT / IGNORE / REPLACE eviction) is finder-independent.
270
+ */
271
+ async findUniqueConflictFor(uc, predicate, newRow, selfPks) {
272
+ const schema = this.tableSchema;
273
+ const coveringMv = this.db._findRowTimeCoveringStructure(schema.schemaName, schema.name, uc);
274
+ if (coveringMv)
275
+ return this.findUniqueConflictViaCoveringMv(coveringMv, uc, predicate, newRow, selfPks);
276
+ const index = this.findIndexForUniqueConstraint(uc);
277
+ if (index) {
278
+ const viaIndex = await this.findUniqueConflictViaIndex(index, uc, predicate, newRow, selfPks);
279
+ if (viaIndex !== INDEX_UNUSABLE)
280
+ return viaIndex;
281
+ }
282
+ return this.findUniqueConflict(uc, predicate, newRow, selfPks);
283
+ }
284
+ /**
285
+ * The `schema.indexes` entry whose physical index store can serve `uc`'s
286
+ * conflict search as a point seek, or undefined when none can.
287
+ *
288
+ * Every non-derived UNIQUE is realized by an index in the materialized schema
289
+ * — a hidden `_uc_*`, or the explicit index it reuses when one covers the same
290
+ * columns (see {@link withImplicitUniqueIndexes} /
291
+ * {@link findReusableIndexForUnique}) — so, like the memory backend, a plain
292
+ * column- or table-level `UNIQUE` is index-servable, not only an explicit
293
+ * `CREATE INDEX`. A UC is index-servable when:
294
+ *
295
+ * - it is index-derived (`derivedFromIndex`, from `CREATE UNIQUE INDEX`) and
296
+ * its named index is still present — the index's partial predicate then
297
+ * equals the constraint's by construction (`appendIndexToTableSchema`); or
298
+ * - some index's columns equal `uc.columns` positionally AND whose predicate
299
+ * is the SAME object as `uc.predicate` (reference identity — the implicit
300
+ * materializer sets it that way). For a FULL UNIQUE that is
301
+ * `undefined === undefined`, which also admits any user full index over the
302
+ * same columns. For a PARTIAL `unique(...) where p` it admits only the
303
+ * co-scoped `_uc_*` (which holds exactly the in-scope rows); an arbitrary
304
+ * user partial index with a DIFFERENT predicate object stays conservative
305
+ * (declined → full scan), because it physically omits rows the constraint
306
+ * still covers. The serving index need not be UNIQUE — a plain index over
307
+ * the constrained columns still holds every in-scope row.
308
+ *
309
+ * Collation guard (see {@link indexSeekHonorsEnforcementCollation}) may still
310
+ * reject the found index, which routes the check back to the full scan.
311
+ */
312
+ findIndexForUniqueConstraint(uc) {
313
+ // NOTE: re-resolved for every constrained ROW written, and the collation guard
314
+ // below re-derives `uniqueEnforcementCollations` each time. Both are linear in
315
+ // `schema.indexes` / `uc.columns` and dwarfed by the seek's I/O, so this is fine
316
+ // now. If a table with many indexes ever shows up on an insert-heavy profile,
317
+ // memoize the (uc → index | undefined) resolution in a WeakMap keyed on the
318
+ // frozen UniqueConstraintSchema, as `predicateCache` above does — a CREATE/DROP
319
+ // INDEX yields fresh constraint objects, so such a cache invalidates itself.
320
+ // Reads the MATERIALIZED index set so the hidden `_uc_*` realizing a plain UNIQUE
321
+ // is visible (the engine-facing `tableSchema` carries only explicit/derived indexes).
322
+ const indexes = this.materializedSchema.indexes;
323
+ if (!indexes || indexes.length === 0)
324
+ return undefined;
325
+ let index;
326
+ if (uc.derivedFromIndex) {
327
+ index = indexes.find(ix => ix.name === uc.derivedFromIndex);
328
+ }
329
+ else {
330
+ // Among the column-set matches, prefer the constraint's OWN index by name
331
+ // (`implicitUniqueIndexName` — the `_uc_*` the materializer minted for it).
332
+ // `withImplicitUniqueIndexes` APPENDS `_uc_*` after the explicit indexes, so a
333
+ // bare first-match would land on an explicit index that
334
+ // `findReusableIndexForUnique` REFUSED for a collation mismatch — whose key
335
+ // bytes now differ from the enforcement collation, so seeking it would
336
+ // under-fetch and silently accept a duplicate. When no `_uc_*` exists the
337
+ // remaining match is the reuse-approved index, whose collations
338
+ // `indexCollationsMatchDeclared` proved equal to the declared ones.
339
+ const candidates = indexes.filter(ix => ix.predicate === uc.predicate
340
+ && ix.columns.length === uc.columns.length
341
+ && ix.columns.every((c, i) => c.index === uc.columns[i]));
342
+ const ownName = implicitUniqueIndexName(this.materializedSchema, uc).toLowerCase();
343
+ index = candidates.find(ix => ix.name.toLowerCase() === ownName) ?? candidates[0];
344
+ }
345
+ if (!index)
346
+ return undefined;
347
+ return this.indexSeekHonorsEnforcementCollation(index, uc) ? index : undefined;
348
+ }
349
+ /**
350
+ * True when a point seek into `index` returns a SUPERSET of `uc`'s true conflict
351
+ * set — the only condition under which the seek may replace the full scan.
352
+ *
353
+ * An index key's leading (index-column) bytes are encoded under the index's own
354
+ * per-column key collations (`resolveIndexKeyCollations`), and the constraint
355
+ * re-validates candidates under its enforcement collations
356
+ * (`uniqueEnforcementCollations` — the index's per-column COLLATE for an
357
+ * index-derived UC, else the declared column collation). For every index a
358
+ * *designed* path can hand this method, the two resolve identically by
359
+ * construction — the seek window is then exactly the C-equal set — so the check
360
+ * is a plain per-column equality of the two resolutions (upper-cased; never-text
361
+ * columns exempt, their bytes being type-native).
362
+ *
363
+ * Kept rather than deleted because one undesigned path can still disagree:
364
+ * `withImplicitUniqueIndexes` skips materializing a `_uc_*` whose NAME is already
365
+ * taken (a user index literally named `_uc_email`, or a named UC colliding with an
366
+ * index name), and the column-set fallback in
367
+ * {@link findIndexForUniqueConstraint} can then hand this a same-columns index
368
+ * whose key collations differ from the enforcement collations. A false `true`
369
+ * there silently accepts a duplicate; a decline only costs the full scan.
370
+ */
371
+ indexSeekHonorsEnforcementCollation(index, uc) {
372
+ const schema = this.tableSchema;
373
+ const keyCollations = resolveIndexKeyCollations(index, schema.columns);
374
+ const enforcement = uniqueEnforcementCollations(schema, uc);
375
+ // Positions align: index.columns[i].index === uc.columns[i], guaranteed by the
376
+ // derived-UC construction (appendIndexToTableSchema) / the column-set match in
377
+ // findIndexForUniqueConstraint.
378
+ return uc.columns.every((colIdx, i) => {
379
+ if (!columnCanHoldText(schema.columns[colIdx]))
380
+ return true;
381
+ const key = keyCollations[i];
382
+ const C = (enforcement[i] ?? 'BINARY').toUpperCase();
383
+ return key !== undefined && key === C;
384
+ });
385
+ }
386
+ /**
387
+ * The index analogue of {@link findUniqueConflict}: seek the index realizing
388
+ * `uc` at the point formed by `newRow`'s constrained-column values, and
389
+ * re-validate each resolved candidate exactly as the full scan does.
390
+ *
391
+ * The seek encodes ALL of `uc.columns` (positionally aligned with the index's
392
+ * columns, guaranteed by `appendIndexToTableSchema` / the column-set match in
393
+ * {@link findIndexForUniqueConstraint}) as a leading prefix of the index key,
394
+ * under the same key collation and per-column DESC directions
395
+ * {@link updateSecondaryIndexes} used to write it. The remaining suffix is the
396
+ * row's PK, so the window spans every entry sharing those column values.
397
+ * {@link iterateEffective} merges this transaction's pending index puts/deletes
398
+ * over the committed entries, giving read-your-own-writes; each entry resolves
399
+ * to its LIVE row through the data key stored as the entry's value.
400
+ *
401
+ * The seek only narrows the CANDIDATE set to a superset (guaranteed by
402
+ * {@link indexSeekHonorsEnforcementCollation}); the authoritative comparison is
403
+ * the identical self-PK exclusion, per-column enforcement-collation compare,
404
+ * and partial-predicate scope check the full scan performs. A partial index
405
+ * already excludes out-of-scope rows physically — the predicate re-check is
406
+ * kept as defense in depth.
407
+ *
408
+ * Returns {@link INDEX_UNUSABLE} rather than a (possibly wrong) answer when an
409
+ * entry carries a legacy empty value.
410
+ */
411
+ async findUniqueConflictViaIndex(index, uc, predicate, newRow, selfPks) {
412
+ const indexStore = await this.ensureIndexStore(index.name);
413
+ // Resolved once, above the candidate loop: the resolver throws on an
414
+ // unregistered name and cannot be inlined, so a per-candidate call would be
415
+ // pure overhead.
416
+ const collations = resolveUniqueEnforcementCollations(this.tableSchema, uc, this.collationResolver);
417
+ const compares = this.uniqueColumnComparators(uc, collations);
418
+ // Same per-column key collations and transforms `updateSecondaryIndexes` wrote
419
+ // the entries under, so the probe for 'A@x' lands on the window holding the
420
+ // NOCASE-keyed 'a@x' entry and the probe for 'PT60M' on the 'PT1H' one.
421
+ const bounds = buildIndexPrefixBounds(uc.columns.map(c => newRow[c]), this.encodeOptions, index.columns.map(c => !!c.desc), resolveIndexKeyCollations(index, this.tableSchema.columns), resolveIndexKeyTransforms(index, this.tableSchema.columns));
422
+ for await (const entry of this.iterateEffective(indexStore, bounds)) {
423
+ // A legacy index store (written before index values carried the data key)
424
+ // holds EMPTY values. `scanIndex` may skip such an entry — a read that
425
+ // returns too few rows. Skipping here would instead ACCEPT a duplicate, so
426
+ // abandon the index and let the caller full-scan. See the NOTE in
427
+ // `scanIndex` for the durable fix.
428
+ if (entry.value.length === 0)
429
+ return INDEX_UNUSABLE;
430
+ // Resolve to the LIVE row: a pending index delete normally suppresses the
431
+ // entry, but a committed entry can lag a row deleted this transaction.
432
+ const candidate = await this.readEffectiveRowByKey(entry.value);
433
+ if (!candidate)
434
+ continue;
435
+ const pk = this.extractPK(candidate);
436
+ if (selfPks.some(skip => this.keysEqual(pk, skip)))
437
+ continue;
438
+ if (uc.columns.some((c, i) => compares[i](newRow[c], candidate[c]) !== 0))
439
+ continue;
440
+ if (predicate && predicate.evaluate(candidate) !== true)
441
+ continue;
442
+ return { pk, row: candidate };
443
+ }
444
+ return null;
445
+ }
446
+ /**
447
+ * Scan committed + pending data rows for a row matching `newRow` on
448
+ * `uc.columns` whose PK is not in `selfPks`. For partial UNIQUE, candidates
449
+ * whose row does not satisfy the predicate are skipped. Returns the first
450
+ * match or null.
451
+ */
452
+ async findUniqueConflict(uc, predicate, newRow, selfPks) {
453
+ const store = await this.ensureStore();
454
+ // Pending ops for THIS table's data store handle — the same handle the
455
+ // write path queues data ops under, so the merge sees only this table's
456
+ // pending state, never a sibling table's on the shared module coordinator.
457
+ const pending = this.coordinator?.isInTransaction()
458
+ ? this.coordinator.getPendingOpsForStore(store)
459
+ : null;
460
+ const constrainedCols = uc.columns;
461
+ // One comparison collation per constrained column — the index's per-column
462
+ // COLLATE for an index-derived UNIQUE, else the declared column collation.
463
+ // Resolved once here, not per candidate row.
464
+ const collations = resolveUniqueEnforcementCollations(this.tableSchema, uc, this.collationResolver);
465
+ const compares = this.uniqueColumnComparators(uc, collations);
466
+ const matches = (candidate) => {
467
+ const pk = this.extractPK(candidate);
468
+ for (const skip of selfPks) {
469
+ if (this.keysEqual(pk, skip))
470
+ return null;
471
+ }
472
+ for (let i = 0; i < constrainedCols.length; i++) {
473
+ const idx = constrainedCols[i];
474
+ if (compares[i](newRow[idx], candidate[idx]) !== 0)
475
+ return null;
476
+ }
477
+ // Partial UNIQUE: candidate must also be in the predicate's scope to conflict.
478
+ if (predicate && predicate.evaluate(candidate) !== true)
479
+ return null;
480
+ return { pk, row: candidate };
481
+ };
482
+ const seen = new Set();
483
+ const bounds = buildFullScanBounds();
484
+ for await (const entry of store.iterate(bounds)) {
485
+ const hex = bytesToHex(entry.key);
486
+ seen.add(hex);
487
+ if (pending?.deletes.has(hex))
488
+ continue;
489
+ const overlay = pending?.puts.get(hex);
490
+ const value = overlay ? overlay.value : entry.value;
491
+ const found = matches(deserializeRow(value));
492
+ if (found)
493
+ return found;
494
+ }
495
+ if (pending) {
496
+ for (const [hex, op] of pending.puts) {
497
+ if (seen.has(hex))
498
+ continue;
499
+ const found = matches(deserializeRow(op.value));
500
+ if (found)
501
+ return found;
502
+ }
503
+ }
504
+ return null;
505
+ }
506
+ /**
507
+ * Find a UNIQUE conflict through a linked row-time covering MV's backing table
508
+ * (the store analogue of the memory `checkUniqueViaMaterializedView`). The
509
+ * backing scan yields candidate conflicting **source** PKs (reads-own-writes via
510
+ * the backing's coordinated connection); each is validated against the *live*
511
+ * store row (committed + this transaction's pending overlay) so a backing entry
512
+ * that lags a row deleted/updated internally this statement is skipped rather
513
+ * than raised as a false conflict. Returns the first real conflict or null.
514
+ */
515
+ async findUniqueConflictViaCoveringMv(mv, uc, predicate, newRow, selfPks) {
516
+ const newSourcePk = this.extractPK(newRow);
517
+ // Resolved once, above the candidate loop.
518
+ const collations = resolveUniqueEnforcementCollations(this.tableSchema, uc, this.collationResolver);
519
+ const compares = this.uniqueColumnComparators(uc, collations);
520
+ const candidates = await this.db._lookupCoveringConflicts(mv, uc, newRow, newSourcePk);
521
+ for (const cand of candidates) {
522
+ const liveRow = await this.readLiveRowByPk(cand.pk);
523
+ if (!liveRow)
524
+ continue; // stale backing candidate (source row gone)
525
+ if (selfPks.some(pk => this.keysEqual(pk, cand.pk)))
526
+ continue;
527
+ // Re-validate under each column's enforcement collation (the index's
528
+ // per-column COLLATE for an index-derived UNIQUE, else declared) — see
529
+ // uniqueEnforcementCollations. The candidate generation
530
+ // (_lookupCoveringConflicts) narrows under the SOURCE column's declared
531
+ // collation, so for a FINER index (BINARY over a NOCASE column) it returns a
532
+ // superset this filters down correctly. A finer/incomparable index-derived
533
+ // UNIQUE whose declared candidate set could be a SUBSET (e.g. a coarser NOCASE
534
+ // index over a BINARY column) is declined upstream by the collation gate in
535
+ // findRowTimeCoveringStructure, so only BINARY-floor or equal-collation MVs
536
+ // reach here — the superset this re-validation can soundly filter.
537
+ if (uc.columns.some((c, i) => compares[i](newRow[c], liveRow[c]) !== 0))
538
+ continue;
539
+ if (predicate && predicate.evaluate(liveRow) !== true)
540
+ continue;
541
+ return { pk: cand.pk, row: liveRow };
542
+ }
543
+ return null;
544
+ }
545
+ /**
546
+ * Declared secondary-UNIQUE enforcement for maintenance writes — the store
547
+ * mirror of the memory manager's `enforceSecondaryUniqueOnMaintenance` (see
548
+ * `vtab/backing-host.ts` § Constraint validation for the contract and
549
+ * docs/mv-constraints.md § Derived-row constraint validation for the
550
+ * semantics). Called by `StoreBackingHost.applyMaintenance` AFTER the op
551
+ * batch lands in the coordinator's pending state: post-batch is load-bearing
552
+ * (a `replace-all` diff applies puts before deletes, so a per-op check would
553
+ * false-positive when the derived set moves a unique value between primary
554
+ * keys), and checking only the WRITTEN images is complete (pre-existing
555
+ * contents already satisfied the constraint).
556
+ *
557
+ * Reuses {@link findUniqueConflict} — pending-overlay reads, per-column
558
+ * collations, NULL-pass, partial-predicate scope, self-PK exclusion — with
559
+ * the covering-MV route deliberately bypassed: a covering MV over THIS table
560
+ * is cascade-maintained only after the batch returns, so it lags the batch
561
+ * and would miss a same-batch colliding pair. The conflict action is a hard
562
+ * abort (a derivation write carries no user OR clause, and a declared
563
+ * `on conflict replace`/`ignore` default must not evict or drop derived
564
+ * rows). Per-image cost is one effective full scan: unlike the DML path
565
+ * ({@link findUniqueConflictFor}), this one is NOT routed through
566
+ * {@link findUniqueConflictViaIndex}, because a backing table keeps no
567
+ * secondary indexes by design — there is never an index store to seek.
568
+ *
569
+ * Zero overhead when the table declares no secondary UNIQUE (every MV-sugar
570
+ * backing, and most maintained tables): one empty-array check.
571
+ */
572
+ async enforceSecondaryUniqueForMaintenance(changes) {
573
+ const schema = this.tableSchema;
574
+ const ucs = schema?.uniqueConstraints;
575
+ if (!schema || !ucs || ucs.length === 0 || changes.length === 0)
576
+ return;
577
+ for (const change of changes) {
578
+ if (change.op === 'delete')
579
+ continue;
580
+ const newRow = change.newRow;
581
+ const selfPks = [this.extractPK(newRow)];
582
+ for (const uc of ucs) {
583
+ // SQL semantics: UNIQUE allows multiple NULLs.
584
+ if (uc.columns.some(idx => newRow[idx] === null))
585
+ continue;
586
+ // Partial UNIQUE: an out-of-scope image contributes nothing.
587
+ const predicate = this.compileFor(uc);
588
+ if (predicate && predicate.evaluate(newRow) !== true)
589
+ continue;
590
+ const conflict = await this.findUniqueConflict(uc, predicate, newRow, selfPks);
591
+ if (conflict) {
592
+ const colNames = uc.columns.map(i => schema.columns[i]?.name ?? String(i));
593
+ throw maintainedTableUniqueViolationError(schema.schemaName, schema.name, uc.name ?? `_uc_${colNames.join('_')}`, colNames, uc.columns.map(i => newRow[i]));
594
+ }
595
+ }
596
+ }
597
+ }
598
+ /**
599
+ * Fully delete the row at `pk` (data + secondary indexes + stats + delete event).
600
+ * Used by REPLACE conflict resolution to evict a conflicting unique row before
601
+ * the caller's insert/update proceeds.
602
+ */
603
+ async deleteRowAt(inTransaction, pk, oldRow) {
604
+ const store = await this.ensureStore();
605
+ const key = this.encodeDataKey(pk);
606
+ if (inTransaction && this.coordinator) {
607
+ this.coordinator.delete(key, store);
608
+ }
609
+ else {
610
+ await store.delete(key);
611
+ }
612
+ await this.updateSecondaryIndexes(inTransaction, oldRow, null, pk);
613
+ this.trackMutation(-1, inTransaction);
614
+ const schema = this.tableSchema;
615
+ this.emitOrQueueDataChange(inTransaction, {
616
+ type: 'delete',
617
+ schemaName: schema.schemaName,
618
+ tableName: schema.name,
619
+ key: pk,
620
+ oldRow,
621
+ });
622
+ }
623
+ }
624
+ //# sourceMappingURL=store-table-constraints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-table-constraints.js","sourceRoot":"","sources":["../../../src/common/store-table-constraints.ts"],"names":[],"mappings":"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"}