@quereus/quereus 4.13.1 → 4.15.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.
Files changed (135) hide show
  1. package/dist/src/core/statement.d.ts +30 -0
  2. package/dist/src/core/statement.d.ts.map +1 -1
  3. package/dist/src/core/statement.js +49 -0
  4. package/dist/src/core/statement.js.map +1 -1
  5. package/dist/src/emit/ast-stringify.d.ts.map +1 -1
  6. package/dist/src/emit/ast-stringify.js +0 -4
  7. package/dist/src/emit/ast-stringify.js.map +1 -1
  8. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  9. package/dist/src/func/builtins/explain.js +89 -62
  10. package/dist/src/func/builtins/explain.js.map +1 -1
  11. package/dist/src/func/registration.d.ts +7 -0
  12. package/dist/src/func/registration.d.ts.map +1 -1
  13. package/dist/src/func/registration.js +7 -0
  14. package/dist/src/func/registration.js.map +1 -1
  15. package/dist/src/index.d.ts +3 -0
  16. package/dist/src/index.d.ts.map +1 -1
  17. package/dist/src/index.js +1 -0
  18. package/dist/src/index.js.map +1 -1
  19. package/dist/src/parser/ast.d.ts +0 -2
  20. package/dist/src/parser/ast.d.ts.map +1 -1
  21. package/dist/src/parser/parser.d.ts +1 -0
  22. package/dist/src/parser/parser.d.ts.map +1 -1
  23. package/dist/src/parser/parser.js +29 -28
  24. package/dist/src/parser/parser.js.map +1 -1
  25. package/dist/src/planner/mutation/capture-correlation.d.ts +57 -0
  26. package/dist/src/planner/mutation/capture-correlation.d.ts.map +1 -0
  27. package/dist/src/planner/mutation/capture-correlation.js +57 -0
  28. package/dist/src/planner/mutation/capture-correlation.js.map +1 -0
  29. package/dist/src/planner/mutation/decomposition.d.ts.map +1 -1
  30. package/dist/src/planner/mutation/decomposition.js +86 -23
  31. package/dist/src/planner/mutation/decomposition.js.map +1 -1
  32. package/dist/src/planner/mutation/lens-enforcement.d.ts.map +1 -1
  33. package/dist/src/planner/mutation/lens-enforcement.js +15 -20
  34. package/dist/src/planner/mutation/lens-enforcement.js.map +1 -1
  35. package/dist/src/planner/mutation/multi-source.d.ts +52 -11
  36. package/dist/src/planner/mutation/multi-source.d.ts.map +1 -1
  37. package/dist/src/planner/mutation/multi-source.js +273 -86
  38. package/dist/src/planner/mutation/multi-source.js.map +1 -1
  39. package/dist/src/planner/mutation/set-op.d.ts.map +1 -1
  40. package/dist/src/planner/mutation/set-op.js +4 -12
  41. package/dist/src/planner/mutation/set-op.js.map +1 -1
  42. package/dist/src/planner/mutation/single-source.js +1 -1
  43. package/dist/src/planner/mutation/single-source.js.map +1 -1
  44. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  45. package/dist/src/runtime/emit/alter-table.js +8 -10
  46. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  47. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  48. package/dist/src/runtime/emit/dml-executor.js +23 -0
  49. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  50. package/dist/src/runtime/emit/materialized-view-helpers.d.ts +16 -4
  51. package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -1
  52. package/dist/src/runtime/emit/materialized-view-helpers.js +182 -25
  53. package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -1
  54. package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -1
  55. package/dist/src/runtime/emit/materialized-view.js +1 -1
  56. package/dist/src/runtime/emit/materialized-view.js.map +1 -1
  57. package/dist/src/runtime/emit/scan.d.ts.map +1 -1
  58. package/dist/src/runtime/emit/scan.js +52 -9
  59. package/dist/src/runtime/emit/scan.js.map +1 -1
  60. package/dist/src/runtime/emit/set-object-tags.js +4 -4
  61. package/dist/src/runtime/emit/set-object-tags.js.map +1 -1
  62. package/dist/src/runtime/emitters.d.ts.map +1 -1
  63. package/dist/src/runtime/emitters.js +6 -0
  64. package/dist/src/runtime/emitters.js.map +1 -1
  65. package/dist/src/runtime/parallel-driver.d.ts +5 -0
  66. package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
  67. package/dist/src/runtime/parallel-driver.js +6 -0
  68. package/dist/src/runtime/parallel-driver.js.map +1 -1
  69. package/dist/src/runtime/scheduler.d.ts +9 -0
  70. package/dist/src/runtime/scheduler.d.ts.map +1 -1
  71. package/dist/src/runtime/scheduler.js +27 -11
  72. package/dist/src/runtime/scheduler.js.map +1 -1
  73. package/dist/src/runtime/types.d.ts +19 -0
  74. package/dist/src/runtime/types.d.ts.map +1 -1
  75. package/dist/src/runtime/types.js.map +1 -1
  76. package/dist/src/runtime/work-counters.d.ts +180 -0
  77. package/dist/src/runtime/work-counters.d.ts.map +1 -0
  78. package/dist/src/runtime/work-counters.js +210 -0
  79. package/dist/src/runtime/work-counters.js.map +1 -0
  80. package/dist/src/schema/ddl-generator.d.ts.map +1 -1
  81. package/dist/src/schema/ddl-generator.js +65 -24
  82. package/dist/src/schema/ddl-generator.js.map +1 -1
  83. package/dist/src/schema/lens-ack.d.ts +1 -1
  84. package/dist/src/schema/lens-ack.js +2 -2
  85. package/dist/src/schema/lens-compiler.d.ts.map +1 -1
  86. package/dist/src/schema/lens-compiler.js +63 -34
  87. package/dist/src/schema/lens-compiler.js.map +1 -1
  88. package/dist/src/schema/lens-prover.d.ts +4 -4
  89. package/dist/src/schema/lens-prover.d.ts.map +1 -1
  90. package/dist/src/schema/lens-prover.js +13 -5
  91. package/dist/src/schema/lens-prover.js.map +1 -1
  92. package/dist/src/schema/lens.d.ts +1 -1
  93. package/dist/src/schema/manager.d.ts.map +1 -1
  94. package/dist/src/schema/manager.js +25 -13
  95. package/dist/src/schema/manager.js.map +1 -1
  96. package/dist/src/schema/reserved-tags.js +1 -1
  97. package/dist/src/schema/reserved-tags.js.map +1 -1
  98. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  99. package/dist/src/schema/schema-differ.js +4 -3
  100. package/dist/src/schema/schema-differ.js.map +1 -1
  101. package/dist/src/schema/table.d.ts +41 -34
  102. package/dist/src/schema/table.d.ts.map +1 -1
  103. package/dist/src/schema/table.js +24 -43
  104. package/dist/src/schema/table.js.map +1 -1
  105. package/dist/src/vtab/alter-event-shape.d.ts +35 -0
  106. package/dist/src/vtab/alter-event-shape.d.ts.map +1 -0
  107. package/dist/src/vtab/alter-event-shape.js +47 -0
  108. package/dist/src/vtab/alter-event-shape.js.map +1 -0
  109. package/dist/src/vtab/memory/layer/alter-column.d.ts +8 -1
  110. package/dist/src/vtab/memory/layer/alter-column.d.ts.map +1 -1
  111. package/dist/src/vtab/memory/layer/alter-column.js +20 -10
  112. package/dist/src/vtab/memory/layer/alter-column.js.map +1 -1
  113. package/dist/src/vtab/memory/layer/base.d.ts +9 -1
  114. package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
  115. package/dist/src/vtab/memory/layer/base.js +12 -1
  116. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  117. package/dist/src/vtab/memory/layer/manager.d.ts +23 -18
  118. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  119. package/dist/src/vtab/memory/layer/manager.js +44 -33
  120. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  121. package/dist/src/vtab/memory/layer/row-convert.d.ts +13 -0
  122. package/dist/src/vtab/memory/layer/row-convert.d.ts.map +1 -1
  123. package/dist/src/vtab/memory/layer/row-convert.js +24 -0
  124. package/dist/src/vtab/memory/layer/row-convert.js.map +1 -1
  125. package/dist/src/vtab/memory/layer/transaction.d.ts +21 -7
  126. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  127. package/dist/src/vtab/memory/layer/transaction.js +30 -14
  128. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  129. package/dist/src/vtab/memory/module.d.ts +0 -8
  130. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  131. package/dist/src/vtab/memory/module.js +2 -25
  132. package/dist/src/vtab/memory/module.js.map +1 -1
  133. package/dist/src/vtab/module.d.ts +20 -2
  134. package/dist/src/vtab/module.d.ts.map +1 -1
  135. package/package.json +6 -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
