@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.
- package/README.md +34 -6
- package/dist/src/common/encoding.d.ts +4 -3
- package/dist/src/common/encoding.d.ts.map +1 -1
- package/dist/src/common/encoding.js +17 -13
- package/dist/src/common/encoding.js.map +1 -1
- package/dist/src/common/events.d.ts +31 -25
- package/dist/src/common/events.d.ts.map +1 -1
- package/dist/src/common/events.js +38 -39
- package/dist/src/common/events.js.map +1 -1
- package/dist/src/common/implicit-unique-index.d.ts +80 -0
- package/dist/src/common/implicit-unique-index.d.ts.map +1 -0
- package/dist/src/common/implicit-unique-index.js +148 -0
- package/dist/src/common/implicit-unique-index.js.map +1 -0
- package/dist/src/common/index.d.ts +7 -3
- package/dist/src/common/index.d.ts.map +1 -1
- package/dist/src/common/index.js +5 -2
- package/dist/src/common/index.js.map +1 -1
- package/dist/src/common/json-key.d.ts +30 -2
- package/dist/src/common/json-key.d.ts.map +1 -1
- package/dist/src/common/json-key.js +49 -2
- package/dist/src/common/json-key.js.map +1 -1
- package/dist/src/common/key-builder.d.ts +40 -20
- package/dist/src/common/key-builder.d.ts.map +1 -1
- package/dist/src/common/key-builder.js +31 -23
- package/dist/src/common/key-builder.js.map +1 -1
- package/dist/src/common/kv-store.d.ts +10 -0
- package/dist/src/common/kv-store.d.ts.map +1 -1
- package/dist/src/common/pk-key-resolution.d.ts +348 -0
- package/dist/src/common/pk-key-resolution.d.ts.map +1 -0
- package/dist/src/common/pk-key-resolution.js +481 -0
- package/dist/src/common/pk-key-resolution.js.map +1 -0
- package/dist/src/common/store-module-access-plan.d.ts +32 -0
- package/dist/src/common/store-module-access-plan.d.ts.map +1 -0
- package/dist/src/common/store-module-access-plan.js +428 -0
- package/dist/src/common/store-module-access-plan.js.map +1 -0
- package/dist/src/common/store-module-alter-column.d.ts +23 -0
- package/dist/src/common/store-module-alter-column.d.ts.map +1 -0
- package/dist/src/common/store-module-alter-column.js +389 -0
- package/dist/src/common/store-module-alter-column.js.map +1 -0
- package/dist/src/common/store-module-alter.d.ts +55 -0
- package/dist/src/common/store-module-alter.d.ts.map +1 -0
- package/dist/src/common/store-module-alter.js +504 -0
- package/dist/src/common/store-module-alter.js.map +1 -0
- package/dist/src/common/store-module-base.d.ts +268 -0
- package/dist/src/common/store-module-base.d.ts.map +1 -0
- package/dist/src/common/store-module-base.js +362 -0
- package/dist/src/common/store-module-base.js.map +1 -0
- package/dist/src/common/store-module-catalog.d.ts +269 -0
- package/dist/src/common/store-module-catalog.d.ts.map +1 -0
- package/dist/src/common/store-module-catalog.js +462 -0
- package/dist/src/common/store-module-catalog.js.map +1 -0
- package/dist/src/common/store-module-index-build.d.ts +88 -0
- package/dist/src/common/store-module-index-build.d.ts.map +1 -0
- package/dist/src/common/store-module-index-build.js +280 -0
- package/dist/src/common/store-module-index-build.js.map +1 -0
- package/dist/src/common/store-module-index.d.ts +116 -0
- package/dist/src/common/store-module-index.d.ts.map +1 -0
- package/dist/src/common/store-module-index.js +373 -0
- package/dist/src/common/store-module-index.js.map +1 -0
- package/dist/src/common/store-module-rename.d.ts +49 -0
- package/dist/src/common/store-module-rename.d.ts.map +1 -0
- package/dist/src/common/store-module-rename.js +268 -0
- package/dist/src/common/store-module-rename.js.map +1 -0
- package/dist/src/common/store-module-schema-rewrite.d.ts +57 -0
- package/dist/src/common/store-module-schema-rewrite.d.ts.map +1 -0
- package/dist/src/common/store-module-schema-rewrite.js +140 -0
- package/dist/src/common/store-module-schema-rewrite.js.map +1 -0
- package/dist/src/common/store-module-schema-sync.d.ts +232 -0
- package/dist/src/common/store-module-schema-sync.d.ts.map +1 -0
- package/dist/src/common/store-module-schema-sync.js +529 -0
- package/dist/src/common/store-module-schema-sync.js.map +1 -0
- package/dist/src/common/store-module.d.ts +43 -909
- package/dist/src/common/store-module.d.ts.map +1 -1
- package/dist/src/common/store-module.js +184 -3276
- package/dist/src/common/store-module.js.map +1 -1
- package/dist/src/common/store-table-base.d.ts +539 -0
- package/dist/src/common/store-table-base.d.ts.map +1 -0
- package/dist/src/common/store-table-base.js +900 -0
- package/dist/src/common/store-table-base.js.map +1 -0
- package/dist/src/common/store-table-constraints.d.ts +237 -0
- package/dist/src/common/store-table-constraints.d.ts.map +1 -0
- package/dist/src/common/store-table-constraints.js +624 -0
- package/dist/src/common/store-table-constraints.js.map +1 -0
- package/dist/src/common/store-table-scan.d.ts +452 -0
- package/dist/src/common/store-table-scan.d.ts.map +1 -0
- package/dist/src/common/store-table-scan.js +901 -0
- package/dist/src/common/store-table-scan.js.map +1 -0
- package/dist/src/common/store-table.d.ts +71 -1144
- package/dist/src/common/store-table.d.ts.map +1 -1
- package/dist/src/common/store-table.js +168 -2385
- package/dist/src/common/store-table.js.map +1 -1
- package/dist/src/testing/index.d.ts +12 -0
- package/dist/src/testing/index.d.ts.map +1 -0
- package/dist/src/testing/index.js +12 -0
- package/dist/src/testing/index.js.map +1 -0
- package/dist/src/testing/kv-assert.d.ts +19 -0
- package/dist/src/testing/kv-assert.d.ts.map +1 -0
- package/dist/src/testing/kv-assert.js +25 -0
- package/dist/src/testing/kv-assert.js.map +1 -0
- package/dist/src/testing/kv-conformance.d.ts.map +1 -1
- package/dist/src/testing/kv-conformance.js +1 -15
- package/dist/src/testing/kv-conformance.js.map +1 -1
- package/dist/src/testing/kv-provider-conformance.d.ts +54 -0
- package/dist/src/testing/kv-provider-conformance.d.ts.map +1 -0
- package/dist/src/testing/kv-provider-conformance.js +183 -0
- package/dist/src/testing/kv-provider-conformance.js.map +1 -0
- 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"}
|