@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,280 @@
1
+ /**
2
+ * Standalone index-population and uniqueness-validation helpers: streaming a table's
3
+ * committed rows into a secondary index's physical store in bounded batches, and the
4
+ * duplicate probes that judge a UNIQUE constraint or UNIQUE index against a row stream
5
+ * before it is enforced.
6
+ *
7
+ * Free functions rather than a layer of the store-module chain — none of them reads
8
+ * module state; each takes the stores and schema it needs.
9
+ */
10
+ import { QuereusError, StatusCode, compilePredicate, logicalTypeCanHoldText, serializeKey } from '@quereus/quereus';
11
+ import { resolveIndexKeyCollations, resolveDedupeKeyTransforms, resolveIndexKeyTransforms, resolvePkKeyCollations, resolvePkKeyTransforms, } from './pk-key-resolution.js';
12
+ import { buildDataKey, buildFullScanBounds, buildIndexKey } from './key-builder.js';
13
+ import { deserializeRow } from './serialization.js';
14
+ // NOTE: this one constant is the only thing tying this file to the module chain (the graph
15
+ // stays acyclic — the base layer is a leaf). If these helpers ever need to be usable without
16
+ // loading the chain, move `DEFAULT_MAX_BATCH_BYTES` to a constants leaf and have the base
17
+ // import it from there instead.
18
+ import { DEFAULT_MAX_BATCH_BYTES } from './store-module-base.js';
19
+ /**
20
+ * Build index entries for all existing rows in a table.
21
+ *
22
+ * `dataEntries` is the row stream to index. Callers choose its visibility:
23
+ * `createIndex` passes the table's EFFECTIVE stream (committed + pending, so
24
+ * an open transaction's rows are indexed too), while `rebuildSecondaryIndexes`
25
+ * passes the raw committed stream — it runs immediately after an ALTER has
26
+ * re-encoded the data store in place, and any pending ops still address the
27
+ * pre-ALTER key bytes.
28
+ *
29
+ * For UNIQUE indexes, performs an in-pass duplicate check (honoring partial
30
+ * predicates and SQL NULL semantics: multiple NULLs are allowed) and throws
31
+ * CONSTRAINT before any entries are written. Mirrors the memory module's
32
+ * populateNewIndex so `CREATE UNIQUE INDEX` over duplicated data fails
33
+ * atomically. `skipDuplicateCheck` suppresses it: `createIndex` sets it when a
34
+ * wrapper module supplied the rows to judge, having already validated them (see
35
+ * {@link validateUniqueIndexOverRows}). Judging `dataEntries` too would reject a
36
+ * committed duplicate the wrapper's transaction has already deleted.
37
+ *
38
+ * `normalizers` MUST be the owning connection's `db.getKeyNormalizerResolver()` —
39
+ * the same resolver `StoreTable.encodeOptions` carries. A rebuild that resolved
40
+ * collations any other way would re-encode the PK suffix under different bytes than
41
+ * the table writes at maintenance time, silently corrupting the index.
42
+ */
43
+ export async function buildIndexEntries(dataEntries, indexStore, tableSchema, indexSchema, keyCollation, normalizers, skipDuplicateCheck = false, maxBatchBytes = DEFAULT_MAX_BATCH_BYTES) {
44
+ // Both halves key per-column: each index COLUMN under its own key collation
45
+ // (`resolveIndexKeyCollations` — index COLLATE ?? table column collation ?? BINARY)
46
+ // and the PK SUFFIX under each PK column's own key collation, so the suffix bytes
47
+ // match the data-store keys — and both halves match
48
+ // `StoreTable.updateSecondaryIndexes`' maintenance writes exactly. Those two call
49
+ // sites are the pair whose drift silently corrupts an index; change one and the
50
+ // other must change with it. `keyCollation` (the table key collation K) remains
51
+ // only as the `EncodeOptions` fallback for entries the resolvers leave undefined.
52
+ const encodeOptions = { collation: keyCollation, normalizers };
53
+ const pkDirections = tableSchema.primaryKeyDefinition.map(pk => !!pk.desc);
54
+ const pkCollations = resolvePkKeyCollations(tableSchema.primaryKeyDefinition, tableSchema.columns, keyCollation);
55
+ const indexCollations = resolveIndexKeyCollations(indexSchema, tableSchema.columns);
56
+ // Key-identity transforms for both halves, mirroring `StoreTable`'s maintenance
57
+ // writes (`updateSecondaryIndexes` / `encodeDataKey`) — a rebuild that skipped them
58
+ // would re-encode a TIMESPAN member under different bytes than DML writes.
59
+ const pkTransforms = resolvePkKeyTransforms(tableSchema.primaryKeyDefinition, tableSchema.columns);
60
+ const indexTransforms = resolveIndexKeyTransforms(indexSchema, tableSchema.columns);
61
+ const indexDirections = indexSchema.columns.map(col => !!col.desc);
62
+ const predicate = indexSchema.predicate
63
+ ? compilePredicate(indexSchema.predicate, tableSchema.columns, tableSchema.name)
64
+ : undefined;
65
+ // NOTE: `seen` holds one signature per DISTINCT indexed key for the WHOLE build and
66
+ // is NOT bounded by the maxBatchBytes chunking below (that bounds only the write
67
+ // batch). A very large UNIQUE index still spikes memory on this set. Bounding it
68
+ // needs a sort- or store-probe-based dedup (a separate design), not a batch knob.
69
+ const seen = (indexSchema.unique && !skipDuplicateCheck) ? new Set() : undefined;
70
+ const indexColIndices = indexSchema.columns.map(col => col.index);
71
+ const indexNormalizers = seen
72
+ ? indexDedupeNormalizers(tableSchema, indexSchema, normalizers)
73
+ : undefined;
74
+ // Deliberately NOT `indexTransforms`: the dedupe signature must reproduce
75
+ // `JSON_TYPE.compare`'s collation-honoring string-scalar case (which `serializeKey`'s
76
+ // normalizer applies), while `indexTransforms` stays the hard-structural physical key
77
+ // bytes `buildIndexKey` persists. See `storeDedupeKeyTransform`'s docstring.
78
+ const dedupeTransforms = seen
79
+ ? resolveDedupeKeyTransforms(indexColIndices, tableSchema.columns)
80
+ : undefined;
81
+ let batch = indexStore.batch();
82
+ // Serialized key bytes accumulated in the CURRENT batch. Flushed and reset once it
83
+ // crosses maxBatchBytes so a table larger than memory never buffers its whole index.
84
+ let batchBytes = 0;
85
+ for await (const entry of dataEntries) {
86
+ const row = deserializeRow(entry.value);
87
+ // Partial index: skip rows whose predicate is not unambiguously TRUE.
88
+ if (predicate && predicate.evaluate(row) !== true)
89
+ continue;
90
+ // Extract PK values
91
+ const pkValues = tableSchema.primaryKeyDefinition.map(pk => row[pk.index]);
92
+ // Extract index column values
93
+ const indexValues = indexSchema.columns.map(col => row[col.index]);
94
+ if (seen) {
95
+ // The signature returns null when any indexed column is NULL —
96
+ // SQL UNIQUE allows multiple NULLs, so those rows never collide.
97
+ const keySig = dedupeRowSignature(row, indexColIndices, indexNormalizers, dedupeTransforms);
98
+ if (keySig !== null) {
99
+ if (seen.has(keySig)) {
100
+ const colNames = indexSchema.columns
101
+ .map(c => tableSchema.columns[c.index]?.name ?? String(c.index))
102
+ .join(', ');
103
+ throw new QuereusError(`UNIQUE constraint failed: ${tableSchema.name} (${colNames})`, StatusCode.CONSTRAINT);
104
+ }
105
+ seen.add(keySig);
106
+ }
107
+ }
108
+ // Build and store index key
109
+ const indexKey = buildIndexKey({ values: indexValues, directions: indexDirections, collations: indexCollations, transforms: indexTransforms }, { values: pkValues, directions: pkDirections, collations: pkCollations, transforms: pkTransforms }, encodeOptions);
110
+ // Index value = the row's encoded DATA key, so an index scan resolves each
111
+ // entry back to its base row via a direct data-store read (see
112
+ // `StoreTable.scanIndex`). Encoded under the same PK directions + per-column
113
+ // PK collations + key transforms as `buildDataKey` / `updateSecondaryIndexes`,
114
+ // so the value byte-matches the data store's key for this row.
115
+ const dataKey = buildDataKey(pkValues, encodeOptions, pkDirections, pkCollations, pkTransforms);
116
+ batch.put(indexKey, dataKey);
117
+ // Bound heap: once the accumulated serialized key bytes cross the budget, flush
118
+ // the batch and start a fresh one. Both callers ITERATE the data store and WRITE
119
+ // the index store — different stores — so a mid-stream flush never mutates the
120
+ // stream being read, and this is safe on every provider. A mid-stream flush
121
+ // failure in `createIndex` is torn down by its try/catch (the whole fresh index
122
+ // store is deleted); in `rebuildSecondaryIndexes` it leaves a partial-but-
123
+ // recoverable index (re-run the rebuild — clear + rebuild is idempotent).
124
+ batchBytes += indexKey.length + dataKey.length;
125
+ if (batchBytes >= maxBatchBytes) {
126
+ await batch.write();
127
+ batch = indexStore.batch();
128
+ batchBytes = 0;
129
+ }
130
+ }
131
+ // Final flush of the residual. May be empty (an empty table, or a build whose last
132
+ // row exactly hit the budget and flushed) — providers accept an empty write.
133
+ await batch.write();
134
+ }
135
+ /**
136
+ * Validates `rows` against a UNIQUE constraint, throwing `CONSTRAINT` on the first
137
+ * duplicate before any schema mutation. Used by `ADD CONSTRAINT UNIQUE` (validate
138
+ * against the current collation) and by `SET COLLATE` (pass an `updatedSchema` whose
139
+ * altered column carries the NEW collation, so the dedup is performed under it).
140
+ * Mirrors the duplicate detection in {@link buildIndexEntries}: a `seen` Set keyed on
141
+ * a per-column collation-aware signature of the constrained values, with SQL NULL
142
+ * semantics (a row with any NULL constrained value never counts as a duplicate) and
143
+ * the partial `predicate` honored.
144
+ *
145
+ * `rows` MUST be the rows the DDL-issuing connection can SEE. Ordinarily that is this
146
+ * table's EFFECTIVE stream (committed rows merged with the open transaction's own
147
+ * pending puts/deletes — `StoreTable.iterateEffectiveEntries`, adapted by
148
+ * {@link rowsFromEntries}); when a wrapper module holds the pending rows outside this
149
+ * module it hands them down as an `EffectiveRowSource` instead. Either way, a
150
+ * committed-only stream would let a duplicate inserted earlier in the same transaction
151
+ * slip past validation and land in the table once the transaction commits.
152
+ *
153
+ * No index store is written — store UNIQUE enforcement is a full-scan over
154
+ * `uniqueConstraints` at write time. The signature is built by
155
+ * {@link dedupeRowSignature} with one normalizer per constrained column, resolved from
156
+ * `tableSchema.columns[idx].collation` through the connection's
157
+ * `db.getKeyNormalizerResolver()`, so a per-column collation registered with
158
+ * `db.registerCollation` is honored (matching write-time `compareSqlValues`
159
+ * enforcement). A comparator-only collation raises: rows that cannot be bucketed
160
+ * cannot be deduped. Columns whose declared type can never hold text take the
161
+ * identity normalizer and so never raise.
162
+ */
163
+ export async function validateUniqueOverExistingRows(rows, tableSchema, uc, keyNormalizers) {
164
+ await assertNoDuplicateRows(rows, tableSchema, uc.columns, uc.columns.map(idx => {
165
+ const column = tableSchema.columns[idx];
166
+ return keyNormalizers(logicalTypeCanHoldText(column.logicalType) ? column.collation : undefined);
167
+ }), uc.predicate ? compilePredicate(uc.predicate, tableSchema.columns, tableSchema.name) : undefined);
168
+ }
169
+ /**
170
+ * Index-shaped twin of {@link validateUniqueOverExistingRows}, used by
171
+ * `StoreModuleIndex.createIndex` when a wrapper module supplies the rows to judge. Dedupes on the
172
+ * index's own columns under the index column's COLLATE (falling back to the table
173
+ * column's), so it enforces exactly what `buildIndexEntries`' suppressed in-pass check
174
+ * would have — over the wrapper's rows instead of this module's committed ones.
175
+ */
176
+ export async function validateUniqueIndexOverRows(rows, tableSchema, indexSchema, keyNormalizers) {
177
+ await assertNoDuplicateRows(rows, tableSchema, indexSchema.columns.map(col => col.index), indexDedupeNormalizers(tableSchema, indexSchema, keyNormalizers), indexSchema.predicate ? compilePredicate(indexSchema.predicate, tableSchema.columns, tableSchema.name) : undefined);
178
+ }
179
+ /** Adapts a raw KV entry stream into the row stream the uniqueness validators consume. */
180
+ export async function* rowsFromEntries(entries) {
181
+ for await (const entry of entries) {
182
+ yield deserializeRow(entry.value);
183
+ }
184
+ }
185
+ /**
186
+ * The rows a DDL-issuing connection can SEE, as every pre-mutation probe in the ALTER
187
+ * path needs them: a wrapper module's `EffectiveRowSource` when the isolation layer
188
+ * holds this transaction's staged rows outside the store, else this table's own
189
+ * effective stream (committed rows merged with the module's buffered puts/deletes).
190
+ *
191
+ * One fresh stream per call — an async generator is single-shot, and an
192
+ * `EffectiveRowSource` is re-callable for exactly that reason, so a probe that needs
193
+ * two walks calls this twice.
194
+ */
195
+ export function effectiveDdlRows(table, rows) {
196
+ return rows ? rows() : rowsFromEntries(table.iterateEffectiveEntries(buildFullScanBounds()));
197
+ }
198
+ /**
199
+ * Per-column key normalizers for a UNIQUE INDEX dedupe signature, drawing each column's
200
+ * collation from the index column (if it carries one) else the underlying table column —
201
+ * so the signature honors a per-column collation registered on this connection, matching
202
+ * write-time enforcement.
203
+ *
204
+ * A column whose declared type can never hold text takes the identity normalizer regardless
205
+ * of its collation (the signature serializer normalizes only string values), so a comparator-only
206
+ * collation named on an integer column is not rejected here when the engine's own hash sites
207
+ * would accept it.
208
+ *
209
+ * NOTE: a JSON (or other collation-blind-but-text-capable) index column with a
210
+ * comparator-only custom collation (registered with no key normalizer) passes DDL —
211
+ * `assertIndexKeyCollationsCanKey` checks `resolveIndexKeyCollations`, which keys such a
212
+ * column hard-`BINARY` regardless of the declared name, and `BINARY` always has a
213
+ * normalizer — but THIS resolver looks up the column's own declared name (JSON can hold
214
+ * text, so it takes the textual branch above), and `keyNormalizers` throws for a name with
215
+ * no registered normalizer. The DDL-time check and this one are asking two different
216
+ * questions (can the physical key encode vs. can the dedupe signature encode) and can
217
+ * disagree. Confirmed by inspection, not exercised by a test: this surfaces as a thrown
218
+ * error at `CREATE UNIQUE INDEX` — confusing, since the same statement's key-collation gate
219
+ * just passed — but not a correctness hole (no bad state is built). If this needs a
220
+ * friendlier message, that is a follow-up, not implied by this ticket.
221
+ */
222
+ function indexDedupeNormalizers(tableSchema, indexSchema, keyNormalizers) {
223
+ return indexSchema.columns.map(col => {
224
+ const column = tableSchema.columns[col.index];
225
+ return keyNormalizers(logicalTypeCanHoldText(column.logicalType)
226
+ ? (col.collation ?? column.collation)
227
+ : undefined);
228
+ });
229
+ }
230
+ /**
231
+ * Collation- and identity-aware dedupe signature of `row` over `colIndices`: each value
232
+ * runs through its column's key transform (`storeDedupeKeyTransform` — TIMESPAN's
233
+ * total-seconds `groupKey`, so 'PT1H' and 'PT60M' sign identically; JSON's structural
234
+ * bytes for everything but a string scalar, so reorder-equal objects sign identically
235
+ * while a string scalar is left for `serializeKey`'s normalizer) before `serializeKey`
236
+ * applies the per-column normalizer. Returns null when any covered value
237
+ * is NULL (SQL UNIQUE allows multiple NULLs). The build/validate-time twin of the
238
+ * write-time typed compare in `StoreTable.uniqueColumnComparators`.
239
+ *
240
+ * NOTE: `transforms` normalizes STRING values only through `serializeKey`'s collation
241
+ * normalizer — a transform whose output is a `Uint8Array` (as `storeSemanticKeyTransform`
242
+ * would produce) bypasses that normalizer entirely (`serializeKey` tags a byte array
243
+ * `x:` and never consults it). So any future semantic-ordering logical type that BOTH
244
+ * carries a key transform AND honors a collation in its `compare` (like JSON_TYPE) needs
245
+ * its own `storeDedupeKeyTransform` branch, or its build-time UNIQUE check silently
246
+ * degrades to BINARY while the write-time check honors the collation.
247
+ */
248
+ function dedupeRowSignature(row, colIndices, normalizers, transforms) {
249
+ const values = colIndices.map((c, i) => {
250
+ const v = row[c];
251
+ const transform = transforms[i];
252
+ return transform && v !== null ? transform(v) : v;
253
+ });
254
+ return serializeKey(values, normalizers);
255
+ }
256
+ /**
257
+ * Throws CONSTRAINT on the first pair of `rows` that share a signature over `columnIndices`.
258
+ *
259
+ * SQL NULL semantics: {@link dedupeRowSignature} returns null when any constrained column is
260
+ * NULL, and such rows never collide. A partial `predicate` restricts the judged set to rows
261
+ * it accepts unambiguously. Shared by {@link validateUniqueOverExistingRows}
262
+ * (constraint columns) and {@link validateUniqueIndexOverRows} (index columns).
263
+ */
264
+ async function assertNoDuplicateRows(rows, tableSchema, columnIndices, normalizers, predicate) {
265
+ const transforms = resolveDedupeKeyTransforms(columnIndices, tableSchema.columns);
266
+ const seen = new Set();
267
+ for await (const row of rows) {
268
+ if (predicate && predicate.evaluate(row) !== true)
269
+ continue;
270
+ const keySig = dedupeRowSignature(row, columnIndices, normalizers, transforms);
271
+ if (keySig === null)
272
+ continue;
273
+ if (seen.has(keySig)) {
274
+ const colNames = columnIndices.map(i => tableSchema.columns[i]?.name ?? String(i)).join(', ');
275
+ throw new QuereusError(`UNIQUE constraint failed: ${tableSchema.name} (${colNames})`, StatusCode.CONSTRAINT);
276
+ }
277
+ seen.add(keySig);
278
+ }
279
+ }
280
+ //# sourceMappingURL=store-module-index-build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-module-index-build.js","sourceRoot":"","sources":["../../../src/common/store-module-index-build.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEpH,OAAO,EACN,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACtB,sBAAsB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,2FAA2F;AAC3F,6FAA6F;AAC7F,0FAA0F;AAC1F,gCAAgC;AAChC,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACtC,WAAmC,EACnC,UAAmB,EACnB,WAAwB,EACxB,WAA6B,EAC7B,YAAoB,EACpB,WAAkC,EAClC,kBAAkB,GAAG,KAAK,EAC1B,gBAAwB,uBAAuB;IAE/C,4EAA4E;IAC5E,oFAAoF;IACpF,kFAAkF;IAClF,oDAAoD;IACpD,kFAAkF;IAClF,gFAAgF;IAChF,gFAAgF;IAChF,kFAAkF;IAClF,MAAM,aAAa,GAAG,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;IAC/D,MAAM,YAAY,GAAG,WAAW,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,sBAAsB,CAAC,WAAW,CAAC,oBAAoB,EAAE,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACjH,MAAM,eAAe,GAAG,yBAAyB,CAAC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACpF,gFAAgF;IAChF,oFAAoF;IACpF,2EAA2E;IAC3E,MAAM,YAAY,GAAG,sBAAsB,CAAC,WAAW,CAAC,oBAAoB,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACnG,MAAM,eAAe,GAAG,yBAAyB,CAAC,WAAW,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACpF,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEnE,MAAM,SAAS,GAAkC,WAAW,CAAC,SAAS;QACrE,CAAC,CAAC,gBAAgB,CAAC,WAAW,CAAC,SAAS,EAAE,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC;QAChF,CAAC,CAAC,SAAS,CAAC;IACb,oFAAoF;IACpF,iFAAiF;IACjF,iFAAiF;IACjF,kFAAkF;IAClF,MAAM,IAAI,GAA4B,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAE1G,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClE,MAAM,gBAAgB,GAAG,IAAI;QAC5B,CAAC,CAAC,sBAAsB,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC;QAC/D,CAAC,CAAC,SAAS,CAAC;IACb,0EAA0E;IAC1E,sFAAsF;IACtF,sFAAsF;IACtF,6EAA6E;IAC7E,MAAM,gBAAgB,GAAG,IAAI;QAC5B,CAAC,CAAC,0BAA0B,CAAC,eAAe,EAAE,WAAW,CAAC,OAAO,CAAC;QAClE,CAAC,CAAC,SAAS,CAAC;IAEb,IAAI,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC;IAC/B,mFAAmF;IACnF,qFAAqF;IACrF,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAExC,sEAAsE;QACtE,IAAI,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,IAAI;YAAE,SAAS;QAE5D,oBAAoB;QACpB,MAAM,QAAQ,GAAG,WAAW,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAE3E,8BAA8B;QAC9B,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAEnE,IAAI,IAAI,EAAE,CAAC;YACV,+DAA+D;YAC/D,iEAAiE;YACjE,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,gBAAiB,EAAE,gBAAiB,CAAC,CAAC;YAC9F,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACrB,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;oBACtB,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO;yBAClC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;yBAC/D,IAAI,CAAC,IAAI,CAAC,CAAC;oBACb,MAAM,IAAI,YAAY,CACrB,6BAA6B,WAAW,CAAC,IAAI,KAAK,QAAQ,GAAG,EAC7D,UAAU,CAAC,UAAU,CACrB,CAAC;gBACH,CAAC;gBACD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAClB,CAAC;QACF,CAAC;QAED,4BAA4B;QAC5B,MAAM,QAAQ,GAAG,aAAa,CAC7B,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,UAAU,EAAE,eAAe,EAAE,EAC9G,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,EAClG,aAAa,CACb,CAAC;QACF,2EAA2E;QAC3E,+DAA+D;QAC/D,6EAA6E;QAC7E,+EAA+E;QAC/E,+DAA+D;QAC/D,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC;QAChG,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE7B,gFAAgF;QAChF,iFAAiF;QACjF,+EAA+E;QAC/E,4EAA4E;QAC5E,gFAAgF;QAChF,2EAA2E;QAC3E,0EAA0E;QAC1E,UAAU,IAAI,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC/C,IAAI,UAAU,IAAI,aAAa,EAAE,CAAC;YACjC,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;YACpB,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC;YAC3B,UAAU,GAAG,CAAC,CAAC;QAChB,CAAC;IACF,CAAC;IAED,mFAAmF;IACnF,6EAA6E;IAC7E,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CACnD,IAAwB,EACxB,WAAwB,EACxB,EAA0B,EAC1B,cAAqC;IAErC,MAAM,qBAAqB,CAC1B,IAAI,EACJ,WAAW,EACX,EAAE,CAAC,OAAO,EACV,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QACpB,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACxC,OAAO,cAAc,CAAC,sBAAsB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAClG,CAAC,CAAC,EACF,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAChG,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAChD,IAAwB,EACxB,WAAwB,EACxB,WAA6B,EAC7B,cAAqC;IAErC,MAAM,qBAAqB,CAC1B,IAAI,EACJ,WAAW,EACX,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EACzC,sBAAsB,CAAC,WAAW,EAAE,WAAW,EAAE,cAAc,CAAC,EAChE,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,WAAW,CAAC,SAAS,EAAE,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAClH,CAAC;AACH,CAAC;AAED,0FAA0F;AAC1F,MAAM,CAAC,KAAK,SAAS,CAAC,CAAC,eAAe,CAAC,OAA+B;IACrE,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QACnC,MAAM,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;AACF,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAiB,EAAE,IAAyB;IAC5E,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,uBAAuB,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;AAC9F,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAS,sBAAsB,CAC9B,WAAwB,EACxB,WAA6B,EAC7B,cAAqC;IAErC,OAAO,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QACpC,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO,cAAc,CAAC,sBAAsB,CAAC,MAAM,CAAC,WAAW,CAAC;YAC/D,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC;YACrC,CAAC,CAAC,SAAS,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAS,kBAAkB,CAC1B,GAAQ,EACR,UAA6B,EAC7B,WAAqC,EACrC,UAAkE;IAElE,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACtC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QACjB,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAChC,OAAO,SAAS,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IACH,OAAO,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,qBAAqB,CACnC,IAAwB,EACxB,WAAwB,EACxB,aAAgC,EAChC,WAAqC,EACrC,SAAwC;IAExC,MAAM,UAAU,GAAG,0BAA0B,CAAC,aAAa,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IAClF,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QAC9B,IAAI,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,IAAI;YAAE,SAAS;QAE5D,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;QAC/E,IAAI,MAAM,KAAK,IAAI;YAAE,SAAS;QAE9B,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9F,MAAM,IAAI,YAAY,CACrB,6BAA6B,WAAW,CAAC,IAAI,KAAK,QAAQ,GAAG,EAC7D,UAAU,CAAC,UAAU,CACrB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC;AACF,CAAC"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * CREATE INDEX / DROP INDEX over a store-backed table, and the physical index stores
3
+ * they bring into (and out of) existence — including the hidden `_uc_*` stores that
4
+ * back a plain UNIQUE constraint, whose set is reconciled against the schema after
5
+ * every DDL that can change it.
6
+ *
7
+ * Fourth layer of the store-module chain:
8
+ * StoreModuleBase -> StoreModuleCatalog -> StoreModuleSchemaSync -> StoreModuleIndex
9
+ * -> StoreModuleAlterColumn -> StoreModuleAlter -> StoreModuleRename -> StoreModule
10
+ */
11
+ import type { Database, EffectiveRowSource, KeyNormalizerResolver, TableIndexSchema, TableSchema } from '@quereus/quereus';
12
+ import { StoreTable } from './store-table.js';
13
+ import { StoreModuleSchemaSync } from './store-module-schema-sync.js';
14
+ export declare abstract class StoreModuleIndex extends StoreModuleSchemaSync {
15
+ /**
16
+ * Creates an index on a store-backed table.
17
+ *
18
+ * `rows` — an {@link EffectiveRowSource} supplied by a wrapper module (the isolation
19
+ * layer) — replaces this module's own rows as the set the UNIQUE duplicate check judges.
20
+ * When present the check runs UP FRONT, before `getIndexStore` opens the index-store
21
+ * directory, so a rejection leaves no directory behind; and `buildIndexEntries` then
22
+ * populates the physical index from this module's own (committed) rows with its in-pass
23
+ * dup check disabled. Those two row sets legitimately differ — the wrapper's transaction
24
+ * may have deleted a committed duplicate — and an index entry with no live row behind it
25
+ * is harmless (see the entry-resolution note in `buildIndexEntries`).
26
+ */
27
+ createIndex(db: Database, schemaName: string, tableName: string, indexSchema: TableIndexSchema, rows?: EffectiveRowSource): Promise<void>;
28
+ /**
29
+ * Drops an index on a store-backed table.
30
+ *
31
+ * Mirrors createIndex: refreshes the connected StoreTable's cached
32
+ * tableSchema (removing the index entry and any UNIQUE constraint
33
+ * synthesized from it, tagged with `derivedFromIndex`), releases the
34
+ * cached index-store handle, and tears down the underlying index store.
35
+ */
36
+ dropIndex(db: Database, schemaName: string, tableName: string, indexName: string): Promise<void>;
37
+ /**
38
+ * Clear and rebuild every secondary index of `schema` against the (already
39
+ * re-encoded) data store. Secondary-index keys embed the PK suffix, so they must
40
+ * be rewritten whenever the data-store PK key bytes change — which happens both
41
+ * on `ALTER PRIMARY KEY` (the PK columns change) and on an `ALTER COLUMN … SET
42
+ * COLLATE` on a PK member (a PK column's key collation changes). Shared by both
43
+ * arms so the clear-then-rebuild stays identical. `schema` must already be the
44
+ * post-ALTER schema (its `primaryKeyDefinition` + column collations drive the new
45
+ * PK-suffix encoding via {@link buildIndexEntries}). `normalizers` is the owning
46
+ * connection's `db.getKeyNormalizerResolver()` — see {@link buildIndexEntries}.
47
+ *
48
+ * NOTE: reads the data store committed-only and writes the index stores outside the
49
+ * coordinator. Sound only because every caller calls `StoreModuleBase.ddlCommitPendingOps`
50
+ * first, so this module's "committed" is "everything live". A caller that skips that
51
+ * flush would rebuild an index missing its transaction's pending rows.
52
+ *
53
+ * `skipDuplicateCheck` suppresses {@link buildIndexEntries}' in-pass UNIQUE check.
54
+ * Both ALTER COLUMN rebuild callers set it — the value-rewriting / key-transform
55
+ * arm and the PK re-key arm (`SET COLLATE` on a PK member): each runs a
56
+ * pre-mutation UNIQUE re-validation that already judged the ISSUING connection's
57
+ * effective rows (a wrapper's overlay included), and this rebuild sees only THIS
58
+ * module's committed rows — a set that may retain a row the wrapper's transaction
59
+ * has deleted, so judging it here would spuriously reject a duplicate pair the
60
+ * probe correctly accepted (and, worse, reject AFTER the data store was already
61
+ * re-keyed). Mirrors the memory module's deliberately non-enforcing base rebuild
62
+ * (the probe is the only guard). `ALTER PRIMARY KEY`'s rebuild still enforces:
63
+ * that arm has no effective-row UNIQUE probe of its own.
64
+ */
65
+ protected rebuildSecondaryIndexes(schemaName: string, tableName: string, table: StoreTable, schema: TableSchema, normalizers: KeyNormalizerResolver, skipDuplicateCheck?: boolean): Promise<void>;
66
+ /**
67
+ * Build / tear down the physical index stores backing implicit UNIQUE indexes
68
+ * (`_uc_*`) after a DDL statement, by diffing the implicit-index NAMES the old vs
69
+ * new schema call for ({@link implicitUniqueIndexNameMap}):
70
+ * - a name newly PRESENT (ADD CONSTRAINT UNIQUE, the target half of a
71
+ * RENAME CONSTRAINT / rename of an unnamed UC's column, or a DROP INDEX that
72
+ * retires the explicit index a UNIQUE was reusing) has its physical store
73
+ * populated from this module's effective rows;
74
+ * - a name newly ABSENT (DROP CONSTRAINT UNIQUE, the source half of a rename, or
75
+ * a CREATE INDEX whose new index now realizes the UNIQUE) has its store torn
76
+ * down, so nothing maintains it and a later rebuild does not reopen stale
77
+ * entries.
78
+ *
79
+ * The SCHEMA entry itself is materialized/removed by `withImplicitUniqueIndexes`
80
+ * on the caller's `table.updateSchema`; only the physical store needs this. Called
81
+ * after every ALTER TABLE and after `createIndex` / `dropIndex`, and a no-op
82
+ * whenever the implicit-index name set is unchanged — the common case, including
83
+ * every PK / collation / data-type ALTER (whose same-name physical re-encode is
84
+ * already done by {@link rebuildSecondaryIndexes}) and every CREATE / DROP INDEX
85
+ * that does not cover a plain UNIQUE's columns.
86
+ *
87
+ * `oldSchema` is the pre-DDL schema: its `uniqueConstraints` give the old names and
88
+ * its `.indexes` the old reuse decisions. Either the engine-facing or the
89
+ * materialized copy works — `findReusableIndexForUnique` skips a constraint's own
90
+ * `_uc_*`, so a materialized input yields the same name set.
91
+ *
92
+ * NOTE: the build populates from THIS module's own effective rows (committed + this
93
+ * transaction's pending), never a wrapper's — mirroring `createIndex`. Under the
94
+ * isolation layer the wrapper's rows are what ADD CONSTRAINT's validation judged;
95
+ * the physical index legitimately fills from this module's committed rows and an
96
+ * entry with no live row behind it is harmless (both readers resolve to the live
97
+ * row). Duplicates were already rejected by `validateUniqueOverExistingRows` (ADD)
98
+ * or cannot exist (RENAME leaves data unchanged), so the in-pass check is skipped.
99
+ */
100
+ protected reconcileImplicitUniqueIndexStores(db: Database, schemaName: string, tableName: string, table: StoreTable, oldSchema: TableSchema): Promise<void>;
101
+ /**
102
+ * Close + delete one index's physical store: release the table's cached handle, then
103
+ * `deleteIndexStore` when the provider implements it (it closes the handle before
104
+ * removing the directory), else just `closeIndexStore`.
105
+ *
106
+ * The single teardown every path shares — `dropIndex`, `createIndex`'s build-failure
107
+ * rollback, the implicit `_uc_*` reconcile above, and `DROP COLUMN`'s removed-index
108
+ * pass (`StoreModuleAlter.alterDropColumn`). Each caller owns the surrounding
109
+ * posture, which deliberately differs: the DDL-commit flush (buffered ops are keyed
110
+ * on the KVStore HANDLE, so a doomed store's queued ops would replay into a closed
111
+ * store at commit — see `StoreModuleBase.ddlCommitPendingOps`) and, for
112
+ * `createIndex`, swallowing a teardown throw so it cannot mask the build error.
113
+ */
114
+ protected tearDownIndexStore(schemaName: string, tableName: string, table: StoreTable, indexName: string): Promise<void>;
115
+ }
116
+ //# sourceMappingURL=store-module-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-module-index.d.ts","sourceRoot":"","sources":["../../../src/common/store-module-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACX,QAAQ,EACR,kBAAkB,EAClB,qBAAqB,EACrB,gBAAgB,EAChB,WAAW,EACX,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AA6BtE,8BAAsB,gBAAiB,SAAQ,qBAAqB;IACnE;;;;;;;;;;;OAWG;IACG,WAAW,CAChB,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,gBAAgB,EAC7B,IAAI,CAAC,EAAE,kBAAkB,GACvB,OAAO,CAAC,IAAI,CAAC;IAmIhB;;;;;;;OAOG;IACG,SAAS,CACd,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAyEhB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;cACa,uBAAuB,CACtC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,qBAAqB,EAClC,kBAAkB,UAAQ,GACxB,OAAO,CAAC,IAAI,CAAC;IA+BhB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;cACa,kCAAkC,CACjD,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,WAAW,GACpB,OAAO,CAAC,IAAI,CAAC;IAsDhB;;;;;;;;;;;;OAYG;cACa,kBAAkB,CACjC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;CAQhB"}