@quereus/quereus 4.8.0 → 4.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/core/database.d.ts +6 -0
- package/dist/src/core/database.d.ts.map +1 -1
- package/dist/src/core/database.js +45 -5
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/core/statement.d.ts.map +1 -1
- package/dist/src/core/statement.js +74 -15
- package/dist/src/core/statement.js.map +1 -1
- package/dist/src/func/builtins/aggregate.d.ts.map +1 -1
- package/dist/src/func/builtins/aggregate.js +88 -35
- package/dist/src/func/builtins/aggregate.js.map +1 -1
- package/dist/src/func/builtins/conversion.d.ts +5 -0
- package/dist/src/func/builtins/conversion.d.ts.map +1 -1
- package/dist/src/func/builtins/conversion.js +16 -2
- package/dist/src/func/builtins/conversion.js.map +1 -1
- package/dist/src/func/builtins/explain.d.ts.map +1 -1
- package/dist/src/func/builtins/explain.js +9 -2
- package/dist/src/func/builtins/explain.js.map +1 -1
- package/dist/src/func/builtins/index.d.ts.map +1 -1
- package/dist/src/func/builtins/index.js +5 -2
- package/dist/src/func/builtins/index.js.map +1 -1
- package/dist/src/func/builtins/scalar.d.ts.map +1 -1
- package/dist/src/func/builtins/scalar.js +4 -2
- package/dist/src/func/builtins/scalar.js.map +1 -1
- package/dist/src/func/builtins/string.d.ts +2 -0
- package/dist/src/func/builtins/string.d.ts.map +1 -1
- package/dist/src/func/builtins/string.js +60 -4
- package/dist/src/func/builtins/string.js.map +1 -1
- package/dist/src/func/registration.d.ts +6 -0
- package/dist/src/func/registration.d.ts.map +1 -1
- package/dist/src/func/registration.js +1 -0
- package/dist/src/func/registration.js.map +1 -1
- package/dist/src/index.d.ts +7 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +21 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/planner/building/constraint-builder.js +1 -1
- package/dist/src/planner/building/constraint-builder.js.map +1 -1
- package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
- package/dist/src/planner/nodes/scalar.js +13 -1
- package/dist/src/planner/nodes/scalar.js.map +1 -1
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.d.ts.map +1 -1
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +121 -51
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
- package/dist/src/planner/rules/shared/index-style-context.d.ts +14 -4
- package/dist/src/planner/rules/shared/index-style-context.d.ts.map +1 -1
- package/dist/src/planner/rules/shared/index-style-context.js +14 -4
- package/dist/src/planner/rules/shared/index-style-context.js.map +1 -1
- package/dist/src/runtime/emission-context.d.ts +14 -1
- package/dist/src/runtime/emission-context.d.ts.map +1 -1
- package/dist/src/runtime/emission-context.js +17 -5
- package/dist/src/runtime/emission-context.js.map +1 -1
- package/dist/src/runtime/emit/aggregate-setup.d.ts +44 -8
- package/dist/src/runtime/emit/aggregate-setup.d.ts.map +1 -1
- package/dist/src/runtime/emit/aggregate-setup.js +79 -15
- package/dist/src/runtime/emit/aggregate-setup.js.map +1 -1
- package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
- package/dist/src/runtime/emit/aggregate.js +21 -106
- package/dist/src/runtime/emit/aggregate.js.map +1 -1
- package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/alter-table.js +212 -155
- package/dist/src/runtime/emit/alter-table.js.map +1 -1
- package/dist/src/runtime/emit/asof-scan.js +1 -1
- package/dist/src/runtime/emit/asof-scan.js.map +1 -1
- package/dist/src/runtime/emit/assertion-drop-guard.d.ts +26 -12
- package/dist/src/runtime/emit/assertion-drop-guard.d.ts.map +1 -1
- package/dist/src/runtime/emit/assertion-drop-guard.js +45 -26
- package/dist/src/runtime/emit/assertion-drop-guard.js.map +1 -1
- package/dist/src/runtime/emit/assertion-rename-helpers.d.ts +6 -6
- package/dist/src/runtime/emit/assertion-rename-helpers.d.ts.map +1 -1
- package/dist/src/runtime/emit/assertion-rename-helpers.js +18 -20
- package/dist/src/runtime/emit/assertion-rename-helpers.js.map +1 -1
- package/dist/src/runtime/emit/between.d.ts +2 -0
- package/dist/src/runtime/emit/between.d.ts.map +1 -1
- package/dist/src/runtime/emit/between.js +7 -8
- package/dist/src/runtime/emit/between.js.map +1 -1
- package/dist/src/runtime/emit/binary.d.ts +27 -5
- package/dist/src/runtime/emit/binary.d.ts.map +1 -1
- package/dist/src/runtime/emit/binary.js +278 -187
- package/dist/src/runtime/emit/binary.js.map +1 -1
- package/dist/src/runtime/emit/case.d.ts +34 -0
- package/dist/src/runtime/emit/case.d.ts.map +1 -1
- package/dist/src/runtime/emit/case.js +18 -11
- package/dist/src/runtime/emit/case.js.map +1 -1
- package/dist/src/runtime/emit/cast.d.ts +2 -0
- package/dist/src/runtime/emit/cast.d.ts.map +1 -1
- package/dist/src/runtime/emit/cast.js +7 -5
- package/dist/src/runtime/emit/cast.js.map +1 -1
- package/dist/src/runtime/emit/column-reference.d.ts +3 -1
- package/dist/src/runtime/emit/column-reference.d.ts.map +1 -1
- package/dist/src/runtime/emit/column-reference.js +6 -2
- package/dist/src/runtime/emit/column-reference.js.map +1 -1
- package/dist/src/runtime/emit/column-rename-cascade.d.ts +84 -0
- package/dist/src/runtime/emit/column-rename-cascade.d.ts.map +1 -0
- package/dist/src/runtime/emit/column-rename-cascade.js +134 -0
- package/dist/src/runtime/emit/column-rename-cascade.js.map +1 -0
- package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
- package/dist/src/runtime/emit/dml-executor.js +21 -0
- package/dist/src/runtime/emit/dml-executor.js.map +1 -1
- package/dist/src/runtime/emit/drop-column-guards.d.ts +82 -53
- package/dist/src/runtime/emit/drop-column-guards.d.ts.map +1 -1
- package/dist/src/runtime/emit/drop-column-guards.js +155 -90
- package/dist/src/runtime/emit/drop-column-guards.js.map +1 -1
- package/dist/src/runtime/emit/drop-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/drop-table.js +5 -0
- package/dist/src/runtime/emit/drop-table.js.map +1 -1
- package/dist/src/runtime/emit/drop-view.d.ts.map +1 -1
- package/dist/src/runtime/emit/drop-view.js +5 -0
- package/dist/src/runtime/emit/drop-view.js.map +1 -1
- package/dist/src/runtime/emit/expression-drop-guard.d.ts +57 -0
- package/dist/src/runtime/emit/expression-drop-guard.d.ts.map +1 -0
- package/dist/src/runtime/emit/expression-drop-guard.js +82 -0
- package/dist/src/runtime/emit/expression-drop-guard.js.map +1 -0
- package/dist/src/runtime/emit/filter.d.ts +1 -1
- package/dist/src/runtime/emit/filter.js +1 -1
- package/dist/src/runtime/emit/hash-aggregate.d.ts.map +1 -1
- package/dist/src/runtime/emit/hash-aggregate.js +18 -88
- package/dist/src/runtime/emit/hash-aggregate.js.map +1 -1
- package/dist/src/runtime/emit/literal.d.ts +14 -1
- package/dist/src/runtime/emit/literal.d.ts.map +1 -1
- package/dist/src/runtime/emit/literal.js +33 -7
- package/dist/src/runtime/emit/literal.js.map +1 -1
- package/dist/src/runtime/emit/materialized-view-helpers.d.ts +33 -10
- package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -1
- package/dist/src/runtime/emit/materialized-view-helpers.js +158 -49
- package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -1
- package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -1
- package/dist/src/runtime/emit/materialized-view.js +3 -0
- package/dist/src/runtime/emit/materialized-view.js.map +1 -1
- package/dist/src/runtime/emit/parameter.d.ts +3 -1
- package/dist/src/runtime/emit/parameter.d.ts.map +1 -1
- package/dist/src/runtime/emit/parameter.js +7 -2
- package/dist/src/runtime/emit/parameter.js.map +1 -1
- package/dist/src/runtime/emit/scalar-function.d.ts +29 -1
- package/dist/src/runtime/emit/scalar-function.d.ts.map +1 -1
- package/dist/src/runtime/emit/scalar-function.js +66 -16
- package/dist/src/runtime/emit/scalar-function.js.map +1 -1
- package/dist/src/runtime/emit/scalar-op.d.ts +63 -0
- package/dist/src/runtime/emit/scalar-op.d.ts.map +1 -0
- package/dist/src/runtime/emit/scalar-op.js +37 -0
- package/dist/src/runtime/emit/scalar-op.js.map +1 -0
- package/dist/src/runtime/emit/scan.d.ts.map +1 -1
- package/dist/src/runtime/emit/scan.js +19 -1
- package/dist/src/runtime/emit/scan.js.map +1 -1
- package/dist/src/runtime/emit/temporal-arithmetic.d.ts +18 -8
- package/dist/src/runtime/emit/temporal-arithmetic.d.ts.map +1 -1
- package/dist/src/runtime/emit/temporal-arithmetic.js +29 -311
- package/dist/src/runtime/emit/temporal-arithmetic.js.map +1 -1
- package/dist/src/runtime/emit/unary.d.ts +2 -0
- package/dist/src/runtime/emit/unary.d.ts.map +1 -1
- package/dist/src/runtime/emit/unary.js +125 -53
- package/dist/src/runtime/emit/unary.js.map +1 -1
- package/dist/src/runtime/emitters.d.ts +22 -0
- package/dist/src/runtime/emitters.d.ts.map +1 -1
- package/dist/src/runtime/emitters.js +29 -0
- package/dist/src/runtime/emitters.js.map +1 -1
- package/dist/src/runtime/scalar-fusion.d.ts +47 -0
- package/dist/src/runtime/scalar-fusion.d.ts.map +1 -0
- package/dist/src/runtime/scalar-fusion.js +275 -0
- package/dist/src/runtime/scalar-fusion.js.map +1 -0
- package/dist/src/runtime/strict-flags.d.ts +9 -0
- package/dist/src/runtime/strict-flags.d.ts.map +1 -1
- package/dist/src/runtime/strict-flags.js +9 -0
- package/dist/src/runtime/strict-flags.js.map +1 -1
- package/dist/src/runtime/strict-fork.js +2 -2
- package/dist/src/runtime/strict-fork.js.map +1 -1
- package/dist/src/runtime/strict-representation.d.ts +78 -0
- package/dist/src/runtime/strict-representation.d.ts.map +1 -0
- package/dist/src/runtime/strict-representation.js +159 -0
- package/dist/src/runtime/strict-representation.js.map +1 -0
- package/dist/src/schema/assertion.d.ts +58 -0
- package/dist/src/schema/assertion.d.ts.map +1 -1
- package/dist/src/schema/assertion.js +78 -0
- package/dist/src/schema/assertion.js.map +1 -1
- package/dist/src/schema/catalog-persistability.d.ts +11 -3
- package/dist/src/schema/catalog-persistability.d.ts.map +1 -1
- package/dist/src/schema/catalog-persistability.js +48 -29
- package/dist/src/schema/catalog-persistability.js.map +1 -1
- package/dist/src/schema/catalog.d.ts +22 -0
- package/dist/src/schema/catalog.d.ts.map +1 -1
- package/dist/src/schema/catalog.js +4 -1
- package/dist/src/schema/catalog.js.map +1 -1
- package/dist/src/schema/column-republication.d.ts +126 -0
- package/dist/src/schema/column-republication.d.ts.map +1 -0
- package/dist/src/schema/column-republication.js +121 -0
- package/dist/src/schema/column-republication.js.map +1 -0
- package/dist/src/schema/column-source-resolver.d.ts +29 -6
- package/dist/src/schema/column-source-resolver.d.ts.map +1 -1
- package/dist/src/schema/column-source-resolver.js +78 -9
- package/dist/src/schema/column-source-resolver.js.map +1 -1
- package/dist/src/schema/expression-dependents.d.ts +160 -0
- package/dist/src/schema/expression-dependents.d.ts.map +1 -0
- package/dist/src/schema/expression-dependents.js +228 -0
- package/dist/src/schema/expression-dependents.js.map +1 -0
- package/dist/src/schema/function.d.ts +15 -0
- package/dist/src/schema/function.d.ts.map +1 -1
- package/dist/src/schema/function.js.map +1 -1
- package/dist/src/schema/object-dependency-closure.d.ts +127 -0
- package/dist/src/schema/object-dependency-closure.d.ts.map +1 -0
- package/dist/src/schema/object-dependency-closure.js +117 -0
- package/dist/src/schema/object-dependency-closure.js.map +1 -0
- package/dist/src/schema/object-ref-resolver.d.ts +83 -0
- package/dist/src/schema/object-ref-resolver.d.ts.map +1 -0
- package/dist/src/schema/object-ref-resolver.js +135 -0
- package/dist/src/schema/object-ref-resolver.js.map +1 -0
- package/dist/src/schema/rename/column-rename.d.ts +228 -0
- package/dist/src/schema/rename/column-rename.d.ts.map +1 -0
- package/dist/src/schema/rename/column-rename.js +1225 -0
- package/dist/src/schema/rename/column-rename.js.map +1 -0
- package/dist/src/schema/rename/self-qualifier-strip.d.ts +29 -0
- package/dist/src/schema/rename/self-qualifier-strip.d.ts.map +1 -0
- package/dist/src/schema/rename/self-qualifier-strip.js +267 -0
- package/dist/src/schema/rename/self-qualifier-strip.js.map +1 -0
- package/dist/src/schema/rename/shared.d.ts +108 -0
- package/dist/src/schema/rename/shared.d.ts.map +1 -0
- package/dist/src/schema/rename/shared.js +49 -0
- package/dist/src/schema/rename/shared.js.map +1 -0
- package/dist/src/schema/rename/table-rename.d.ts +263 -0
- package/dist/src/schema/rename/table-rename.d.ts.map +1 -0
- package/dist/src/schema/rename/table-rename.js +860 -0
- package/dist/src/schema/rename/table-rename.js.map +1 -0
- package/dist/src/schema/rename-rewriter.d.ts +18 -278
- package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
- package/dist/src/schema/rename-rewriter.js +17 -1506
- package/dist/src/schema/rename-rewriter.js.map +1 -1
- package/dist/src/schema/schema-differ.d.ts.map +1 -1
- package/dist/src/schema/schema-differ.js +228 -21
- package/dist/src/schema/schema-differ.js.map +1 -1
- package/dist/src/types/builtin-types.d.ts.map +1 -1
- package/dist/src/types/builtin-types.js +29 -36
- package/dist/src/types/builtin-types.js.map +1 -1
- package/dist/src/types/cast-semantics.d.ts +7 -5
- package/dist/src/types/cast-semantics.d.ts.map +1 -1
- package/dist/src/types/cast-semantics.js +20 -9
- package/dist/src/types/cast-semantics.js.map +1 -1
- package/dist/src/types/index.d.ts +1 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js +1 -1
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/registry.d.ts.map +1 -1
- package/dist/src/types/registry.js +2 -1
- package/dist/src/types/registry.js.map +1 -1
- package/dist/src/types/temporal-ops.d.ts +119 -0
- package/dist/src/types/temporal-ops.d.ts.map +1 -0
- package/dist/src/types/temporal-ops.js +348 -0
- package/dist/src/types/temporal-ops.js.map +1 -0
- package/dist/src/types/temporal-types.d.ts +11 -0
- package/dist/src/types/temporal-types.d.ts.map +1 -1
- package/dist/src/types/temporal-types.js +87 -0
- package/dist/src/types/temporal-types.js.map +1 -1
- package/dist/src/util/affinity.d.ts +2 -1
- package/dist/src/util/affinity.d.ts.map +1 -1
- package/dist/src/util/affinity.js +16 -5
- package/dist/src/util/affinity.js.map +1 -1
- package/dist/src/util/ast-spine-clone.d.ts +2 -2
- package/dist/src/util/ast-spine-clone.js +2 -2
- package/dist/src/util/coercion.d.ts +22 -7
- package/dist/src/util/coercion.d.ts.map +1 -1
- package/dist/src/util/coercion.js +28 -15
- package/dist/src/util/coercion.js.map +1 -1
- package/dist/src/util/comparison.d.ts +25 -0
- package/dist/src/util/comparison.d.ts.map +1 -1
- package/dist/src/util/comparison.js +25 -0
- package/dist/src/util/comparison.js.map +1 -1
- package/dist/src/util/key-tuple-codec.d.ts +12 -3
- package/dist/src/util/key-tuple-codec.d.ts.map +1 -1
- package/dist/src/util/key-tuple-codec.js.map +1 -1
- package/dist/src/util/numeric-canonical.d.ts +26 -0
- package/dist/src/util/numeric-canonical.d.ts.map +1 -0
- package/dist/src/util/numeric-canonical.js +66 -0
- package/dist/src/util/numeric-canonical.js.map +1 -0
- package/dist/src/util/value-text.d.ts +48 -0
- package/dist/src/util/value-text.d.ts.map +1 -0
- package/dist/src/util/value-text.js +35 -0
- package/dist/src/util/value-text.js.map +1 -0
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +14 -5
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/dist/src/vtab/module.d.ts +25 -0
- package/dist/src/vtab/module.d.ts.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { Database } from '../core/database.js';
|
|
2
|
+
import type { ObjectRefResolvers } from './object-ref-resolver.js';
|
|
3
|
+
import type { ResolveColumnInSource } from './rename-rewriter.js';
|
|
4
|
+
/**
|
|
5
|
+
* Column REPUBLICATION: which views / materialized views expose a table's
|
|
6
|
+
* column as one of their own output columns — a bare passthrough projection
|
|
7
|
+
* (`select x from t`), or a `*` / `t.*` whose frame binds the table.
|
|
8
|
+
*
|
|
9
|
+
* Two verbs consume the same lineage, which is why it lives here in `schema/`
|
|
10
|
+
* rather than inside either verb's emitter:
|
|
11
|
+
*
|
|
12
|
+
* - `ALTER TABLE … RENAME COLUMN` re-targets its propagation on every
|
|
13
|
+
* republisher, breadth-first, because rewriting a body shifts the name that
|
|
14
|
+
* body PUBLISHES and its readers then need the same rename with the view as
|
|
15
|
+
* the target ({@link scanShiftedPublishers}, driven by
|
|
16
|
+
* `runtime/emit/column-rename-cascade.ts`).
|
|
17
|
+
* - `ALTER TABLE … DROP COLUMN` refuses when a live rule (CHECK / DEFAULT /
|
|
18
|
+
* generated body / assertion) reads the column, and a rule can read it
|
|
19
|
+
* THROUGH a republisher without any body in the chain spelling the column's
|
|
20
|
+
* name (`create view v as select * from t` + a rule reading `v.x`). The
|
|
21
|
+
* drop guards therefore probe each reached body against every republication
|
|
22
|
+
* target ({@link collectColumnRepublication}), not against the base table
|
|
23
|
+
* alone — restoring the invariant that the drop refuses exactly the
|
|
24
|
+
* references a rename would have rewritten.
|
|
25
|
+
*/
|
|
26
|
+
/** One round's rename target: the object whose published column shifts old → new. */
|
|
27
|
+
export interface ColumnRenameCascadeTarget {
|
|
28
|
+
/** Canonical `<schema>.<name>` key of the target (see {@link objectRefKey}). */
|
|
29
|
+
targetKey: string;
|
|
30
|
+
/** The target's bare name — what unqualified references in dependent bodies spell. */
|
|
31
|
+
tableName: string;
|
|
32
|
+
}
|
|
33
|
+
/** Visited-set key for one (target, column) pair of a cascade / fixpoint round. */
|
|
34
|
+
export declare const visitKeyOf: (target: ColumnRenameCascadeTarget, oldColLower: string) => string;
|
|
35
|
+
export interface ShiftScanOpts {
|
|
36
|
+
/**
|
|
37
|
+
* Probe a spine clone with the round's rewrite applied first — the read-only
|
|
38
|
+
* pre-flight, whose bodies have not been rewritten yet. The live driver's
|
|
39
|
+
* scan runs after the round's in-place rewrites and reads the live ASTs.
|
|
40
|
+
*/
|
|
41
|
+
probeOnClone: boolean;
|
|
42
|
+
/** MVs whose published names cannot shift (pre-existing staleness — the
|
|
43
|
+
* backing columns are not renamed for those). */
|
|
44
|
+
isMvExcluded: (mv: {
|
|
45
|
+
schemaName: string;
|
|
46
|
+
name: string;
|
|
47
|
+
derivation: {
|
|
48
|
+
stale?: boolean;
|
|
49
|
+
};
|
|
50
|
+
}) => boolean;
|
|
51
|
+
/** Called once per dependent whose published names the target's rename shifts. */
|
|
52
|
+
onShifted: (dependent: ColumnRenameCascadeTarget) => void;
|
|
53
|
+
/** Pre-flight only: a shifted dependent ALSO already publishes `newCol`. */
|
|
54
|
+
onCollision?: (kind: 'view' | 'materialized view', schemaName: string, name: string) => void;
|
|
55
|
+
/**
|
|
56
|
+
* Called for a view / MV with an EXPLICIT column list whose body republishes
|
|
57
|
+
* the column. Such an object never shifts a published name (the list pins
|
|
58
|
+
* them — why the rename skips it), but a column DROP changes the arity its
|
|
59
|
+
* `*` produces and breaks the object outright. Only the drop's fixpoint
|
|
60
|
+
* passes this; when absent the object is skipped without paying the probe,
|
|
61
|
+
* exactly as the cascade always has.
|
|
62
|
+
*/
|
|
63
|
+
onListedShifted?: (kind: 'view' | 'materialized view', schemaName: string, name: string) => void;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* One round's dependent scan, shared by the rename cascade (pre-flight and
|
|
67
|
+
* live driver) and the drop fixpoint: every schema's plain views and
|
|
68
|
+
* maintained tables. An explicit column list pins the published names (the
|
|
69
|
+
* same guard `cte.columns` is inside the CTE exposure analysis), so a listed
|
|
70
|
+
* object is never a shift target — it is reported through
|
|
71
|
+
* {@link ShiftScanOpts.onListedShifted} instead, when that arm is wired.
|
|
72
|
+
*/
|
|
73
|
+
export declare function scanShiftedPublishers(db: Database, target: ColumnRenameCascadeTarget, oldCol: string, newCol: string, resolvers: ObjectRefResolvers, resolveColumnInSource: ResolveColumnInSource, opts: ShiftScanOpts): void;
|
|
74
|
+
/** A listed view / MV a column drop would break outright — see {@link ColumnRepublication.brokenListed}. */
|
|
75
|
+
export interface BrokenListedRepublisher {
|
|
76
|
+
/** Canonical `<schema>.<name>` key, for `ObjectReach.namerOf`. */
|
|
77
|
+
key: string;
|
|
78
|
+
/** Error-message spelling: `view 'v'` / `materialized view 'm'`. */
|
|
79
|
+
describe: string;
|
|
80
|
+
}
|
|
81
|
+
/** What {@link collectColumnRepublication} returns — the drop guards' lineage answer. */
|
|
82
|
+
export interface ColumnRepublication {
|
|
83
|
+
/**
|
|
84
|
+
* The seed plus every view / MV that republishes the column, transitively,
|
|
85
|
+
* breadth-first — the SEED FIRST, so a guard sweeping targets in order
|
|
86
|
+
* reports base-table matches with the message spelling it always has.
|
|
87
|
+
*/
|
|
88
|
+
targets: ReadonlyArray<ColumnRenameCascadeTarget>;
|
|
89
|
+
/**
|
|
90
|
+
* Views / MVs with an EXPLICIT column list whose body republishes the
|
|
91
|
+
* column. These are NOT targets — a pinned list publishes no shifted name —
|
|
92
|
+
* but dropping the column changes the arity their `*` produces and breaks
|
|
93
|
+
* the object outright, so a rule whose reach names one at all must refuse.
|
|
94
|
+
*/
|
|
95
|
+
brokenListed: ReadonlyArray<BrokenListedRepublisher>;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Read-only republication fixpoint for `ALTER TABLE … DROP COLUMN`: the same
|
|
99
|
+
* breadth-first walk the rename cascade's pre-flight runs
|
|
100
|
+
* (`assertColumnRenameCascadePublishable`), minus its collision arm, plus the
|
|
101
|
+
* listed-object arm above.
|
|
102
|
+
*
|
|
103
|
+
* Nothing is renamed here, so each round probes with a SENTINEL new name
|
|
104
|
+
* ({@link PROBE_COLUMN_NAME} — the same trick `columnReferencedInAst` uses):
|
|
105
|
+
* `probeOnClone` applies the sentinel rename to a spine clone and asks
|
|
106
|
+
* `bodyExposesRenamedColumn` against it, mutating nothing. Downstream rounds
|
|
107
|
+
* keep asking about `columnName` unchanged — a republisher exposes the column
|
|
108
|
+
* under its own name, which is what its readers spell.
|
|
109
|
+
*
|
|
110
|
+
* The pristine catalog gives the same answers the cascade's live rounds would,
|
|
111
|
+
* for the pre-flight's own reason: a round only rewrites references binding
|
|
112
|
+
* ITS OWN target, which no other round's exposure question consults.
|
|
113
|
+
*
|
|
114
|
+
* MATERIALIZED VIEWS are treated exactly like views — `isMvExcluded` never
|
|
115
|
+
* fires — deliberately CONSERVATIVE: an MV's backing columns survive the drop,
|
|
116
|
+
* so a rule reading the column through the MV would in fact keep working
|
|
117
|
+
* (against frozen contents, with the MV marked stale and its next
|
|
118
|
+
* `refresh materialized view` failing). Refusing anyway keeps one rule for
|
|
119
|
+
* both object kinds and matches what the named-projection spelling already
|
|
120
|
+
* does (pinned by 41.10.2 §27) and what `DROP TABLE` does for the same object.
|
|
121
|
+
* The cascade's stale-MV exclusion is rename-specific (a pre-stale MV's
|
|
122
|
+
* backing columns are not renamed) and has no drop analogue, so staleness is
|
|
123
|
+
* not consulted at all.
|
|
124
|
+
*/
|
|
125
|
+
export declare function collectColumnRepublication(db: Database, seed: ColumnRenameCascadeTarget, columnName: string, resolvers: ObjectRefResolvers, resolveColumnInSource: ResolveColumnInSource): ColumnRepublication;
|
|
126
|
+
//# sourceMappingURL=column-republication.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"column-republication.d.ts","sourceRoot":"","sources":["../../../src/schema/column-republication.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAGlE;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,qFAAqF;AACrF,MAAM,WAAW,yBAAyB;IACzC,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,mFAAmF;AACnF,eAAO,MAAM,UAAU,GAAI,QAAQ,yBAAyB,EAAE,aAAa,MAAM,KAAG,MAC/C,CAAC;AAEtC,MAAM,WAAW,aAAa;IAC7B;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;IACtB;sDACkD;IAClD,YAAY,EAAE,CAAC,EAAE,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE;YAAE,KAAK,CAAC,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE,KAAK,OAAO,CAAC;IACrG,kFAAkF;IAClF,SAAS,EAAE,CAAC,SAAS,EAAE,yBAAyB,KAAK,IAAI,CAAC;IAC1D,4EAA4E;IAC5E,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7F;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjG;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACpC,EAAE,EAAE,QAAQ,EACZ,MAAM,EAAE,yBAAyB,EACjC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,kBAAkB,EAC7B,qBAAqB,EAAE,qBAAqB,EAC5C,IAAI,EAAE,aAAa,GACjB,IAAI,CA2CN;AAED,4GAA4G;AAC5G,MAAM,WAAW,uBAAuB;IACvC,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,yFAAyF;AACzF,MAAM,WAAW,mBAAmB;IACnC;;;;OAIG;IACH,OAAO,EAAE,aAAa,CAAC,yBAAyB,CAAC,CAAC;IAClD;;;;;OAKG;IACH,YAAY,EAAE,aAAa,CAAC,uBAAuB,CAAC,CAAC;CACrD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,0BAA0B,CACzC,EAAE,EAAE,QAAQ,EACZ,IAAI,EAAE,yBAAyB,EAC/B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,kBAAkB,EAC7B,qBAAqB,EAAE,qBAAqB,GAC1C,mBAAmB,CA4BrB"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { isMaintainedTable } from './derivation.js';
|
|
2
|
+
import { PROBE_COLUMN_NAME, bodyExposesRenamedColumn, bodyPublishesColumnNamed, objectRefKey, renameColumnInAst, } from './rename-rewriter.js';
|
|
3
|
+
import { spineCloneAst } from '../util/ast-spine-clone.js';
|
|
4
|
+
/** Visited-set key for one (target, column) pair of a cascade / fixpoint round. */
|
|
5
|
+
export const visitKeyOf = (target, oldColLower) => `${target.targetKey}:${oldColLower}`;
|
|
6
|
+
/**
|
|
7
|
+
* One round's dependent scan, shared by the rename cascade (pre-flight and
|
|
8
|
+
* live driver) and the drop fixpoint: every schema's plain views and
|
|
9
|
+
* maintained tables. An explicit column list pins the published names (the
|
|
10
|
+
* same guard `cte.columns` is inside the CTE exposure analysis), so a listed
|
|
11
|
+
* object is never a shift target — it is reported through
|
|
12
|
+
* {@link ShiftScanOpts.onListedShifted} instead, when that arm is wired.
|
|
13
|
+
*/
|
|
14
|
+
export function scanShiftedPublishers(db, target, oldCol, newCol, resolvers, resolveColumnInSource, opts) {
|
|
15
|
+
for (const schema of db.schemaManager._getAllSchemas()) {
|
|
16
|
+
const resolve = resolvers.forHomeSchema(schema.name);
|
|
17
|
+
const shifted = (body) => {
|
|
18
|
+
let probe = body;
|
|
19
|
+
if (opts.probeOnClone) {
|
|
20
|
+
probe = spineCloneAst(body);
|
|
21
|
+
// Row-image mode 'none': a view / MV body is a relation with no written
|
|
22
|
+
// row (its `with inverse` / `with defaults` subtrees self-suppress).
|
|
23
|
+
renameColumnInAst(probe, target.tableName, oldCol, newCol, resolve, target.targetKey, 'none', resolveColumnInSource);
|
|
24
|
+
}
|
|
25
|
+
return bodyExposesRenamedColumn(probe, target.tableName, oldCol, newCol, resolve, target.targetKey, resolveColumnInSource);
|
|
26
|
+
};
|
|
27
|
+
for (const view of Array.from(schema.getAllViews())) {
|
|
28
|
+
if (view.columns && view.columns.length > 0) {
|
|
29
|
+
if (opts.onListedShifted && shifted(view.selectAst)) {
|
|
30
|
+
opts.onListedShifted('view', schema.name, view.name);
|
|
31
|
+
}
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (!shifted(view.selectAst))
|
|
35
|
+
continue;
|
|
36
|
+
if (opts.onCollision && bodyPublishesColumnNamed(view.selectAst, newCol, resolve, resolveColumnInSource)) {
|
|
37
|
+
opts.onCollision('view', schema.name, view.name);
|
|
38
|
+
}
|
|
39
|
+
opts.onShifted({ targetKey: objectRefKey(schema.name, view.name), tableName: view.name });
|
|
40
|
+
}
|
|
41
|
+
for (const table of Array.from(schema.getAllTables())) {
|
|
42
|
+
if (!isMaintainedTable(table))
|
|
43
|
+
continue;
|
|
44
|
+
if (opts.isMvExcluded(table))
|
|
45
|
+
continue;
|
|
46
|
+
const d = table.derivation;
|
|
47
|
+
if (d.columns && d.columns.length > 0) {
|
|
48
|
+
if (opts.onListedShifted && shifted(d.selectAst)) {
|
|
49
|
+
opts.onListedShifted('materialized view', schema.name, table.name);
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (!shifted(d.selectAst))
|
|
54
|
+
continue;
|
|
55
|
+
if (opts.onCollision && bodyPublishesColumnNamed(d.selectAst, newCol, resolve, resolveColumnInSource)) {
|
|
56
|
+
opts.onCollision('materialized view', schema.name, table.name);
|
|
57
|
+
}
|
|
58
|
+
opts.onShifted({ targetKey: objectRefKey(schema.name, table.name), tableName: table.name });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Read-only republication fixpoint for `ALTER TABLE … DROP COLUMN`: the same
|
|
64
|
+
* breadth-first walk the rename cascade's pre-flight runs
|
|
65
|
+
* (`assertColumnRenameCascadePublishable`), minus its collision arm, plus the
|
|
66
|
+
* listed-object arm above.
|
|
67
|
+
*
|
|
68
|
+
* Nothing is renamed here, so each round probes with a SENTINEL new name
|
|
69
|
+
* ({@link PROBE_COLUMN_NAME} — the same trick `columnReferencedInAst` uses):
|
|
70
|
+
* `probeOnClone` applies the sentinel rename to a spine clone and asks
|
|
71
|
+
* `bodyExposesRenamedColumn` against it, mutating nothing. Downstream rounds
|
|
72
|
+
* keep asking about `columnName` unchanged — a republisher exposes the column
|
|
73
|
+
* under its own name, which is what its readers spell.
|
|
74
|
+
*
|
|
75
|
+
* The pristine catalog gives the same answers the cascade's live rounds would,
|
|
76
|
+
* for the pre-flight's own reason: a round only rewrites references binding
|
|
77
|
+
* ITS OWN target, which no other round's exposure question consults.
|
|
78
|
+
*
|
|
79
|
+
* MATERIALIZED VIEWS are treated exactly like views — `isMvExcluded` never
|
|
80
|
+
* fires — deliberately CONSERVATIVE: an MV's backing columns survive the drop,
|
|
81
|
+
* so a rule reading the column through the MV would in fact keep working
|
|
82
|
+
* (against frozen contents, with the MV marked stale and its next
|
|
83
|
+
* `refresh materialized view` failing). Refusing anyway keeps one rule for
|
|
84
|
+
* both object kinds and matches what the named-projection spelling already
|
|
85
|
+
* does (pinned by 41.10.2 §27) and what `DROP TABLE` does for the same object.
|
|
86
|
+
* The cascade's stale-MV exclusion is rename-specific (a pre-stale MV's
|
|
87
|
+
* backing columns are not renamed) and has no drop analogue, so staleness is
|
|
88
|
+
* not consulted at all.
|
|
89
|
+
*/
|
|
90
|
+
export function collectColumnRepublication(db, seed, columnName, resolvers, resolveColumnInSource) {
|
|
91
|
+
const colLower = columnName.toLowerCase();
|
|
92
|
+
const targets = [seed];
|
|
93
|
+
const brokenListed = [];
|
|
94
|
+
const flaggedListed = new Set();
|
|
95
|
+
const visited = new Set([visitKeyOf(seed, colLower)]);
|
|
96
|
+
const queue = [seed];
|
|
97
|
+
while (queue.length > 0) {
|
|
98
|
+
const target = queue.shift();
|
|
99
|
+
scanShiftedPublishers(db, target, columnName, PROBE_COLUMN_NAME, resolvers, resolveColumnInSource, {
|
|
100
|
+
probeOnClone: true,
|
|
101
|
+
isMvExcluded: () => false,
|
|
102
|
+
onShifted: dependent => {
|
|
103
|
+
const key = visitKeyOf(dependent, colLower);
|
|
104
|
+
if (visited.has(key))
|
|
105
|
+
return;
|
|
106
|
+
visited.add(key);
|
|
107
|
+
targets.push(dependent);
|
|
108
|
+
queue.push(dependent);
|
|
109
|
+
},
|
|
110
|
+
onListedShifted: (kind, schemaName, name) => {
|
|
111
|
+
const key = objectRefKey(schemaName, name);
|
|
112
|
+
if (flaggedListed.has(key))
|
|
113
|
+
return;
|
|
114
|
+
flaggedListed.add(key);
|
|
115
|
+
brokenListed.push({ key, describe: `${kind} '${name}'` });
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
return { targets, brokenListed };
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=column-republication.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"column-republication.js","sourceRoot":"","sources":["../../../src/schema/column-republication.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +1,41 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Database } from '../core/database.js';
|
|
2
2
|
import type { ResolveColumnInSource } from './rename-rewriter.js';
|
|
3
3
|
/**
|
|
4
4
|
* The catalog-backed {@link ResolveColumnInSource} every scope-aware walk over a
|
|
5
5
|
* schema-object expression consults to tell an unqualified reference that binds to an
|
|
6
6
|
* inner FROM source from one that binds to the table under consideration.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* Four callers, one definition, so no two of them can disagree about what a name
|
|
9
9
|
* resolves to: `runRenameColumn`'s pre-flight probe and its real propagation, the
|
|
10
|
-
* DROP COLUMN guards
|
|
11
|
-
* planner's self-qualifier
|
|
10
|
+
* DROP COLUMN guards (`runtime/emit/drop-column-guards.ts` and
|
|
11
|
+
* `schema/expression-dependents.ts`), and the constraint planner's self-qualifier
|
|
12
|
+
* strip (`planner/building/constraint-builder.ts`).
|
|
13
|
+
*
|
|
14
|
+
* A source may be a TABLE (a maintained table included — its backing columns are
|
|
15
|
+
* real) or a VIEW. A view exposes a column when its explicit column list names it,
|
|
16
|
+
* or — with no list — when its body publishes it ({@link bodyPublishesColumnNamed}:
|
|
17
|
+
* a result-column alias, a bare projection, or a `*` / `t.*` / `a.*` over a source
|
|
18
|
+
* that exposes it — a FROM alias only changes which qualifier names the source, so
|
|
19
|
+
* `select * from t a` publishes exactly what `select * from t` does). The view arm
|
|
20
|
+
* recurses through this same resolver, so a view over a
|
|
21
|
+
* view answers too; views cannot be recursive, so the per-question in-flight set is
|
|
22
|
+
* insurance against a malformed catalog, the same role the visited set plays in
|
|
23
|
+
* `reachableObjects`.
|
|
12
24
|
*
|
|
13
25
|
* Resolves against the LIVE catalog on every call, so sharing one instance across
|
|
14
26
|
* passes does not by itself freeze the answer between them — see the rename
|
|
15
|
-
* pre-flight's comment for why its two passes agree anyway.
|
|
27
|
+
* pre-flight's comment for why its two passes agree anyway. The view arm's
|
|
28
|
+
* unqualified names likewise resolve LIVE down the view's home schema path
|
|
29
|
+
* ({@link Database._homeSchemaPath}), matching how the view body plans.
|
|
30
|
+
*
|
|
31
|
+
* NOTE: deliberately NO cross-call memo. The rename propagation shares one
|
|
32
|
+
* instance across its pre-flight and its live cascade rounds, and the rounds
|
|
33
|
+
* rewrite view bodies in place — a memoized "does view X expose col?" answer taken
|
|
34
|
+
* before a round would be stale after it. The per-question in-flight set bounds the
|
|
35
|
+
* recursion instead. The one hot-ish caller is `constraint-builder.ts` at
|
|
36
|
+
* plan-build time, where the view arm only runs for a CHECK whose subquery FROMs a
|
|
37
|
+
* view; if that ever profiles hot, add a cross-call memo guarded by a catalog
|
|
38
|
+
* generation counter.
|
|
16
39
|
*/
|
|
17
|
-
export declare function buildColumnSourceResolver(
|
|
40
|
+
export declare function buildColumnSourceResolver(db: Database): ResolveColumnInSource;
|
|
18
41
|
//# sourceMappingURL=column-source-resolver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column-source-resolver.d.ts","sourceRoot":"","sources":["../../../src/schema/column-source-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"column-source-resolver.d.ts","sourceRoot":"","sources":["../../../src/schema/column-source-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,qBAAqB,EAAoB,MAAM,sBAAsB,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,QAAQ,GAAG,qBAAqB,CAyB7E"}
|
|
@@ -1,22 +1,91 @@
|
|
|
1
|
+
import { bodyPublishesColumnNamed, objectRefKey } from './rename-rewriter.js';
|
|
1
2
|
/**
|
|
2
3
|
* The catalog-backed {@link ResolveColumnInSource} every scope-aware walk over a
|
|
3
4
|
* schema-object expression consults to tell an unqualified reference that binds to an
|
|
4
5
|
* inner FROM source from one that binds to the table under consideration.
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
+
* Four callers, one definition, so no two of them can disagree about what a name
|
|
7
8
|
* resolves to: `runRenameColumn`'s pre-flight probe and its real propagation, the
|
|
8
|
-
* DROP COLUMN guards
|
|
9
|
-
* planner's self-qualifier
|
|
9
|
+
* DROP COLUMN guards (`runtime/emit/drop-column-guards.ts` and
|
|
10
|
+
* `schema/expression-dependents.ts`), and the constraint planner's self-qualifier
|
|
11
|
+
* strip (`planner/building/constraint-builder.ts`).
|
|
12
|
+
*
|
|
13
|
+
* A source may be a TABLE (a maintained table included — its backing columns are
|
|
14
|
+
* real) or a VIEW. A view exposes a column when its explicit column list names it,
|
|
15
|
+
* or — with no list — when its body publishes it ({@link bodyPublishesColumnNamed}:
|
|
16
|
+
* a result-column alias, a bare projection, or a `*` / `t.*` / `a.*` over a source
|
|
17
|
+
* that exposes it — a FROM alias only changes which qualifier names the source, so
|
|
18
|
+
* `select * from t a` publishes exactly what `select * from t` does). The view arm
|
|
19
|
+
* recurses through this same resolver, so a view over a
|
|
20
|
+
* view answers too; views cannot be recursive, so the per-question in-flight set is
|
|
21
|
+
* insurance against a malformed catalog, the same role the visited set plays in
|
|
22
|
+
* `reachableObjects`.
|
|
10
23
|
*
|
|
11
24
|
* Resolves against the LIVE catalog on every call, so sharing one instance across
|
|
12
25
|
* passes does not by itself freeze the answer between them — see the rename
|
|
13
|
-
* pre-flight's comment for why its two passes agree anyway.
|
|
26
|
+
* pre-flight's comment for why its two passes agree anyway. The view arm's
|
|
27
|
+
* unqualified names likewise resolve LIVE down the view's home schema path
|
|
28
|
+
* ({@link Database._homeSchemaPath}), matching how the view body plans.
|
|
29
|
+
*
|
|
30
|
+
* NOTE: deliberately NO cross-call memo. The rename propagation shares one
|
|
31
|
+
* instance across its pre-flight and its live cascade rounds, and the rounds
|
|
32
|
+
* rewrite view bodies in place — a memoized "does view X expose col?" answer taken
|
|
33
|
+
* before a round would be stale after it. The per-question in-flight set bounds the
|
|
34
|
+
* recursion instead. The one hot-ish caller is `constraint-builder.ts` at
|
|
35
|
+
* plan-build time, where the view arm only runs for a CHECK whose subquery FROMs a
|
|
36
|
+
* view; if that ever profiles hot, add a cross-call memo guarded by a catalog
|
|
37
|
+
* generation counter.
|
|
38
|
+
*/
|
|
39
|
+
export function buildColumnSourceResolver(db) {
|
|
40
|
+
const answer = (schemaName, sourceName, columnName, inFlight) => {
|
|
41
|
+
const targetSchema = db.schemaManager.getSchema(schemaName);
|
|
42
|
+
if (!targetSchema)
|
|
43
|
+
return false;
|
|
44
|
+
const colLower = columnName.toLowerCase();
|
|
45
|
+
const table = targetSchema.getTable(sourceName);
|
|
46
|
+
if (table)
|
|
47
|
+
return table.columnIndexMap.has(colLower);
|
|
48
|
+
const view = targetSchema.getView(sourceName);
|
|
49
|
+
if (!view)
|
|
50
|
+
return false;
|
|
51
|
+
if (view.columns && view.columns.length > 0) {
|
|
52
|
+
return view.columns.some(c => c.toLowerCase() === colLower);
|
|
53
|
+
}
|
|
54
|
+
const key = `${objectRefKey(targetSchema.name, view.name)}:${colLower}`;
|
|
55
|
+
if (inFlight.has(key))
|
|
56
|
+
return false;
|
|
57
|
+
inFlight.add(key);
|
|
58
|
+
try {
|
|
59
|
+
const recurse = (s, t, c) => answer(s, t, c, inFlight);
|
|
60
|
+
return bodyPublishesColumnNamed(view.selectAst, columnName, liveHomePathResolver(db, view.schemaName), recurse);
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
inFlight.delete(key);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
return (schemaName, sourceName, columnName) => answer(schemaName, sourceName, columnName, new Set());
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Live {@link ResolveObjectRef} for one home schema — the same resolution rule
|
|
70
|
+
* `snapshotObjectRefResolvers` snapshots (qualified passthrough; unqualified →
|
|
71
|
+
* first home-path schema holding a table or view of the name; miss → home key),
|
|
72
|
+
* answered against the live catalog. Live is right here: this resolver's contract
|
|
73
|
+
* is live answers, and the rename cascade's mid-statement body rewrites change
|
|
74
|
+
* published COLUMNS, never the object names this resolves.
|
|
14
75
|
*/
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
76
|
+
function liveHomePathResolver(db, homeSchemaName) {
|
|
77
|
+
return (schema, name) => {
|
|
78
|
+
if (schema !== undefined)
|
|
79
|
+
return objectRefKey(schema, name);
|
|
80
|
+
for (const pathSchemaName of db._homeSchemaPath(homeSchemaName)) {
|
|
81
|
+
const pathSchema = db.schemaManager.getSchema(pathSchemaName);
|
|
82
|
+
if (!pathSchema)
|
|
83
|
+
continue;
|
|
84
|
+
if (pathSchema.getTable(name) !== undefined || pathSchema.getView(name) !== undefined) {
|
|
85
|
+
return objectRefKey(pathSchemaName, name);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return objectRefKey(homeSchemaName, name);
|
|
20
89
|
};
|
|
21
90
|
}
|
|
22
91
|
//# sourceMappingURL=column-source-resolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"column-source-resolver.js","sourceRoot":"","sources":["../../../src/schema/column-source-resolver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"column-source-resolver.js","sourceRoot":"","sources":["../../../src/schema/column-source-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type { Database } from '../core/database.js';
|
|
2
|
+
import type { TableSchema } from './table.js';
|
|
3
|
+
/**
|
|
4
|
+
* The catalog query "which stored, table-attached expressions reference this object?",
|
|
5
|
+
* shared by every DROP guard that has to refuse breaking one.
|
|
6
|
+
*
|
|
7
|
+
* A CHECK constraint, a column DEFAULT and a `GENERATED ALWAYS AS` body may all contain
|
|
8
|
+
* a subquery, so any of them can legitimately name a column or a table belonging to some
|
|
9
|
+
* OTHER table, in some other schema. `ALTER TABLE … RENAME` has always known this — it
|
|
10
|
+
* rewrites those expressions across every table in every schema — while the DROP guards
|
|
11
|
+
* used to scan only the altered table's own constraints and columns. The gap let
|
|
12
|
+
* `alter table t drop column v` and `drop table t` succeed while another table's CHECK
|
|
13
|
+
* still read `t.v`, leaving that table unwritable with an error naming neither the
|
|
14
|
+
* dropped object nor the constraint that broke.
|
|
15
|
+
*
|
|
16
|
+
* Everything here therefore walks the catalog the same way the rename propagation does —
|
|
17
|
+
* ONE {@link snapshotObjectRefResolvers} snapshot, a resolver per OWNING schema, the same
|
|
18
|
+
* scope-aware probes — so "the drop refuses exactly what a rename would have rewritten"
|
|
19
|
+
* holds by construction rather than by comment.
|
|
20
|
+
*
|
|
21
|
+
* **The own-table / other-table probe split is load-bearing.** It mirrors
|
|
22
|
+
* `rewriteTableForColumnRename`'s `isRenamedTable` branch:
|
|
23
|
+
*
|
|
24
|
+
* - On the **probed table itself**, the *seeded* probe
|
|
25
|
+
* ({@link columnReferencedInCheckExpression}) — an unqualified name in a CHECK /
|
|
26
|
+
* DEFAULT there binds the owning table implicitly.
|
|
27
|
+
* - On **any other table**, the *unseeded* probe ({@link columnReferencedInAst}) — no
|
|
28
|
+
* implicit binding, so only an explicit reference through a subquery counts. Getting
|
|
29
|
+
* this backwards false-refuses on every table that merely happens to have a like-named
|
|
30
|
+
* column.
|
|
31
|
+
*
|
|
32
|
+
* The seed answers only that binding question. What a bare `new.` / `old.` qualifier
|
|
33
|
+
* NAMES is a separate, explicitly-passed
|
|
34
|
+
* {@link import('./rename-rewriter.js').RowImageContext} — `'own'` on the seeded
|
|
35
|
+
* base-target probe, `'foreign'` on every other ROOT body (that table's row image is its
|
|
36
|
+
* own columns, not ours), `'none'` on the view / MV bodies below the root. See
|
|
37
|
+
* {@link columnProbe}.
|
|
38
|
+
*
|
|
39
|
+
* Partial-index predicates need no arm: the parser rejects a subquery in a partial-index
|
|
40
|
+
* predicate, so such a predicate can only name its own table, and `runDropColumn`'s
|
|
41
|
+
* existing predicate guard covers that case.
|
|
42
|
+
*
|
|
43
|
+
* Views are deliberately NOT probed as *dependents*. Dropping a table or column out from
|
|
44
|
+
* under a plain view stays allowed and breaks the view — the engine's stated asymmetry
|
|
45
|
+
* (see `runtime/emit/assertion-drop-guard.ts`): a broken view breaks queries OF that view,
|
|
46
|
+
* while a broken CHECK makes a whole table unwritable.
|
|
47
|
+
*
|
|
48
|
+
* Each probe runs over the REACH of the stored expression — {@link reachableObjects}, the
|
|
49
|
+
* same breadth-first closure over stored view / materialized-view bodies the assertion
|
|
50
|
+
* guards consume — not over the expression alone. Two consequences, both load-bearing:
|
|
51
|
+
*
|
|
52
|
+
* - A DIRECT reference matches exactly where a rename would have rewritten it, so the two
|
|
53
|
+
* definitions still cannot drift; the reach path is empty there, which is what keeps the
|
|
54
|
+
* guards' direct message spelling unchanged.
|
|
55
|
+
* - An INDIRECT reference — the expression names a view, whose body names the dropped
|
|
56
|
+
* object, to any depth — matches too. Without that, `check (n < (select max(v) from vv))`
|
|
57
|
+
* over `create view vv as select v from t` let `drop table t` /
|
|
58
|
+
* `alter table t drop column v` through and left the referencing table unwritable with
|
|
59
|
+
* an error naming neither the dropped object nor the constraint that broke.
|
|
60
|
+
*
|
|
61
|
+
* The root body is walked with `rowImageContext` and every body below it without — see
|
|
62
|
+
* `reachableObjects`' `rootOpts`. Rooting a CHECK / DEFAULT without it would put a table
|
|
63
|
+
* literally called `new` in the reach and false-refuse its own drop.
|
|
64
|
+
*
|
|
65
|
+
* NOTE: each probe walks every table in every schema, re-walking already-parsed ASTs, and
|
|
66
|
+
* now builds one closure PER STORED EXPRESSION rather than per table. The closure only
|
|
67
|
+
* expands objects a body actually names, so an expression naming no view adds no reached
|
|
68
|
+
* bodies at all — but it is still one extra walk per expression for the COLUMN verb, which
|
|
69
|
+
* pays `collectTableRefsInAst` to build the reach and then the column probe on top (the
|
|
70
|
+
* table verb reads its answer straight off the reach, so it is walk-for-walk with the
|
|
71
|
+
* one-hop probe it replaced). The COLUMN verb additionally runs one republication
|
|
72
|
+
* fixpoint per guard call (`schema/column-republication.ts` — a catalog sweep per round)
|
|
73
|
+
* and probes bodies × targets instead of bodies × 1; targets beyond the base table exist
|
|
74
|
+
* only when some view republishes the dropped column, so the common case pays one sweep
|
|
75
|
+
* and nothing else. Reasoned from the call shape, not measured. DDL is rare and
|
|
76
|
+
* schemas hold handfuls of tables, so this is not worth optimising now; if it ever shows as
|
|
77
|
+
* hot, gate each table on a cheap literal name scan of its stored SQL before paying for the
|
|
78
|
+
* AST walk.
|
|
79
|
+
*/
|
|
80
|
+
/** A stored, table-attached expression that references a probed object. */
|
|
81
|
+
export interface ExpressionDependent {
|
|
82
|
+
/** The table carrying the expression. */
|
|
83
|
+
table: TableSchema;
|
|
84
|
+
/** True when {@link table} IS the probed table (a self-reference), false otherwise. */
|
|
85
|
+
ownTable: boolean;
|
|
86
|
+
/** What to call it in an error: `CHECK constraint 'ck1'`, `the DEFAULT of column 'w'`, … */
|
|
87
|
+
describe: string;
|
|
88
|
+
/**
|
|
89
|
+
* The stored bodies the expression traversed to reach the probed object, each already
|
|
90
|
+
* described (`view 'v'`, `materialized view 'm'`) — EMPTY when the expression names the
|
|
91
|
+
* object itself. Feed it to `describeReachPath` to phrase an indirect refusal.
|
|
92
|
+
*/
|
|
93
|
+
path: ReadonlyArray<string>;
|
|
94
|
+
/**
|
|
95
|
+
* Present when the match is not a body NAMING the column but a view / MV the drop
|
|
96
|
+
* would BREAK OUTRIGHT: the object declares an explicit column list over a body
|
|
97
|
+
* whose `*` republishes the dropped column, so the drop changes the star's arity
|
|
98
|
+
* and every reference to the object breaks — not just references to one column.
|
|
99
|
+
* The value is the object's description (`view 'v'`), for the refusal message.
|
|
100
|
+
*/
|
|
101
|
+
breaksEntirely?: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Which family of stored expressions a column probe walks. The two exist separately
|
|
105
|
+
* because `runDropColumn` reports them through two guards with two different messages,
|
|
106
|
+
* ordered by widening blast radius.
|
|
107
|
+
*/
|
|
108
|
+
export type ColumnExpressionArm =
|
|
109
|
+
/** CHECK constraint expressions. */
|
|
110
|
+
'check'
|
|
111
|
+
/** Column DEFAULT and `GENERATED ALWAYS AS` expressions. */
|
|
112
|
+
| 'columnExpression';
|
|
113
|
+
/**
|
|
114
|
+
* The FIRST table in ANY schema whose `arm` expressions name
|
|
115
|
+
* `<tableSchema.schemaName>.<tableSchema.name>.<columnName>`, or `undefined` when none
|
|
116
|
+
* does. The probed table itself is scanned first, so a self-reference is always the one
|
|
117
|
+
* reported and the guards' own-table messages never change spelling because an unrelated
|
|
118
|
+
* schema happens to sort earlier.
|
|
119
|
+
*
|
|
120
|
+
* Only the first hit is returned: every caller is a guard that throws on it, and stopping
|
|
121
|
+
* early keeps the walk off the remaining schemas.
|
|
122
|
+
*
|
|
123
|
+
* Two expressions are skipped on the probed table itself, both deliberately:
|
|
124
|
+
*
|
|
125
|
+
* - The dropped column's **own** DEFAULT / generated body — it goes away with the column,
|
|
126
|
+
* so a self-naming default (`a integer default (new.a)`) is not something the drop
|
|
127
|
+
* orphans.
|
|
128
|
+
* - **Every** own-table generated body — `runDropColumn` already refuses off
|
|
129
|
+
* `generatedColumnDependencies`, the resolved column-index map
|
|
130
|
+
* `extractGeneratedColumnDependencies` builds, and reporting it twice would only change
|
|
131
|
+
* which of two messages the user sees. A generated body on ANOTHER table is not covered
|
|
132
|
+
* by that map and IS reported here.
|
|
133
|
+
*/
|
|
134
|
+
export declare function findColumnExpressionDependent(db: Database, tableSchema: TableSchema, columnName: string, arm: ColumnExpressionArm): ExpressionDependent | undefined;
|
|
135
|
+
/**
|
|
136
|
+
* The FIRST table in ANY schema whose CHECK / DEFAULT / `GENERATED ALWAYS AS` expressions
|
|
137
|
+
* name `<schemaName>.<objectName>`, or `undefined` when none does.
|
|
138
|
+
*
|
|
139
|
+
* The dropped object itself is skipped: its own CHECKs naming itself vanish with it, so
|
|
140
|
+
* refusing on them would make every self-referencing table undroppable. (The column verb
|
|
141
|
+
* keeps its target in the walk — a column drop leaves the rest of the table behind.)
|
|
142
|
+
*
|
|
143
|
+
* All three arms run with the walker's `rowImageContext` on the ROOT expression, exactly as
|
|
144
|
+
* `renameTableInCheckConstraints` / `renameTableInColumnExpressions` do: these
|
|
145
|
+
* expressions evaluate against a written row, so a bare `new.` / `old.` qualifier names
|
|
146
|
+
* that row image rather than a table literally called `new`.
|
|
147
|
+
*
|
|
148
|
+
* The match is `namerOf` over the expression's whole reach, so a CHECK that reads a view
|
|
149
|
+
* whose body reads the dropped object matches too, and `path` carries the shortest chain
|
|
150
|
+
* for the error to quote — empty exactly when the expression names the object itself.
|
|
151
|
+
*/
|
|
152
|
+
export declare function findTableExpressionDependent(db: Database, schemaName: string, objectName: string): ExpressionDependent | undefined;
|
|
153
|
+
/**
|
|
154
|
+
* How an error should spell `table` when the object being dropped lives in `homeSchemaName`:
|
|
155
|
+
* bare when the two share a schema, schema-qualified when they do not — the same rule the
|
|
156
|
+
* rest of the engine's messages follow, and the only way a cross-schema refusal names a
|
|
157
|
+
* table the user can actually find.
|
|
158
|
+
*/
|
|
159
|
+
export declare function describeDependentTable(table: TableSchema, homeSchemaName: string): string;
|
|
160
|
+
//# sourceMappingURL=expression-dependents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expression-dependents.d.ts","sourceRoot":"","sources":["../../../src/schema/expression-dependents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAuB,MAAM,YAAY,CAAC;AAanE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AAEH,2EAA2E;AAC3E,MAAM,WAAW,mBAAmB;IACnC,yCAAyC;IACzC,KAAK,EAAE,WAAW,CAAC;IACnB,uFAAuF;IACvF,QAAQ,EAAE,OAAO,CAAC;IAClB,4FAA4F;IAC5F,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5B;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB;AAC9B,oCAAoC;AAClC,OAAO;AACT,4DAA4D;GAC1D,kBAAkB,CAAC;AAEtB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,6BAA6B,CAC5C,EAAE,EAAE,QAAQ,EACZ,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,mBAAmB,GACtB,mBAAmB,GAAG,SAAS,CAoBjC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAC3C,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GAChB,mBAAmB,GAAG,SAAS,CAgBjC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAIzF"}
|