@quereus/isolation 4.3.1 → 4.3.2
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.
- package/README.md +25 -5
- package/dist/src/filter-info.d.ts +34 -0
- package/dist/src/filter-info.d.ts.map +1 -0
- package/dist/src/filter-info.js +51 -0
- package/dist/src/filter-info.js.map +1 -0
- package/dist/src/flush.d.ts +36 -0
- package/dist/src/flush.d.ts.map +1 -0
- package/dist/src/flush.js +110 -0
- package/dist/src/flush.js.map +1 -0
- package/dist/src/isolated-table.d.ts +251 -56
- package/dist/src/isolated-table.d.ts.map +1 -1
- package/dist/src/isolated-table.js +658 -320
- package/dist/src/isolated-table.js.map +1 -1
- package/dist/src/isolation-module.d.ts +394 -32
- package/dist/src/isolation-module.d.ts.map +1 -1
- package/dist/src/isolation-module.js +821 -136
- package/dist/src/isolation-module.js.map +1 -1
- package/dist/src/overlay-rows.d.ts +49 -0
- package/dist/src/overlay-rows.d.ts.map +1 -0
- package/dist/src/overlay-rows.js +85 -0
- package/dist/src/overlay-rows.js.map +1 -0
- package/package.json +4 -3
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Database, MaybePromise, Row, TableIndexSchema as IndexSchema, FilterInfo, SchemaChangeInfo, UpdateArgs, VirtualTableConnection, UpdateResult } from '@quereus/quereus';
|
|
2
2
|
import { VirtualTable } from '@quereus/quereus';
|
|
3
|
+
import type { EffectiveRowSource } from '@quereus/quereus';
|
|
3
4
|
import type { IsolationModule } from './isolation-module.js';
|
|
4
5
|
import { type IsolatedTableCallback } from './isolated-connection.js';
|
|
5
6
|
/**
|
|
@@ -29,15 +30,59 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
|
|
|
29
30
|
* lets the GC reclaim entries for retired constraints.
|
|
30
31
|
*/
|
|
31
32
|
private readonly predicateCache;
|
|
33
|
+
/**
|
|
34
|
+
* `db.getCollationResolver()`, bound once at connect. Both the overlay/underlying
|
|
35
|
+
* merge comparators and the UNIQUE conflict checks resolve collation names through
|
|
36
|
+
* it, so a collation registered with `db.registerCollation` participates instead of
|
|
37
|
+
* silently degrading to BINARY.
|
|
38
|
+
*
|
|
39
|
+
* The overlay's key comparator and the underlying table's must agree, or a staged
|
|
40
|
+
* row fails to shadow the base row it replaces; both now derive from this one
|
|
41
|
+
* database registry.
|
|
42
|
+
*/
|
|
43
|
+
private readonly collationResolver;
|
|
44
|
+
/**
|
|
45
|
+
* `db.getKeyNormalizerResolver()`, bound once at connect beside {@link collationResolver}
|
|
46
|
+
* for the same reason: the modified-PK set's key encoding and the comparators above must
|
|
47
|
+
* agree on which rows are equal, or a staged row fails to shadow the base row it replaces.
|
|
48
|
+
*/
|
|
49
|
+
private readonly keyNormalizerResolver;
|
|
50
|
+
/**
|
|
51
|
+
* Per-PK-column comparison functions and sort directions, resolved from the PK
|
|
52
|
+
* columns' declared collations and memoized against the `TableSchema` object
|
|
53
|
+
* identity — an `alter table` hands this instance a fresh (frozen) schema object,
|
|
54
|
+
* which invalidates the entry.
|
|
55
|
+
*/
|
|
56
|
+
private pkCollationCache?;
|
|
32
57
|
/**
|
|
33
58
|
* Returns the connection-scoped set of savepoint depths that pre-date the overlay.
|
|
34
59
|
* Stored in IsolationModule (keyed by db+schema+table) so all IsolatedTable instances
|
|
35
60
|
* for the same connection see the same set — important because each statement creates
|
|
36
61
|
* a fresh IsolatedTable instance via module.connect(), so instance-local state would
|
|
37
62
|
* be lost between the createSavepoint callback and the ensureOverlay() call.
|
|
63
|
+
*
|
|
64
|
+
* NOTE: keyed by the name this IsolatedTable was *constructed* with, which after a
|
|
65
|
+
* mid-transaction `alter table … rename to …` is the pre-rename name. Deliberate:
|
|
66
|
+
* this same instance stays the registered connection's callback object for the rest
|
|
67
|
+
* of the transaction and clears the set at commit/rollback, so the key must not move
|
|
68
|
+
* out from under it. A statement after the rename connects a fresh IsolatedTable under
|
|
69
|
+
* the new name, which builds its own set from `Database.registerConnection`'s savepoint
|
|
70
|
+
* replay. See `IsolationModule.renameTable`.
|
|
38
71
|
*/
|
|
39
72
|
private get savepointsBeforeOverlay();
|
|
40
|
-
|
|
73
|
+
/**
|
|
74
|
+
* @param schemaName Schema name as supplied to `IsolationModule.create()`/`.connect()` — the
|
|
75
|
+
* same identity `IsolationModule.underlyingTables` is keyed by.
|
|
76
|
+
* @param tableName Bare table name from the same source. These MUST NOT be read off
|
|
77
|
+
* `underlyingTable.schemaName` / `.tableName`: `VirtualTable.tableName` is contracted bare,
|
|
78
|
+
* but an underlying module that reports a schema-qualified name there (lamina-quereus does,
|
|
79
|
+
* using the field as a catalogue key) would key this table's overlay as
|
|
80
|
+
* `<dbId>:store.store.widget` while `underlyingTables` holds `store.widget`. The commit
|
|
81
|
+
* flush looks the overlay's key up in `underlyingTables`, misses, and silently discards
|
|
82
|
+
* every staged row. Keying off the connect-time pair keeps both maps on one identity by
|
|
83
|
+
* construction, whatever the underlying self-reports.
|
|
84
|
+
*/
|
|
85
|
+
constructor(db: Database, module: IsolationModule, schemaName: string, tableName: string, underlyingTable: VirtualTable, readCommitted?: boolean);
|
|
41
86
|
/**
|
|
42
87
|
* Gets the tombstone column name from the module.
|
|
43
88
|
*/
|
|
@@ -47,13 +92,14 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
|
|
|
47
92
|
*/
|
|
48
93
|
private getOverlayState;
|
|
49
94
|
/**
|
|
50
|
-
* Throws if this connection's overlay was poisoned by a cross-connection ALTER
|
|
51
|
-
* (see `IsolationModule.alterTable`)
|
|
52
|
-
* PRE-alter column layout,
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* rolling back, which discards the
|
|
95
|
+
* Throws if this connection's overlay was poisoned by a cross-connection DDL: an ALTER
|
|
96
|
+
* that could not migrate it (see `IsolationModule.alterTable`), leaving its rows in the
|
|
97
|
+
* PRE-alter column layout, or a DROP TABLE that removed the table underneath it (see
|
|
98
|
+
* `IsolationModule.destroy`). Either way it can neither be merged into a read nor
|
|
99
|
+
* flushed. Called at the data-op chokepoints (write, the merged read branch, and the
|
|
100
|
+
* commit flush) — never on the committed-snapshot read path, which bypasses the overlay
|
|
101
|
+
* entirely and stays safe. The connection recovers by rolling back, which discards the
|
|
102
|
+
* overlay (and its poison).
|
|
57
103
|
*/
|
|
58
104
|
private assertOverlayUsable;
|
|
59
105
|
/**
|
|
@@ -151,26 +197,89 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
|
|
|
151
197
|
*
|
|
152
198
|
* Instead of position-based merging (which fails when overlay entries have
|
|
153
199
|
* different index key values than the underlying rows they shadow), this:
|
|
154
|
-
* 1.
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
200
|
+
* 1. Full-scans the overlay ONCE, collecting all modified PKs and the non-tombstone
|
|
201
|
+
* data rows that fall inside the query's constraint window
|
|
202
|
+
* 2. Sorts the collected overlay rows by the scan's (indexKey, PK) sort key
|
|
203
|
+
* 3. Queries underlying via secondary index, excluding modified PKs, and merges the
|
|
204
|
+
* sorted overlay rows in by sort key
|
|
205
|
+
*
|
|
206
|
+
* The overlay is deliberately never asked to resolve the query's index name. The
|
|
207
|
+
* underlying module may drive this scan under an index it minted itself (lamina
|
|
208
|
+
* mints `_column_<id>_`, `_compound_<name>_`, `_nd_<name>_`, `_intersect_<ids>_`
|
|
209
|
+
* per plan) — a name no table schema, and therefore no overlay, declares — so
|
|
210
|
+
* re-issuing the index-named FilterInfo against the overlay would throw
|
|
211
|
+
* "Secondary index not found". The isolation layer filters and sorts the overlay
|
|
212
|
+
* delta itself instead.
|
|
158
213
|
*/
|
|
159
214
|
private mergedSecondaryIndexQuery;
|
|
160
215
|
/**
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
*
|
|
216
|
+
* Determine the order the underlying scan emits, from the planner's typed access path.
|
|
217
|
+
*
|
|
218
|
+
* A `fullScan` (or a provably-empty plan) merges by primary key: every underlying module
|
|
219
|
+
* the isolation layer wraps emits an unbounded scan in primary-key order. That is a
|
|
220
|
+
* contract on the underlying, not an inference from any string — see
|
|
221
|
+
* docs/design-isolation-layer.md.
|
|
222
|
+
*
|
|
223
|
+
* `role` is authoritative over `name`: a descriptor with `role: 'primary'` IS the table's
|
|
224
|
+
* primary key however the module named it (an alias like `_primary_1`), so it merges by PK.
|
|
225
|
+
* An `unresolvedIndex` — a name the engine could not resolve to any index, with no
|
|
226
|
+
* module-supplied descriptor — cannot yield a comparator, so we fail loudly rather than
|
|
227
|
+
* silently merge by the wrong sort key.
|
|
167
228
|
*/
|
|
168
|
-
private
|
|
229
|
+
private resolveScanIndex;
|
|
169
230
|
/**
|
|
170
231
|
* Adapts FilterInfo for the overlay table schema (which has an extra tombstone column).
|
|
171
232
|
* The constraints and index references remain the same since the overlay has matching indexes.
|
|
233
|
+
*
|
|
234
|
+
* The one mismatch is the index NAME. The underlying may drive its PK plan under a per-plan
|
|
235
|
+
* alias (e.g. `_primary_1`) that the overlay MemoryTable does not know — the overlay always
|
|
236
|
+
* names its PK index `_primary_`. When the access path is the primary key under such an
|
|
237
|
+
* alias, retarget the FilterInfo's index name to `_primary_` so the overlay re-plans it as a
|
|
238
|
+
* primary-key scan instead of failing to resolve a non-existent secondary index of that name.
|
|
239
|
+
* A genuine secondary scan (or the bare `_primary_`) is returned unchanged.
|
|
172
240
|
*/
|
|
173
241
|
private adaptFilterInfoForOverlay;
|
|
242
|
+
/**
|
|
243
|
+
* Builds the window predicate for the overlay side of a merged secondary-index read.
|
|
244
|
+
*
|
|
245
|
+
* The overlay is full-scanned there (it cannot resolve an underlying-minted index
|
|
246
|
+
* name), so every staged row surfaces — including rows outside the query's window.
|
|
247
|
+
* This predicate re-applies the pushed constraints that the underlying's index seek
|
|
248
|
+
* enforces on its own stream.
|
|
249
|
+
*
|
|
250
|
+
* Interpretation follows the plan kind:
|
|
251
|
+
* - `scan` pushes no window — everything matches.
|
|
252
|
+
* - `eqSeek` / `rangeSeek` / `prefixRangeSeek` / `multiSeek` carry one genuine
|
|
253
|
+
* (column, op, value) triple per constraint entry. Per-column EQ values form an
|
|
254
|
+
* IN set — the planner encodes an IN multi-seek as one EQ constraint per seek
|
|
255
|
+
* value on the same column, and a composite IN as its full per-column
|
|
256
|
+
* cross-product — so EQ matches when the row equals ANY of the column's values,
|
|
257
|
+
* while range bounds all AND together.
|
|
258
|
+
* - `multiRangeSeek` constraint entries are positional placeholders (every arg is
|
|
259
|
+
* stamped GE); the real OR-of-ranges lives in the idxStr `rangeOps` parameters,
|
|
260
|
+
* decoded by {@link buildMultiRangeWindowMatcher}.
|
|
261
|
+
*
|
|
262
|
+
* Comparisons run under the index key column's collation (falling back to the table
|
|
263
|
+
* column's, then BINARY) with seek semantics for NULL: a NULL operand or a NULL row
|
|
264
|
+
* value never matches, mirroring what an index seek returns. Operators the matcher
|
|
265
|
+
* does not interpret (LIKE, MATCH, ...) are ignored — that can only let through
|
|
266
|
+
* rows a residual Filter above still removes, never drop rows.
|
|
267
|
+
*/
|
|
268
|
+
private buildConstraintMatcher;
|
|
269
|
+
/**
|
|
270
|
+
* Window matcher for a `multiRangeSeek` — an OR of ranges over the index's leading
|
|
271
|
+
* key column. The FilterInfo's constraint entries are positional placeholders for
|
|
272
|
+
* this plan kind, so the ranges are decoded from the idxStr `rangeCount`/`rangeOps`
|
|
273
|
+
* parameters exactly as the memory module's scan-plan builder does.
|
|
274
|
+
*/
|
|
275
|
+
private buildMultiRangeWindowMatcher;
|
|
276
|
+
/**
|
|
277
|
+
* Comparison collation for a window-matcher column: the index key column's declared
|
|
278
|
+
* collation when the column is part of the scanned index (the seek's own window
|
|
279
|
+
* follows the index collation), else the table column's declared collation, else
|
|
280
|
+
* BINARY.
|
|
281
|
+
*/
|
|
282
|
+
private constraintCollation;
|
|
174
283
|
/**
|
|
175
284
|
* Queries the overlay table and converts rows to MergeEntry format.
|
|
176
285
|
*
|
|
@@ -194,10 +303,44 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
|
|
|
194
303
|
* @param indexInfo Which index is being scanned. Defaults to primary key scan.
|
|
195
304
|
*/
|
|
196
305
|
private buildMergeConfig;
|
|
306
|
+
/**
|
|
307
|
+
* Per-PK-column comparison functions for this table's current schema, resolved
|
|
308
|
+
* against THIS database's collation registry (so `db.registerCollation` names
|
|
309
|
+
* participate) rather than the process-global built-in trio.
|
|
310
|
+
*
|
|
311
|
+
* A PK column with no declared `COLLATE` resolves to BINARY; a PK definition
|
|
312
|
+
* shorter than the key being compared (or absent entirely) yields BINARY for the
|
|
313
|
+
* trailing positions, matching the prior `collation === undefined` behaviour.
|
|
314
|
+
*
|
|
315
|
+
* Memoized on the schema object so comparator construction — and the per-call
|
|
316
|
+
* {@link keysEqual} — never re-resolves per row. Resolution is not retroactive: a
|
|
317
|
+
* collation registered *after* a comparator was built is not picked up, the same
|
|
318
|
+
* contract `Database.registerCollation` documents engine-wide.
|
|
319
|
+
*
|
|
320
|
+
* NOTE: this is the *comparison* collation only. The store's physical key bytes come
|
|
321
|
+
* from a separate encoder registry that does not consult the database — see
|
|
322
|
+
* `fix/bug-store-key-encoder-ignores-database-collations`.
|
|
323
|
+
*/
|
|
324
|
+
private getPkCollations;
|
|
325
|
+
/**
|
|
326
|
+
* Per-PK-column sort directions (`true` ⇒ DESC), positionally aligned with
|
|
327
|
+
* {@link getPkCollations}. Only the ordering comparator needs them; `keysEqual`
|
|
328
|
+
* asks about equality, which direction cannot change.
|
|
329
|
+
*/
|
|
330
|
+
private getPkDirections;
|
|
331
|
+
private getPkKeyShape;
|
|
197
332
|
/**
|
|
198
333
|
* Gets the primary key comparator, preferring the underlying table's comparator.
|
|
199
334
|
*/
|
|
200
335
|
private getComparePK;
|
|
336
|
+
/**
|
|
337
|
+
* Per-column comparators derived from an index descriptor's key columns — the
|
|
338
|
+
* fallback when the underlying exposes no `getIndexComparator` for the index
|
|
339
|
+
* (always the case for a module-minted synthetic name). Honors each key column's
|
|
340
|
+
* declared direction and collation so the merge walks the underlying's emission
|
|
341
|
+
* order.
|
|
342
|
+
*/
|
|
343
|
+
private buildDescriptorComparators;
|
|
201
344
|
/**
|
|
202
345
|
* Builds a sort key comparator for secondary index scans.
|
|
203
346
|
*
|
|
@@ -213,6 +356,15 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
|
|
|
213
356
|
* Gets the primary key column indices from the underlying table schema.
|
|
214
357
|
*/
|
|
215
358
|
getPrimaryKeyIndices(): number[];
|
|
359
|
+
/**
|
|
360
|
+
* Coerce each cell to its declared column logical type before PK extraction and
|
|
361
|
+
* conflict detection — the same step StoreTable.coerceRow / MemoryTableManager.performInsert
|
|
362
|
+
* run. Without it, an ON CONFLICT insert whose proposed key is a different storage class than
|
|
363
|
+
* the stored key (TEXT '1' into an INTEGER key holding 1) probes the underlying with the
|
|
364
|
+
* un-coerced key, misses the committed row, and stages the proposed row instead of updating
|
|
365
|
+
* the existing one (bug-store-isolation-upsert-affinity-coerced-pk).
|
|
366
|
+
*/
|
|
367
|
+
private coerceRow;
|
|
216
368
|
/**
|
|
217
369
|
* Performs INSERT, UPDATE, or DELETE on the overlay.
|
|
218
370
|
* Changes are not visible to underlying until commit.
|
|
@@ -298,11 +450,74 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
|
|
|
298
450
|
*/
|
|
299
451
|
private checkMergedPKConflict;
|
|
300
452
|
/**
|
|
301
|
-
*
|
|
302
|
-
*
|
|
303
|
-
*
|
|
453
|
+
* Finds a row conflicting with `newRow` on `uc.columns` across the MERGED view —
|
|
454
|
+
* this connection's overlay superimposed on the underlying committed rows —
|
|
455
|
+
* excluding `selfPks`. For partial UNIQUE, candidates outside the predicate's scope
|
|
456
|
+
* are skipped.
|
|
457
|
+
*
|
|
458
|
+
* The merged view splits cleanly into two disjoint halves, each searched the way it
|
|
459
|
+
* is cheap to search:
|
|
460
|
+
*
|
|
461
|
+
* merged view = (overlay rows) ∪ (underlying rows with no overlay entry)
|
|
462
|
+
*
|
|
463
|
+
* Phase 1 scans the small in-memory overlay; Phase 2 seeks/scans the large
|
|
464
|
+
* underlying, skipping any candidate whose PK the overlay already owns (Phase 1's
|
|
465
|
+
* territory, whatever the underlying still says). Together they cover the merged
|
|
466
|
+
* view exactly once with no row visited twice.
|
|
467
|
+
*
|
|
468
|
+
* Phase 1 runs first, so when the constraint was ALREADY violated an overlay-side
|
|
469
|
+
* conflict is reported in preference to an underlying one. Under a satisfied
|
|
470
|
+
* constraint at most one conflicting row can exist, so this tie-break only changes
|
|
471
|
+
* WHICH row is named in that pre-violated case.
|
|
304
472
|
*/
|
|
305
473
|
private findMergedUniqueConflict;
|
|
474
|
+
/**
|
|
475
|
+
* Phase 1 — scan the overlay (this connection's uncommitted write set, small and
|
|
476
|
+
* in-memory) for a live row conflicting with `newRow`. Tombstones and `selfPks` are
|
|
477
|
+
* skipped; a matching live overlay row IS the merged row (stripped of the trailing
|
|
478
|
+
* tombstone column), and its overlay value — not any stale underlying value — is
|
|
479
|
+
* what the merged view holds for that PK
|
|
480
|
+
* (isolation-merged-unique-stale-underlying-false-positive).
|
|
481
|
+
*/
|
|
482
|
+
private findOverlayUniqueConflict;
|
|
483
|
+
/**
|
|
484
|
+
* Phase 2 — find an underlying committed row conflicting with `newRow`, skipping
|
|
485
|
+
* `selfPks` and any PK the overlay already owns (Phase 1's territory). The lookup is
|
|
486
|
+
* an index seek when {@link canSeekForConstraint} allows it, else the full scan —
|
|
487
|
+
* either way the per-column match runs, so a module that ignores the index hint and
|
|
488
|
+
* returns extra rows stays correct. `getOverlayRow` fires only for the candidates the
|
|
489
|
+
* seek actually returned, so it no longer costs one lookup per underlying row.
|
|
490
|
+
*/
|
|
491
|
+
private findUnderlyingUniqueConflict;
|
|
492
|
+
/**
|
|
493
|
+
* True-match test shared by both merged-check phases so they compare identically:
|
|
494
|
+
* `candidate` matches `newRow` on every constrained column under that column's
|
|
495
|
+
* enforcement collation (NULLs never match), and — for a partial UNIQUE — the
|
|
496
|
+
* predicate holds for `candidate`.
|
|
497
|
+
*
|
|
498
|
+
* The per-column collation (the index's per-column COLLATE for an index-derived
|
|
499
|
+
* UNIQUE, else the declared column collation) enforces a UNIQUE over a collated
|
|
500
|
+
* column against merged rows through the isolation path
|
|
501
|
+
* (unique-constraint-honors-column-collation / store-index-derived-unique).
|
|
502
|
+
*/
|
|
503
|
+
private rowMatchesUniqueConstraint;
|
|
504
|
+
/**
|
|
505
|
+
* The secondary index Phase 2 may seek for `uc`, or null to fall back to a full scan.
|
|
506
|
+
*
|
|
507
|
+
* Seek only when the constraint was synthesized from a `CREATE UNIQUE INDEX`
|
|
508
|
+
* (`derivedFromIndex` names a live entry in `tableSchema.indexes`) AND every key
|
|
509
|
+
* column's effective enforcement collation is BINARY.
|
|
510
|
+
*
|
|
511
|
+
* NOTE: the BINARY gate is load-bearing, not an optimisation choice. The store's
|
|
512
|
+
* physical index key bytes come from a separate encoder registry that does NOT
|
|
513
|
+
* consult the database's collation registry
|
|
514
|
+
* (backlog/debt-store-index-keys-use-column-collation, see the comment at
|
|
515
|
+
* getPkKeyShape above). Seeking a NOCASE index for 'B@X' would miss the committed
|
|
516
|
+
* 'b@x' that the full scan catches, turning this perf fix into a LOST UNIQUE
|
|
517
|
+
* violation. Widen this gate (to per-column enforcement collations generally) only
|
|
518
|
+
* once that encoder defect is fixed.
|
|
519
|
+
*/
|
|
520
|
+
private canSeekForConstraint;
|
|
306
521
|
/**
|
|
307
522
|
* Checks all non-PK UNIQUE constraints against the merged view.
|
|
308
523
|
* Returns null when all pass or REPLACE evictions succeed.
|
|
@@ -317,41 +532,12 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
|
|
|
317
532
|
begin(): Promise<void>;
|
|
318
533
|
sync(): Promise<void>;
|
|
319
534
|
commit(): Promise<void>;
|
|
320
|
-
/**
|
|
321
|
-
* Flushes overlay changes to underlying (if any) and discards the overlay.
|
|
322
|
-
* Shared by commit() and onConnectionCommit().
|
|
323
|
-
*/
|
|
324
|
-
private flushAndClearOverlay;
|
|
325
|
-
/**
|
|
326
|
-
* Flushes all overlay changes to the underlying table.
|
|
327
|
-
* Called during commit to persist changes.
|
|
328
|
-
*
|
|
329
|
-
* This method manages the underlying table's transaction lifecycle independently
|
|
330
|
-
* to ensure that flushed data is committed and won't be rolled back by subsequent
|
|
331
|
-
* transaction rollbacks.
|
|
332
|
-
*/
|
|
333
|
-
private flushOverlayToUnderlying;
|
|
334
|
-
/**
|
|
335
|
-
* Asserts that an underlying write performed during the commit flush succeeded.
|
|
336
|
-
*
|
|
337
|
-
* The overlay's merged-view pre-checks ({@link checkMergedPKConflict} /
|
|
338
|
-
* {@link checkMergedUniqueConstraints}) resolve every constraint before commit, so a
|
|
339
|
-
* `constraint` result returned here means a real invariant was violated *after* those
|
|
340
|
-
* checks. Historically this result was discarded, silently dropping the colliding
|
|
341
|
-
* write and surfacing as data corruption. Convert it into a loud INTERNAL error; the
|
|
342
|
-
* caller's try/catch rolls back the underlying flush transaction and rethrows.
|
|
343
|
-
*/
|
|
344
|
-
private assertFlushWriteOk;
|
|
345
|
-
/**
|
|
346
|
-
* Checks if a row with the given primary key exists in the underlying table.
|
|
347
|
-
* Uses O(log n) point lookup via the PK index.
|
|
348
|
-
*/
|
|
349
|
-
private rowExistsInUnderlying;
|
|
350
535
|
rollback(): Promise<void>;
|
|
351
536
|
/**
|
|
352
|
-
* Discards the connection-scoped overlay entirely.
|
|
353
|
-
*
|
|
354
|
-
* the reference
|
|
537
|
+
* Discards the connection-scoped overlay entirely. The module frees the overlay's
|
|
538
|
+
* staging table (see IsolationModule.clearConnectionOverlay → releaseOverlayTable) rather
|
|
539
|
+
* than merely dropping the reference — the overlay module's registry pins the manager, so
|
|
540
|
+
* a bare reference-drop leaked it for the life of the Database. A fresh overlay is created
|
|
355
541
|
* lazily via ensureOverlay() on the next write.
|
|
356
542
|
*/
|
|
357
543
|
private clearOverlay;
|
|
@@ -361,7 +547,16 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
|
|
|
361
547
|
disconnect(): Promise<void>;
|
|
362
548
|
rename(newName: string): Promise<void>;
|
|
363
549
|
alterSchema(changeInfo: SchemaChangeInfo): Promise<void>;
|
|
364
|
-
|
|
550
|
+
/**
|
|
551
|
+
* Index DDL delegates to the module rather than driving the underlying and the overlay
|
|
552
|
+
* directly. The module owns the full protocol — validating against the issuing
|
|
553
|
+
* connection's effective rows, then REBUILDING every affected overlay under the new
|
|
554
|
+
* schema — and a bare `underlying.createIndex()` + `overlay.createIndex()` pair silently
|
|
555
|
+
* skips both halves. The engine only ever reaches the module-level hook, so these
|
|
556
|
+
* instance methods exist for a module that wraps `IsolationModule` in turn; routing them
|
|
557
|
+
* through the module keeps that path on the same protocol.
|
|
558
|
+
*/
|
|
559
|
+
createIndex(indexInfo: IndexSchema, rows?: EffectiveRowSource): Promise<void>;
|
|
365
560
|
dropIndex(indexName: string): Promise<void>;
|
|
366
561
|
/**
|
|
367
562
|
* Returns whether there are pending uncommitted changes.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isolated-table.d.ts","sourceRoot":"","sources":["../../src/isolated-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"isolated-table.d.ts","sourceRoot":"","sources":["../../src/isolated-table.ts"],"names":[],"mappings":"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"}
|