@quereus/isolation 4.13.0 → 4.14.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.
package/dist/src/flush.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { QuereusError, StatusCode, isConstraintViolation } from '@quereus/quereus';
2
- import { makePkPointLookupFilter } from './filter-info.js';
2
+ import { makePkEquals, probeRowByPk } from './pk-probe.js';
3
3
  import { collectOverlayEntries } from './overlay-rows.js';
4
4
  /**
5
5
  * Applies every staged overlay row to the underlying table WITHOUT committing.
@@ -55,11 +55,16 @@ export async function applyOverlayToUnderlying(underlyingTable, overlayTable, to
55
55
  // staged drafts). Each PK appears at most once in the overlay, so no write in
56
56
  // this flush can change another entry's existence answer — hoisting the
57
57
  // probes is answer-preserving as well as one fewer read per written row.
58
+ //
59
+ // The equality test is built once per flush: the probe verifies each returned row's
60
+ // key rather than trusting the seek, and that comparison must be the collation-aware
61
+ // / semantic-ordering one the rest of the layer keys rows by.
62
+ const pkEquals = makePkEquals(underlyingSchema, underlyingTable.db.getCollationResolver());
58
63
  const existsInUnderlying = new Map();
59
64
  for (const entry of ordered) {
60
65
  if (entry.isTombstone)
61
66
  continue;
62
- existsInUnderlying.set(entry, await rowExistsInUnderlying(underlyingTable, pkIndices, entry.pk));
67
+ existsInUnderlying.set(entry, await rowExistsInUnderlying(underlyingTable, pkIndices, entry.pk, pkEquals));
63
68
  }
64
69
  for (const entry of ordered) {
65
70
  if (entry.isTombstone) {
@@ -96,15 +101,14 @@ export async function applyOverlayToUnderlying(underlyingTable, overlayTable, to
96
101
  }
97
102
  /**
98
103
  * Checks if a row with the given primary key exists in the underlying table.
99
- * Uses an O(log n) point lookup via the PK index.
104
+ *
105
+ * Drives the PK index for an O(log n) lookup where the module can serve one, but
106
+ * verifies the key of every row it gets back — see {@link probeRowByPk}. Believing an
107
+ * unverified first row here classifies a fresh PK as an `update`, which writes against a
108
+ * key that does not exist and silently loses the row.
100
109
  */
