@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
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { QuereusError } from '../../common/errors.js';
|
|
2
2
|
import { StatusCode } from '../../common/types.js';
|
|
3
|
-
import {
|
|
4
|
-
import { columnReferencedInAst, columnReferencedInCheckExpression } from '../../schema/rename-rewriter.js';
|
|
3
|
+
import { columnReferencedInAst, objectRefKey } from '../../schema/rename-rewriter.js';
|
|
5
4
|
import { buildColumnSourceResolver } from '../../schema/column-source-resolver.js';
|
|
5
|
+
import { snapshotObjectRefResolvers } from '../../schema/object-ref-resolver.js';
|
|
6
|
+
import { collectColumnRepublication } from '../../schema/column-republication.js';
|
|
7
|
+
import { assertionReachesHomeSchemaFirst, describeOwnedAssertion } from '../../schema/assertion.js';
|
|
8
|
+
import { describeReachPath } from '../../schema/object-dependency-closure.js';
|
|
9
|
+
import { findColumnExpressionDependent, describeDependentTable, } from '../../schema/expression-dependents.js';
|
|
6
10
|
/**
|
|
7
11
|
* The `ALTER TABLE … DROP COLUMN` guards over dependents that `runDropColumn` does not
|
|
8
|
-
* otherwise see:
|
|
9
|
-
*
|
|
10
|
-
* *another* table pointing **at** the column.
|
|
12
|
+
* otherwise see: a column DEFAULT or `GENERATED ALWAYS AS` body that names the column, a
|
|
13
|
+
* CHECK constraint that names it, an assertion whose CHECK body names it, and a foreign
|
|
14
|
+
* key in *another* table pointing **at** the column.
|
|
11
15
|
*
|
|
12
16
|
* Whether a dependent is removed with the column or blocks the drop turns on two
|
|
13
17
|
* questions: is it defined by a *column set* or by an *expression*, and does it live on
|
|
@@ -21,9 +25,10 @@ import { buildColumnSourceResolver } from '../../schema/column-source-resolver.j
|
|
|
21
25
|
* `WHERE`, and — here — a column DEFAULT, a CHECK expression and an assertion body) are
|
|
22
26
|
* arbitrary user-authored logic with no narrowed form at all. The only choices are
|
|
23
27
|
* delete-it-silently and refuse, and the engine **refuses**, `StatusCode.CONSTRAINT`.
|
|
24
|
-
* - **Dependents living in another table** —
|
|
25
|
-
*
|
|
26
|
-
*
|
|
28
|
+
* - **Dependents living in another table** — a foreign key whose *parent* column is the
|
|
29
|
+
* one being dropped, and (through a subquery) another table's CHECK / DEFAULT /
|
|
30
|
+
* generated body — refuse regardless of shape. Removing one would silently weaken, or
|
|
31
|
+
* outright break, a constraint on a table the user did not name in the statement.
|
|
27
32
|
*
|
|
28
33
|
* Refuse is right for all four guards here because it is what the two expression guards
|
|
29
34
|
* already inside `runDropColumn` do (so the function gains no second policy), it is
|
|
@@ -32,93 +37,123 @@ import { buildColumnSourceResolver } from '../../schema/column-source-resolver.j
|
|
|
32
37
|
* assertion. Cascading here would make `drop table f` and `alter table f drop column x`
|
|
33
38
|
* disagree about the same object.
|
|
34
39
|
*
|
|
40
|
+
* The two expression guards below scan **every table in every schema**, not just the
|
|
41
|
+
* altered one, via `schema/expression-dependents.ts` — a CHECK or DEFAULT may contain a
|
|
42
|
+
* subquery, so another table's expression can legitimately name this column, and
|
|
43
|
+
* `ALTER TABLE … RENAME COLUMN` has always rewritten exactly those. See that module for
|
|
44
|
+
* the shared walk and the seeded/unseeded probe split it turns on. All three guards follow
|
|
45
|
+
* view / materialized-view bodies through the same closure
|
|
46
|
+
* (`schema/object-dependency-closure.ts`), so a CHECK reaching the column only through a
|
|
47
|
+
* view refuses the drop and the refusal names the chain.
|
|
48
|
+
*
|
|
35
49
|
* Known cost, accepted: an **unnamed** table-level CHECK cannot be dropped
|
|
36
50
|
* (`DROP CONSTRAINT` resolves by name only), so refusing leaves such a column
|
|
37
|
-
* undroppable short of rebuilding the table — again SQLite's position. The
|
|
38
|
-
* message quotes the constraint's expression so the user can at least see what is
|
|
39
|
-
* the way.
|
|
51
|
+
* undroppable short of rebuilding the referencing table — again SQLite's position. The
|
|
52
|
+
* refusal message quotes the constraint's expression so the user can at least see what is
|
|
53
|
+
* in the way.
|
|
40
54
|
*
|
|
41
55
|
* All four guards must run **before** `requireVtabModule` / `module.alterTable`, so a
|
|
42
56
|
* refused statement never reaches a persisting module and the table is left untouched
|
|
43
57
|
* rather than reverted.
|
|
44
58
|
*/
|
|
45
59
|
/**
|
|
46
|
-
* Refuses the drop when
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* the
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* `
|
|
68
|
-
*
|
|
69
|
-
* is load-bearing elsewhere (evaluation order), so it stays where it is.
|
|
60
|
+
* Refuses the drop when a column DEFAULT or `GENERATED ALWAYS AS` body — on the altered
|
|
61
|
+
* table or on any other table in any schema — names the column.
|
|
62
|
+
*
|
|
63
|
+
* A default is evaluated against the row being written, so on the altered table it names
|
|
64
|
+
* its siblings through the row-image qualifier — `b integer default (new.a + 1)`.
|
|
65
|
+
* Dropping `a` leaves that default uncompilable and the table unable to accept any new
|
|
66
|
+
* row at all, with an error naming a column the user deliberately removed. On ANOTHER
|
|
67
|
+
* table the same expression reaches this column only through a subquery
|
|
68
|
+
* (`w integer default ((select min(v) from t))`), and the damage is worse: that table
|
|
69
|
+
* becomes unwritable and the error names neither `t`, nor the dropped column, nor the
|
|
70
|
+
* default that broke.
|
|
71
|
+
*
|
|
72
|
+
* "Names" is decided by {@link findColumnExpressionDependent}, which shares its walk with
|
|
73
|
+
* the rename propagation — so the drop refuses exactly the references a rename would have
|
|
74
|
+
* rewritten, case folding (`NEW.A`) and the `"new"`-named-table shadowing edge included,
|
|
75
|
+
* and the two definitions cannot drift. That scope-awareness is load-bearing rather than
|
|
76
|
+
* decorative: a default whose subquery reads a like-named column on another table
|
|
77
|
+
* (`default ((select min(v) from u))`) must NOT false-refuse dropping this table's own `v`.
|
|
78
|
+
*
|
|
79
|
+
* Two expressions on the altered table are deliberately skipped — the dropped column's
|
|
80
|
+
* own default (it goes away with the column) and every own-table generated body
|
|
81
|
+
* (`runDropColumn` already refuses off `generatedColumnDependencies`). See
|
|
82
|
+
* {@link findColumnExpressionDependent} for both.
|
|
70
83
|
*/
|
|
71
|
-
export function
|
|
72
|
-
|
|
73
|
-
const resolveColumnInSource = buildColumnSourceResolver(db.schemaManager);
|
|
74
|
-
for (const col of tableSchema.columns) {
|
|
75
|
-
if (col.name.toLowerCase() === lowerColumn)
|
|
76
|
-
continue;
|
|
77
|
-
if (!col.defaultValue)
|
|
78
|
-
continue;
|
|
79
|
-
if (!columnReferencedInCheckExpression(col.defaultValue, tableSchema.name, columnName, tableSchema.schemaName, resolveColumnInSource))
|
|
80
|
-
continue;
|
|
81
|
-
throw new QuereusError(`Cannot drop column '${columnName}' from '${tableSchema.name}': it is referenced by the DEFAULT of column '${col.name}'`, StatusCode.CONSTRAINT);
|
|
82
|
-
}
|
|
84
|
+
export function assertNoColumnExpressionNamesColumn(db, tableSchema, columnName) {
|
|
85
|
+
refuseColumnExpressionDependent(db, tableSchema, columnName, 'columnExpression');
|
|
83
86
|
}
|
|
84
87
|
/**
|
|
85
|
-
* Refuses the drop when
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* Only the constraints on `tableSchema.checkConstraints` at drop time are probed —
|
|
88
|
+
* Refuses the drop when a CHECK constraint — on the altered table or on any other table
|
|
89
|
+
* in any schema — names the column.
|
|
90
|
+
*
|
|
91
|
+
* Same walk, same equivalence with the rename, as
|
|
92
|
+
* {@link assertNoColumnExpressionNamesColumn}. A CHECK may contain a subquery, so a
|
|
93
|
+
* depth-blind name match (what the partial-index guard next door can afford, its
|
|
94
|
+
* predicates admitting no subqueries) would both false-refuse
|
|
95
|
+
* `check ((select min(v) from u) >= 0)` when dropping this table's own `v` AND miss
|
|
96
|
+
* another table's `check (n < (select max(v) from t))` entirely.
|
|
97
|
+
*
|
|
98
|
+
* Only the constraints on each table's `checkConstraints` at drop time are probed —
|
|
97
99
|
* the user's declared set. Lens- and FK-synthesized entries are attached to a write
|
|
98
|
-
* plan's constraint list, not to the catalog
|
|
100
|
+
* plan's constraint list, not to the catalog entries this reads.
|
|
99
101
|
*
|
|
100
102
|
* A CHECK naming the column through the row-image qualifiers — `check (new.a > 0)`,
|
|
101
103
|
* `check on delete (old.a > 0)` — refuses the drop just like the unqualified spelling:
|
|
102
|
-
* the
|
|
104
|
+
* the seeded walk owns that namespace, shadowing edge included, so a CHECK whose subquery
|
|
103
105
|
* reads a real table named `"new"` still does not block dropping this table's own
|
|
104
106
|
* like-named column.
|
|
105
107
|
*/
|
|
106
108
|
export function assertNoCheckConstraintNamesColumn(db, tableSchema, columnName) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
109
|
+
refuseColumnExpressionDependent(db, tableSchema, columnName, 'check');
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The shared body of the two expression guards: probe, then refuse with a message that
|
|
113
|
+
* names the dropped column, the table it is being dropped from, the offending expression,
|
|
114
|
+
* and — when the expression lives somewhere else — the table carrying it. The own-table
|
|
115
|
+
* message is unchanged from before this guard learned to scan other tables.
|
|
116
|
+
*
|
|
117
|
+
* A {@link ExpressionDependent.breaksEntirely} match gets its own spelling: the
|
|
118
|
+
* expression references a view / MV the drop breaks OUTRIGHT (an explicit column list
|
|
119
|
+
* over a `*` covering the column), so telling the user one column is referenced would
|
|
120
|
+
* send them hunting for a name no body spells.
|
|
121
|
+
*/
|
|
122
|
+
function refuseColumnExpressionDependent(db, tableSchema, columnName, arm) {
|
|
123
|
+
const dependent = findColumnExpressionDependent(db, tableSchema, columnName, arm);
|
|
124
|
+
if (!dependent)
|
|
125
|
+
return;
|
|
126
|
+
if (dependent.breaksEntirely) {
|
|
127
|
+
throw new QuereusError(`Cannot drop column '${columnName}' from '${tableSchema.name}': `
|
|
128
|
+
+ `${referencedBy(dependent, tableSchema.schemaName)} references ${dependent.breaksEntirely}, `
|
|
129
|
+
+ `whose explicit column list would no longer match its body once '*' expands without the `
|
|
130
|
+
+ `column — dropping the column breaks it outright, not just one column`, StatusCode.CONSTRAINT);
|
|
118
131
|
}
|
|
132
|
+
throw new QuereusError(`Cannot drop column '${columnName}' from '${tableSchema.name}': ${refersTo(dependent, tableSchema.schemaName)}`, StatusCode.CONSTRAINT);
|
|
119
133
|
}
|
|
120
134
|
/**
|
|
121
|
-
*
|
|
135
|
+
* How the refusal describes the reference. A DIRECT one keeps the wording these guards
|
|
136
|
+
* have always used; an indirect one leads with the expression and names the chain, the
|
|
137
|
+
* same `… reaches it through view 'v'` split `assertNoAssertionDependsOn` uses. It is NOT
|
|
138
|
+
* the spelling {@link assertNoAssertionNamesColumn} uses next door
|
|
139
|
+
* (`it is referenced by assertion 'a' through view 'v'`) — that message was already in
|
|
140
|
+
* tests when the closure landed, and both read.
|
|
141
|
+
*/
|
|
142
|
+
function refersTo(dependent, homeSchemaName) {
|
|
143
|
+
const what = referencedBy(dependent, homeSchemaName);
|
|
144
|
+
return dependent.path.length === 0
|
|
145
|
+
? `it is referenced by ${what}`
|
|
146
|
+
: `${what} reaches it${describeReachPath(dependent.path)}`;
|
|
147
|
+
}
|
|
148
|
+
/** `CHECK constraint 'ck1'`, or `CHECK constraint 'ck1' on table 'x'` when it lives elsewhere. */
|
|
149
|
+
function referencedBy(dependent, homeSchemaName) {
|
|
150
|
+
if (dependent.ownTable)
|
|
151
|
+
return dependent.describe;
|
|
152
|
+
return `${dependent.describe} on table ${describeDependentTable(dependent.table, homeSchemaName)}`;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Refuses the drop when a live assertion's CHECK body, or any stored view /
|
|
156
|
+
* materialized-view body that assertion can reach, names the column.
|
|
122
157
|
*
|
|
123
158
|
* Blast radius is why this one is worth a guard at all: `AssertionEvaluator`
|
|
124
159
|
* recompiles **every** live assertion on any commit that touched any table, so a
|
|
@@ -130,25 +165,55 @@ export function assertNoCheckConstraintNamesColumn(db, tableSchema, columnName)
|
|
|
130
165
|
* (unlike a CHECK). A body that names the table but not the column — `select *`
|
|
131
166
|
* included — is not a reference and does not block the drop.
|
|
132
167
|
*
|
|
133
|
-
*
|
|
134
|
-
* `
|
|
135
|
-
*
|
|
136
|
-
*
|
|
168
|
+
* The same probe runs over EVERY body in the assertion's reach, its own included, so
|
|
169
|
+
* `create view v as select id, x from t` plus `create assertion a check (… from v
|
|
170
|
+
* where x < 0)` refuses `alter table t drop column x` — the match is on `v`'s body,
|
|
171
|
+
* not the assertion's.
|
|
172
|
+
*
|
|
173
|
+
* Each body is probed against every COLUMN REPUBLICATION target
|
|
174
|
+
* (`schema/column-republication.ts`), not the base table alone: a view that
|
|
175
|
+
* re-exposes the column by a star (`create view v as select * from t`, `select t.*`,
|
|
176
|
+
* or a materialized view of either) spells the name nowhere, and a reader's
|
|
177
|
+
* `where x < 0` references the column against `v`. Targets are swept OUTER — base
|
|
178
|
+
* table first, bodies inner — so every match the base sweep finds is found at the
|
|
179
|
+
* body it always was and the existing message spellings do not move. The
|
|
180
|
+
* broken-listed arm follows the sweep: an explicit column list over a covering `*`
|
|
181
|
+
* (`create view v(a, b) as select * from t`) breaks the whole view on the drop
|
|
182
|
+
* (the star's arity changes), so an assertion whose reach names such a view at all
|
|
183
|
+
* refuses, with a message saying the view breaks outright. The fixpoint's second
|
|
184
|
+
* catalog snapshot is taken at the same pre-mutation point as
|
|
185
|
+
* `assertionReachesHomeSchemaFirst`'s, so the two answer identically.
|
|
186
|
+
*
|
|
187
|
+
* Scope is EVERY schema, matching `assertNoAssertionDependsOn`: an assertion in
|
|
188
|
+
* `temp` naming `main.t`'s column blocks the drop, while one whose bare `t` resolves
|
|
189
|
+
* to `temp.t` does not. Each body resolves its unqualified names under its own home
|
|
190
|
+
* schema path. The scan itself is {@link assertionReachesHomeSchemaFirst}, shared
|
|
191
|
+
* with the table verb.
|
|
137
192
|
*/
|
|
138
193
|
export function assertNoAssertionNamesColumn(db, tableSchema, columnName) {
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
194
|
+
const resolveColumnInSource = buildColumnSourceResolver(db);
|
|
195
|
+
const tableKey = objectRefKey(tableSchema.schemaName, tableSchema.name);
|
|
196
|
+
const republication = collectColumnRepublication(db, { targetKey: tableKey, tableName: tableSchema.name }, columnName, snapshotObjectRefResolvers(db), resolveColumnInSource);
|
|
197
|
+
for (const { owned, reach } of assertionReachesHomeSchemaFirst(db, tableSchema.schemaName)) {
|
|
198
|
+
for (const target of republication.targets) {
|
|
199
|
+
for (const reached of reach.bodies) {
|
|
200
|
+
// Row-image mode 'none': an assertion body and every view / MV body in
|
|
201
|
+
// its reach are relations with no written row.
|
|
202
|
+
if (!columnReferencedInAst(reached.body, target.tableName, columnName, reached.resolve, target.targetKey, 'none', resolveColumnInSource))
|
|
203
|
+
continue;
|
|
204
|
+
throw new QuereusError(`Cannot drop column '${columnName}' from '${tableSchema.name}': it is referenced by `
|
|
205
|
+
+ `assertion ${describeOwnedAssertion(owned, tableSchema.schemaName)}`
|
|
206
|
+
+ `${describeReachPath(reached.path)} — drop or redefine the assertion first`, StatusCode.CONSTRAINT);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
for (const broken of republication.brokenListed) {
|
|
210
|
+
if (!reach.namerOf(broken.key))
|
|
211
|
+
continue;
|
|
212
|
+
throw new QuereusError(`Cannot drop column '${columnName}' from '${tableSchema.name}': assertion `
|
|
213
|
+
+ `${describeOwnedAssertion(owned, tableSchema.schemaName)} references ${broken.describe}, `
|
|
214
|
+
+ `whose explicit column list would no longer match its body once '*' expands without the `
|
|
215
|
+
+ `column — dropping the column breaks it outright — drop or redefine the assertion first`, StatusCode.CONSTRAINT);
|
|
216
|
+
}
|
|
152
217
|
}
|
|
153
218
|
}
|
|
154
219
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drop-column-guards.js","sourceRoot":"","sources":["../../../../src/runtime/emit/drop-column-guards.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"drop-column-guards.js","sourceRoot":"","sources":["../../../../src/runtime/emit/drop-column-guards.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drop-table.d.ts","sourceRoot":"","sources":["../../../../src/runtime/emit/drop-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAC;AAI/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"drop-table.d.ts","sourceRoot":"","sources":["../../../../src/runtime/emit/drop-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAC;AAI/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAO9D,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,eAAe,GAAG,WAAW,CAqDpF"}
|
|
@@ -5,6 +5,7 @@ import { dropMaintainedTable } from './materialized-view.js';
|
|
|
5
5
|
import { requireVtabModule } from '../../schema/table.js';
|
|
6
6
|
import { assertDdlTransactionPolicy } from './ddl-transaction-policy.js';
|
|
7
7
|
import { assertNoAssertionDependsOn } from './assertion-drop-guard.js';
|
|
8
|
+
import { assertNoExpressionDependsOn } from './expression-drop-guard.js';
|
|
8
9
|
export function emitDropTable(plan, ctx) {
|
|
9
10
|
const schemaManager = ctx.db.schemaManager;
|
|
10
11
|
const stmt = plan.statementAst; // AST.DropStmt
|
|
@@ -27,6 +28,10 @@ export function emitDropTable(plan, ctx) {
|
|
|
27
28
|
// `IF EXISTS` drop of an absent name is a no-op with nothing to protect
|
|
28
29
|
// (and any assertion naming that name is already broken).
|
|
29
30
|
assertNoAssertionDependsOn(rctx.db, targetSchemaName, objectName, 'table');
|
|
31
|
+
// Another table's CHECK / DEFAULT / generated body may name this one through a
|
|
32
|
+
// subquery; dropping out from under it leaves that table unwritable. Same gate
|
|
33
|
+
// (table exists) and same layer (emitter, not `SchemaManager.dropTable`) as above.
|
|
34
|
+
assertNoExpressionDependsOn(rctx.db, targetSchemaName, objectName, 'table');
|
|
30
35
|
}
|
|
31
36
|
// Ensure we're in a transaction before DDL (lazy/JIT transaction start)
|
|
32
37
|
await rctx.db._ensureTransaction();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drop-table.js","sourceRoot":"","sources":["../../../../src/runtime/emit/drop-table.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAiB,MAAM,uBAAuB,CAAC;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"drop-table.js","sourceRoot":"","sources":["../../../../src/runtime/emit/drop-table.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAiB,MAAM,uBAAuB,CAAC;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAEzE,MAAM,UAAU,aAAa,CAAC,IAAmB,EAAE,GAAoB;IACtE,MAAM,aAAa,GAAG,GAAG,CAAC,EAAE,CAAC,aAAa,CAAC;IAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,eAAe;IAE/C,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,aAAa,CAAC,oBAAoB,EAAE,CAAC;IAClF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAElC,IAAI,IAAI,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC;QACjC,+CAA+C;QAC/C,qGAAqG;QACrG,MAAM,IAAI,YAAY,CAAC,yBAAyB,IAAI,CAAC,UAAU,sCAAsC,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAChI,CAAC;IAED,KAAK,UAAU,GAAG,CAAC,IAAoB;QACtC,yEAAyE;QACzE,yEAAyE;QACzE,wDAAwD;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;QAC5E,IAAI,MAAM,EAAE,CAAC;YACZ,0BAA0B,CACzB,IAAI,CAAC,EAAE,EAAE,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,EACzD,cAAc,UAAU,EAAE,CAC1B,CAAC;YACF,+DAA+D;YAC/D,oEAAoE;YACpE,wEAAwE;YACxE,0DAA0D;YAC1D,0BAA0B,CAAC,IAAI,CAAC,EAAE,EAAE,gBAAgB,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;YAC3E,+EAA+E;YAC/E,+EAA+E;YAC/E,mFAAmF;YACnF,2BAA2B,CAAC,IAAI,CAAC,EAAE,EAAE,gBAAgB,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QAC7E,CAAC;QAED,wEAAwE;QACxE,MAAM,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC;QAEnC,yEAAyE;QACzE,yEAAyE;QACzE,wEAAwE;QACxE,wCAAwC;QACxC,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,kBAAkB,CAAC,gBAAgB,EAAE,UAAU,CAAC,CAAC;QAC1F,IAAI,UAAU,EAAE,CAAC;YAChB,MAAM,mBAAmB,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;YAC/C,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,gBAAgB,EAAE,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEnF,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,aAAa,gBAAgB,IAAI,UAAU,GAAG,EAAE,CAAC;AAC9F,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drop-view.d.ts","sourceRoot":"","sources":["../../../../src/runtime/emit/drop-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"drop-view.d.ts","sourceRoot":"","sources":["../../../../src/runtime/emit/drop-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAC;AAC1E,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAM9D,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,eAAe,GAAG,WAAW,CA2EnF"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { QuereusError } from '../../common/errors.js';
|
|
2
2
|
import { StatusCode } from '../../common/types.js';
|
|
3
3
|
import { assertNoAssertionDependsOn } from './assertion-drop-guard.js';
|
|
4
|
+
import { assertNoExpressionDependsOn } from './expression-drop-guard.js';
|
|
4
5
|
export function emitDropView(plan, _ctx) {
|
|
5
6
|
async function run(rctx) {
|
|
6
7
|
// Ensure we're in a transaction before DDL (lazy/JIT transaction start)
|
|
@@ -21,6 +22,10 @@ export function emitDropView(plan, _ctx) {
|
|
|
21
22
|
// An assertion body may name a view exactly as it names a base table, and
|
|
22
23
|
// dropping it out from under one breaks every write to the database.
|
|
23
24
|
assertNoAssertionDependsOn(rctx.db, plan.schemaName, plan.viewName, 'view');
|
|
25
|
+
// A CHECK / DEFAULT / generated body may read a VIEW through a subquery exactly as
|
|
26
|
+
// it reads a base table, so the referencing table breaks the same way. (The
|
|
27
|
+
// asymmetry is on the other side: a table dropped under a plain view stays legal.)
|
|
28
|
+
assertNoExpressionDependsOn(rctx.db, plan.schemaName, plan.viewName, 'view');
|
|
24
29
|
// Remove the view from the schema manager
|
|
25
30
|
const schema = rctx.db.schemaManager.getSchema(plan.schemaName);
|
|
26
31
|
if (!schema) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drop-view.js","sourceRoot":"","sources":["../../../../src/runtime/emit/drop-view.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAiB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"drop-view.js","sourceRoot":"","sources":["../../../../src/runtime/emit/drop-view.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAiB,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAEzE,MAAM,UAAU,YAAY,CAAC,IAAkB,EAAE,IAAqB;IACrE,KAAK,UAAU,GAAG,CAAC,IAAoB;QACtC,wEAAwE;QACxE,MAAM,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC;QAEnC,mEAAmE;QACnE,IAAI,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9E,MAAM,IAAI,YAAY,CACrB,IAAI,IAAI,CAAC,QAAQ,uDAAuD,EACxE,UAAU,CAAC,KAAK,CAChB,CAAC;QACH,CAAC;QAED,uBAAuB;QACvB,MAAM,YAAY,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEnF,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,MAAM,IAAI,YAAY,CACrB,SAAS,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,QAAQ,kBAAkB,EAC3D,UAAU,CAAC,KAAK,CAChB,CAAC;QACH,CAAC;QAED,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,qEAAqE;YACrE,OAAO,IAAI,CAAC;QACb,CAAC;QAED,0EAA0E;QAC1E,qEAAqE;QACrE,0BAA0B,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC5E,mFAAmF;QACnF,4EAA4E;QAC5E,mFAAmF;QACnF,2BAA2B,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAE7E,0CAA0C;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChE,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,YAAY,CACrB,WAAW,IAAI,CAAC,UAAU,kBAAkB,EAC5C,UAAU,CAAC,KAAK,CAChB,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjD,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,MAAM,IAAI,YAAY,CACrB,SAAS,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,QAAQ,kBAAkB,EAC3D,UAAU,CAAC,KAAK,CAChB,CAAC;QACH,CAAC;QAED,0EAA0E;QAC1E,2EAA2E;QAC3E,wDAAwD;QACxD,IAAI,OAAO,IAAI,YAAY,EAAE,CAAC;YAC7B,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC,YAAY,CAAC;gBACtD,IAAI,EAAE,cAAc;gBACpB,yCAAyC;gBACzC,2EAA2E;gBAC3E,UAAU,EAAE,YAAY,CAAC,UAAU;gBACnC,UAAU,EAAE,YAAY,CAAC,IAAI;gBAC7B,SAAS,EAAE,YAAY;aACvB,CAAC,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC,CAAC,wDAAwD;IACtE,CAAC;IAED,OAAO;QACN,MAAM,EAAE,EAAE;QACV,GAAG;QACH,IAAI,EAAE,YAAY,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,QAAQ,GAAG;KACrD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { Database } from '../../core/database.js';
|
|
2
|
+
import type { DroppableObjectKind } from './assertion-drop-guard.js';
|
|
3
|
+
/**
|
|
4
|
+
* Refuses to drop a table / view / materialized view that another table's stored
|
|
5
|
+
* expression — a CHECK constraint, a column DEFAULT, or a `GENERATED ALWAYS AS` body —
|
|
6
|
+
* can still REACH through a subquery: directly, or through any chain of view /
|
|
7
|
+
* materialized-view bodies.
|
|
8
|
+
*
|
|
9
|
+
* The damage this prevents is the same one `assertNoCheckConstraintNamesColumn` prevents
|
|
10
|
+
* for the column verb, and both verbs resolve at the same missing catalog capability:
|
|
11
|
+
*
|
|
12
|
+
* ```sql
|
|
13
|
+
* create table t (id integer primary key, v integer);
|
|
14
|
+
* create table x (id integer primary key, n integer, check (n < (select max(v) from t)));
|
|
15
|
+
* drop table t; -- used to be accepted
|
|
16
|
+
* insert into x values (1, 1); -- Table 't' not found in schema path: main
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* `x` is now unwritable, and the error names neither the dropped table nor the constraint
|
|
20
|
+
* that broke. Refusing keeps the failure attached to the statement that caused it, which
|
|
21
|
+
* is what the whole expression-dependent family already does — and it keeps
|
|
22
|
+
* `drop table t` and `alter table t drop column v` from disagreeing about the same CHECK.
|
|
23
|
+
*
|
|
24
|
+
* Policy is **refuse**, not cascade, on the same reasoning as
|
|
25
|
+
* {@link assertNoAssertionDependsOn}: a cascade would silently delete a user's integrity
|
|
26
|
+
* rule. This is stricter than plain VIEWs, which are deliberately left to break (a broken
|
|
27
|
+
* view breaks queries OF that view; a broken CHECK makes a whole table unwritable). Views
|
|
28
|
+
* are guarded on the DROPPED side rather than the referencing side for that reason: a
|
|
29
|
+
* CHECK subquery may read a view, and dropping that view breaks the referencing table
|
|
30
|
+
* just as thoroughly as dropping a table would, so `DROP VIEW` and
|
|
31
|
+
* `DROP MATERIALIZED VIEW` call this too.
|
|
32
|
+
*
|
|
33
|
+
* Refusal never traps anyone: dropping (or rebuilding) the referencing constraint lets the
|
|
34
|
+
* drop through. Accepted cost, exactly as for the column verb: an **unnamed** table-level
|
|
35
|
+
* CHECK has no name for `DROP CONSTRAINT` to resolve, so a table it names can only be
|
|
36
|
+
* dropped by rebuilding the referencing table. The message quotes such a constraint's
|
|
37
|
+
* expression so the user can at least see what is in the way.
|
|
38
|
+
*
|
|
39
|
+
* Called from the user-facing DDL emitters only (`emitDropTable`, `emitDropView`,
|
|
40
|
+
* `emitDropMaterializedView`) — never from `SchemaManager.dropTable`, which also drives
|
|
41
|
+
* rollback, catalog import and the declarative differ's drop/recreate. Same wiring, and
|
|
42
|
+
* same reason, as {@link assertNoAssertionDependsOn}: a differ convergence that replaces
|
|
43
|
+
* both `t` and `x` must not be vetoed.
|
|
44
|
+
*
|
|
45
|
+
* Not gated on `IF EXISTS`: that clause governs ABSENCE, not dependency. Callers already
|
|
46
|
+
* skip the guard when the object does not exist, since there is then nothing to protect.
|
|
47
|
+
*
|
|
48
|
+
* "Can reach" is decided by {@link findTableExpressionDependent}, which runs the same
|
|
49
|
+
* breadth-first closure over stored bodies ({@link reachableObjects}) that
|
|
50
|
+
* {@link assertNoAssertionDependsOn} does — so a CHECK reading `vv` where
|
|
51
|
+
* `create view vv as select v from t` refuses `drop table t`, and the two guard families
|
|
52
|
+
* cannot disagree about what "reaches" means. The refusal names the chain, because a user
|
|
53
|
+
* told to fix a constraint whose body does not mention the dropped object has nothing to
|
|
54
|
+
* act on otherwise.
|
|
55
|
+
*/
|
|
56
|
+
export declare function assertNoExpressionDependsOn(db: Database, schemaName: string, objectName: string, objectKind: DroppableObjectKind): void;
|
|
57
|
+
//# sourceMappingURL=expression-drop-guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expression-drop-guard.d.ts","sourceRoot":"","sources":["../../../../src/runtime/emit/expression-drop-guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAKvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,wBAAgB,2BAA2B,CAC1C,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,mBAAmB,GAC7B,IAAI,CAYN"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { QuereusError } from '../../common/errors.js';
|
|
2
|
+
import { StatusCode } from '../../common/types.js';
|
|
3
|
+
import { findTableExpressionDependent, describeDependentTable } from '../../schema/expression-dependents.js';
|
|
4
|
+
import { describeReachPath } from '../../schema/object-dependency-closure.js';
|
|
5
|
+
/**
|
|
6
|
+
* Refuses to drop a table / view / materialized view that another table's stored
|
|
7
|
+
* expression — a CHECK constraint, a column DEFAULT, or a `GENERATED ALWAYS AS` body —
|
|
8
|
+
* can still REACH through a subquery: directly, or through any chain of view /
|
|
9
|
+
* materialized-view bodies.
|
|
10
|
+
*
|
|
11
|
+
* The damage this prevents is the same one `assertNoCheckConstraintNamesColumn` prevents
|
|
12
|
+
* for the column verb, and both verbs resolve at the same missing catalog capability:
|
|
13
|
+
*
|
|
14
|
+
* ```sql
|
|
15
|
+
* create table t (id integer primary key, v integer);
|
|
16
|
+
* create table x (id integer primary key, n integer, check (n < (select max(v) from t)));
|
|
17
|
+
* drop table t; -- used to be accepted
|
|
18
|
+
* insert into x values (1, 1); -- Table 't' not found in schema path: main
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* `x` is now unwritable, and the error names neither the dropped table nor the constraint
|
|
22
|
+
* that broke. Refusing keeps the failure attached to the statement that caused it, which
|
|
23
|
+
* is what the whole expression-dependent family already does — and it keeps
|
|
24
|
+
* `drop table t` and `alter table t drop column v` from disagreeing about the same CHECK.
|
|
25
|
+
*
|
|
26
|
+
* Policy is **refuse**, not cascade, on the same reasoning as
|
|
27
|
+
* {@link assertNoAssertionDependsOn}: a cascade would silently delete a user's integrity
|
|
28
|
+
* rule. This is stricter than plain VIEWs, which are deliberately left to break (a broken
|
|
29
|
+
* view breaks queries OF that view; a broken CHECK makes a whole table unwritable). Views
|
|
30
|
+
* are guarded on the DROPPED side rather than the referencing side for that reason: a
|
|
31
|
+
* CHECK subquery may read a view, and dropping that view breaks the referencing table
|
|
32
|
+
* just as thoroughly as dropping a table would, so `DROP VIEW` and
|
|
33
|
+
* `DROP MATERIALIZED VIEW` call this too.
|
|
34
|
+
*
|
|
35
|
+
* Refusal never traps anyone: dropping (or rebuilding) the referencing constraint lets the
|
|
36
|
+
* drop through. Accepted cost, exactly as for the column verb: an **unnamed** table-level
|
|
37
|
+
* CHECK has no name for `DROP CONSTRAINT` to resolve, so a table it names can only be
|
|
38
|
+
* dropped by rebuilding the referencing table. The message quotes such a constraint's
|
|
39
|
+
* expression so the user can at least see what is in the way.
|
|
40
|
+
*
|
|
41
|
+
* Called from the user-facing DDL emitters only (`emitDropTable`, `emitDropView`,
|
|
42
|
+
* `emitDropMaterializedView`) — never from `SchemaManager.dropTable`, which also drives
|
|
43
|
+
* rollback, catalog import and the declarative differ's drop/recreate. Same wiring, and
|
|
44
|
+
* same reason, as {@link assertNoAssertionDependsOn}: a differ convergence that replaces
|
|
45
|
+
* both `t` and `x` must not be vetoed.
|
|
46
|
+
*
|
|
47
|
+
* Not gated on `IF EXISTS`: that clause governs ABSENCE, not dependency. Callers already
|
|
48
|
+
* skip the guard when the object does not exist, since there is then nothing to protect.
|
|
49
|
+
*
|
|
50
|
+
* "Can reach" is decided by {@link findTableExpressionDependent}, which runs the same
|
|
51
|
+
* breadth-first closure over stored bodies ({@link reachableObjects}) that
|
|
52
|
+
* {@link assertNoAssertionDependsOn} does — so a CHECK reading `vv` where
|
|
53
|
+
* `create view vv as select v from t` refuses `drop table t`, and the two guard families
|
|
54
|
+
* cannot disagree about what "reaches" means. The refusal names the chain, because a user
|
|
55
|
+
* told to fix a constraint whose body does not mention the dropped object has nothing to
|
|
56
|
+
* act on otherwise.
|
|
57
|
+
*/
|
|
58
|
+
export function assertNoExpressionDependsOn(db, schemaName, objectName, objectKind) {
|
|
59
|
+
const dependent = findTableExpressionDependent(db, schemaName, objectName);
|
|
60
|
+
if (!dependent)
|
|
61
|
+
return;
|
|
62
|
+
// The catalog's spelling of the schema rather than the caller's: DROP emitters pass the
|
|
63
|
+
// name as the user typed it, so `drop table MAIN.t` would otherwise report a schema
|
|
64
|
+
// spelling that appears nowhere in the catalog. Same rule as `assertNoAssertionDependsOn`.
|
|
65
|
+
const home = db.schemaManager.getSchema(schemaName)?.name ?? schemaName;
|
|
66
|
+
const on = `on table ${describeDependentTable(dependent.table, home)}`;
|
|
67
|
+
throw new QuereusError(`cannot drop ${objectKind} '${home}.${objectName}': ${refersTo(dependent, on)} — drop or redefine it first`, StatusCode.CONSTRAINT);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* How the refusal describes the reference. A DIRECT one keeps the wording this guard has
|
|
71
|
+
* always used; an indirect one leads with the expression and names the chain, the same
|
|
72
|
+
* `… reaches it through view 'v'` split `assertNoAssertionDependsOn` uses for the same
|
|
73
|
+
* verb. (The DROP COLUMN assertion guard spells its indirect clause differently —
|
|
74
|
+
* `it is referenced by assertion 'a' through view 'v'` — because that message was already
|
|
75
|
+
* in tests when the closure landed; both read, and neither is worth churning.)
|
|
76
|
+
*/
|
|
77
|
+
function refersTo(dependent, on) {
|
|
78
|
+
return dependent.path.length === 0
|
|
79
|
+
? `it is referenced by ${dependent.describe} ${on}`
|
|
80
|
+
: `${dependent.describe} ${on} reaches it${describeReachPath(dependent.path)}`;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=expression-drop-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expression-drop-guard.js","sourceRoot":"","sources":["../../../../src/runtime/emit/expression-drop-guard.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,4BAA4B,EAAE,sBAAsB,EAA4B,MAAM,uCAAuC,CAAC;AACvI,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAG9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,MAAM,UAAU,2BAA2B,CAC1C,EAAY,EACZ,UAAkB,EAClB,UAAkB,EAClB,UAA+B;IAE/B,MAAM,SAAS,GAAG,4BAA4B,CAAC,EAAE,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IAC3E,IAAI,CAAC,SAAS;QAAE,OAAO;IACvB,wFAAwF;IACxF,oFAAoF;IACpF,2FAA2F;IAC3F,MAAM,IAAI,GAAG,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,IAAI,IAAI,UAAU,CAAC;IACxE,MAAM,EAAE,GAAG,YAAY,sBAAsB,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;IACvE,MAAM,IAAI,YAAY,CACrB,eAAe,UAAU,KAAK,IAAI,IAAI,UAAU,MAAM,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,8BAA8B,EAC3G,UAAU,CAAC,UAAU,CACrB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,QAAQ,CAAC,SAA8B,EAAE,EAAU;IAC3D,OAAO,SAAS,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QACjC,CAAC,CAAC,uBAAuB,SAAS,CAAC,QAAQ,IAAI,EAAE,EAAE;QACnD,CAAC,CAAC,GAAG,SAAS,CAAC,QAAQ,IAAI,EAAE,cAAc,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;AACjF,CAAC"}
|
|
@@ -17,7 +17,7 @@ import type { EmissionContext } from '../emission-context.js';
|
|
|
17
17
|
* predicate used before, so blob / string / numeric truthiness is unchanged.
|
|
18
18
|
*
|
|
19
19
|
* Nested `AND`s that are not at the top level of the predicate (under a `NOT`, inside
|
|
20
|
-
* a `CASE`, below an `OR`) are untouched and still route through `
|
|
20
|
+
* a `CASE`, below an `OR`) are untouched and still route through `buildLogicalOpSpec`.
|
|
21
21
|
*/
|
|
22
22
|
export declare function emitFilter(plan: FilterNode, ctx: EmissionContext): Instruction;
|
|
23
23
|
//# sourceMappingURL=filter.d.ts.map
|
|
@@ -41,7 +41,7 @@ function evaluatePredicate(rctx, predicate) {
|
|
|
41
41
|
* predicate used before, so blob / string / numeric truthiness is unchanged.
|
|
42
42
|
*
|
|
43
43
|
* Nested `AND`s that are not at the top level of the predicate (under a `NOT`, inside
|
|
44
|
-
* a `CASE`, below an `OR`) are untouched and still route through `
|
|
44
|
+
* a `CASE`, below an `OR`) are untouched and still route through `buildLogicalOpSpec`.
|
|
45
45
|
*/
|
|
46
46
|
export function emitFilter(plan, ctx) {
|
|
47
47
|
const sourceInstruction = emitPlanNode(plan.source, ctx);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash-aggregate.d.ts","sourceRoot":"","sources":["../../../../src/runtime/emit/hash-aggregate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAC;AAI/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"hash-aggregate.d.ts","sourceRoot":"","sources":["../../../../src/runtime/emit/hash-aggregate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,aAAa,CAAC;AAI/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAsB9D,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,EAAE,eAAe,GAAG,WAAW,CA4O5F"}
|