- if (!columns[pk.index].notNull) {
2277
- throw new QuereusError(`Column '${columns[pk.index].name}' must be NOT NULL to participate in PRIMARY KEY`, StatusCode.CONSTRAINT);
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: `set collate` on a PK member gets a stricter pre-pass
2303
- * ({@link validateRekeyedPrimaryKey}): no layer in the chain, base included, may hold a collision.
2304
- * That is what lets every apply step succeed unconditionally, and what
2305
- * `TransactionLayer.rekeyPrimaryKey` relies on. The rewrite arm needs no PK pre-pass and cannot
2306
- * shadow one: a retype of a PK column is rejected upstream, the backfill only fires on a column
2307
- * holding NULLs (which a PK member cannot — the engine enforces NOT NULL on every PK member
2308
- * regardless of the declared nullability), and `pkColumnRekeyed` is set only by `set collate`,
2309
- * which never sets `rewrite` — so whenever `pkColumnRekeyed` is true, the `structuresRekeyed` arm
2310
- * still runs.
2311
- * NOTE: if PK members ever become genuinely nullable, the backfill arm gains a PK collision path
2312
- * (two NULL keys → one DEFAULT) and needs `validateRekeyedPrimaryKey` plus a primary-tree re-key
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
- this.baseLayer.rebuildPrimaryTreeFromRows(convertedBaseRows);
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 both statements that move the key:
3159
- * `alter column … set collate` on a PK member (the comparator moves) and
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 (row) => {
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 columns never reach here — any retype of a key column is rejected before
3318
- * any mutation, and SET NOT NULL leaves the key bytes unchanged — so the primary tree's keys are
3319
- * stable and no re-key is needed.
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()) {