@quereus/quereus 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/func/builtins/explain.js +1 -1
- package/dist/src/func/builtins/explain.js.map +1 -1
- package/dist/src/planner/mutation/capture-correlation.d.ts +57 -0
- package/dist/src/planner/mutation/capture-correlation.d.ts.map +1 -0
- package/dist/src/planner/mutation/capture-correlation.js +57 -0
- package/dist/src/planner/mutation/capture-correlation.js.map +1 -0
- package/dist/src/planner/mutation/decomposition.d.ts.map +1 -1
- package/dist/src/planner/mutation/decomposition.js +86 -23
- package/dist/src/planner/mutation/decomposition.js.map +1 -1
- package/dist/src/planner/mutation/lens-enforcement.d.ts.map +1 -1
- package/dist/src/planner/mutation/lens-enforcement.js +15 -20
- package/dist/src/planner/mutation/lens-enforcement.js.map +1 -1
- package/dist/src/planner/mutation/multi-source.d.ts +52 -11
- package/dist/src/planner/mutation/multi-source.d.ts.map +1 -1
- package/dist/src/planner/mutation/multi-source.js +273 -86
- package/dist/src/planner/mutation/multi-source.js.map +1 -1
- package/dist/src/planner/mutation/set-op.d.ts.map +1 -1
- package/dist/src/planner/mutation/set-op.js +4 -12
- package/dist/src/planner/mutation/set-op.js.map +1 -1
- package/dist/src/planner/mutation/single-source.js +1 -1
- package/dist/src/planner/mutation/single-source.js.map +1 -1
- package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/alter-table.js +8 -10
- package/dist/src/runtime/emit/alter-table.js.map +1 -1
- package/dist/src/runtime/emit/materialized-view-helpers.d.ts +16 -4
- package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -1
- package/dist/src/runtime/emit/materialized-view-helpers.js +182 -25
- package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -1
- package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -1
- package/dist/src/runtime/emit/materialized-view.js +1 -1
- package/dist/src/runtime/emit/materialized-view.js.map +1 -1
- package/dist/src/schema/ddl-generator.d.ts.map +1 -1
- package/dist/src/schema/ddl-generator.js +65 -24
- package/dist/src/schema/ddl-generator.js.map +1 -1
- package/dist/src/schema/lens-ack.d.ts +1 -1
- package/dist/src/schema/lens-ack.js +2 -2
- package/dist/src/schema/lens-compiler.d.ts.map +1 -1
- package/dist/src/schema/lens-compiler.js +63 -34
- package/dist/src/schema/lens-compiler.js.map +1 -1
- package/dist/src/schema/lens-prover.d.ts +4 -4
- package/dist/src/schema/lens-prover.d.ts.map +1 -1
- package/dist/src/schema/lens-prover.js +13 -5
- package/dist/src/schema/lens-prover.js.map +1 -1
- package/dist/src/schema/lens.d.ts +1 -1
- package/dist/src/schema/manager.d.ts.map +1 -1
- package/dist/src/schema/manager.js +25 -13
- package/dist/src/schema/manager.js.map +1 -1
- package/dist/src/schema/reserved-tags.js +1 -1
- package/dist/src/schema/reserved-tags.js.map +1 -1
- package/dist/src/schema/schema-differ.d.ts.map +1 -1
- package/dist/src/schema/schema-differ.js +4 -3
- package/dist/src/schema/schema-differ.js.map +1 -1
- package/dist/src/schema/table.d.ts +41 -34
- package/dist/src/schema/table.d.ts.map +1 -1
- package/dist/src/schema/table.js +24 -43
- package/dist/src/schema/table.js.map +1 -1
- package/dist/src/vtab/filter-info.d.ts +9 -0
- package/dist/src/vtab/filter-info.d.ts.map +1 -1
- package/dist/src/vtab/filter-info.js +10 -1
- package/dist/src/vtab/filter-info.js.map +1 -1
- package/dist/src/vtab/memory/layer/alter-column.d.ts +8 -1
- package/dist/src/vtab/memory/layer/alter-column.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/alter-column.js +20 -10
- package/dist/src/vtab/memory/layer/alter-column.js.map +1 -1
- package/dist/src/vtab/memory/layer/base.d.ts +9 -1
- package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/base.js +12 -1
- package/dist/src/vtab/memory/layer/base.js.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts +23 -18
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +44 -33
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/dist/src/vtab/memory/layer/row-convert.d.ts +13 -0
- package/dist/src/vtab/memory/layer/row-convert.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/row-convert.js +24 -0
- package/dist/src/vtab/memory/layer/row-convert.js.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.d.ts +21 -7
- package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.js +30 -14
- package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
- package/dist/src/vtab/module.d.ts +20 -2
- package/dist/src/vtab/module.d.ts.map +1 -1
- package/package.json +3 -3
|
@@ -2273,9 +2273,9 @@ export class MemoryTableManager {
|
|
|
2273
2273
|
throw new QuereusError(`Duplicate column '${columns[pk.index].name}' in PRIMARY KEY definition`, StatusCode.ERROR);
|
|
2274
2274
|
}
|
|
2275
2275
|
seen.add(pk.index);
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2276
|
+
// A nullable member is keyable here: this backend compares NULL == NULL as
|
|
2277
|
+
// equal and orders NULL first, so a NULL-containing key is an ordinary key.
|
|
2278
|
+
// See docs/schema.md § Primary-key nullability.
|
|
2279
2279
|
}
|
|
2280
2280
|
return rekeySchemaPrimaryKey(this.tableSchema, newPkColumns);
|
|
2281
2281
|
}
|
|
@@ -2299,28 +2299,29 @@ export class MemoryTableManager {
|
|
|
2299
2299
|
* untouched — hence no `mapRow` — and only the comparator the structures are keyed by moves.
|
|
2300
2300
|
* `newSchema` carries the new collations, so the probe indexes compare as the rebuilt ones will.
|
|
2301
2301
|
*
|
|
2302
|
-
* The primary key:
|
|
2303
|
-
* ({@link validateRekeyedPrimaryKey}): no layer in the chain, base included, may hold a
|
|
2304
|
-
* That is what lets every apply step succeed unconditionally, and what
|
|
2305
|
-
* `TransactionLayer.rekeyPrimaryKey`
|
|
2306
|
-
*
|
|
2307
|
-
*
|
|
2308
|
-
*
|
|
2309
|
-
*
|
|
2310
|
-
*
|
|
2311
|
-
*
|
|
2312
|
-
*
|
|
2313
|
-
* of its own.
|
|
2302
|
+
* The primary key: a change that moves a PK member's keys (`pkColumnRekeyed`) gets a stricter
|
|
2303
|
+
* pre-pass ({@link validateRekeyedPrimaryKey}): no layer in the chain, base included, may hold a
|
|
2304
|
+
* collision. That is what lets every apply step succeed unconditionally, and what
|
|
2305
|
+
* `TransactionLayer.rekeyPrimaryKey` / `convertColumn` rely on. Both arms can set it: `set
|
|
2306
|
+
* collate` moves the comparator (the `structuresRekeyed` arm, values untouched), and the `set
|
|
2307
|
+
* not null` backfill moves the key VALUES (the rewrite arm — key membership does not imply NOT
|
|
2308
|
+
* NULL, so any key column can be nullable and two NULL keys can converge on one DEFAULT).
|
|
2309
|
+
* The rewrite arm probes the CONVERTED rows through the same `mapRow`, on both of the pass's
|
|
2310
|
+
* row sets: the effective rows decide legality, and the layer chain — whose base rebuild is
|
|
2311
|
+
* what would merge two committed rows — decides representability. A retype of a PK column is
|
|
2312
|
+
* rejected upstream, so `rewrite` + `pkColumnRekeyed` is only ever the backfill.
|
|
2314
2313
|
*/
|
|
2315
2314
|
async validateAlterColumnPlan(plan, rows) {
|
|
2316
2315
|
if (plan.rewrite) {
|
|
2317
2316
|
const { convert, convertNulls } = plan.rewrite;
|
|
2318
|
-
await this.validateRekeyedUniqueStructures(plan.newSchema, plan.colIndex, rows,
|
|
2319
2317
|
// Unlike `convertBaseRows`, a conversion failure here is NOT swallowed. Every row
|
|
2320
2318
|
// the probe sees is visible to the transaction, and the `set data type` pre-pass
|
|
2321
2319
|
// already proved each one convertible, so a throw is unreachable; surfacing it as
|
|
2322
2320
|
// MISMATCH still beats probing a stale value that could mask a collision.
|
|
2323
|
-
row => convertRowAtIndex(row, plan.colIndex, convert, convertNulls)
|
|
2321
|
+
const mapRow = row => convertRowAtIndex(row, plan.colIndex, convert, convertNulls);
|
|
2322
|
+
await this.validateRekeyedUniqueStructures(plan.newSchema, plan.colIndex, rows, mapRow);
|
|
2323
|
+
if (plan.pkColumnRekeyed)
|
|
2324
|
+
await this.validateRekeyedPrimaryKey(plan.newSchema, rows, mapRow);
|
|
2324
2325
|
}
|
|
2325
2326
|
else if (plan.structuresRekeyed) {
|
|
2326
2327
|
await this.validateRekeyedUniqueStructures(plan.newSchema, plan.colIndex, rows);
|
|
@@ -2367,7 +2368,10 @@ export class MemoryTableManager {
|
|
|
2367
2368
|
// `set not null` (`convertNulls`): null base values are mapped to the DEFAULT literal.
|
|
2368
2369
|
const convertedBaseRows = this.convertBaseRows(plan.colIndex, plan.rewrite.convert, plan.rewrite.convertNulls);
|
|
2369
2370
|
undo.basePrimaryTree = this.baseLayer.primaryTree;
|
|
2370
|
-
|
|
2371
|
+
// `assertDistinctKeys` only when the rewrite moves the KEY values (the backfill of a
|
|
2372
|
+
// key member): the pre-pass has already refused any converging pair, so this is the
|
|
2373
|
+
// invariant check that turns a hole in it into a throw instead of a merged row.
|
|
2374
|
+
this.baseLayer.rebuildPrimaryTreeFromRows(convertedBaseRows, plan.pkColumnRekeyed);
|
|
2371
2375
|
}
|
|
2372
2376
|
else if (plan.structuresRekeyed) {
|
|
2373
2377
|
this.baseLayer.rebuildAllSecondaryIndexes();
|
|
@@ -3155,8 +3159,10 @@ export class MemoryTableManager {
|
|
|
3155
3159
|
}
|
|
3156
3160
|
}
|
|
3157
3161
|
/**
|
|
3158
|
-
* The primary-key re-key pre-pass, shared by
|
|
3159
|
-
* `alter column … set collate` on a PK member (the comparator moves)
|
|
3162
|
+
* The primary-key re-key pre-pass, shared by every statement that moves the key:
|
|
3163
|
+
* `alter column … set collate` on a PK member (the comparator moves), `alter column … set
|
|
3164
|
+
* not null` on a PK member (the key VALUES move — null → DEFAULT — so the caller passes the
|
|
3165
|
+
* conversion as `mapRow` and both passes judge the post-backfill rows), and
|
|
3160
3166
|
* `alter table … alter primary key` (the key columns move — {@link alterPrimaryKey}).
|
|
3161
3167
|
* Runs before anything is mutated, so a rejection leaves the table, the schema and the
|
|
3162
3168
|
* transaction untouched.
|
|
@@ -3202,34 +3208,37 @@ export class MemoryTableManager {
|
|
|
3202
3208
|
* collisions anywhere in the chain, every primary key resolves to at most one row in
|
|
3203
3209
|
* each layer under the new definition.
|
|
3204
3210
|
*/
|
|
3205
|
-
async validateRekeyedPrimaryKey(newSchema, rows) {
|
|
3211
|
+
async validateRekeyedPrimaryKey(newSchema, rows, mapRow) {
|
|
3206
3212
|
const newPkFunctions = createPrimaryKeyFunctions(newSchema, this.collationResolver);
|
|
3207
3213
|
const connection = this.ddlConnection();
|
|
3208
3214
|
const view = connection
|
|
3209
3215
|
? (connection.pendingTransactionLayer ?? connection.readLayer)
|
|
3210
3216
|
: this.baseLayer;
|
|
3211
|
-
await this.assertNoPrimaryKeyCollisionInRows(rows ? rows() : this.effectiveDdlRows(), newPkFunctions, primaryKeyArity(newSchema) !== 1);
|
|
3217
|
+
await this.assertNoPrimaryKeyCollisionInRows(rows ? rows() : this.effectiveDdlRows(), newPkFunctions, primaryKeyArity(newSchema) !== 1, mapRow);
|
|
3212
3218
|
// `ensureSchemaChangeSafety` has already drained every committed layer into the base and
|
|
3213
3219
|
// rejected sibling connections with open work, so this walk covers the transaction's own
|
|
3214
3220
|
// layers plus the base — every tree a rollback could restore.
|
|
3215
3221
|
for (let layer = rows ? view : view.getParent(); layer; layer = layer.getParent()) {
|
|
3216
|
-
this.assertNoPrimaryKeyCollisionInLayer(layer, newPkFunctions);
|
|
3222
|
+
this.assertNoPrimaryKeyCollisionInLayer(layer, newPkFunctions, mapRow);
|
|
3217
3223
|
}
|
|
3218
3224
|
}
|
|
3219
3225
|
/**
|
|
3220
3226
|
* A duplicate-key detector over the new primary key functions: feed it rows, and it returns
|
|
3221
3227
|
* the key the moment one repeats. Shared by both arms of {@link validateRekeyedPrimaryKey}
|
|
3222
3228
|
* so the async (effective-row) arm and the sync (layer-tree) arm cannot disagree about what
|
|
3223
|
-
* counts as a collision.
|
|
3229
|
+
* counts as a collision. `mapRow`, when given, is applied to each row BEFORE its key is
|
|
3230
|
+
* extracted — the value-rewriting ALTER's per-row conversion, so the probe judges the keys
|
|
3231
|
+
* the rows will have AFTER the rewrite, not the ones stored now.
|
|
3224
3232
|
*
|
|
3225
3233
|
* NOTE: the probe holds every row it has seen, because the BTree derives its key from the
|
|
3226
3234
|
* stored value — so an ALTER over a large table transiently doubles that table's row
|
|
3227
3235
|
* references. If a wide table ever makes this the memory peak, key the probe by the PK
|
|
3228
3236
|
* encoding (`primaryKeyFunctions.encode`) into a `Set` instead of by the row.
|
|
3229
3237
|
*/
|
|
3230
|
-
makePrimaryKeyProbe(pkFunctions) {
|
|
3238
|
+
makePrimaryKeyProbe(pkFunctions, mapRow) {
|
|
3231
3239
|
const probe = new BTree((row) => pkFunctions.extractFromRow(row), pkFunctions.compare);
|
|
3232
|
-
return (
|
|
3240
|
+
return (stored) => {
|
|
3241
|
+
const row = mapRow ? mapRow(stored) : stored;
|
|
3233
3242
|
const key = pkFunctions.extractFromRow(row);
|
|
3234
3243
|
if (probe.get(key) !== undefined)
|
|
3235
3244
|
return key;
|
|
@@ -3242,8 +3251,8 @@ export class MemoryTableManager {
|
|
|
3242
3251
|
* when two of the rows the DDL transaction can SEE share a primary key under `pkFunctions`.
|
|
3243
3252
|
* Takes a wrapper's merged async stream or this manager's own synchronous layered view.
|
|
3244
3253
|
*/
|
|
3245
|
-
async assertNoPrimaryKeyCollisionInRows(rows, pkFunctions, keyIsTuple) {
|
|
3246
|
-
const seen = this.makePrimaryKeyProbe(pkFunctions);
|
|
3254
|
+
async assertNoPrimaryKeyCollisionInRows(rows, pkFunctions, keyIsTuple, mapRow) {
|
|
3255
|
+
const seen = this.makePrimaryKeyProbe(pkFunctions, mapRow);
|
|
3247
3256
|
for await (const row of rows) {
|
|
3248
3257
|
const key = seen(row);
|
|
3249
3258
|
if (key === undefined)
|
|
@@ -3266,11 +3275,11 @@ export class MemoryTableManager {
|
|
|
3266
3275
|
* deep savepoint stack over a large table ever makes an ALTER slow, note that a layer's rows
|
|
3267
3276
|
* differ from its parent's only at the keys it wrote, so the walk can be narrowed to those.
|
|
3268
3277
|
*/
|
|
3269
|
-
assertNoPrimaryKeyCollisionInLayer(layer, pkFunctions) {
|
|
3278
|
+
assertNoPrimaryKeyCollisionInLayer(layer, pkFunctions, mapRow) {
|
|
3270
3279
|
const tree = layer.getModificationTree('primary');
|
|
3271
3280
|
if (!tree)
|
|
3272
3281
|
return;
|
|
3273
|
-
const seen = this.makePrimaryKeyProbe(pkFunctions);
|
|
3282
|
+
const seen = this.makePrimaryKeyProbe(pkFunctions, mapRow);
|
|
3274
3283
|
for (const row of iteratePrimaryRows(tree)) {
|
|
3275
3284
|
if (seen(row) !== undefined) {
|
|
3276
3285
|
throw new QuereusError(`Cannot re-key the primary key of table ${this._tableName}: `
|
|
@@ -3314,9 +3323,11 @@ export class MemoryTableManager {
|
|
|
3314
3323
|
* `convertNulls` routes null own-values through `convert` (the SET NOT NULL null → DEFAULT map);
|
|
3315
3324
|
* SET DATA TYPE leaves them untouched. No-op in autocommit.
|
|
3316
3325
|
*
|
|
3317
|
-
* PRIMARY-KEY
|
|
3318
|
-
*
|
|
3319
|
-
*
|
|
3326
|
+
* A retype of a PRIMARY-KEY column never reaches here (rejected before any mutation), but the
|
|
3327
|
+
* SET NOT NULL backfill of a key member does — its keys move with the values. The layer's own
|
|
3328
|
+
* rows re-key themselves (their keys are extracted from the converted row); the layer's staged
|
|
3329
|
+
* DELETIONS carry only a key, which `convertColumn` re-derives under the same conversion. The
|
|
3330
|
+
* pre-pass has already proved no two rows converge anywhere in the chain.
|
|
3320
3331
|
*/
|
|
3321
3332
|
convertColumnOnOpenLayers(newSchema, colIndex, convert, convertNulls = false) {
|
|
3322
3333
|
for (const layer of this.openTransactionLayersOldestFirst()) {
|