@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,389 @@
1
+ /**
2
+ * ALTER TABLE ... ALTER COLUMN: the one ALTER arm that can rewrite stored values and
3
+ * re-encode physical keys. The orchestrating method decides the order of the throw-only
4
+ * checks and the mutations; the per-attribute sub-branches below it are pure — each
5
+ * returns the rewritten column schema plus a DEFERRED value-rewrite closure, mutating
6
+ * nothing itself.
7
+ *
8
+ * Fifth layer of the store-module chain:
9
+ * StoreModuleBase -> StoreModuleCatalog -> StoreModuleSchemaSync -> StoreModuleIndex
10
+ * -> StoreModuleAlterColumn -> StoreModuleAlter -> StoreModuleRename -> StoreModule
11
+ */
12
+ import { QuereusError, StatusCode, buildColumnIndexMap, foldDefaultToType, planRetypeConversion, validateCollationForType, } from '@quereus/quereus';
13
+ import { storeSemanticKeyTransform } from './pk-key-resolution.js';
14
+ import { withImplicitUniqueIndexes } from './implicit-unique-index.js';
15
+ import { StoreModuleIndex } from './store-module-index.js';
16
+ import { effectiveDdlRows, validateUniqueOverExistingRows } from './store-module-index-build.js';
17
+ export class StoreModuleAlterColumn extends StoreModuleIndex {
18
+ /** ALTER COLUMN arm of `StoreModuleAlter.alterTable`: change one attribute (NOT NULL / data type /
19
+ * default / collation), running the physical re-key + existing-row re-validation the
20
+ * collation / PK paths require, then persist. Behavior-preserving extraction. */
21
+ async alterColumnChange(db, schemaName, tableName, table, oldSchema, change, rows) {
22
+ const colNameLower = change.columnName.toLowerCase();
23
+ const colIndex = oldSchema.columns.findIndex(c => c.name.toLowerCase() === colNameLower);
24
+ if (colIndex === -1) {
25
+ throw new QuereusError(`Column '${change.columnName}' not found.`, StatusCode.ERROR);
26
+ }
27
+ const oldCol = oldSchema.columns[colIndex];
28
+ // Pull exactly one attribute from the change. Each sub-helper returns the new
29
+ // column schema plus whether the collation bytes changed (`collationChanged` gates
30
+ // the existing-row UNIQUE re-validation and PK re-key below) plus a DEFERRED
31
+ // `valueConvert` closure when the change rewrites stored values — the sub-helper
32
+ // itself mutates nothing. Or null when the column is already in the desired state —
33
+ // preserving the pre-refactor early exits (SET NOT NULL no-op, SET COLLATE
34
+ // already-explicit) that leave the table and any open transaction untouched.
35
+ let attr;
36
+ if (change.setNotNull !== undefined) {
37
+ attr = await alterColumnSetNotNull(table, oldSchema, oldCol, colIndex, change, rows);
38
+ }
39
+ else if (change.setDataType !== undefined) {
40
+ attr = await alterColumnSetDataType(table, oldSchema, oldCol, colIndex, change);
41
+ }
42
+ else if (change.setDefault !== undefined) {
43
+ attr = { newCol: { ...oldCol, defaultValue: change.setDefault }, collationChanged: false };
44
+ }
45
+ else if (change.setCollation !== undefined) {
46
+ attr = alterColumnSetCollation(oldCol, change, (n) => db.isCollationRegistered(n));
47
+ }
48
+ else {
49
+ throw new QuereusError('ALTER COLUMN requires an attribute to change', StatusCode.INTERNAL);
50
+ }
51
+ if (attr === null) {
52
+ return oldSchema;
53
+ }
54
+ const { newCol, collationChanged, valueConvert } = attr;
55
+ // Named for the PENDING act, not a completed one: the deferred value rewrite (SET DATA
56
+ // TYPE conversion / SET NOT NULL backfill) is applied below, after every throw-only
57
+ // check. Both gates that read this run BEFORE it, while the store still holds the old
58
+ // values.
59
+ const rewritesValues = valueConvert !== undefined;
60
+ const updatedColumns = oldSchema.columns.map((c, i) => i === colIndex ? newCol : c);
61
+ // Mirror the memory module (MemoryTableManager.alterColumn): a per-column
62
+ // collation change propagates into every index column ordering by this
63
+ // column, so a `derivedFromIndex` UNIQUE re-keys its enforcement under the
64
+ // new collation. StoreTable.uniqueEnforcementCollations reads the index's
65
+ // per-column collation, so without this the index entry would stay stale
66
+ // and the derived UNIQUE would keep enforcing the OLD collation after the
67
+ // ALTER. NOT metadata-only: the store keys each index column under its own
68
+ // effective collation (resolveIndexKeyCollations), so every index covering
69
+ // this column holds stale key bytes until the rebuild below re-encodes them.
70
+ // An index column with an explicit COLLATE is re-collated too — matching
71
+ // memory, which clobbers it the same way (no surface preserves a differing
72
+ // index COLLATE across an ALTER COLUMN SET COLLATE on its column).
73
+ const updatedIndexes = (collationChanged && oldSchema.indexes)
74
+ ? oldSchema.indexes.map(idx => ({
75
+ ...idx,
76
+ columns: idx.columns.map(ic => ic.index === colIndex ? { ...ic, collation: newCol.collation } : ic),
77
+ }))
78
+ : oldSchema.indexes;
79
+ const updatedSchema = {
80
+ ...oldSchema,
81
+ columns: Object.freeze(updatedColumns),
82
+ columnIndexMap: buildColumnIndexMap(updatedColumns),
83
+ indexes: updatedIndexes ? Object.freeze(updatedIndexes) : updatedIndexes,
84
+ };
85
+ // SET DATA TYPE onto/off a type with a key transform (TIMESPAN's total-seconds
86
+ // groupKey, JSON's structural encoder — see `storeSemanticKeyTransform`)
87
+ // changes the physical KEY BYTES a value encodes to, even when the stored
88
+ // VALUE bytes don't change (text → timespan keeps TEXT physical). Treated
89
+ // exactly like a collation change below: existing-row UNIQUE re-validation
90
+ // (equal-elapsed spellings now collide), a PK re-key when the column is a PK
91
+ // member, and a secondary-index rebuild (index keys encode the column's
92
+ // values). A same-type no-op ALTER never gets here (`inferType` returns the
93
+ // shared type object, so the identity check short-circuits).
94
+ const keyTransformChanged = oldCol.logicalType !== newCol.logicalType
95
+ && (storeSemanticKeyTransform(oldCol.logicalType) !== undefined
96
+ || storeSemanticKeyTransform(newCol.logicalType) !== undefined);
97
+ // Existing-row UNIQUE re-validation (Option A, non-PK UNIQUE). Two ways an ALTER
98
+ // COLUMN can make rows that were distinct collide, both judged here BEFORE any
99
+ // mutation/persist so the first collision throws CONSTRAINT and leaves the table
100
+ // unchanged and writable (matches the ADD CONSTRAINT rollback shape):
101
+ // - SET COLLATE / a key-transform change: the comparators change ('a'/'A' collide
102
+ // under NOCASE). Re-scan under the NEW collation (`updatedSchema` carries it).
103
+ // - a value-REWRITING change (`valueConvert`: SET DATA TYPE, or a SET NOT NULL
104
+ // null → DEFAULT backfill): the comparators are unchanged but the VALUES collapse
105
+ // ('1'/'01' → 1; two NULLs → the same DEFAULT). The probe judges the CONVERTED
106
+ // rows — the same closure the deferred rewrite below applies — while the store
107
+ // still holds the old values. A standalone `create unique index` synthesizes a
108
+ // `derivedFromIndex` entry in `uniqueConstraints`, so both declaration shapes are
109
+ // reachable through this walk.
110
+ // The PK is intentionally excluded — it never appears in `uniqueConstraints`;
111
+ // its physical re-key/re-validation is the `pkRekeyNeeded` block below.
112
+ //
113
+ // NOTE: one full row scan per covering constraint, and this gate now fires on the
114
+ // COMMON retype/backfill path, not only on the rare collation/transform ones. Fine
115
+ // while tables covered by several UNIQUE constraints over one column are rare; if a
116
+ // wide-constraint table makes ALTER COLUMN slow, judge all covering constraints in a
117
+ // single pass (one `seen` Set per constraint, one stream).
118
+ if (collationChanged || keyTransformChanged || rewritesValues) {
119
+ const coveringConstraints = (updatedSchema.uniqueConstraints ?? [])
120
+ .filter(uc => uc.columns.includes(colIndex));
121
+ for (const uc of coveringConstraints) {
122
+ // Fresh generator per constraint — an async generator is single-shot.
123
+ const effectiveRows = effectiveDdlRows(table, rows);
124
+ await validateUniqueOverExistingRows(valueConvert ? convertRowsAtIndex(effectiveRows, colIndex, valueConvert) : effectiveRows, updatedSchema, uc, db.getKeyNormalizerResolver());
125
+ }
126
+ }
127
+ // SET COLLATE on a PRIMARY KEY member (Option B physical re-key): re-encode
128
+ // every data-store key under the column's new key collation, then rebuild every
129
+ // secondary index (its keys embed the PK suffix). Runs AFTER the non-PK UNIQUE
130
+ // re-validation above so every throw-only check precedes the first store
131
+ // mutation. `updatedSchema.columns` carries the new collation, so the new key
132
+ // bytes follow it.
133
+ const pkRekeyNeeded = (collationChanged || keyTransformChanged)
134
+ && oldSchema.primaryKeyDefinition.some(def => def.index === colIndex);
135
+ if (pkRekeyNeeded) {
136
+ // The two throw-only re-key questions — "is the change legal?" over the rows
137
+ // this transaction can SEE (CONSTRAINT), then "can the store carry it?" over
138
+ // the committed rows a rollback must restore (BUSY) — asked BEFORE the DDL
139
+ // flush below, so either refusal leaves the store, the catalog AND the
140
+ // enclosing transaction untouched. Mirrors the memory backend's
141
+ // `MemoryTableManager.validateRekeyedPrimaryKey`. The effective probe judges
142
+ // the wrapper-supplied `rows` when the isolation layer holds the
143
+ // transaction's staged rows outside this store — closing the
144
+ // staged-vs-committed hole the old post-flush pass fell through (a staged
145
+ // insert colliding with a committed row was caught by neither side) — else
146
+ // this module's own effective entries, which include its buffered ops, so a
147
+ // pending insert that is itself the duplicate is caught without flushing.
148
+ await table.validateRekeyedPrimaryKey(oldSchema.primaryKeyDefinition, updatedSchema.columns, effectiveDdlRows(table, rows));
149
+ // Physical re-key ahead — flush buffered writes (see
150
+ // `StoreModuleBase.ddlCommitPendingOps`). Every refusal this arm can make has
151
+ // already run above, reading effectively and throwing without the flush, so a
152
+ // rejected ALTER keeps the transaction alive; `rekeyRows`' own pass 1 is now a
153
+ // backstop, not the gate.
154
+ await this.ddlCommitPendingOps();
155
+ await table.rekeyRows(oldSchema.primaryKeyDefinition, updatedSchema.columns);
156
+ // Materialize so the implicit `_uc_*` PK suffix is re-encoded under the new
157
+ // key collation too (`updatedSchema` carries none on its own). NON-enforcing
158
+ // (`skipDuplicateCheck`): this rebuild reads only committed rows, which may
159
+ // retain a row a wrapper's transaction has deleted whose indexed value
160
+ // collides with a survivor — the pre-mutation
161
+ // `validateUniqueOverExistingRows` walk above already judged every unique
162
+ // structure covering the altered column against the transaction's effective
163
+ // rows, and an index NOT covering it has unchanged values and collation, so
164
+ // it cannot newly collide (the PK-suffix change never affects index-column
165
+ // uniqueness). See `rebuildSecondaryIndexes`' skipDuplicateCheck contract.
166
+ await this.rebuildSecondaryIndexes(schemaName, tableName, table, withImplicitUniqueIndexes(updatedSchema), db.getKeyNormalizerResolver(), true);
167
+ }
168
+ // Deferred value rewrite (SET DATA TYPE physical conversion / SET NOT NULL DEFAULT
169
+ // backfill): every throw-only check above has passed, so the store mutation is now
170
+ // safe — a rejected ALTER never reaches this point, leaving values, DDL and the
171
+ // transaction untouched. Flush buffered writes first so `mapRowsAtIndex` rewrites this
172
+ // transaction's rows too; unflushed, they would replay under the OLD physical type
173
+ // (see `StoreModuleBase.ddlCommitPendingOps`; a re-flush after the PK re-key's own is a no-op).
174
+ //
175
+ // NOTE: `valueConvert` and `pkRekeyNeeded` cannot both be set today, and this ordering
176
+ // depends on that. `valueConvert` comes only from SET DATA TYPE or SET NOT NULL;
177
+ // SET NOT NULL changes neither collation nor logical type, so it never sets
178
+ // `pkRekeyNeeded`, and SET DATA TYPE on a PK member is refused both upstream (every live
179
+ // caller — the engine's ALTER COLUMN emitter, see `runAlterColumn` in
180
+ // runtime/emit/alter-table.ts, and the materialized-view reshape, which declares a
181
+ // key-column retype inexpressible) AND locally, by `alterColumnSetDataType` itself. If a
182
+ // PK-member retype is ever admitted (that local guard removed), this rewrite must move IN
183
+ // FRONT of the `pkRekeyNeeded` block: otherwise `rekeyRows` and its index rebuild encode
184
+ // the PRE-rewrite values and the rebuild below is skipped, leaving keys and indexes
185
+ // disagreeing with the stored values.
186
+ if (valueConvert) {
187
+ await this.ddlCommitPendingOps();
188
+ await table.mapRowsAtIndex(colIndex, valueConvert);
189
+ }
190
+ // The value rewrite above changed stored column values in place (same PK, new value) —
191
+ // and a key-identity transform change re-encodes the column's index-key bytes even with
192
+ // values untouched. Likewise a SET COLLATE on a non-PK column covered by any index
193
+ // (explicit or hidden `_uc_*`): index KEY bytes encode the indexed column values under
194
+ // the column's own effective collation (resolveIndexKeyCollations), so the persisted
195
+ // entries are keyed under the OLD collation until rebuilt — an index-backed lookup or
196
+ // UNIQUE enforcement seek after the ALTER would find nothing. In every case any index
197
+ // covering this column still points at the OLD bytes until rebuilt (mirrors the memory
198
+ // module's `valueConvert` rebuild in MemoryTableManager.alterColumn).
199
+ // `rebuildSecondaryIndexes` reads committed-only, so flush buffered writes first — the
200
+ // value rewrite above already did, and the transform-only / collation-only paths must
201
+ // too; a re-flush with nothing pending is a no-op. Skipped when the PK re-key above
202
+ // already rebuilt every index, so no double rebuild. Materialize so an implicit `_uc_*`
203
+ // over the rewritten column is rebuilt against the new value bytes too (the covering
204
+ // check reads the materialized set for the same reason). The rebuild is NON-enforcing
205
+ // (`skipDuplicateCheck`): the UNIQUE re-validation above already judged the issuer's
206
+ // effective rows — it runs on `collationChanged` too, so the contract holds for the
207
+ // collation arm — and this module's committed rows may retain a row a wrapper's
208
+ // transaction has deleted whose converted value duplicates a survivor — enforcing here
209
+ // would spuriously reject what the probe correctly accepted.
210
+ const materializedUpdated = withImplicitUniqueIndexes(updatedSchema);
211
+ const indexCoversAlteredColumn = (materializedUpdated.indexes ?? [])
212
+ .some(ix => ix.columns.some(ic => ic.index === colIndex));
213
+ if ((rewritesValues || keyTransformChanged || (collationChanged && indexCoversAlteredColumn)) && !pkRekeyNeeded) {
214
+ await this.ddlCommitPendingOps();
215
+ await this.rebuildSecondaryIndexes(schemaName, tableName, table, materializedUpdated, db.getKeyNormalizerResolver(), true);
216
+ }
217
+ table.updateSchema(updatedSchema);
218
+ await this.saveTableDDL(updatedSchema);
219
+ // No emit here: the dispatcher (`StoreModuleAlter.alterTable`) raises the ONE
220
+ // event per statement after every arm, gated on `change.ddl`.
221
+ return updatedSchema;
222
+ }
223
+ }
224
+ /**
225
+ * SET NOT NULL / DROP NOT NULL sub-branch of {@link alterColumnChange}. Returns the
226
+ * new column schema, or null when the column is already in the desired nullability
227
+ * (the pre-refactor `return oldSchema` no-op). Mutates nothing: the NULL-backfill
228
+ * probe is throw-only, and the backfill itself is returned as a deferred
229
+ * `valueConvert` (null → DEFAULT) the caller applies only after every throw-only
230
+ * check — including the UNIQUE re-validation over the backfilled values — has passed.
231
+ *
232
+ * `rows` is the wrapper-supplied effective row source (the isolation overlay). When present,
233
+ * the reject-vs-backfill decision scans it instead of `table.rowsWithNullAtIndex`: behind the
234
+ * isolation layer the issuer's pending inserts live in the wrapper's overlay, not this store,
235
+ * so the store's own count would miss them and wrongly accept the ALTER. The committed-store
236
+ * `mapRowsAtIndex` backfill is unchanged — the overlay-resident pending rows are the isolation
237
+ * layer's job (its overlay migration), this store only owns its committed rows.
238
+ */
239
+ async function alterColumnSetNotNull(table, oldSchema, oldCol, colIndex, change, rows) {
240
+ let newCol;
241
+ let valueConvert;
242
+ if (change.setNotNull === true && !oldCol.notNull) {
243
+ // Backfill NULLs from a literal DEFAULT, or throw. Routed through the shared
244
+ // `foldDefaultToType` so (a) a signed numeric default (`default -5`, a UnaryExpr)
245
+ // is recognized here exactly as the memory module recognizes it, and (b) the
246
+ // literal is converted to the column's declared type, so a backfilled cell matches
247
+ // what an INSERT under the same DEFAULT would store.
248
+ const defaultLiteral = foldDefaultToType(oldCol.defaultValue, oldCol.logicalType, change.columnName);
249
+ // Decide reject-vs-backfill over the DDL transaction's EFFECTIVE rows. `rows()` (the
250
+ // isolation overlay) sees the issuer's pending inserts; `rowsWithNullAtIndex` (run
251
+ // directly, no wrapper) sees the store's own effective rows. Either way a NULL the
252
+ // transaction can see is backfilled, or rejects the ALTER, like any other row.
253
+ let anyNull;
254
+ if (rows) {
255
+ anyNull = false;
256
+ for await (const row of rows()) {
257
+ if (row[colIndex] === null) {
258
+ anyNull = true;
259
+ break;
260
+ }
261
+ }
262
+ }
263
+ else {
264
+ anyNull = (await table.rowsWithNullAtIndex(colIndex)) > 0;
265
+ }
266
+ if (anyNull) {
267
+ if (defaultLiteral === undefined || defaultLiteral === null) {
268
+ // Throw-only, and before the DDL-commit below: the transaction survives.
269
+ throw new QuereusError(`column ${change.columnName} contains NULL values`, StatusCode.CONSTRAINT);
270
+ }
271
+ const fill = defaultLiteral;
272
+ // Backfill DEFERRED: the caller flushes + `mapRowsAtIndex`es this closure only
273
+ // after its throw-only checks pass. Run directly, that fills the transaction's
274
+ // rows too (the probe saw them). Behind isolation the issuer's overlay-resident
275
+ // NULL rows are filled by the isolation layer's overlay migration, not here —
276
+ // this store never holds them.
277
+ valueConvert = (v) => v === null ? fill : v;
278
+ }
279
+ newCol = { ...oldCol, notNull: true };
280
+ }
281
+ else if (change.setNotNull === false && oldCol.notNull) {
282
+ if (oldSchema.primaryKeyDefinition.some(def => def.index === colIndex)) {
283
+ throw new QuereusError(`Cannot DROP NOT NULL on PRIMARY KEY column '${change.columnName}'`, StatusCode.CONSTRAINT);
284
+ }
285
+ newCol = { ...oldCol, notNull: false };
286
+ }
287
+ else {
288
+ return null; // already in desired state
289
+ }
290
+ return { newCol, collationChanged: false, valueConvert };
291
+ }
292
+ /**
293
+ * SET DATA TYPE sub-branch of {@link alterColumnChange}. Returns the retyped column
294
+ * schema. Mutates nothing: for every retype between DIFFERENT logical types, a
295
+ * throw-only convert pass over the live rows proves every value convertible, and the
296
+ * conversion itself is returned as a deferred `valueConvert` the caller applies only
297
+ * after every throw-only check — including the UNIQUE re-validation over the converted
298
+ * values — has passed. Gated on logical-type IDENTITY, not the physical storage class:
299
+ * `inferType` flattens aliases to the shared type object (`varchar(50)` IS `TEXT_TYPE`),
300
+ * so an alias retype is schema-only, while a same-class retype (text → date) still
301
+ * rejects values the new type refuses and rewrites the rest to the new type's
302
+ * canonical spelling ('2024-06-05T00:00:00Z' → '2024-06-05') — exactly as an INSERT
303
+ * would have stored them.
304
+ *
305
+ * A retype of a PRIMARY KEY member is refused here rather than converted: the rewrite
306
+ * below is `mapRowsAtIndex`, a payload-only rewrite that reuses `entry.key` verbatim, so
307
+ * a PK column's physical key bytes would stay encoded under the OLD type while the value
308
+ * moves to the new one — unfindable by any lookup under the new encoding, and the same
309
+ * `keyTransformChanged` path in the caller would re-key from the pre-rewrite values before
310
+ * this rewrite ever ran (see the NOTE above the `valueConvert` block in
311
+ * {@link alterColumnChange}). Every live SQL caller already refuses this earlier (the
312
+ * engine's `runAlterColumn` and the materialized-view reshape's inexpressibility check),
313
+ * so this only guards a direct module call — mirrors the memory backend's carve-out
314
+ * (`MemoryTableManager.alterColumn`).
315
+ */
316
+ async function alterColumnSetDataType(table, oldSchema, oldCol, colIndex, change) {
317
+ const { newLogicalType, convert } = planRetypeConversion(change.setDataType, oldCol.logicalType, change.columnName);
318
+ let valueConvert;
319
+ if (convert) {
320
+ if (oldSchema.primaryKeyDefinition.some(def => def.index === colIndex)) {
321
+ throw new QuereusError(`Cannot change the data type of primary key column '${change.columnName}' of table '${oldSchema.name}'.`, StatusCode.CONSTRAINT);
322
+ }
323
+ // Throw-only pass over the LIVE rows, so an unconvertible value this
324
+ // transaction inserted rejects the ALTER with the transaction still intact.
325
+ // The rewrite itself is DEFERRED: the caller flushes + `mapRowsAtIndex`es
326
+ // this closure only after its remaining throw-only checks pass.
327
+ // NOTE: pre-existing gap — this scan reads the store's own effective rows and
328
+ // ignores a wrapper-supplied `rows` stream (unlike the memory module's arm). No
329
+ // hole under isolation: the wrapper's `validateOverlayMigration` converts every
330
+ // staged overlay value itself before the underlying mutates.
331
+ for await (const value of table.iterateEffectiveValuesAtIndex(colIndex)) {
332
+ if (value !== null)
333
+ convert(value);
334
+ }
335
+ valueConvert = (v) => v === null ? v : convert(v);
336
+ }
337
+ return { newCol: { ...oldCol, logicalType: newLogicalType }, collationChanged: false, valueConvert };
338
+ }
339
+ /**
340
+ * SET COLLATE sub-branch of {@link alterColumnChange}. Returns the recollated column
341
+ * schema with `collationChanged` set when the collation bytes actually change (a bare
342
+ * metadata flip keeps it false), or null when the column is already explicit in the
343
+ * desired collation (the pre-refactor `return oldSchema` no-op). Synchronous — no
344
+ * row scan happens here; the caller runs the re-validation / re-key the flag gates.
345
+ */
346
+ function alterColumnSetCollation(oldCol, change, isCollationRegistered) {
347
+ // Per-column collation update. PRIMARY KEY uniqueness/ordering is enforced
348
+ // PHYSICALLY in the key bytes under a PER-COLUMN key collation
349
+ // (`StoreTable.pkKeyCollations`), so a PK-column SET COLLATE is honored
350
+ // natively by physically re-keying the data store + rebuilding every
351
+ // secondary index under the new collation (the `isPkColumn` block below),
352
+ // mirroring the memory module's primary re-key. A re-key that would collide
353
+ // under the new collation throws CONSTRAINT before any mutation. For non-PK
354
+ // UNIQUE constraints we re-validate existing rows under the new collation
355
+ // (Option A). Query-layer ORDER BY / `=` / `table_info().collation` pick the
356
+ // new collation up from the column schema once this updated schema re-registers.
357
+ const normalized = validateCollationForType(change.setCollation, oldCol.logicalType, change.columnName, isCollationRegistered);
358
+ const nameMatches = normalized === (oldCol.collation || 'BINARY');
359
+ if (nameMatches && oldCol.collationExplicit) {
360
+ return null; // already explicit in the desired collation — no scan, no re-key, no re-persist
361
+ }
362
+ // SET COLLATE is a user declaration with the same standing as a
363
+ // CREATE-time COLLATE clause, so mark the collation explicit (rank 2
364
+ // in the comparison lattice) regardless of the column's creation
365
+ // history — including SET COLLATE binary. When only the name matches
366
+ // but the column was not yet explicit (a defaulted collation, or one
367
+ // inherited from session default_collation), flip the flag as a
368
+ // METADATA-ONLY change: the collation bytes are unchanged, so keep
369
+ // collationChanged false to skip rekeyRows / validateUniqueOverExistingRows
370
+ // below while still re-registering the schema and re-persisting DDL.
371
+ // A different name takes the full physical re-key path AND sets the flag.
372
+ return { newCol: { ...oldCol, collation: normalized, collationExplicit: true }, collationChanged: !nameMatches };
373
+ }
374
+ /**
375
+ * Read-side wrap for a value-rewriting ALTER COLUMN's pre-mutation UNIQUE probe: each row's
376
+ * value at `colIndex` run through `convert` (the sub-branch's deferred `valueConvert`, which
377
+ * owns its own NULL handling), so the probe judges the POST-alter values while the store
378
+ * still holds the old ones. Mutates nothing — the memory module's `convertRowAtIndex`
379
+ * counterpart. A conversion failure propagates: the setDataType pre-pass already proved
380
+ * every visible value convertible, so a throw here is unreachable, and surfacing it beats
381
+ * probing a stale value that could mask a collision.
382
+ */
383
+ async function* convertRowsAtIndex(rows, colIndex, convert) {
384
+ for await (const row of rows) {
385
+ const newVal = convert(row[colIndex]);
386
+ yield newVal === row[colIndex] ? row : row.map((v, i) => i === colIndex ? newVal : v);
387
+ }
388
+ }
389
+ //# sourceMappingURL=store-module-alter-column.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-module-alter-column.js","sourceRoot":"","sources":["../../../src/common/store-module-alter-column.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * ALTER TABLE dispatch and every arm except ALTER COLUMN: add / drop / rename a column,
3
+ * change the primary key, and add / drop / rename a table constraint. Each arm returns
4
+ * the rewritten table schema; the dispatcher owns what is common to all of them
5
+ * (resolving the table, reconciling the implicit UNIQUE index stores afterwards).
6
+ *
7
+ * Sixth layer of the store-module chain:
8
+ * StoreModuleBase -> StoreModuleCatalog -> StoreModuleSchemaSync -> StoreModuleIndex
9
+ * -> StoreModuleAlterColumn -> StoreModuleAlter -> StoreModuleRename -> StoreModule
10
+ */
11
+ import type { Database, EffectiveRowSource, SchemaChangeInfo, TableSchema } from '@quereus/quereus';
12
+ import { StoreModuleAlterColumn } from './store-module-alter-column.js';
13
+ export declare abstract class StoreModuleAlter extends StoreModuleAlterColumn {
14
+ /**
15
+ * Alters an existing store table's structure. Resolves the table, captures the
16
+ * pre-alter schema, and dispatches to the per-change-type `alter*` helper below;
17
+ * the helper does the arm's work (row migration, physical re-key, constraint
18
+ * validation, DDL persist) and returns the updated TableSchema for the engine to
19
+ * register. The shared preamble (schema subscription, reconnect, not-found throw,
20
+ * `defaultNotNull`) lives here so every arm sees the same resolved state.
21
+ */
22
+ alterTable(db: Database, schemaName: string, tableName: string, change: SchemaChangeInfo, rows?: EffectiveRowSource): Promise<TableSchema>;
23
+ /**
24
+ * ADD COLUMN arm of {@link alterTable}: append the new column, eagerly migrate
25
+ * each row (literal or per-row backfill), and persist. Behavior-preserving
26
+ * extraction of the former `switch` arm.
27
+ *
28
+ * The store always appends. A caller-chosen `insertAtIndex` (module-API only; SQL never
29
+ * produces one) is rejected unless it names the append position, rather than silently
30
+ * landing the column somewhere the caller did not ask for.
31
+ */
32
+ private alterAddColumn;
33
+ /** DROP COLUMN arm of {@link alterTable}: drop the column slot, reindex PK / indexes /
34
+ * UNIQUE, migrate rows, re-encode or tear down the affected physical index stores,
35
+ * and persist. */
36
+ private alterDropColumn;
37
+ /** RENAME COLUMN arm of {@link alterTable}: schema-only rewrite (columns, indexes, self-FK,
38
+ * in-place predicate / CHECK AST rewrite) and persist. Behavior-preserving extraction. */
39
+ private alterRenameColumn;
40
+ /** ALTER PRIMARY KEY arm of {@link alterTable}: physically re-key the data store, rebuild
41
+ * secondary indexes, and persist. Behavior-preserving extraction. */
42
+ private alterPrimaryKeyChange;
43
+ /** ADD CONSTRAINT arm of {@link alterTable}: validate existing rows as the constraint kind
44
+ * (UNIQUE / FOREIGN KEY / CHECK) requires, then persist. Behavior-preserving extraction. */
45
+ private alterAddConstraint;
46
+ /** DROP CONSTRAINT arm of {@link alterTable}: schema-only catalog rewrite dropping a named
47
+ * constraint, then persist. Behavior-preserving extraction. */
48
+ private alterDropConstraint;
49
+ /** RENAME CONSTRAINT arm of {@link alterTable}: schema-only rename of a named constraint,
50
+ * then persist. A renamed named-UNIQUE changes its implicit `_uc_*` index name, so
51
+ * `reconcileImplicitUniqueIndexStores` (run after this arm) MOVES the physical store —
52
+ * tears down the old-named store and rebuilds the new-named one from effective rows. */
53
+ private alterRenameConstraint;
54
+ }
55
+ //# sourceMappingURL=store-module-alter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-module-alter.d.ts","sourceRoot":"","sources":["../../../src/common/store-module-alter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAEX,QAAQ,EACR,kBAAkB,EAElB,gBAAgB,EAGhB,WAAW,EACX,MAAM,kBAAkB,CAAC;AAoB1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAIxE,8BAAsB,gBAAiB,SAAQ,sBAAsB;IACpE;;;;;;;OAOG;IACG,UAAU,CACf,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,gBAAgB,EACxB,IAAI,CAAC,EAAE,kBAAkB,GACvB,OAAO,CAAC,WAAW,CAAC;IAgFvB;;;;;;;;OAQG;YACW,cAAc;IAgG5B;;uBAEmB;YACL,eAAe;IA2G7B;+FAC2F;YAC7E,iBAAiB;IA4F/B;0EACsE;YACxD,qBAAqB;IAwCnC;iGAC6F;YAC/E,kBAAkB;IA+DhC;oEACgE;YAClD,mBAAmB;IAoCjC;;;6FAGyF;YAC3E,qBAAqB;CAoCnC"}