101
- async function rowExistsInUnderlying(underlyingTable, pkIndices, pk) {
102
- if (!underlyingTable.query)
103
- return false;
104
- for await (const _row of underlyingTable.query(makePkPointLookupFilter(pkIndices, pk))) {
105
- return true;
106
- }
107
- return false;
110
+ async function rowExistsInUnderlying(underlyingTable, pkIndices, pk, pkEquals) {
111
+ return (await probeRowByPk(underlyingTable, pkIndices, pk, pkEquals)) !== undefined;
108
112
  }
109
113
  /**
110
114
  * Asserts that an underlying write performed during the commit flush succeeded.
@@ -1 +1 @@
1
- {"version":3,"file":"flush.js","sourceRoot":"","sources":["../../src/flush.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flush.js","sourceRoot":"","sources":["../../src/flush.ts"],"names":[],"mappings":"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"}
@@ -42,27 +42,14 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
42
42
  */
43
43
  private readonly collationResolver;
44
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.
45
+ * The PK key shape (per-column comparison functions and sort directions) and the
46
+ * equality test derived from it, memoized against the `TableSchema` object identity —
47
+ * an `alter table` hands this instance a fresh (frozen) schema object, which
48
+ * invalidates the entry. Both are built by `pk-probe.ts`, which is also what the
49
+ * commit flush uses, so the merge order, the write path's "same logical key" test,
50
+ * and the flush's existence probes cannot drift apart.
48
51
  */
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?;
57
- /**
58
- * Per-PK-column typed EQUALITY comparators for semantic-ordering members (TIMESPAN,
59
- * JSON — see the engine's `hasSemanticOrdering`), `undefined` elsewhere. The
60
- * underlying backends collapse semantically-equal PK spellings onto one row (the
61
- * memory table's typed BTree; the store's `groupKey`-transformed key bytes), so
62
- * shadowing and self-PK questions here must call 'PT1H' and 'PT60M' the same key
63
- * too. Memoized against the schema object like {@link pkCollationCache}.
64
- */
65
- private pkSemanticCache?;
52
+ private pkShapeCache?;
66
53
  /**
67
54
  * The `VirtualTable` statistics pair, forwarded to the wrapped table.
68
55
  *
@@ -92,7 +79,6 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
92
79
  */
93
80
  readonly getStatistics?: () => Promise<TableStatistics | undefined> | TableStatistics | undefined;
94
81
  readonly saveStatistics?: (stats: TableStatistics) => Promise<void>;
95
- private getPkSemanticComparators;
96
82
  /**
97
83
  * Returns the connection-scoped set of savepoint depths that pre-date the overlay.
98
84
  * Stored in IsolationModule (keyed by db+schema+table) so all IsolatedTable instances
@@ -286,12 +272,17 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
286
272
  */
287
273
  private adaptFilterInfoForOverlay;
288
274
  /**
289
- * Builds the window predicate for the overlay side of a merged secondary-index read.
275
+ * Builds the window predicate for the overlay side of a merged read.
276
+ *
277
+ * Both merged paths need it, for the same reason: the overlay's stream is not bound by
278
+ * the constraints the underlying negotiated. A merged secondary read full-scans the
279
+ * overlay outright (it cannot resolve an underlying-minted index name); a merged primary
280
+ * read hands the overlay the underlying's FilterInfo, which the overlay module never
281
+ * claimed and may legally answer with a superset. Either way this predicate re-applies
282
+ * the pushed constraints that the underlying's index seek enforces on its own stream.
290
283
  *
291
- * The overlay is full-scanned there (it cannot resolve an underlying-minted index
292
- * name), so every staged row surfaces — including rows outside the query's window.
293
- * This predicate re-applies the pushed constraints that the underlying's index seek
294
- * enforces on its own stream.
284
+ * Returns the shared {@link MATCH_ALL_ROWS} when the scan pushes no window, so callers
285
+ * can skip the per-row call entirely on the full-scan path.
295
286
  *
296
287
  * Interpretation follows the plan kind:
297
288
  * - `scan` pushes no window — everything matches.
@@ -349,6 +340,19 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
349
340
  *
350
341
  * Uses the same FilterInfo as the underlying query so both streams are in the same order.
351
342
  * For secondary index scans, the sort key includes both the index key and primary key.
343
+ *
344
+ * The window is re-applied here rather than trusted: `filterInfo` was negotiated with
345
+ * the UNDERLYING module, and the engine dropped the residual on the underlying's claim,
346
+ * but the OVERLAY module never claimed anything. A module is entitled to answer a seek
347
+ * it cannot serve with any superset of the requested rows — up to the whole table — so a
348
+ * host-supplied scan-only `IsolationConfig.overlay` would otherwise merge staged rows
349
+ * from outside the query's window into the answer. This is the same re-check
350
+ * {@link mergedSecondaryIndexQuery} already runs over its full overlay scan, and a no-op
351
+ * (the identity matcher) for the full-scan reads the default memory overlay serves.
352
+ *
353
+ * Tombstones bypass the window deliberately: a tombstone carries null non-PK columns, so
354
+ * a window over a non-key column would reject it, and an out-of-window tombstone is inert
355
+ * anyway — it can only shadow a PK the underlying stream does not carry.
352
356
  */
353
357
  private queryOverlayAsMergeEntries;
354
358
  /**
@@ -368,33 +372,18 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
368
372
  */
369
373
  private buildMergeConfig;
370
374
  /**
371
- * Per-PK-column comparison functions for this table's current schema, resolved
372
- * against THIS database's collation registry (so `db.registerCollation` names
373
- * participate) rather than the process-global built-in trio.
374
- *
375
- * A PK column with no declared `COLLATE` resolves to BINARY; a PK definition
376
- * shorter than the key being compared (or absent entirely) yields BINARY for the
377
- * trailing positions, matching the prior `collation === undefined` behaviour.
375
+ * Per-PK-column comparison functions and sort directions for this table's current
376
+ * schema, resolved against THIS database's collation registry (so
377
+ * `db.registerCollation` names participate) rather than the process-global built-in
378
+ * trio. See {@link makePkKeyShape} for what each comparator is.
378
379
  *
379
380
  * Memoized on the schema object so comparator construction — and the per-call
380
- * {@link keysEqual} — never re-resolves per row. Resolution is not retroactive: a
381
- * collation registered *after* a comparator was built is not picked up, the same
382
- * contract `Database.registerCollation` documents engine-wide.
383
- *
384
- * NOTE: this is the *comparison* collation only. The store's physical key bytes are
385
- * produced by the key NORMALIZER of the same collation, resolved through the same
386
- * connection's registry (`bug-store-key-encoder-ignores-database-collations`, landed),
387
- * so the two agree on equality — but only on ORDER for a collation asserting
388
- * `orderPreserving` (see docs/store.md § Order preservation).
381
+ * {@link keysEqual} — never re-resolves per row.
389
382
  */
390
- private getPkCollations;
391
- /**
392
- * Per-PK-column sort directions (`true` ⇒ DESC), positionally aligned with
393
- * {@link getPkCollations}. Only the ordering comparator needs them; `keysEqual`
394
- * asks about equality, which direction cannot change.
395
- */
396
- private getPkDirections;
397
383
  private getPkKeyShape;
384
+ /** The collation-aware / semantic-ordering "same logical key" test for this schema. */
385
+ private getPkEquals;
386
+ private getPkShapeEntry;
398
387
  /**
399
388
  * Gets the primary key comparator, preferring the underlying table's comparator.
400
389
  */
@@ -468,24 +457,38 @@ export declare class IsolatedTable extends VirtualTable implements IsolatedTable
468
457
  */
469
458
  private attachEvicted;
470
459
  /**
471
- * Gets a row from the overlay by primary key using O(log n) point lookup.
460
+ * Gets a row from the overlay by primary key, driving an O(log n) point lookup and
461
+ * verifying the key of whatever comes back (see {@link probeRowByPk}). The overlay
462
+ * schema appends the tombstone column AFTER the table's own columns, so the table's
463
+ * PK column indices address the overlay row unchanged.
464
+ *
465
+ * The default overlay is a memory table that serves the seek, so verification is a
466
+ * no-op there; it is load-bearing when a host supplies a scan-only module as
467
+ * `IsolationConfig.overlay`.
472
468
  */
473
469
  private getOverlayRow;
474
470
  /**
475
471
  * Creates a FilterInfo for a full table scan (no constraints).
476
472
  */
477
473
  private createFullScanFilterInfo;
478
- /**
479
- * Creates a FilterInfo for a primary key point lookup (equality on all PK columns).
480
- * This produces O(log n) lookups instead of O(n) full scans.
481
- */
482
- private buildPKPointLookupFilter;
483
474
  /**
484
475
  * Returns the compiled predicate for a partial-UNIQUE constraint, or undefined
485
476
  * when the constraint covers the full table. Compilation is memoized per
486
477
  * UniqueConstraintSchema instance so the hot UNIQUE-check path doesn't recompile.
487
478
  */
488
479
  private compileFor;
480
+ /**
481
+ * "Same logical key?" — compared under each PK column's declared collation, not
482
+ * BINARY. The underlying store keys rows collation-aware (e.g. a NOCASE text PK), so
483
+ * a case-only PK rewrite ('apple' → 'APPLE') is the SAME logical key. A binary
484
+ * comparison here would mis-classify it as a PK relocation, then resolve the "new"
485
+ * key back to the same physical underlying row and raise a false UNIQUE PK conflict.
486
+ * A semantic-ordering member compares through its type's `compare` for the same
487
+ * reason: both backends key 'PT1H' and 'PT60M' as one row.
488
+ *
489
+ * This is the same function the PK probes verify their returned rows with — one
490
+ * definition, so the write path and the probes cannot disagree about key identity.
491
+ */
489
492
  private keysEqual;
490
493
  private getUnderlyingRow;
491
494
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"isolated-table.d.ts","sourceRoot":"","sources":["../../src/isolated-table.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"isolated-table.d.ts","sourceRoot":"","sources":["../../src/isolated-table.ts"],"names":[],"mappings":"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"}