@quereus/quereus 3.3.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/src/common/datatype.d.ts +12 -0
- package/dist/src/common/datatype.d.ts.map +1 -1
- package/dist/src/common/datatype.js.map +1 -1
- package/dist/src/common/types.d.ts +24 -0
- package/dist/src/common/types.d.ts.map +1 -1
- package/dist/src/common/types.js.map +1 -1
- package/dist/src/core/database-assertions.d.ts +37 -9
- package/dist/src/core/database-assertions.d.ts.map +1 -1
- package/dist/src/core/database-assertions.js +62 -110
- package/dist/src/core/database-assertions.js.map +1 -1
- package/dist/src/core/database-events.d.ts +163 -0
- package/dist/src/core/database-events.d.ts.map +1 -1
- package/dist/src/core/database-events.js +235 -21
- package/dist/src/core/database-events.js.map +1 -1
- package/dist/src/core/database-external-changes.d.ts +28 -0
- package/dist/src/core/database-external-changes.d.ts.map +1 -0
- package/dist/src/core/database-external-changes.js +242 -0
- package/dist/src/core/database-external-changes.js.map +1 -0
- package/dist/src/core/database-internal.d.ts +50 -1
- package/dist/src/core/database-internal.d.ts.map +1 -1
- package/dist/src/core/database-materialized-views.d.ts +1253 -0
- package/dist/src/core/database-materialized-views.d.ts.map +1 -0
- package/dist/src/core/database-materialized-views.js +3064 -0
- package/dist/src/core/database-materialized-views.js.map +1 -0
- package/dist/src/core/database-options.d.ts +4 -0
- package/dist/src/core/database-options.d.ts.map +1 -1
- package/dist/src/core/database-options.js +10 -0
- package/dist/src/core/database-options.js.map +1 -1
- package/dist/src/core/database-transaction.d.ts +19 -3
- package/dist/src/core/database-transaction.d.ts.map +1 -1
- package/dist/src/core/database-transaction.js +30 -3
- package/dist/src/core/database-transaction.js.map +1 -1
- package/dist/src/core/database-watchers.d.ts +19 -0
- package/dist/src/core/database-watchers.d.ts.map +1 -1
- package/dist/src/core/database-watchers.js +63 -3
- package/dist/src/core/database-watchers.js.map +1 -1
- package/dist/src/core/database.d.ts +203 -11
- package/dist/src/core/database.d.ts.map +1 -1
- package/dist/src/core/database.js +493 -29
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/core/derived-row-validator.d.ts +137 -0
- package/dist/src/core/derived-row-validator.d.ts.map +1 -0
- package/dist/src/core/derived-row-validator.js +314 -0
- package/dist/src/core/derived-row-validator.js.map +1 -0
- package/dist/src/core/statement.d.ts.map +1 -1
- package/dist/src/core/statement.js +30 -9
- package/dist/src/core/statement.js.map +1 -1
- package/dist/src/emit/ast-stringify.d.ts +135 -1
- package/dist/src/emit/ast-stringify.d.ts.map +1 -1
- package/dist/src/emit/ast-stringify.js +793 -118
- package/dist/src/emit/ast-stringify.js.map +1 -1
- package/dist/src/func/builtins/aggregate.d.ts.map +1 -1
- package/dist/src/func/builtins/aggregate.js +11 -10
- package/dist/src/func/builtins/aggregate.js.map +1 -1
- package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
- package/dist/src/func/builtins/builtin-window-functions.js +32 -0
- package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
- package/dist/src/func/builtins/explain.d.ts +3 -0
- package/dist/src/func/builtins/explain.d.ts.map +1 -1
- package/dist/src/func/builtins/explain.js +229 -0
- 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 +10 -2
- package/dist/src/func/builtins/index.js.map +1 -1
- package/dist/src/func/builtins/json.d.ts.map +1 -1
- package/dist/src/func/builtins/json.js +3 -2
- package/dist/src/func/builtins/json.js.map +1 -1
- package/dist/src/func/builtins/mutation.d.ts +2 -0
- package/dist/src/func/builtins/mutation.d.ts.map +1 -0
- package/dist/src/func/builtins/mutation.js +53 -0
- package/dist/src/func/builtins/mutation.js.map +1 -0
- package/dist/src/func/builtins/schema.d.ts +2 -0
- package/dist/src/func/builtins/schema.d.ts.map +1 -1
- package/dist/src/func/builtins/schema.js +713 -26
- package/dist/src/func/builtins/schema.js.map +1 -1
- package/dist/src/func/builtins/string.js +1 -1
- package/dist/src/func/builtins/string.js.map +1 -1
- package/dist/src/func/registration.d.ts +9 -0
- package/dist/src/func/registration.d.ts.map +1 -1
- package/dist/src/func/registration.js +4 -0
- package/dist/src/func/registration.js.map +1 -1
- package/dist/src/index.d.ts +25 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +27 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/parser/ast.d.ts +353 -21
- package/dist/src/parser/ast.d.ts.map +1 -1
- package/dist/src/parser/index.d.ts +14 -1
- package/dist/src/parser/index.d.ts.map +1 -1
- package/dist/src/parser/index.js +19 -0
- package/dist/src/parser/index.js.map +1 -1
- package/dist/src/parser/lexer.d.ts +9 -0
- package/dist/src/parser/lexer.d.ts.map +1 -1
- package/dist/src/parser/lexer.js +9 -0
- package/dist/src/parser/lexer.js.map +1 -1
- package/dist/src/parser/parser.d.ts +276 -7
- package/dist/src/parser/parser.d.ts.map +1 -1
- package/dist/src/parser/parser.js +1387 -469
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/src/parser/visitor.d.ts.map +1 -1
- package/dist/src/parser/visitor.js +12 -8
- package/dist/src/parser/visitor.js.map +1 -1
- package/dist/src/planner/analysis/assertion-classifier.d.ts.map +1 -1
- package/dist/src/planner/analysis/assertion-classifier.js +4 -0
- package/dist/src/planner/analysis/assertion-classifier.js.map +1 -1
- package/dist/src/planner/analysis/assertion-hoist-cache.d.ts.map +1 -1
- package/dist/src/planner/analysis/assertion-hoist-cache.js +8 -4
- package/dist/src/planner/analysis/assertion-hoist-cache.js.map +1 -1
- package/dist/src/planner/analysis/authored-inverse.d.ts +22 -0
- package/dist/src/planner/analysis/authored-inverse.d.ts.map +1 -0
- package/dist/src/planner/analysis/authored-inverse.js +267 -0
- package/dist/src/planner/analysis/authored-inverse.js.map +1 -0
- package/dist/src/planner/analysis/change-scope.d.ts +34 -4
- package/dist/src/planner/analysis/change-scope.d.ts.map +1 -1
- package/dist/src/planner/analysis/change-scope.js +108 -7
- package/dist/src/planner/analysis/change-scope.js.map +1 -1
- package/dist/src/planner/analysis/check-extraction.d.ts +36 -2
- package/dist/src/planner/analysis/check-extraction.d.ts.map +1 -1
- package/dist/src/planner/analysis/check-extraction.js +174 -46
- package/dist/src/planner/analysis/check-extraction.js.map +1 -1
- package/dist/src/planner/analysis/coarsened-key.d.ts +109 -0
- package/dist/src/planner/analysis/coarsened-key.d.ts.map +1 -0
- package/dist/src/planner/analysis/coarsened-key.js +228 -0
- package/dist/src/planner/analysis/coarsened-key.js.map +1 -0
- package/dist/src/planner/analysis/comparison-collation.d.ts +216 -0
- package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -0
- package/dist/src/planner/analysis/comparison-collation.js +341 -0
- package/dist/src/planner/analysis/comparison-collation.js.map +1 -0
- package/dist/src/planner/analysis/constraint-extractor.d.ts +3 -1
- package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.js +192 -9
- package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
- package/dist/src/planner/analysis/coverage-prover.d.ts +321 -0
- package/dist/src/planner/analysis/coverage-prover.d.ts.map +1 -0
- package/dist/src/planner/analysis/coverage-prover.js +1038 -0
- package/dist/src/planner/analysis/coverage-prover.js.map +1 -0
- package/dist/src/planner/analysis/key-filter.d.ts +22 -0
- package/dist/src/planner/analysis/key-filter.d.ts.map +1 -0
- package/dist/src/planner/analysis/key-filter.js +105 -0
- package/dist/src/planner/analysis/key-filter.js.map +1 -0
- package/dist/src/planner/analysis/partial-unique-extraction.d.ts +36 -1
- package/dist/src/planner/analysis/partial-unique-extraction.d.ts.map +1 -1
- package/dist/src/planner/analysis/partial-unique-extraction.js +148 -22
- package/dist/src/planner/analysis/partial-unique-extraction.js.map +1 -1
- package/dist/src/planner/analysis/predicate-normalizer.d.ts.map +1 -1
- package/dist/src/planner/analysis/predicate-normalizer.js +30 -1
- package/dist/src/planner/analysis/predicate-normalizer.js.map +1 -1
- package/dist/src/planner/analysis/predicate-shape.d.ts +36 -1
- package/dist/src/planner/analysis/predicate-shape.d.ts.map +1 -1
- package/dist/src/planner/analysis/predicate-shape.js +51 -13
- package/dist/src/planner/analysis/predicate-shape.js.map +1 -1
- package/dist/src/planner/analysis/query-rewrite-matcher.d.ts +314 -0
- package/dist/src/planner/analysis/query-rewrite-matcher.d.ts.map +1 -0
- package/dist/src/planner/analysis/query-rewrite-matcher.js +1081 -0
- package/dist/src/planner/analysis/query-rewrite-matcher.js.map +1 -0
- package/dist/src/planner/analysis/scalar-invertibility.d.ts +92 -0
- package/dist/src/planner/analysis/scalar-invertibility.d.ts.map +1 -0
- package/dist/src/planner/analysis/scalar-invertibility.js +129 -0
- package/dist/src/planner/analysis/scalar-invertibility.js.map +1 -0
- package/dist/src/planner/analysis/update-lineage.d.ts +196 -0
- package/dist/src/planner/analysis/update-lineage.d.ts.map +1 -0
- package/dist/src/planner/analysis/update-lineage.js +322 -0
- package/dist/src/planner/analysis/update-lineage.js.map +1 -0
- package/dist/src/planner/analysis/view-complement.d.ts +42 -0
- package/dist/src/planner/analysis/view-complement.d.ts.map +1 -0
- package/dist/src/planner/analysis/view-complement.js +54 -0
- package/dist/src/planner/analysis/view-complement.js.map +1 -0
- package/dist/src/planner/building/alter-table.d.ts +1 -1
- package/dist/src/planner/building/alter-table.d.ts.map +1 -1
- package/dist/src/planner/building/alter-table.js +211 -2
- package/dist/src/planner/building/alter-table.js.map +1 -1
- package/dist/src/planner/building/block.d.ts.map +1 -1
- package/dist/src/planner/building/block.js +18 -1
- package/dist/src/planner/building/block.js.map +1 -1
- package/dist/src/planner/building/constraint-builder.d.ts +33 -5
- package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
- package/dist/src/planner/building/constraint-builder.js +63 -28
- package/dist/src/planner/building/constraint-builder.js.map +1 -1
- package/dist/src/planner/building/create-view.d.ts +9 -0
- package/dist/src/planner/building/create-view.d.ts.map +1 -1
- package/dist/src/planner/building/create-view.js +41 -12
- package/dist/src/planner/building/create-view.js.map +1 -1
- package/dist/src/planner/building/ddl.d.ts.map +1 -1
- package/dist/src/planner/building/ddl.js +94 -0
- package/dist/src/planner/building/ddl.js.map +1 -1
- package/dist/src/planner/building/declare-schema.d.ts +1 -0
- package/dist/src/planner/building/declare-schema.d.ts.map +1 -1
- package/dist/src/planner/building/declare-schema.js +4 -1
- package/dist/src/planner/building/declare-schema.js.map +1 -1
- package/dist/src/planner/building/default-scope.d.ts +26 -0
- package/dist/src/planner/building/default-scope.d.ts.map +1 -0
- package/dist/src/planner/building/default-scope.js +41 -0
- package/dist/src/planner/building/default-scope.js.map +1 -0
- package/dist/src/planner/building/delete.d.ts +19 -1
- package/dist/src/planner/building/delete.d.ts.map +1 -1
- package/dist/src/planner/building/delete.js +109 -30
- package/dist/src/planner/building/delete.js.map +1 -1
- package/dist/src/planner/building/dml-target.d.ts +118 -0
- package/dist/src/planner/building/dml-target.d.ts.map +1 -0
- package/dist/src/planner/building/dml-target.js +282 -0
- package/dist/src/planner/building/dml-target.js.map +1 -0
- package/dist/src/planner/building/drop-index.d.ts.map +1 -1
- package/dist/src/planner/building/drop-index.js +4 -1
- package/dist/src/planner/building/drop-index.js.map +1 -1
- package/dist/src/planner/building/drop-view.d.ts.map +1 -1
- package/dist/src/planner/building/drop-view.js +4 -2
- package/dist/src/planner/building/drop-view.js.map +1 -1
- package/dist/src/planner/building/expression.d.ts.map +1 -1
- package/dist/src/planner/building/expression.js +60 -21
- package/dist/src/planner/building/expression.js.map +1 -1
- package/dist/src/planner/building/foreign-key-builder.d.ts +30 -0
- package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -1
- package/dist/src/planner/building/foreign-key-builder.js +160 -129
- package/dist/src/planner/building/foreign-key-builder.js.map +1 -1
- package/dist/src/planner/building/insert.d.ts +45 -2
- package/dist/src/planner/building/insert.d.ts.map +1 -1
- package/dist/src/planner/building/insert.js +257 -88
- package/dist/src/planner/building/insert.js.map +1 -1
- package/dist/src/planner/building/lens-auxiliary-access.d.ts +22 -0
- package/dist/src/planner/building/lens-auxiliary-access.d.ts.map +1 -0
- package/dist/src/planner/building/lens-auxiliary-access.js +132 -0
- package/dist/src/planner/building/lens-auxiliary-access.js.map +1 -0
- package/dist/src/planner/building/materialized-view.d.ts +16 -0
- package/dist/src/planner/building/materialized-view.d.ts.map +1 -0
- package/dist/src/planner/building/materialized-view.js +57 -0
- package/dist/src/planner/building/materialized-view.js.map +1 -0
- package/dist/src/planner/building/returning-star.d.ts +32 -0
- package/dist/src/planner/building/returning-star.d.ts.map +1 -0
- package/dist/src/planner/building/returning-star.js +45 -0
- package/dist/src/planner/building/returning-star.js.map +1 -0
- package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
- package/dist/src/planner/building/select-aggregates.js +47 -0
- package/dist/src/planner/building/select-aggregates.js.map +1 -1
- package/dist/src/planner/building/select-compound.d.ts.map +1 -1
- package/dist/src/planner/building/select-compound.js +84 -11
- package/dist/src/planner/building/select-compound.js.map +1 -1
- package/dist/src/planner/building/select-context.d.ts +10 -2
- package/dist/src/planner/building/select-context.d.ts.map +1 -1
- package/dist/src/planner/building/select-context.js +7 -1
- package/dist/src/planner/building/select-context.js.map +1 -1
- package/dist/src/planner/building/select-modifiers.js +6 -0
- package/dist/src/planner/building/select-modifiers.js.map +1 -1
- package/dist/src/planner/building/select-ordinal.d.ts +18 -0
- package/dist/src/planner/building/select-ordinal.d.ts.map +1 -1
- package/dist/src/planner/building/select-ordinal.js +30 -0
- package/dist/src/planner/building/select-ordinal.js.map +1 -1
- package/dist/src/planner/building/select-projections.d.ts +8 -2
- package/dist/src/planner/building/select-projections.d.ts.map +1 -1
- package/dist/src/planner/building/select-projections.js +26 -4
- package/dist/src/planner/building/select-projections.js.map +1 -1
- package/dist/src/planner/building/select-window.d.ts.map +1 -1
- package/dist/src/planner/building/select-window.js +8 -5
- package/dist/src/planner/building/select-window.js.map +1 -1
- package/dist/src/planner/building/select.d.ts.map +1 -1
- package/dist/src/planner/building/select.js +164 -59
- package/dist/src/planner/building/select.js.map +1 -1
- package/dist/src/planner/building/set-object-tags.d.ts +7 -0
- package/dist/src/planner/building/set-object-tags.d.ts.map +1 -0
- package/dist/src/planner/building/set-object-tags.js +38 -0
- package/dist/src/planner/building/set-object-tags.js.map +1 -0
- package/dist/src/planner/building/tag-diagnostics.d.ts +27 -0
- package/dist/src/planner/building/tag-diagnostics.d.ts.map +1 -0
- package/dist/src/planner/building/tag-diagnostics.js +37 -0
- package/dist/src/planner/building/tag-diagnostics.js.map +1 -0
- package/dist/src/planner/building/update.d.ts +18 -1
- package/dist/src/planner/building/update.d.ts.map +1 -1
- package/dist/src/planner/building/update.js +134 -58
- package/dist/src/planner/building/update.js.map +1 -1
- package/dist/src/planner/building/view-mutation-builder.d.ts +15 -0
- package/dist/src/planner/building/view-mutation-builder.d.ts.map +1 -0
- package/dist/src/planner/building/view-mutation-builder.js +1158 -0
- package/dist/src/planner/building/view-mutation-builder.js.map +1 -0
- package/dist/src/planner/building/with.d.ts +11 -0
- package/dist/src/planner/building/with.d.ts.map +1 -1
- package/dist/src/planner/building/with.js +48 -10
- package/dist/src/planner/building/with.js.map +1 -1
- package/dist/src/planner/cost/index.d.ts +83 -0
- package/dist/src/planner/cost/index.d.ts.map +1 -1
- package/dist/src/planner/cost/index.js +114 -0
- package/dist/src/planner/cost/index.js.map +1 -1
- package/dist/src/planner/framework/characteristics.d.ts +38 -4
- package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
- package/dist/src/planner/framework/characteristics.js +50 -6
- package/dist/src/planner/framework/characteristics.js.map +1 -1
- package/dist/src/planner/framework/pass.d.ts.map +1 -1
- package/dist/src/planner/framework/pass.js +2 -1
- package/dist/src/planner/framework/pass.js.map +1 -1
- package/dist/src/planner/framework/registry.d.ts +39 -1
- package/dist/src/planner/framework/registry.d.ts.map +1 -1
- package/dist/src/planner/framework/registry.js +18 -2
- package/dist/src/planner/framework/registry.js.map +1 -1
- package/dist/src/planner/mutation/backward-body.d.ts +131 -0
- package/dist/src/planner/mutation/backward-body.d.ts.map +1 -0
- package/dist/src/planner/mutation/backward-body.js +135 -0
- package/dist/src/planner/mutation/backward-body.js.map +1 -0
- package/dist/src/planner/mutation/cte-flatten.d.ts +17 -0
- package/dist/src/planner/mutation/cte-flatten.d.ts.map +1 -0
- package/dist/src/planner/mutation/cte-flatten.js +364 -0
- package/dist/src/planner/mutation/cte-flatten.js.map +1 -0
- package/dist/src/planner/mutation/decomposition.d.ts +273 -0
- package/dist/src/planner/mutation/decomposition.d.ts.map +1 -0
- package/dist/src/planner/mutation/decomposition.js +1719 -0
- package/dist/src/planner/mutation/decomposition.js.map +1 -0
- package/dist/src/planner/mutation/lens-enforcement.d.ts +165 -0
- package/dist/src/planner/mutation/lens-enforcement.d.ts.map +1 -0
- package/dist/src/planner/mutation/lens-enforcement.js +745 -0
- package/dist/src/planner/mutation/lens-enforcement.js.map +1 -0
- package/dist/src/planner/mutation/multi-source.d.ts +568 -0
- package/dist/src/planner/mutation/multi-source.d.ts.map +1 -0
- package/dist/src/planner/mutation/multi-source.js +2915 -0
- package/dist/src/planner/mutation/multi-source.js.map +1 -0
- package/dist/src/planner/mutation/mutation-diagnostic.d.ts +37 -0
- package/dist/src/planner/mutation/mutation-diagnostic.d.ts.map +1 -0
- package/dist/src/planner/mutation/mutation-diagnostic.js +24 -0
- package/dist/src/planner/mutation/mutation-diagnostic.js.map +1 -0
- package/dist/src/planner/mutation/mutation-tags.d.ts +33 -0
- package/dist/src/planner/mutation/mutation-tags.d.ts.map +1 -0
- package/dist/src/planner/mutation/mutation-tags.js +31 -0
- package/dist/src/planner/mutation/mutation-tags.js.map +1 -0
- package/dist/src/planner/mutation/propagate.d.ts +97 -0
- package/dist/src/planner/mutation/propagate.d.ts.map +1 -0
- package/dist/src/planner/mutation/propagate.js +220 -0
- package/dist/src/planner/mutation/propagate.js.map +1 -0
- package/dist/src/planner/mutation/scope-transform.d.ts +181 -0
- package/dist/src/planner/mutation/scope-transform.d.ts.map +1 -0
- package/dist/src/planner/mutation/scope-transform.js +574 -0
- package/dist/src/planner/mutation/scope-transform.js.map +1 -0
- package/dist/src/planner/mutation/set-op.d.ts +242 -0
- package/dist/src/planner/mutation/set-op.d.ts.map +1 -0
- package/dist/src/planner/mutation/set-op.js +1687 -0
- package/dist/src/planner/mutation/set-op.js.map +1 -0
- package/dist/src/planner/mutation/single-source.d.ts +261 -0
- package/dist/src/planner/mutation/single-source.d.ts.map +1 -0
- package/dist/src/planner/mutation/single-source.js +1096 -0
- package/dist/src/planner/mutation/single-source.js.map +1 -0
- package/dist/src/planner/nodes/aggregate-node.js +3 -3
- package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
- package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/alias-node.js +5 -1
- package/dist/src/planner/nodes/alias-node.js.map +1 -1
- package/dist/src/planner/nodes/alter-table-node.d.ts +124 -1
- package/dist/src/planner/nodes/alter-table-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/alter-table-node.js +27 -0
- package/dist/src/planner/nodes/alter-table-node.js.map +1 -1
- package/dist/src/planner/nodes/analyze-node.d.ts +2 -1
- package/dist/src/planner/nodes/analyze-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/analyze-node.js +18 -1
- package/dist/src/planner/nodes/analyze-node.js.map +1 -1
- package/dist/src/planner/nodes/asserted-keys-node.d.ts +43 -0
- package/dist/src/planner/nodes/asserted-keys-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/asserted-keys-node.js +99 -0
- package/dist/src/planner/nodes/asserted-keys-node.js.map +1 -0
- package/dist/src/planner/nodes/async-gather-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/async-gather-node.js +33 -8
- package/dist/src/planner/nodes/async-gather-node.js.map +1 -1
- package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/bloom-join-node.js +2 -1
- package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
- package/dist/src/planner/nodes/create-view-node.d.ts +7 -2
- package/dist/src/planner/nodes/create-view-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/create-view-node.js +4 -1
- package/dist/src/planner/nodes/create-view-node.js.map +1 -1
- package/dist/src/planner/nodes/declarative-schema.d.ts +13 -1
- package/dist/src/planner/nodes/declarative-schema.d.ts.map +1 -1
- package/dist/src/planner/nodes/declarative-schema.js +32 -0
- package/dist/src/planner/nodes/declarative-schema.js.map +1 -1
- package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/distinct-node.js +2 -0
- package/dist/src/planner/nodes/distinct-node.js.map +1 -1
- package/dist/src/planner/nodes/dml-executor-node.d.ts +29 -1
- package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/dml-executor-node.js +27 -3
- package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
- package/dist/src/planner/nodes/eager-prefetch-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/eager-prefetch-node.js +2 -0
- package/dist/src/planner/nodes/eager-prefetch-node.js.map +1 -1
- package/dist/src/planner/nodes/envelope-scan-node.d.ts +42 -0
- package/dist/src/planner/nodes/envelope-scan-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/envelope-scan-node.js +62 -0
- package/dist/src/planner/nodes/envelope-scan-node.js.map +1 -0
- package/dist/src/planner/nodes/fanout-lookup-join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/fanout-lookup-join-node.js +11 -1
- package/dist/src/planner/nodes/fanout-lookup-join-node.js.map +1 -1
- package/dist/src/planner/nodes/filter.d.ts.map +1 -1
- package/dist/src/planner/nodes/filter.js +63 -13
- package/dist/src/planner/nodes/filter.js.map +1 -1
- package/dist/src/planner/nodes/join-node.d.ts +41 -1
- package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-node.js +78 -8
- package/dist/src/planner/nodes/join-node.js.map +1 -1
- package/dist/src/planner/nodes/join-utils.d.ts +33 -6
- package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-utils.js +124 -9
- package/dist/src/planner/nodes/join-utils.js.map +1 -1
- package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts +104 -0
- package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/lens-auxiliary-access-node.js +91 -0
- package/dist/src/planner/nodes/lens-auxiliary-access-node.js.map +1 -0
- package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
- package/dist/src/planner/nodes/limit-offset.js +4 -5
- package/dist/src/planner/nodes/limit-offset.js.map +1 -1
- package/dist/src/planner/nodes/materialized-view-nodes.d.ts +69 -0
- package/dist/src/planner/nodes/materialized-view-nodes.d.ts.map +1 -0
- package/dist/src/planner/nodes/materialized-view-nodes.js +111 -0
- package/dist/src/planner/nodes/materialized-view-nodes.js.map +1 -0
- package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/merge-join-node.js +2 -1
- package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
- package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/ordinal-slice-node.js +2 -0
- package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.d.ts +9 -0
- package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.js +9 -0
- package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
- package/dist/src/planner/nodes/plan-node.d.ts +265 -5
- package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/plan-node.js.map +1 -1
- package/dist/src/planner/nodes/pragma.d.ts +2 -1
- package/dist/src/planner/nodes/pragma.d.ts.map +1 -1
- package/dist/src/planner/nodes/pragma.js +12 -0
- package/dist/src/planner/nodes/pragma.js.map +1 -1
- package/dist/src/planner/nodes/project-node.d.ts +14 -1
- package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/project-node.js +85 -11
- package/dist/src/planner/nodes/project-node.js.map +1 -1
- package/dist/src/planner/nodes/reference.d.ts.map +1 -1
- package/dist/src/planner/nodes/reference.js +62 -27
- package/dist/src/planner/nodes/reference.js.map +1 -1
- package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/retrieve-node.js +7 -0
- package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
- package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/returning-node.js +10 -3
- package/dist/src/planner/nodes/returning-node.js.map +1 -1
- package/dist/src/planner/nodes/scalar.d.ts +20 -0
- package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
- package/dist/src/planner/nodes/scalar.js +71 -14
- package/dist/src/planner/nodes/scalar.js.map +1 -1
- package/dist/src/planner/nodes/set-object-tags-node.d.ts +39 -0
- package/dist/src/planner/nodes/set-object-tags-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/set-object-tags-node.js +41 -0
- package/dist/src/planner/nodes/set-object-tags-node.js.map +1 -0
- package/dist/src/planner/nodes/set-operation-node.d.ts +123 -1
- package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/set-operation-node.js +291 -18
- package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
- package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
- package/dist/src/planner/nodes/single-row.js +3 -0
- package/dist/src/planner/nodes/single-row.js.map +1 -1
- package/dist/src/planner/nodes/sort.d.ts.map +1 -1
- package/dist/src/planner/nodes/sort.js +7 -6
- package/dist/src/planner/nodes/sort.js.map +1 -1
- package/dist/src/planner/nodes/subquery.d.ts +2 -0
- package/dist/src/planner/nodes/subquery.d.ts.map +1 -1
- package/dist/src/planner/nodes/subquery.js +18 -2
- package/dist/src/planner/nodes/subquery.js.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.js +23 -3
- package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
- package/dist/src/planner/nodes/table-function-call.js +6 -0
- package/dist/src/planner/nodes/table-function-call.js.map +1 -1
- package/dist/src/planner/nodes/values-node.d.ts +1 -0
- package/dist/src/planner/nodes/values-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/values-node.js +16 -6
- package/dist/src/planner/nodes/values-node.js.map +1 -1
- package/dist/src/planner/nodes/view-mutation-node.d.ts +259 -0
- package/dist/src/planner/nodes/view-mutation-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/view-mutation-node.js +273 -0
- package/dist/src/planner/nodes/view-mutation-node.js.map +1 -0
- package/dist/src/planner/nodes/window-function.d.ts +17 -1
- package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
- package/dist/src/planner/nodes/window-function.js +15 -1
- package/dist/src/planner/nodes/window-function.js.map +1 -1
- package/dist/src/planner/nodes/window-node.js +2 -2
- package/dist/src/planner/nodes/window-node.js.map +1 -1
- package/dist/src/planner/optimizer.d.ts.map +1 -1
- package/dist/src/planner/optimizer.js +372 -39
- package/dist/src/planner/optimizer.js.map +1 -1
- package/dist/src/planner/planning-context.d.ts +1 -1
- package/dist/src/planner/planning-context.d.ts.map +1 -1
- package/dist/src/planner/rules/access/lens-access-form-matcher.d.ts +70 -0
- package/dist/src/planner/rules/access/lens-access-form-matcher.d.ts.map +1 -0
- package/dist/src/planner/rules/access/lens-access-form-matcher.js +156 -0
- package/dist/src/planner/rules/access/lens-access-form-matcher.js.map +1 -0
- package/dist/src/planner/rules/access/rule-lens-auxiliary-access.d.ts +31 -0
- package/dist/src/planner/rules/access/rule-lens-auxiliary-access.d.ts.map +1 -0
- package/dist/src/planner/rules/access/rule-lens-auxiliary-access.js +176 -0
- package/dist/src/planner/rules/access/rule-lens-auxiliary-access.js.map +1 -0
- package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.js +435 -37
- package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
- package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts.map +1 -1
- package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js +9 -0
- package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js.map +1 -1
- package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts +39 -0
- package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts.map +1 -0
- package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js +616 -0
- package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js.map +1 -0
- package/dist/src/planner/rules/cache/rule-scalar-cse.d.ts.map +1 -1
- package/dist/src/planner/rules/cache/rule-scalar-cse.js +8 -1
- package/dist/src/planner/rules/cache/rule-scalar-cse.js.map +1 -1
- package/dist/src/planner/rules/join/equi-pair-extractor.d.ts +36 -0
- package/dist/src/planner/rules/join/equi-pair-extractor.d.ts.map +1 -1
- package/dist/src/planner/rules/join/equi-pair-extractor.js +38 -1
- package/dist/src/planner/rules/join/equi-pair-extractor.js.map +1 -1
- package/dist/src/planner/rules/join/rule-fanout-batched-outer.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-fanout-batched-outer.js +10 -0
- package/dist/src/planner/rules/join/rule-fanout-batched-outer.js.map +1 -1
- package/dist/src/planner/rules/join/rule-fanout-lookup-join.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-fanout-lookup-join.js +19 -1
- package/dist/src/planner/rules/join/rule-fanout-lookup-join.js.map +1 -1
- package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts +130 -0
- package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts.map +1 -0
- package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js +206 -0
- package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js.map +1 -0
- package/dist/src/planner/rules/join/rule-join-elimination.d.ts +67 -14
- package/dist/src/planner/rules/join/rule-join-elimination.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-join-elimination.js +81 -25
- package/dist/src/planner/rules/join/rule-join-elimination.js.map +1 -1
- package/dist/src/planner/rules/join/rule-join-existence-pruning.d.ts +84 -0
- package/dist/src/planner/rules/join/rule-join-existence-pruning.d.ts.map +1 -0
- package/dist/src/planner/rules/join/rule-join-existence-pruning.js +138 -0
- package/dist/src/planner/rules/join/rule-join-existence-pruning.js.map +1 -0
- package/dist/src/planner/rules/join/rule-join-greedy-commute.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-join-greedy-commute.js +9 -1
- package/dist/src/planner/rules/join/rule-join-greedy-commute.js.map +1 -1
- package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-join-physical-selection.js +12 -1
- package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -1
- package/dist/src/planner/rules/join/rule-lateral-top1-asof.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-lateral-top1-asof.js +4 -0
- package/dist/src/planner/rules/join/rule-lateral-top1-asof.js.map +1 -1
- package/dist/src/planner/rules/join/rule-monotonic-merge-join.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-monotonic-merge-join.js +4 -0
- package/dist/src/planner/rules/join/rule-monotonic-merge-join.js.map +1 -1
- package/dist/src/planner/rules/join/rule-quickpick-enumeration.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-quickpick-enumeration.js +10 -0
- package/dist/src/planner/rules/join/rule-quickpick-enumeration.js.map +1 -1
- package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.d.ts +286 -0
- package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.d.ts.map +1 -0
- package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.js +548 -0
- package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.js.map +1 -0
- package/dist/src/planner/rules/parallel/rule-async-gather-union-all.d.ts.map +1 -1
- package/dist/src/planner/rules/parallel/rule-async-gather-union-all.js +9 -1
- package/dist/src/planner/rules/parallel/rule-async-gather-union-all.js.map +1 -1
- package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.d.ts.map +1 -1
- package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js +7 -0
- package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js.map +1 -1
- package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.d.ts.map +1 -1
- package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.js +10 -1
- package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts.map +1 -1
- package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js +9 -0
- package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts.map +1 -1
- package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +18 -0
- package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts.map +1 -1
- package/dist/src/planner/rules/predicate/rule-filter-contradiction.js +7 -0
- package/dist/src/planner/rules/predicate/rule-filter-contradiction.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts.map +1 -1
- package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +9 -0
- package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js +13 -3
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -1
- package/dist/src/planner/rules/retrieve/rule-projection-pruning.d.ts.map +1 -1
- package/dist/src/planner/rules/retrieve/rule-projection-pruning.js +14 -0
- package/dist/src/planner/rules/retrieve/rule-projection-pruning.js.map +1 -1
- package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts +1 -1
- package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js +4 -4
- package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js.map +1 -1
- package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts.map +1 -1
- package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js +8 -0
- package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js.map +1 -1
- package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts.map +1 -1
- package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js +7 -0
- package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js.map +1 -1
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +12 -0
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
- package/dist/src/planner/type-utils.d.ts +14 -0
- package/dist/src/planner/type-utils.d.ts.map +1 -1
- package/dist/src/planner/type-utils.js +66 -21
- package/dist/src/planner/type-utils.js.map +1 -1
- package/dist/src/planner/util/fd-utils.d.ts +177 -43
- package/dist/src/planner/util/fd-utils.d.ts.map +1 -1
- package/dist/src/planner/util/fd-utils.js +396 -101
- package/dist/src/planner/util/fd-utils.js.map +1 -1
- package/dist/src/planner/util/ind-utils.d.ts +27 -1
- package/dist/src/planner/util/ind-utils.d.ts.map +1 -1
- package/dist/src/planner/util/ind-utils.js +80 -6
- package/dist/src/planner/util/ind-utils.js.map +1 -1
- package/dist/src/planner/util/key-utils.d.ts.map +1 -1
- package/dist/src/planner/util/key-utils.js +81 -12
- package/dist/src/planner/util/key-utils.js.map +1 -1
- package/dist/src/planner/util/set-op-wrapper.d.ts +37 -0
- package/dist/src/planner/util/set-op-wrapper.d.ts.map +1 -0
- package/dist/src/planner/util/set-op-wrapper.js +82 -0
- package/dist/src/planner/util/set-op-wrapper.js.map +1 -0
- package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
- package/dist/src/planner/validation/plan-validator.js +1 -0
- package/dist/src/planner/validation/plan-validator.js.map +1 -1
- package/dist/src/runtime/context-helpers.d.ts +13 -1
- package/dist/src/runtime/context-helpers.d.ts.map +1 -1
- package/dist/src/runtime/context-helpers.js +7 -1
- package/dist/src/runtime/context-helpers.js.map +1 -1
- package/dist/src/runtime/delta-executor.d.ts +30 -1
- package/dist/src/runtime/delta-executor.d.ts.map +1 -1
- package/dist/src/runtime/delta-executor.js +29 -4
- package/dist/src/runtime/delta-executor.js.map +1 -1
- package/dist/src/runtime/emit/add-constraint.d.ts.map +1 -1
- package/dist/src/runtime/emit/add-constraint.js +38 -5
- package/dist/src/runtime/emit/add-constraint.js.map +1 -1
- package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
- package/dist/src/runtime/emit/aggregate.js +10 -8
- package/dist/src/runtime/emit/aggregate.js.map +1 -1
- package/dist/src/runtime/emit/alter-table.d.ts +1 -1
- package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/alter-table.js +664 -108
- package/dist/src/runtime/emit/alter-table.js.map +1 -1
- package/dist/src/runtime/emit/analyze.d.ts.map +1 -1
- package/dist/src/runtime/emit/analyze.js +2 -1
- package/dist/src/runtime/emit/analyze.js.map +1 -1
- package/dist/src/runtime/emit/asof-scan.d.ts.map +1 -1
- package/dist/src/runtime/emit/asof-scan.js +18 -5
- package/dist/src/runtime/emit/asof-scan.js.map +1 -1
- package/dist/src/runtime/emit/asserted-keys.d.ts +13 -0
- package/dist/src/runtime/emit/asserted-keys.d.ts.map +1 -0
- package/dist/src/runtime/emit/asserted-keys.js +13 -0
- package/dist/src/runtime/emit/asserted-keys.js.map +1 -0
- package/dist/src/runtime/emit/between.d.ts.map +1 -1
- package/dist/src/runtime/emit/between.js +24 -19
- package/dist/src/runtime/emit/between.js.map +1 -1
- package/dist/src/runtime/emit/binary.d.ts.map +1 -1
- package/dist/src/runtime/emit/binary.js +5 -9
- package/dist/src/runtime/emit/binary.js.map +1 -1
- package/dist/src/runtime/emit/block.d.ts.map +1 -1
- package/dist/src/runtime/emit/block.js +11 -2
- package/dist/src/runtime/emit/block.js.map +1 -1
- package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -1
- package/dist/src/runtime/emit/bloom-join.js +8 -2
- package/dist/src/runtime/emit/bloom-join.js.map +1 -1
- package/dist/src/runtime/emit/constraint-check.js +15 -0
- package/dist/src/runtime/emit/constraint-check.js.map +1 -1
- package/dist/src/runtime/emit/create-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/create-table.js +8 -0
- package/dist/src/runtime/emit/create-table.js.map +1 -1
- package/dist/src/runtime/emit/create-view.d.ts.map +1 -1
- package/dist/src/runtime/emit/create-view.js +16 -1
- package/dist/src/runtime/emit/create-view.js.map +1 -1
- package/dist/src/runtime/emit/dml-executor.d.ts +27 -0
- package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
- package/dist/src/runtime/emit/dml-executor.js +413 -193
- package/dist/src/runtime/emit/dml-executor.js.map +1 -1
- package/dist/src/runtime/emit/drop-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/drop-table.js +10 -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 +17 -0
- package/dist/src/runtime/emit/drop-view.js.map +1 -1
- package/dist/src/runtime/emit/envelope-scan.d.ts +13 -0
- package/dist/src/runtime/emit/envelope-scan.d.ts.map +1 -0
- package/dist/src/runtime/emit/envelope-scan.js +22 -0
- package/dist/src/runtime/emit/envelope-scan.js.map +1 -0
- package/dist/src/runtime/emit/join.d.ts +10 -2
- package/dist/src/runtime/emit/join.d.ts.map +1 -1
- package/dist/src/runtime/emit/join.js +128 -38
- package/dist/src/runtime/emit/join.js.map +1 -1
- package/dist/src/runtime/emit/lens-auxiliary-access.d.ts +16 -0
- package/dist/src/runtime/emit/lens-auxiliary-access.d.ts.map +1 -0
- package/dist/src/runtime/emit/lens-auxiliary-access.js +16 -0
- package/dist/src/runtime/emit/lens-auxiliary-access.js.map +1 -0
- package/dist/src/runtime/emit/materialized-view-helpers.d.ts +640 -0
- package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -0
- package/dist/src/runtime/emit/materialized-view-helpers.js +2576 -0
- package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -0
- package/dist/src/runtime/emit/materialized-view.d.ts +31 -0
- package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -0
- package/dist/src/runtime/emit/materialized-view.js +187 -0
- package/dist/src/runtime/emit/materialized-view.js.map +1 -0
- package/dist/src/runtime/emit/merge-join.d.ts.map +1 -1
- package/dist/src/runtime/emit/merge-join.js +15 -3
- package/dist/src/runtime/emit/merge-join.js.map +1 -1
- package/dist/src/runtime/emit/project.d.ts.map +1 -1
- package/dist/src/runtime/emit/project.js +10 -5
- package/dist/src/runtime/emit/project.js.map +1 -1
- package/dist/src/runtime/emit/schema-declarative.d.ts +1 -0
- package/dist/src/runtime/emit/schema-declarative.d.ts.map +1 -1
- package/dist/src/runtime/emit/schema-declarative.js +101 -5
- package/dist/src/runtime/emit/schema-declarative.js.map +1 -1
- package/dist/src/runtime/emit/set-object-tags.d.ts +16 -0
- package/dist/src/runtime/emit/set-object-tags.d.ts.map +1 -0
- package/dist/src/runtime/emit/set-object-tags.js +57 -0
- package/dist/src/runtime/emit/set-object-tags.js.map +1 -0
- package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
- package/dist/src/runtime/emit/set-operation.js +140 -24
- package/dist/src/runtime/emit/set-operation.js.map +1 -1
- package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
- package/dist/src/runtime/emit/subquery.js +110 -5
- package/dist/src/runtime/emit/subquery.js.map +1 -1
- package/dist/src/runtime/emit/unary.d.ts.map +1 -1
- package/dist/src/runtime/emit/unary.js +34 -6
- package/dist/src/runtime/emit/unary.js.map +1 -1
- package/dist/src/runtime/emit/view-mutation.d.ts +70 -0
- package/dist/src/runtime/emit/view-mutation.d.ts.map +1 -0
- package/dist/src/runtime/emit/view-mutation.js +299 -0
- package/dist/src/runtime/emit/view-mutation.js.map +1 -0
- package/dist/src/runtime/emit/window.js +29 -5
- package/dist/src/runtime/emit/window.js.map +1 -1
- package/dist/src/runtime/foreign-key-actions.d.ts +66 -3
- package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
- package/dist/src/runtime/foreign-key-actions.js +580 -172
- package/dist/src/runtime/foreign-key-actions.js.map +1 -1
- package/dist/src/runtime/parallel-driver.d.ts +4 -1
- package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
- package/dist/src/runtime/parallel-driver.js +5 -1
- package/dist/src/runtime/parallel-driver.js.map +1 -1
- package/dist/src/runtime/register.d.ts.map +1 -1
- package/dist/src/runtime/register.js +17 -1
- package/dist/src/runtime/register.js.map +1 -1
- package/dist/src/runtime/types.d.ts +10 -0
- package/dist/src/runtime/types.d.ts.map +1 -1
- package/dist/src/runtime/types.js.map +1 -1
- package/dist/src/schema/basis-backfill.d.ts +63 -0
- package/dist/src/schema/basis-backfill.d.ts.map +1 -0
- package/dist/src/schema/basis-backfill.js +161 -0
- package/dist/src/schema/basis-backfill.js.map +1 -0
- package/dist/src/schema/catalog.d.ts +115 -1
- package/dist/src/schema/catalog.d.ts.map +1 -1
- package/dist/src/schema/catalog.js +249 -22
- package/dist/src/schema/catalog.js.map +1 -1
- package/dist/src/schema/change-events.d.ts +42 -1
- package/dist/src/schema/change-events.d.ts.map +1 -1
- package/dist/src/schema/change-events.js.map +1 -1
- package/dist/src/schema/column.d.ts +16 -0
- package/dist/src/schema/column.d.ts.map +1 -1
- package/dist/src/schema/column.js.map +1 -1
- package/dist/src/schema/constraint-builder.d.ts +182 -0
- package/dist/src/schema/constraint-builder.d.ts.map +1 -0
- package/dist/src/schema/constraint-builder.js +424 -0
- package/dist/src/schema/constraint-builder.js.map +1 -0
- package/dist/src/schema/ddl-generator.d.ts +86 -1
- package/dist/src/schema/ddl-generator.d.ts.map +1 -1
- package/dist/src/schema/ddl-generator.js +316 -20
- package/dist/src/schema/ddl-generator.js.map +1 -1
- package/dist/src/schema/declared-schema-manager.d.ts +51 -0
- package/dist/src/schema/declared-schema-manager.d.ts.map +1 -1
- package/dist/src/schema/declared-schema-manager.js +61 -0
- package/dist/src/schema/declared-schema-manager.js.map +1 -1
- package/dist/src/schema/derivation.d.ts +106 -0
- package/dist/src/schema/derivation.d.ts.map +1 -0
- package/dist/src/schema/derivation.js +25 -0
- package/dist/src/schema/derivation.js.map +1 -0
- package/dist/src/schema/function.d.ts +13 -0
- package/dist/src/schema/function.d.ts.map +1 -1
- package/dist/src/schema/function.js.map +1 -1
- package/dist/src/schema/lens-ack.d.ts +90 -0
- package/dist/src/schema/lens-ack.d.ts.map +1 -0
- package/dist/src/schema/lens-ack.js +361 -0
- package/dist/src/schema/lens-ack.js.map +1 -0
- package/dist/src/schema/lens-compiler.d.ts +62 -0
- package/dist/src/schema/lens-compiler.d.ts.map +1 -0
- package/dist/src/schema/lens-compiler.js +1594 -0
- package/dist/src/schema/lens-compiler.js.map +1 -0
- package/dist/src/schema/lens-fk-discovery.d.ts +175 -0
- package/dist/src/schema/lens-fk-discovery.d.ts.map +1 -0
- package/dist/src/schema/lens-fk-discovery.js +336 -0
- package/dist/src/schema/lens-fk-discovery.js.map +1 -0
- package/dist/src/schema/lens-prover.d.ts +336 -0
- package/dist/src/schema/lens-prover.d.ts.map +1 -0
- package/dist/src/schema/lens-prover.js +1988 -0
- package/dist/src/schema/lens-prover.js.map +1 -0
- package/dist/src/schema/lens.d.ts +254 -0
- package/dist/src/schema/lens.d.ts.map +1 -0
- package/dist/src/schema/lens.js +21 -0
- package/dist/src/schema/lens.js.map +1 -0
- package/dist/src/schema/manager.d.ts +676 -18
- package/dist/src/schema/manager.d.ts.map +1 -1
- package/dist/src/schema/manager.js +1573 -238
- package/dist/src/schema/manager.js.map +1 -1
- package/dist/src/schema/mapping-advertisement-tags.d.ts +39 -0
- package/dist/src/schema/mapping-advertisement-tags.d.ts.map +1 -0
- package/dist/src/schema/mapping-advertisement-tags.js +216 -0
- package/dist/src/schema/mapping-advertisement-tags.js.map +1 -0
- package/dist/src/schema/rename-rewriter.d.ts +45 -4
- package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
- package/dist/src/schema/rename-rewriter.js +412 -19
- package/dist/src/schema/rename-rewriter.js.map +1 -1
- package/dist/src/schema/reserved-tags-policy.d.ts +32 -0
- package/dist/src/schema/reserved-tags-policy.d.ts.map +1 -0
- package/dist/src/schema/reserved-tags-policy.js +34 -0
- package/dist/src/schema/reserved-tags-policy.js.map +1 -0
- package/dist/src/schema/reserved-tags.d.ts +170 -0
- package/dist/src/schema/reserved-tags.d.ts.map +1 -0
- package/dist/src/schema/reserved-tags.js +507 -0
- package/dist/src/schema/reserved-tags.js.map +1 -0
- package/dist/src/schema/schema-differ.d.ts +158 -2
- package/dist/src/schema/schema-differ.d.ts.map +1 -1
- package/dist/src/schema/schema-differ.js +1460 -78
- package/dist/src/schema/schema-differ.js.map +1 -1
- package/dist/src/schema/schema-hasher.d.ts +8 -3
- package/dist/src/schema/schema-hasher.d.ts.map +1 -1
- package/dist/src/schema/schema-hasher.js +22 -2
- package/dist/src/schema/schema-hasher.js.map +1 -1
- package/dist/src/schema/schema.d.ts +25 -1
- package/dist/src/schema/schema.d.ts.map +1 -1
- package/dist/src/schema/schema.js +36 -2
- package/dist/src/schema/schema.js.map +1 -1
- package/dist/src/schema/table.d.ts +259 -10
- package/dist/src/schema/table.d.ts.map +1 -1
- package/dist/src/schema/table.js +309 -26
- package/dist/src/schema/table.js.map +1 -1
- package/dist/src/schema/unique-enforcement.d.ts +78 -0
- package/dist/src/schema/unique-enforcement.d.ts.map +1 -0
- package/dist/src/schema/unique-enforcement.js +93 -0
- package/dist/src/schema/unique-enforcement.js.map +1 -0
- package/dist/src/schema/view.d.ts +83 -2
- package/dist/src/schema/view.d.ts.map +1 -1
- package/dist/src/schema/view.js +67 -1
- package/dist/src/schema/view.js.map +1 -1
- package/dist/src/schema/window-function.d.ts +9 -1
- package/dist/src/schema/window-function.d.ts.map +1 -1
- package/dist/src/schema/window-function.js.map +1 -1
- package/dist/src/util/comparison.d.ts +24 -0
- package/dist/src/util/comparison.d.ts.map +1 -1
- package/dist/src/util/comparison.js +34 -0
- package/dist/src/util/comparison.js.map +1 -1
- package/dist/src/util/mutation-statement.d.ts.map +1 -1
- package/dist/src/util/mutation-statement.js +4 -1
- package/dist/src/util/mutation-statement.js.map +1 -1
- package/dist/src/util/serialization.d.ts +9 -0
- package/dist/src/util/serialization.d.ts.map +1 -1
- package/dist/src/util/serialization.js +26 -0
- package/dist/src/util/serialization.js.map +1 -1
- package/dist/src/vtab/backing-host.d.ts +286 -0
- package/dist/src/vtab/backing-host.d.ts.map +1 -0
- package/dist/src/vtab/backing-host.js +118 -0
- package/dist/src/vtab/backing-host.js.map +1 -0
- package/dist/src/vtab/best-access-plan.d.ts +21 -0
- package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
- package/dist/src/vtab/best-access-plan.js.map +1 -1
- package/dist/src/vtab/capabilities.d.ts +5 -5
- package/dist/src/vtab/capabilities.d.ts.map +1 -1
- package/dist/src/vtab/mapping-advertisement.d.ts +163 -0
- package/dist/src/vtab/mapping-advertisement.d.ts.map +1 -0
- package/dist/src/vtab/mapping-advertisement.js +2 -0
- package/dist/src/vtab/mapping-advertisement.js.map +1 -0
- package/dist/src/vtab/memory/index.d.ts +64 -4
- package/dist/src/vtab/memory/index.d.ts.map +1 -1
- package/dist/src/vtab/memory/index.js +119 -12
- package/dist/src/vtab/memory/index.js.map +1 -1
- package/dist/src/vtab/memory/layer/base.d.ts +38 -1
- package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/base.js +112 -24
- package/dist/src/vtab/memory/layer/base.js.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts +291 -4
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +1050 -91
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/dist/src/vtab/memory/layer/plan-filter.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/plan-filter.js +35 -6
- package/dist/src/vtab/memory/layer/plan-filter.js.map +1 -1
- package/dist/src/vtab/memory/layer/scan-layer.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/scan-layer.js +66 -14
- package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
- package/dist/src/vtab/memory/layer/scan-plan.d.ts +14 -0
- package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/scan-plan.js +27 -4
- package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.js +5 -1
- package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
- package/dist/src/vtab/memory/module.d.ts +17 -0
- package/dist/src/vtab/memory/module.d.ts.map +1 -1
- package/dist/src/vtab/memory/module.js +82 -3
- package/dist/src/vtab/memory/module.js.map +1 -1
- package/dist/src/vtab/memory/table.d.ts.map +1 -1
- package/dist/src/vtab/memory/table.js +15 -5
- package/dist/src/vtab/memory/table.js.map +1 -1
- package/dist/src/vtab/memory/types.d.ts +20 -2
- package/dist/src/vtab/memory/types.d.ts.map +1 -1
- package/dist/src/vtab/memory/utils/predicate.d.ts.map +1 -1
- package/dist/src/vtab/memory/utils/predicate.js +46 -24
- package/dist/src/vtab/memory/utils/predicate.js.map +1 -1
- package/dist/src/vtab/memory/utils/primary-key-encode.d.ts +31 -0
- package/dist/src/vtab/memory/utils/primary-key-encode.d.ts.map +1 -0
- package/dist/src/vtab/memory/utils/primary-key-encode.js +101 -0
- package/dist/src/vtab/memory/utils/primary-key-encode.js.map +1 -0
- package/dist/src/vtab/memory/utils/primary-key.d.ts +8 -0
- package/dist/src/vtab/memory/utils/primary-key.d.ts.map +1 -1
- package/dist/src/vtab/memory/utils/primary-key.js +12 -5
- package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
- package/dist/src/vtab/module.d.ts +203 -4
- package/dist/src/vtab/module.d.ts.map +1 -1
- package/dist/src/vtab/table.d.ts +9 -0
- package/dist/src/vtab/table.d.ts.map +1 -1
- package/dist/src/vtab/table.js.map +1 -1
- package/package.json +6 -5
|
@@ -4,6 +4,8 @@ import { StatusCode } from '../common/types.js';
|
|
|
4
4
|
import { createLogger } from '../common/logger.js';
|
|
5
5
|
import { expressionToString, quoteIdentifier } from '../emit/ast-stringify.js';
|
|
6
6
|
import { sqlValuesEqual } from '../util/comparison.js';
|
|
7
|
+
import { resolveSlotBasisSource } from '../schema/lens-prover.js';
|
|
8
|
+
import { findLogicalParentFkRefs, logicalToBasisColumnMap, matchingBasisFksForLensRef, basisFksOverriddenByDivergentLensFk, } from '../schema/lens-fk-discovery.js';
|
|
7
9
|
const log = createLogger('runtime:fk-actions');
|
|
8
10
|
/**
|
|
9
11
|
* Executes cascading foreign key actions when a parent row is deleted or updated.
|
|
@@ -13,9 +15,13 @@ const log = createLogger('runtime:fk-actions');
|
|
|
13
15
|
* @param operation 'delete' or 'update'
|
|
14
16
|
* @param oldRow The old row values from the parent table
|
|
15
17
|
* @param newRow The new row values (undefined for delete)
|
|
18
|
+
* @param lensRouted Whether this basis write was routed through a lens view. The
|
|
19
|
+
* divergent-basis-FK suppression (a logical FK overriding the physical basis action)
|
|
20
|
+
* applies ONLY then; a basis-direct write (`false`) bears its physical basis FK action
|
|
21
|
+
* unsuppressed — see {@link executeForeignKeyActionsAndLens}.
|
|
16
22
|
* @param visitedTables Set of table names already visited (for cycle detection)
|
|
17
23
|
*/
|
|
18
|
-
export async function executeForeignKeyActions(db, parentTable, operation, oldRow, newRow, visitedTables) {
|
|
24
|
+
export async function executeForeignKeyActions(db, parentTable, operation, oldRow, newRow, lensRouted = false, visitedTables) {
|
|
19
25
|
if (!db.options.getBooleanOption('foreign_keys'))
|
|
20
26
|
return;
|
|
21
27
|
const visited = visitedTables ?? new Set();
|
|
@@ -24,39 +30,64 @@ export async function executeForeignKeyActions(db, parentTable, operation, oldRo
|
|
|
24
30
|
throw new QuereusError(`Foreign key cascade cycle detected involving table '${parentTable.name}'`, StatusCode.CONSTRAINT);
|
|
25
31
|
}
|
|
26
32
|
visited.add(parentKey);
|
|
33
|
+
// Basis FKs a divergent non-RESTRICT logical FK overrides — their physical action is
|
|
34
|
+
// suppressed here so the logical action (fired by the lens walker) governs alone.
|
|
35
|
+
// ONLY for a lens-routed write: a basis-direct write bears no logical FK semantics, so
|
|
36
|
+
// its physical basis action must run unsuppressed (else the cascade is dropped entirely
|
|
37
|
+
// once the lens walker is gated off). Cheap-empty otherwise.
|
|
38
|
+
const suppressed = lensRouted
|
|
39
|
+
? basisFksOverriddenByDivergentLensFk(parentTable, operation, db.schemaManager)
|
|
40
|
+
: new Set();
|
|
27
41
|
try {
|
|
28
|
-
// Find all child tables with FKs referencing this parent
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
await executeSingleFKAction(db, childTable, fk, action, parentTable, parentColIndices, oldParentValues, operation === 'update' ? newRow : undefined, visited);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
42
|
+
// Find all child tables with FKs referencing this parent. The reverse FK index is keyed
|
|
43
|
+
// on the referenced schema.table, so the two discovery filters (referencedTable /
|
|
44
|
+
// targetSchema match) are satisfied by the lookup and drop out; the per-FK body is
|
|
45
|
+
// unchanged. The index returns the shared empty array (the O(1) gate) when nothing
|
|
46
|
+
// references this parent — the common case short-circuits with no allocation.
|
|
47
|
+
for (const { childTable, fk } of db.schemaManager.getReferencingForeignKeys(parentTable.schemaName, parentTable.name)) {
|
|
48
|
+
const action = operation === 'delete' ? fk.onDelete : fk.onUpdate;
|
|
49
|
+
// RESTRICT is handled by parent-side constraint checks, not actions
|
|
50
|
+
if (action === 'restrict')
|
|
51
|
+
continue;
|
|
52
|
+
// Suppressed: a divergent non-RESTRICT logical FK over the same columns
|
|
53
|
+
// replaces this basis action (the lens walker fires the logical action).
|
|
54
|
+
if (suppressed.has(fk))
|
|
55
|
+
continue;
|
|
56
|
+
const parentColIndices = resolveReferencedColumns(fk, parentTable);
|
|
57
|
+
if (parentColIndices.length !== fk.columns.length)
|
|
58
|
+
continue;
|
|
59
|
+
// Get old parent values for the referenced columns
|
|
60
|
+
const oldParentValues = parentColIndices.map(idx => oldRow[idx]);
|
|
61
|
+
// Skip if any old value is NULL (NULLs don't participate in FK matching)
|
|
62
|
+
if (oldParentValues.some(v => v === null || v === undefined))
|
|
63
|
+
continue;
|
|
64
|
+
await executeSingleFKAction(db, childTable, fk, action, parentTable, parentColIndices, oldParentValues, operation === 'update' ? newRow : undefined, visited);
|
|
54
65
|
}
|
|
55
66
|
}
|
|
56
67
|
finally {
|
|
57
68
|
visited.delete(parentKey);
|
|
58
69
|
}
|
|
59
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* The combined physical + lens FK-action entry point the DML executor fires after
|
|
73
|
+
* every basis row delete/update. Runs the physical {@link executeForeignKeyActions}
|
|
74
|
+
* (cascade / set-null / set-default over declared basis `TableSchema.foreignKeys`)
|
|
75
|
+
* and then the logical dual {@link executeLensForeignKeyActions} (the same actions
|
|
76
|
+
* over a *logical* FK that lives only on a lens slot's `enforced-fk` obligation). A
|
|
77
|
+
* single wrapper keeps the two sites from drifting — wherever a basis row write fires
|
|
78
|
+
* physical FK actions, the logical cascade fires too. The physical half is unconditional;
|
|
79
|
+
* the logical half fires ONLY for a write routed through a lens view (`lensRouted`), so a
|
|
80
|
+
* basis-direct write bears solely its physical (basis-declared) FK semantics — consistent
|
|
81
|
+
* with the plan-time lens RESTRICT collector and logical CHECK, which attach at the lens
|
|
82
|
+
* boundary only. The lens half is a further cheap early return when `foreign_keys` is off
|
|
83
|
+
* or no lens slot is backed by `parentTable`.
|
|
84
|
+
*/
|
|
85
|
+
export async function executeForeignKeyActionsAndLens(db, parentTable, operation, oldRow, newRow, lensRouted = false) {
|
|
86
|
+
await executeForeignKeyActions(db, parentTable, operation, oldRow, newRow, lensRouted);
|
|
87
|
+
if (lensRouted) {
|
|
88
|
+
await executeLensForeignKeyActions(db, parentTable, operation, oldRow, newRow);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
60
91
|
/**
|
|
61
92
|
* Pre-walk the FK action graph rooted at `parentTable` and assert that no
|
|
62
93
|
* RESTRICT child anywhere in the transitive cascade closure blocks the
|
|
@@ -78,9 +109,24 @@ export async function executeForeignKeyActions(db, parentTable, operation, oldRo
|
|
|
78
109
|
* child's projected new row.
|
|
79
110
|
* 3. Cycle detection via a `visited` set keyed by
|
|
80
111
|
* `${schemaName}.${tableName}` (matches the existing walker's key).
|
|
112
|
+
*
|
|
113
|
+
* `lensRouted` gates the two *logical* FK steps: the lens RESTRICT pre-check (step 1b)
|
|
114
|
+
* and the divergent-basis-FK suppression (in step 1 and step 2). It is `true` only for a
|
|
115
|
+
* write routed through a lens view, and is carried UNCHANGED into the recursion: the
|
|
116
|
+
* nested levels form the transitive closure of *this* write, so a lens-routed top means
|
|
117
|
+
* the whole closure inherits logical FK semantics. This is required to catch a logical
|
|
118
|
+
* RESTRICT below an *agreeing* basis cascade — that basis cascade runs as a basis-direct
|
|
119
|
+
* write at runtime (which never fires the deeper lens RESTRICT) and the agreeing lens
|
|
120
|
+
* cascade is elided (so it never re-enters through the child view either), leaving this
|
|
121
|
+
* pre-walk as the sole enforcer. A basis-direct top write passes `false`, so the whole
|
|
122
|
+
* recursion stays basis-only.
|
|
81
123
|
*/
|
|
82
|
-
export async function assertTransitiveRestrictsForParentMutation(db, parentTable, operation, oldRow, newRow, visited) {
|
|
83
|
-
log('TRANSITIVE entry: parent=%s op=%s fk-pragma=%o', parentTable.name, operation, db.options.getBooleanOption('foreign_keys'));
|
|
124
|
+
export async function assertTransitiveRestrictsForParentMutation(db, parentTable, operation, oldRow, newRow, lensRouted = false, visited) {
|
|
125
|
+
log('TRANSITIVE entry: parent=%s op=%s lensRouted=%o fk-pragma=%o', parentTable.name, operation, lensRouted, db.options.getBooleanOption('foreign_keys'));
|
|
126
|
+
// Trust-the-origin apply path: RESTRICT is enforced by the origin at its own commit,
|
|
127
|
+
// so the receiver skips it (gating cascade-action propagation is intentionally NOT here).
|
|
128
|
+
if (db._isFkRestrictSuppressed())
|
|
129
|
+
return;
|
|
84
130
|
if (!db.options.getBooleanOption('foreign_keys'))
|
|
85
131
|
return;
|
|
86
132
|
const visitedSet = visited ?? new Set();
|
|
@@ -89,106 +135,133 @@ export async function assertTransitiveRestrictsForParentMutation(db, parentTable
|
|
|
89
135
|
return;
|
|
90
136
|
visitedSet.add(parentKey);
|
|
91
137
|
try {
|
|
92
|
-
// Step 1: direct RESTRICT scan for this parent.
|
|
138
|
+
// Step 1: direct RESTRICT scan for this parent. The divergent-basis-FK suppression
|
|
139
|
+
// inside it applies only when this top-level write is lens-routed (a basis-direct
|
|
140
|
+
// write bears its physical basis RESTRICT unsuppressed).
|
|
93
141
|
log('TRANSITIVE step1: parent=%s op=%s', parentTable.name, operation);
|
|
94
|
-
await assertNoRestrictedChildrenForParentMutation(db, parentTable, operation, oldRow, newRow);
|
|
142
|
+
await assertNoRestrictedChildrenForParentMutation(db, parentTable, operation, oldRow, newRow, lensRouted);
|
|
143
|
+
// Step 1b: lens RESTRICT pre-check — the logical dual, keyed off the *logical* FK
|
|
144
|
+
// action. Fired here (pre-basis-op, riding the same pre-mutation timing) so a logical
|
|
145
|
+
// RESTRICT over a non-restrict basis FK observes the pre-cascade child state, which a
|
|
146
|
+
// deferred commit-time `NOT EXISTS` cannot. ONLY for a lens-routed write — a logical FK
|
|
147
|
+
// governs only writes through the lens; a basis-direct write bears no logical RESTRICT.
|
|
148
|
+
// Direct (non-recursive): transitivity through basis cascades rides this enclosing walk
|
|
149
|
+
// (a nested basis cascade re-enters the DML executor as a basis-direct write — its own
|
|
150
|
+
// `lensRouted = false`; a genuine logical cascade re-enters through the child *view* and
|
|
151
|
+
// gets a fresh `lensRouted = true`, so logical transitivity is preserved either way).
|
|
152
|
+
if (lensRouted) {
|
|
153
|
+
await assertLensRestrictsForParentMutation(db, parentTable, operation, oldRow, newRow);
|
|
154
|
+
}
|
|
95
155
|
// Step 2: recurse through cascading children that would propagate a
|
|
96
156
|
// referenced-column change. For each FK whose action would rewrite or
|
|
97
157
|
// delete child rows, scan the matching children NOW (pre-mutation, so
|
|
98
158
|
// the parent's OLD values still resolve), compute the projected child
|
|
99
159
|
// row, and recurse with that child as the new "parent".
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
160
|
+
// Basis cascading FKs a divergent non-RESTRICT logical FK overrides — skip them in
|
|
161
|
+
// the recursion: the physical cascade they walk will not run (the logical action
|
|
162
|
+
// replaces it), and the logical action's own transitivity is enforced when its
|
|
163
|
+
// child-view DML re-enters this walk at the next level. ONLY for a lens-routed write
|
|
164
|
+
// (else the basis cascade governs unsuppressed and must be walked).
|
|
165
|
+
const suppressed = lensRouted
|
|
166
|
+
? basisFksOverriddenByDivergentLensFk(parentTable, operation, db.schemaManager)
|
|
167
|
+
: new Set();
|
|
168
|
+
// The reverse FK index is keyed on the referenced schema.table, so the two discovery
|
|
169
|
+
// filters (referencedTable / targetSchema match) are satisfied by the lookup and drop
|
|
170
|
+
// out; the per-FK body below is unchanged.
|
|
171
|
+
for (const { childTable, fk } of db.schemaManager.getReferencingForeignKeys(parentTable.schemaName, parentTable.name)) {
|
|
172
|
+
const action = operation === 'delete' ? fk.onDelete : fk.onUpdate;
|
|
173
|
+
if (action !== 'cascade' && action !== 'setNull' && action !== 'setDefault')
|
|
174
|
+
continue;
|
|
175
|
+
// Suppressed: the logical action replaces this basis cascade, so the
|
|
176
|
+
// physical cascade it would walk never runs — do not recurse through it.
|
|
177
|
+
if (suppressed.has(fk))
|
|
178
|
+
continue;
|
|
179
|
+
const parentColIndices = resolveReferencedColumns(fk, parentTable);
|
|
180
|
+
if (parentColIndices.length !== fk.columns.length)
|
|
181
|
+
continue;
|
|
182
|
+
// MATCH SIMPLE: NULL parent values cannot be referenced.
|
|
183
|
+
const oldParentValues = parentColIndices.map(idx => oldRow[idx]);
|
|
184
|
+
if (oldParentValues.some(v => v === null || v === undefined))
|
|
185
|
+
continue;
|
|
186
|
+
// UPDATE-only short-circuit: skip if no referenced parent column changed.
|
|
187
|
+
let newParentValues;
|
|
188
|
+
if (operation === 'update' && newRow !== undefined) {
|
|
189
|
+
let anyChanged = false;
|
|
190
|
+
for (const idx of parentColIndices) {
|
|
191
|
+
if (!sqlValuesEqual(oldRow[idx], newRow[idx])) {
|
|
192
|
+
anyChanged = true;
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (!anyChanged)
|
|
105
197
|
continue;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
198
|
+
newParentValues = parentColIndices.map(idx => newRow[idx]);
|
|
199
|
+
}
|
|
200
|
+
// Scan child rows that match the OLD parent values.
|
|
201
|
+
const childColQuoted = fk.columns.map(idx => quoteIdentifier(childTable.columns[idx].name));
|
|
202
|
+
const whereClause = childColQuoted.map(c => `${c} = ?`).join(' AND ');
|
|
203
|
+
const schemaPrefix = childTable.schemaName.toLowerCase() !== 'main'
|
|
204
|
+
? `${quoteIdentifier(childTable.schemaName)}.`
|
|
205
|
+
: '';
|
|
206
|
+
const sql = `select * from ${schemaPrefix}${quoteIdentifier(childTable.name)} where ${whereClause}`;
|
|
207
|
+
log('TRANSITIVE pre-walk: %s with params %o', sql, oldParentValues);
|
|
208
|
+
const stmt = db.prepare(sql);
|
|
209
|
+
try {
|
|
210
|
+
stmt.bindAll(oldParentValues);
|
|
211
|
+
for await (const childOldRow of stmt._iterateRowsRaw()) {
|
|
212
|
+
let childNewRow;
|
|
213
|
+
let childOp;
|
|
214
|
+
if (action === 'cascade' && operation === 'delete') {
|
|
215
|
+
childOp = 'delete';
|
|
216
|
+
childNewRow = undefined;
|
|
217
|
+
}
|
|
218
|
+
else if (action === 'cascade' && operation === 'update' && newParentValues) {
|
|
219
|
+
childOp = 'update';
|
|
220
|
+
const next = [...childOldRow];
|
|
221
|
+
for (let i = 0; i < fk.columns.length; i++) {
|
|
222
|
+
next[fk.columns[i]] = newParentValues[i];
|
|
131
223
|
}
|
|
132
|
-
|
|
133
|
-
continue;
|
|
134
|
-
newParentValues = parentColIndices.map(idx => newRow[idx]);
|
|
224
|
+
childNewRow = next;
|
|
135
225
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
: '';
|
|
142
|
-
const sql = `select * from ${schemaPrefix}${quoteIdentifier(childTable.name)} where ${whereClause}`;
|
|
143
|
-
log('TRANSITIVE pre-walk: %s with params %o', sql, oldParentValues);
|
|
144
|
-
const stmt = db.prepare(sql);
|
|
145
|
-
try {
|
|
146
|
-
stmt.bindAll(oldParentValues);
|
|
147
|
-
for await (const childOldRow of stmt._iterateRowsRaw()) {
|
|
148
|
-
let childNewRow;
|
|
149
|
-
let childOp;
|
|
150
|
-
if (action === 'cascade' && operation === 'delete') {
|
|
151
|
-
childOp = 'delete';
|
|
152
|
-
childNewRow = undefined;
|
|
153
|
-
}
|
|
154
|
-
else if (action === 'cascade' && operation === 'update' && newParentValues) {
|
|
155
|
-
childOp = 'update';
|
|
156
|
-
const next = [...childOldRow];
|
|
157
|
-
for (let i = 0; i < fk.columns.length; i++) {
|
|
158
|
-
next[fk.columns[i]] = newParentValues[i];
|
|
159
|
-
}
|
|
160
|
-
childNewRow = next;
|
|
161
|
-
}
|
|
162
|
-
else if (action === 'setNull') {
|
|
163
|
-
childOp = 'update';
|
|
164
|
-
const next = [...childOldRow];
|
|
165
|
-
for (let i = 0; i < fk.columns.length; i++) {
|
|
166
|
-
next[fk.columns[i]] = null;
|
|
167
|
-
}
|
|
168
|
-
childNewRow = next;
|
|
169
|
-
}
|
|
170
|
-
else if (action === 'setDefault') {
|
|
171
|
-
// SET DEFAULT recursion: pass the child OLD row as both
|
|
172
|
-
// old and new. The recursion's column-change short-circuit
|
|
173
|
-
// will treat this as "no FK column moved" and the per-target
|
|
174
|
-
// cascade SQL (executeSingleFKAction) still fires its own
|
|
175
|
-
// RESTRICT enforcement for non-rowid-chained backends. This
|
|
176
|
-
// matches the coverage gap SET DEFAULT already has in
|
|
177
|
-
// rowid-chained backends — no regression beyond status quo.
|
|
178
|
-
childOp = 'update';
|
|
179
|
-
childNewRow = childOldRow;
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
continue;
|
|
183
|
-
}
|
|
184
|
-
await assertTransitiveRestrictsForParentMutation(db, childTable, childOp, childOldRow, childNewRow, visitedSet);
|
|
226
|
+
else if (action === 'setNull') {
|
|
227
|
+
childOp = 'update';
|
|
228
|
+
const next = [...childOldRow];
|
|
229
|
+
for (let i = 0; i < fk.columns.length; i++) {
|
|
230
|
+
next[fk.columns[i]] = null;
|
|
185
231
|
}
|
|
232
|
+
childNewRow = next;
|
|
186
233
|
}
|
|
187
|
-
|
|
188
|
-
|
|
234
|
+
else if (action === 'setDefault') {
|
|
235
|
+
// SET DEFAULT recursion: pass the child OLD row as both
|
|
236
|
+
// old and new. The recursion's column-change short-circuit
|
|
237
|
+
// will treat this as "no FK column moved" and the per-target
|
|
238
|
+
// cascade SQL (executeSingleFKAction) still fires its own
|
|
239
|
+
// RESTRICT enforcement for non-rowid-chained backends. This
|
|
240
|
+
// matches the coverage gap SET DEFAULT already has in
|
|
241
|
+
// rowid-chained backends — no regression beyond status quo.
|
|
242
|
+
childOp = 'update';
|
|
243
|
+
childNewRow = childOldRow;
|
|
189
244
|
}
|
|
245
|
+
else {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
// Recurse carrying the SAME `lensRouted`: the nested levels are the
|
|
249
|
+
// transitive closure of *this* write, so when the top-level write is
|
|
250
|
+
// lens-routed every level inherits the logical FK semantics. This is
|
|
251
|
+
// load-bearing for a logical RESTRICT sitting below an *agreeing*
|
|
252
|
+
// basis cascade (basis + logical both cascade): at runtime that basis
|
|
253
|
+
// cascade executes as a basis-direct write — which does NOT fire the
|
|
254
|
+
// deeper lens RESTRICT — and the agreeing lens cascade is elided, so it
|
|
255
|
+
// never re-enters through the child view either. The ONLY place that
|
|
256
|
+
// deeper RESTRICT is caught is this pre-walk recursing with the lens flag
|
|
257
|
+
// still set. For a basis-direct top-level write `lensRouted` is already
|
|
258
|
+
// false, so the recursion correctly stays basis-only throughout.
|
|
259
|
+
await assertTransitiveRestrictsForParentMutation(db, childTable, childOp, childOldRow, childNewRow, lensRouted, visitedSet);
|
|
190
260
|
}
|
|
191
261
|
}
|
|
262
|
+
finally {
|
|
263
|
+
await stmt.finalize();
|
|
264
|
+
}
|
|
192
265
|
}
|
|
193
266
|
}
|
|
194
267
|
finally {
|
|
@@ -209,68 +282,77 @@ export async function assertTransitiveRestrictsForParentMutation(db, parentTable
|
|
|
209
282
|
* No-op when `foreign_keys` is off, when no FK references this parent table
|
|
210
283
|
* with action `'restrict'`, when any old referenced value is NULL (MATCH SIMPLE),
|
|
211
284
|
* or — for UPDATE — when no referenced parent column changed.
|
|
285
|
+
*
|
|
286
|
+
* `lensRouted` gates the divergent-basis-FK suppression: only a write through the lens
|
|
287
|
+
* lets a divergent non-RESTRICT logical FK override (suppress) the basis RESTRICT. A
|
|
288
|
+
* basis-direct write (`false`) enforces its physical basis RESTRICT unsuppressed.
|
|
212
289
|
*/
|
|
213
|
-
export async function assertNoRestrictedChildrenForParentMutation(db, parentTable, operation, oldRow, newRow) {
|
|
290
|
+
export async function assertNoRestrictedChildrenForParentMutation(db, parentTable, operation, oldRow, newRow, lensRouted = false) {
|
|
291
|
+
// Trust-the-origin apply path: RESTRICT is enforced by the origin at its own commit,
|
|
292
|
+
// so the receiver skips it (gating cascade-action propagation is intentionally NOT here).
|
|
293
|
+
if (db._isFkRestrictSuppressed())
|
|
294
|
+
return;
|
|
214
295
|
if (!db.options.getBooleanOption('foreign_keys'))
|
|
215
296
|
return;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
for
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
continue;
|
|
245
|
-
}
|
|
246
|
-
// MATCH SIMPLE: NULL parent values cannot be referenced.
|
|
247
|
-
const oldParentValues = parentColIndices.map(idx => oldRow[idx]);
|
|
248
|
-
if (oldParentValues.some(v => v === null || v === undefined))
|
|
249
|
-
continue;
|
|
250
|
-
const childColNames = fk.columns.map(idx => quoteIdentifier(childTable.columns[idx].name));
|
|
251
|
-
const whereClause = childColNames.map(c => `${c} = ?`).join(' AND ');
|
|
252
|
-
const schemaPrefix = childTable.schemaName.toLowerCase() !== 'main'
|
|
253
|
-
? `${quoteIdentifier(childTable.schemaName)}.`
|
|
254
|
-
: '';
|
|
255
|
-
const sql = `select 1 from ${schemaPrefix}${quoteIdentifier(childTable.name)} where ${whereClause} limit 1`;
|
|
256
|
-
log('RESTRICT check (%s): %s with params %o', operation, sql, oldParentValues);
|
|
257
|
-
const stmt = db.prepare(sql);
|
|
258
|
-
try {
|
|
259
|
-
stmt.bindAll(oldParentValues);
|
|
260
|
-
let referenced = false;
|
|
261
|
-
for await (const _row of stmt._iterateRowsRaw()) {
|
|
262
|
-
referenced = true;
|
|
263
|
-
break;
|
|
264
|
-
}
|
|
265
|
-
if (referenced) {
|
|
266
|
-
const opName = operation === 'delete' ? 'DELETE' : 'UPDATE';
|
|
267
|
-
throw new QuereusError(`FOREIGN KEY constraint failed: ${opName} on '${parentTable.name}' violates RESTRICT from '${childTable.name}'`, StatusCode.CONSTRAINT);
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
finally {
|
|
271
|
-
await stmt.finalize();
|
|
297
|
+
// Basis RESTRICT FKs a divergent non-RESTRICT logical FK overrides — their RESTRICT
|
|
298
|
+
// pre-check is suppressed so the parent mutation a logical cascade must complete is
|
|
299
|
+
// not aborted. ONLY for a lens-routed write: a basis-direct write bears no logical FK
|
|
300
|
+
// semantics, so its physical basis RESTRICT must stand unsuppressed. Cheap-empty otherwise.
|
|
301
|
+
const suppressed = lensRouted
|
|
302
|
+
? basisFksOverriddenByDivergentLensFk(parentTable, operation, db.schemaManager)
|
|
303
|
+
: new Set();
|
|
304
|
+
// The reverse FK index is keyed on the referenced schema.table, so the two discovery
|
|
305
|
+
// filters (referencedTable / targetSchema match) are satisfied by the lookup and drop
|
|
306
|
+
// out; the per-FK body below is unchanged.
|
|
307
|
+
for (const { childTable, fk } of db.schemaManager.getReferencingForeignKeys(parentTable.schemaName, parentTable.name)) {
|
|
308
|
+
const action = operation === 'delete' ? fk.onDelete : fk.onUpdate;
|
|
309
|
+
if (action !== 'restrict')
|
|
310
|
+
continue;
|
|
311
|
+
// Suppressed: a divergent non-RESTRICT logical FK over the same columns
|
|
312
|
+
// replaces this basis RESTRICT (the logical cascade must run, not abort).
|
|
313
|
+
if (suppressed.has(fk))
|
|
314
|
+
continue;
|
|
315
|
+
const parentColIndices = resolveReferencedColumns(fk, parentTable);
|
|
316
|
+
if (parentColIndices.length !== fk.columns.length)
|
|
317
|
+
continue;
|
|
318
|
+
// UPDATE: only enforce when at least one referenced parent column changed.
|
|
319
|
+
if (operation === 'update' && newRow !== undefined) {
|
|
320
|
+
let anyChanged = false;
|
|
321
|
+
for (const idx of parentColIndices) {
|
|
322
|
+
if (!sqlValuesEqual(oldRow[idx], newRow[idx])) {
|
|
323
|
+
anyChanged = true;
|
|
324
|
+
break;
|
|
272
325
|
}
|
|
273
326
|
}
|
|
327
|
+
if (!anyChanged)
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
// MATCH SIMPLE: NULL parent values cannot be referenced.
|
|
331
|
+
const oldParentValues = parentColIndices.map(idx => oldRow[idx]);
|
|
332
|
+
if (oldParentValues.some(v => v === null || v === undefined))
|
|
333
|
+
continue;
|
|
334
|
+
const childColNames = fk.columns.map(idx => quoteIdentifier(childTable.columns[idx].name));
|
|
335
|
+
const whereClause = childColNames.map(c => `${c} = ?`).join(' AND ');
|
|
336
|
+
const schemaPrefix = childTable.schemaName.toLowerCase() !== 'main'
|
|
337
|
+
? `${quoteIdentifier(childTable.schemaName)}.`
|
|
338
|
+
: '';
|
|
339
|
+
const sql = `select 1 from ${schemaPrefix}${quoteIdentifier(childTable.name)} where ${whereClause} limit 1`;
|
|
340
|
+
log('RESTRICT check (%s): %s with params %o', operation, sql, oldParentValues);
|
|
341
|
+
const stmt = db.prepare(sql);
|
|
342
|
+
try {
|
|
343
|
+
stmt.bindAll(oldParentValues);
|
|
344
|
+
let referenced = false;
|
|
345
|
+
for await (const _row of stmt._iterateRowsRaw()) {
|
|
346
|
+
referenced = true;
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
if (referenced) {
|
|
350
|
+
const opName = operation === 'delete' ? 'DELETE' : 'UPDATE';
|
|
351
|
+
throw new QuereusError(`FOREIGN KEY constraint failed: ${opName} on '${parentTable.name}' violates RESTRICT from '${childTable.name}'`, StatusCode.CONSTRAINT);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
finally {
|
|
355
|
+
await stmt.finalize();
|
|
274
356
|
}
|
|
275
357
|
}
|
|
276
358
|
}
|
|
@@ -328,4 +410,330 @@ async function executeSingleFKAction(db, childTable, fk, action, parentTable, pa
|
|
|
328
410
|
}
|
|
329
411
|
}
|
|
330
412
|
}
|
|
413
|
+
// ---------------------------------------------------------------------------
|
|
414
|
+
// Lens cascade walker — the logical dual of executeForeignKeyActions.
|
|
415
|
+
//
|
|
416
|
+
// A logical FK lives only on a child lens slot's `enforced-fk` obligation (on no
|
|
417
|
+
// basis table), so executeForeignKeyActions — which scans declared
|
|
418
|
+
// `TableSchema.foreignKeys` — never sees it. When a lens-backed logical *parent* is
|
|
419
|
+
// deleted / re-keyed, the basis op runs but no logical cascade fires. This walker is
|
|
420
|
+
// fired (via executeForeignKeyActionsAndLens) right after each basis row write: it
|
|
421
|
+
// reverse-maps the basis parent table to the logical parent slot(s) it backs,
|
|
422
|
+
// discovers the referencing logical FKs, and — for the non-RESTRICT actions
|
|
423
|
+
// (cascade / set-null / set-default) — issues the propagating DML against the logical
|
|
424
|
+
// child *view*. Issuing against the view (not the basis child) re-enters the full
|
|
425
|
+
// lens write path, so the child's own constraints + any nested logical cascade fire,
|
|
426
|
+
// exactly as a user-issued `delete from x.child` would. Recursion + termination work
|
|
427
|
+
// identically to executeSingleFKAction's SQL-issuing path: each cascade is a real
|
|
428
|
+
// nested statement and a cycle terminates by data exhaustion.
|
|
429
|
+
// ---------------------------------------------------------------------------
|
|
430
|
+
/**
|
|
431
|
+
* Propagates the non-RESTRICT parent-side actions (cascade / set-null / set-default)
|
|
432
|
+
* of a *logical* FK through the lens when a lens-backed logical parent is deleted or
|
|
433
|
+
* updated. The logical dual of {@link executeForeignKeyActions}.
|
|
434
|
+
*
|
|
435
|
+
* No-op (early return) when `foreign_keys` is off, or when the O(1)
|
|
436
|
+
* `SchemaManager.basisTableBacksLogicalParentFk` gate says `basisParentTable` backs no
|
|
437
|
+
* logical-FK-referenced parent slot — so non-lens DML pays one `Set.has`, not a scan
|
|
438
|
+
* over the lens slots. On a gate hit the reverse-map slot scan below is the
|
|
439
|
+
* confirmation: it walks every lens slot whose single basis spine is `basisParentTable`
|
|
440
|
+
* (a multi-source / decomposition parent resolves to no single spine and never matches,
|
|
441
|
+
* consistent with the gate's omission).
|
|
442
|
+
*/
|
|
443
|
+
export async function executeLensForeignKeyActions(db, basisParentTable, operation, oldRow, newRow) {
|
|
444
|
+
if (!db.options.getBooleanOption('foreign_keys'))
|
|
445
|
+
return;
|
|
446
|
+
const sm = db.schemaManager;
|
|
447
|
+
// O(1) gate: nothing below can match when this basis table backs no logical-FK
|
|
448
|
+
// parent slot — skip the slot scan entirely (the common non-lens / no-logical-FK case).
|
|
449
|
+
if (!sm.basisTableBacksLogicalParentFk(basisParentTable.schemaName, basisParentTable.name))
|
|
450
|
+
return;
|
|
451
|
+
const basisNameLower = basisParentTable.name.toLowerCase();
|
|
452
|
+
const basisSchemaLower = basisParentTable.schemaName.toLowerCase();
|
|
453
|
+
// Reverse-map basis → logical parent slots: every lens slot whose single basis
|
|
454
|
+
// spine is `basisParentTable` (usually 0 or 1). A multi-source / decomposition
|
|
455
|
+
// parent resolves to no single spine and never matches (documented boundary).
|
|
456
|
+
for (const schema of sm._getAllSchemas()) {
|
|
457
|
+
for (const parentSlot of schema.getAllLensSlots()) {
|
|
458
|
+
const basis = resolveSlotBasisSource(parentSlot, sm);
|
|
459
|
+
if (!basis)
|
|
460
|
+
continue;
|
|
461
|
+
if (basis.name.toLowerCase() !== basisNameLower)
|
|
462
|
+
continue;
|
|
463
|
+
if (basis.schemaName.toLowerCase() !== basisSchemaLower)
|
|
464
|
+
continue;
|
|
465
|
+
await executeLensFkActionsForParentSlot(db, parentSlot, basisParentTable, operation, oldRow, newRow);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Resolves a logical parent FK ref's referenced OLD (and, for UPDATE, NEW) values off the
|
|
471
|
+
* basis parent write row — the extraction + skip logic shared by the lens cascade walker
|
|
472
|
+
* ({@link executeLensFkActionsForParentSlot}) and the lens RESTRICT pre-check
|
|
473
|
+
* ({@link assertLensRestrictsForParentMutation}), factored out so the two paths cannot drift.
|
|
474
|
+
*
|
|
475
|
+
* Maps each logical parent referenced column → its basis column (via `parentMap`) → basis
|
|
476
|
+
* index, and reads the values off `oldRow` / `newRow` by basis index. Returns `undefined`
|
|
477
|
+
* (⇒ skip this ref) when:
|
|
478
|
+
* - a referenced column has no plain basis projection (cannot read its basis value);
|
|
479
|
+
* - MATCH SIMPLE: any OLD referenced value is NULL (participates in no FK match); or
|
|
480
|
+
* - UPDATE: no referenced parent column actually changed (`sqlValuesEqual` short-circuit).
|
|
481
|
+
*/
|
|
482
|
+
function resolveLensFkParentReferencedValues(ref, parentMap, basisParentTable, operation, oldRow, newRow) {
|
|
483
|
+
// Logical referenced column → basis column → basis index. A column with no plain basis
|
|
484
|
+
// projection disqualifies the ref (cannot read its basis value).
|
|
485
|
+
const basisIndices = [];
|
|
486
|
+
for (const logicalCol of ref.parentLogicalColumns) {
|
|
487
|
+
const basisColName = parentMap.get(logicalCol.toLowerCase());
|
|
488
|
+
const basisIdx = basisColName !== undefined
|
|
489
|
+
? basisParentTable.columnIndexMap.get(basisColName.toLowerCase())
|
|
490
|
+
: undefined;
|
|
491
|
+
if (basisIdx === undefined)
|
|
492
|
+
return undefined;
|
|
493
|
+
basisIndices.push(basisIdx);
|
|
494
|
+
}
|
|
495
|
+
// MATCH SIMPLE: a NULL referenced value participates in no FK match.
|
|
496
|
+
const oldParentValues = basisIndices.map(i => oldRow[i]);
|
|
497
|
+
if (oldParentValues.some(v => v === null || v === undefined))
|
|
498
|
+
return undefined;
|
|
499
|
+
// UPDATE short-circuit: skip when no referenced parent column actually changed.
|
|
500
|
+
let newParentValues;
|
|
501
|
+
if (operation === 'update' && newRow !== undefined) {
|
|
502
|
+
let anyChanged = false;
|
|
503
|
+
for (const i of basisIndices) {
|
|
504
|
+
if (!sqlValuesEqual(oldRow[i], newRow[i])) {
|
|
505
|
+
anyChanged = true;
|
|
506
|
+
break;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
if (!anyChanged)
|
|
510
|
+
return undefined;
|
|
511
|
+
newParentValues = basisIndices.map(i => newRow[i]);
|
|
512
|
+
}
|
|
513
|
+
return { oldParentValues, newParentValues };
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Fires the logical cascade for one logical parent slot backed by `basisParentTable`.
|
|
517
|
+
* For each referencing logical FK with a non-RESTRICT op-action it: elides when an
|
|
518
|
+
* equivalent basis FK with an **agreeing** op-action already propagates over the basis
|
|
519
|
+
* (a divergent basis action is instead suppressed and the logical action wins — see
|
|
520
|
+
* {@link basisFksOverriddenByDivergentLensFk}), applies MATCH SIMPLE + the UPDATE
|
|
521
|
+
* referenced-column-change short-circuit, and issues the logical-child DML.
|
|
522
|
+
*/
|
|
523
|
+
async function executeLensFkActionsForParentSlot(db, parentSlot, basisParentTable, operation, oldRow, newRow) {
|
|
524
|
+
const sm = db.schemaManager;
|
|
525
|
+
const refs = findLogicalParentFkRefs(parentSlot, sm);
|
|
526
|
+
if (refs.length === 0)
|
|
527
|
+
return;
|
|
528
|
+
// Maps each logical parent referenced column → its basis column, so the OLD/NEW
|
|
529
|
+
// referenced values can be read off the basis write row by basis index.
|
|
530
|
+
const parentMap = logicalToBasisColumnMap(parentSlot);
|
|
531
|
+
for (const ref of refs) {
|
|
532
|
+
const { fk } = ref;
|
|
533
|
+
const rawAction = operation === 'delete' ? fk.onDelete : fk.onUpdate;
|
|
534
|
+
if (rawAction !== 'cascade' && rawAction !== 'setNull' && rawAction !== 'setDefault')
|
|
535
|
+
continue;
|
|
536
|
+
const action = rawAction;
|
|
537
|
+
// Action-aware elision (compose with the physical walker): elide the lens cascade
|
|
538
|
+
// only when an equivalent basis FK exists whose op-action AGREES with the logical
|
|
539
|
+
// action — then the physical executeForeignKeyActions already propagates the same
|
|
540
|
+
// action over the basis (and the logical view reflects it), so firing on top would
|
|
541
|
+
// double-mutate. When the matches DIVERGE (e.g. logical set-null over basis cascade,
|
|
542
|
+
// or logical cascade over basis restrict) the logical action wins: the basis FK is
|
|
543
|
+
// suppressed at every enforcement site (basisFksOverriddenByDivergentLensFk) and the
|
|
544
|
+
// lens cascade fires here. With no match the basis enforces nothing ⇒ fire. The two
|
|
545
|
+
// halves are exact complements in the single-equivalent-basis-FK case (one action).
|
|
546
|
+
const matches = matchingBasisFksForLensRef(ref, parentSlot, basisParentTable, sm);
|
|
547
|
+
const agree = matches.length > 0
|
|
548
|
+
&& matches.every(m => (operation === 'delete' ? m.onDelete : m.onUpdate) === action);
|
|
549
|
+
if (agree) {
|
|
550
|
+
log('lens cascade %s on %s: elided — basis child carries an AGREEING equivalent FK (the physical walker propagates over the basis)', fk.name ?? '<anon>', parentSlot.logicalTable.name);
|
|
551
|
+
continue;
|
|
552
|
+
}
|
|
553
|
+
// Read the parent's referenced OLD (and NEW) values off the basis row, applying the
|
|
554
|
+
// shared MATCH SIMPLE + UPDATE referenced-column-change skip rules. `undefined` ⇒
|
|
555
|
+
// skip this ref (unmappable column, NULL referenced value, or no key change).
|
|
556
|
+
const values = resolveLensFkParentReferencedValues(ref, parentMap, basisParentTable, operation, oldRow, newRow);
|
|
557
|
+
if (!values)
|
|
558
|
+
continue;
|
|
559
|
+
await issueLensFkAction(db, ref, action, operation, values.oldParentValues, values.newParentValues);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Issues the propagating DML against the logical child *view* — the logical dual of
|
|
564
|
+
* {@link executeSingleFKAction}. Uses the logical child schema / table / column names
|
|
565
|
+
* and binds the OLD parent values (and NEW for cascade-update) as parameters (never
|
|
566
|
+
* inlined). The default for SET DEFAULT is the **logical** child column's
|
|
567
|
+
* `defaultValue` AST (stringified), or NULL when none. Because the target is the
|
|
568
|
+
* registered logical view, the DML re-enters the lens write path and its own
|
|
569
|
+
* constraints + nested cascades fire.
|
|
570
|
+
*/
|
|
571
|
+
async function issueLensFkAction(db, ref, action, operation, oldParentValues, newParentValues) {
|
|
572
|
+
const childTable = ref.childSlot.logicalTable;
|
|
573
|
+
const childLogicalColumns = ref.childLogicalColumns;
|
|
574
|
+
const schemaPrefix = childTable.schemaName.toLowerCase() !== 'main'
|
|
575
|
+
? `${quoteIdentifier(childTable.schemaName)}.`
|
|
576
|
+
: '';
|
|
577
|
+
const qualifiedChild = `${schemaPrefix}${quoteIdentifier(childTable.name)}`;
|
|
578
|
+
const whereClause = childLogicalColumns.map(c => `${quoteIdentifier(c)} = ?`).join(' and ');
|
|
579
|
+
switch (action) {
|
|
580
|
+
case 'cascade': {
|
|
581
|
+
if (operation === 'delete') {
|
|
582
|
+
const sql = `delete from ${qualifiedChild} where ${whereClause}`;
|
|
583
|
+
log('LENS CASCADE DELETE: %s with params %o', sql, oldParentValues);
|
|
584
|
+
await db._execWithinTransaction(sql, oldParentValues);
|
|
585
|
+
}
|
|
586
|
+
else {
|
|
587
|
+
// CASCADE UPDATE: rewrite the child FK columns to the NEW parent values
|
|
588
|
+
// (SET) for rows that still reference the OLD values (WHERE).
|
|
589
|
+
const setClauses = childLogicalColumns.map(c => `${quoteIdentifier(c)} = ?`).join(', ');
|
|
590
|
+
const sql = `update ${qualifiedChild} set ${setClauses} where ${whereClause}`;
|
|
591
|
+
const params = [...(newParentValues ?? []), ...oldParentValues];
|
|
592
|
+
log('LENS CASCADE UPDATE: %s with params %o', sql, params);
|
|
593
|
+
await db._execWithinTransaction(sql, params);
|
|
594
|
+
}
|
|
595
|
+
break;
|
|
596
|
+
}
|
|
597
|
+
case 'setNull': {
|
|
598
|
+
const setClauses = childLogicalColumns.map(c => `${quoteIdentifier(c)} = null`).join(', ');
|
|
599
|
+
const sql = `update ${qualifiedChild} set ${setClauses} where ${whereClause}`;
|
|
600
|
+
log('LENS SET NULL: %s with params %o', sql, oldParentValues);
|
|
601
|
+
await db._execWithinTransaction(sql, oldParentValues);
|
|
602
|
+
break;
|
|
603
|
+
}
|
|
604
|
+
case 'setDefault': {
|
|
605
|
+
const setClauses = childLogicalColumns.map((c, i) => {
|
|
606
|
+
const defaultVal = childTable.columns[ref.fk.columns[i]]?.defaultValue;
|
|
607
|
+
if (defaultVal === null || defaultVal === undefined)
|
|
608
|
+
return `${quoteIdentifier(c)} = null`;
|
|
609
|
+
// The logical child column's default AST, stringified (parametrizing it is
|
|
610
|
+
// unnecessary — a default is a constant expression).
|
|
611
|
+
return `${quoteIdentifier(c)} = (${expressionToString(defaultVal)})`;
|
|
612
|
+
}).join(', ');
|
|
613
|
+
const sql = `update ${qualifiedChild} set ${setClauses} where ${whereClause}`;
|
|
614
|
+
log('LENS SET DEFAULT: %s with params %o', sql, oldParentValues);
|
|
615
|
+
await db._execWithinTransaction(sql, oldParentValues);
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
// ---------------------------------------------------------------------------
|
|
621
|
+
// Lens RESTRICT pre-check — the logical dual of assertNoRestrictedChildrenForParentMutation.
|
|
622
|
+
//
|
|
623
|
+
// A *logical* FK with a RESTRICT op-action over a *non-restrict basis* FK (or no basis FK)
|
|
624
|
+
// cannot be enforced by the deferred plan-time `NOT EXISTS` the collector retains: a
|
|
625
|
+
// same-statement basis CASCADE / SET NULL / SET DEFAULT mutates the basis children
|
|
626
|
+
// mid-statement, so the deferred check would observe the *post-cascade* state and pass.
|
|
627
|
+
// Mirroring the physical RESTRICT pre-check, this scan is fired BEFORE the basis op (it
|
|
628
|
+
// rides assertTransitiveRestrictsForParentMutation, which the DML executor invokes before
|
|
629
|
+
// vtab.update), so it observes the *pre-cascade* child state and rejects the mutation.
|
|
630
|
+
//
|
|
631
|
+
// Keyed off the *logical* FK action (the physical pre-check is keyed off the basis action
|
|
632
|
+
// and scans declared TableSchema.foreignKeys, so it never sees a logical-only FK). The scan
|
|
633
|
+
// is direct (non-recursive); transitivity rides the enclosing basis transitive walk.
|
|
634
|
+
// ---------------------------------------------------------------------------
|
|
635
|
+
/**
|
|
636
|
+
* Backend-agnostic RESTRICT pre-check for a *logical* parent-side FK, the logical dual of
|
|
637
|
+
* {@link assertNoRestrictedChildrenForParentMutation}. Fired by the runtime DML executor
|
|
638
|
+
* (via {@link assertTransitiveRestrictsForParentMutation}) BEFORE the basis parent DELETE /
|
|
639
|
+
* UPDATE hits the vtab, so it observes the pre-cascade child state — the timing a deferred
|
|
640
|
+
* `NOT EXISTS` cannot achieve against a same-statement basis cascade.
|
|
641
|
+
*
|
|
642
|
+
* No-op (early return) when `foreign_keys` is off, or when the O(1)
|
|
643
|
+
* `SchemaManager.basisTableBacksLogicalParentFk` gate says `basisParentTable` backs no
|
|
644
|
+
* logical-FK-referenced parent slot — so non-lens DML pays one `Set.has`, not a scan over
|
|
645
|
+
* the lens slots. On a gate hit the reverse-map slot scan below confirms; the
|
|
646
|
+
* single-source-spine boundary is identical to the cascade walker's
|
|
647
|
+
* ({@link executeLensForeignKeyActions}).
|
|
648
|
+
*/
|
|
649
|
+
export async function assertLensRestrictsForParentMutation(db, basisParentTable, operation, oldRow, newRow) {
|
|
650
|
+
// Trust-the-origin apply path: RESTRICT is enforced by the origin at its own commit,
|
|
651
|
+
// so the receiver skips it (gating cascade-action propagation is intentionally NOT here).
|
|
652
|
+
if (db._isFkRestrictSuppressed())
|
|
653
|
+
return;
|
|
654
|
+
if (!db.options.getBooleanOption('foreign_keys'))
|
|
655
|
+
return;
|
|
656
|
+
const sm = db.schemaManager;
|
|
657
|
+
// O(1) gate: nothing below can match when this basis table backs no logical-FK
|
|
658
|
+
// parent slot — skip the slot scan entirely (the common non-lens / no-logical-FK case).
|
|
659
|
+
if (!sm.basisTableBacksLogicalParentFk(basisParentTable.schemaName, basisParentTable.name))
|
|
660
|
+
return;
|
|
661
|
+
const basisNameLower = basisParentTable.name.toLowerCase();
|
|
662
|
+
const basisSchemaLower = basisParentTable.schemaName.toLowerCase();
|
|
663
|
+
// Reverse-map basis → logical parent slots: every lens slot whose single basis spine is
|
|
664
|
+
// `basisParentTable` (usually 0 or 1). A multi-source / decomposition parent resolves to
|
|
665
|
+
// no single spine and never matches (the documented boundary).
|
|
666
|
+
for (const schema of sm._getAllSchemas()) {
|
|
667
|
+
for (const parentSlot of schema.getAllLensSlots()) {
|
|
668
|
+
const basis = resolveSlotBasisSource(parentSlot, sm);
|
|
669
|
+
if (!basis)
|
|
670
|
+
continue;
|
|
671
|
+
if (basis.name.toLowerCase() !== basisNameLower)
|
|
672
|
+
continue;
|
|
673
|
+
if (basis.schemaName.toLowerCase() !== basisSchemaLower)
|
|
674
|
+
continue;
|
|
675
|
+
await assertLensRestrictsForParentSlot(db, parentSlot, basisParentTable, operation, oldRow, newRow);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Enforces the RESTRICT logical FKs referencing one logical parent slot backed by
|
|
681
|
+
* `basisParentTable`. For each referencing logical FK with a RESTRICT op-action it reads the
|
|
682
|
+
* parent's referenced OLD values off the basis write row (shared
|
|
683
|
+
* {@link resolveLensFkParentReferencedValues} — MATCH SIMPLE + UPDATE short-circuit) and
|
|
684
|
+
* scans the logical child view for a surviving reference, throwing on a match.
|
|
685
|
+
*/
|
|
686
|
+
async function assertLensRestrictsForParentSlot(db, parentSlot, basisParentTable, operation, oldRow, newRow) {
|
|
687
|
+
const sm = db.schemaManager;
|
|
688
|
+
const refs = findLogicalParentFkRefs(parentSlot, sm);
|
|
689
|
+
if (refs.length === 0)
|
|
690
|
+
return;
|
|
691
|
+
// Maps each logical parent referenced column → its basis column, so the OLD referenced
|
|
692
|
+
// values can be read off the basis write row by basis index.
|
|
693
|
+
const parentMap = logicalToBasisColumnMap(parentSlot);
|
|
694
|
+
for (const ref of refs) {
|
|
695
|
+
const { fk } = ref;
|
|
696
|
+
const action = operation === 'delete' ? fk.onDelete : fk.onUpdate;
|
|
697
|
+
// Only RESTRICT is enforced here — the non-RESTRICT actions are *propagated* by the
|
|
698
|
+
// cascade walker (executeLensForeignKeyActions), not rejected.
|
|
699
|
+
if (action !== 'restrict')
|
|
700
|
+
continue;
|
|
701
|
+
const values = resolveLensFkParentReferencedValues(ref, parentMap, basisParentTable, operation, oldRow, newRow);
|
|
702
|
+
if (!values)
|
|
703
|
+
continue;
|
|
704
|
+
await assertNoLensChildReferences(db, ref, parentSlot, operation, values.oldParentValues);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Scans the logical child *view* (schema-qualified, logical column names — exactly what
|
|
709
|
+
* {@link issueLensFkAction} reads) for a row still referencing the OLD parent values, and
|
|
710
|
+
* throws a RESTRICT {@link QuereusError} (message parallel to the physical pre-check's,
|
|
711
|
+
* matcher-compatible with `/constraint|foreign|fk/i`) when one survives.
|
|
712
|
+
*/
|
|
713
|
+
async function assertNoLensChildReferences(db, ref, parentSlot, operation, oldParentValues) {
|
|
714
|
+
const childTable = ref.childSlot.logicalTable;
|
|
715
|
+
const schemaPrefix = childTable.schemaName.toLowerCase() !== 'main'
|
|
716
|
+
? `${quoteIdentifier(childTable.schemaName)}.`
|
|
717
|
+
: '';
|
|
718
|
+
const qualifiedChild = `${schemaPrefix}${quoteIdentifier(childTable.name)}`;
|
|
719
|
+
const whereClause = ref.childLogicalColumns.map(c => `${quoteIdentifier(c)} = ?`).join(' and ');
|
|
720
|
+
const sql = `select 1 from ${qualifiedChild} where ${whereClause} limit 1`;
|
|
721
|
+
log('LENS RESTRICT check (%s): %s with params %o', operation, sql, oldParentValues);
|
|
722
|
+
const stmt = db.prepare(sql);
|
|
723
|
+
try {
|
|
724
|
+
stmt.bindAll(oldParentValues);
|
|
725
|
+
let referenced = false;
|
|
726
|
+
for await (const _row of stmt._iterateRowsRaw()) {
|
|
727
|
+
referenced = true;
|
|
728
|
+
break;
|
|
729
|
+
}
|
|
730
|
+
if (referenced) {
|
|
731
|
+
const opName = operation === 'delete' ? 'DELETE' : 'UPDATE';
|
|
732
|
+
throw new QuereusError(`FOREIGN KEY constraint failed: ${opName} on '${parentSlot.logicalTable.name}' violates RESTRICT from '${childTable.name}'`, StatusCode.CONSTRAINT);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
finally {
|
|
736
|
+
await stmt.finalize();
|
|
737
|
+
}
|
|
738
|
+
}
|
|
331
739
|
//# sourceMappingURL=foreign-key-actions.js.map
|