@quereus/quereus 3.2.1 → 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 -106
- 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 +795 -120
- 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 +277 -8
- package/dist/src/parser/parser.d.ts.map +1 -1
- package/dist/src/parser/parser.js +1393 -471
- 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/binding-extractor.d.ts.map +1 -1
- package/dist/src/planner/analysis/binding-extractor.js +9 -6
- package/dist/src/planner/analysis/binding-extractor.js.map +1 -1
- 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 +115 -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 +13 -1
- package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.js +220 -21
- 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 +116 -34
- 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 +51 -13
- 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/physical-utils.d.ts.map +1 -1
- package/dist/src/planner/framework/physical-utils.js +7 -1
- package/dist/src/planner/framework/physical-utils.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.d.ts +6 -4
- package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/aggregate-node.js +11 -9
- 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 +21 -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/hash-aggregate.d.ts.map +1 -1
- package/dist/src/planner/nodes/hash-aggregate.js +6 -16
- package/dist/src/planner/nodes/hash-aggregate.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 +131 -10
- 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 +12 -0
- package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
- package/dist/src/planner/nodes/limit-offset.js +52 -3
- 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 +103 -16
- 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 +63 -30
- 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 +302 -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 +8 -7
- package/dist/src/planner/nodes/sort.js.map +1 -1
- package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
- package/dist/src/planner/nodes/stream-aggregate.js +8 -23
- package/dist/src/planner/nodes/stream-aggregate.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 +3 -1
- package/dist/src/planner/nodes/values-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/values-node.js +26 -0
- 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 +3 -3
- 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-aggregate-streaming.d.ts.map +1 -1
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +8 -27
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
- package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts +9 -3
- 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 +56 -5
- 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/distinct/rule-distinct-elimination.d.ts +8 -7
- package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts.map +1 -1
- package/dist/src/planner/rules/distinct/rule-distinct-elimination.js +14 -21
- package/dist/src/planner/rules/distinct/rule-distinct-elimination.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 +42 -5
- 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.js +25 -9
- 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 +19 -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 +14 -2
- 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 +5 -2
- 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 +10 -1
- 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-grow-retrieve.js +2 -2
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.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 +16 -0
- package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts.map +1 -1
- package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js +47 -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/rules/window/rule-monotonic-window.js +1 -1
- package/dist/src/planner/rules/window/rule-monotonic-window.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 +228 -36
- package/dist/src/planner/util/fd-utils.d.ts.map +1 -1
- package/dist/src/planner/util/fd-utils.js +501 -84
- 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 +26 -3
- package/dist/src/planner/util/key-utils.d.ts.map +1 -1
- package/dist/src/planner/util/key-utils.js +182 -33
- 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 +38 -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 +24 -9
- 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 +24 -36
- 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 +12 -4
- package/dist/src/runtime/emit/bloom-join.js.map +1 -1
- package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
- package/dist/src/runtime/emit/constraint-check.js +50 -1
- 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/delete.d.ts.map +1 -1
- package/dist/src/runtime/emit/delete.js +15 -5
- package/dist/src/runtime/emit/delete.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 +19 -5
- 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/types/temporal-types.d.ts.map +1 -1
- package/dist/src/types/temporal-types.js +71 -36
- package/dist/src/types/temporal-types.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
|
@@ -8,8 +8,9 @@ import { createLogger } from '../../common/logger.js';
|
|
|
8
8
|
import { ColumnReferenceNode, ParameterReferenceNode } from '../nodes/reference.js';
|
|
9
9
|
import { BetweenNode, BinaryOpNode, CastNode, CollateNode, LiteralNode, UnaryOpNode } from '../nodes/scalar.js';
|
|
10
10
|
import { InNode } from '../nodes/subquery.js';
|
|
11
|
-
import { compareSqlValues } from '../../util/comparison.js';
|
|
11
|
+
import { compareSqlValues, normalizeCollationName } from '../../util/comparison.js';
|
|
12
12
|
import { flipComparison } from '../analysis/predicate-shape.js';
|
|
13
|
+
import { effectiveBetweenBoundCollation, effectiveComparisonCollation, effectiveInCollation, isValueDiscriminatingEquality, operandCollation } from '../analysis/comparison-collation.js';
|
|
13
14
|
const log = createLogger('planner:fd');
|
|
14
15
|
/**
|
|
15
16
|
* Per-node cap on the number of FDs we materialize. The propagation rules
|
|
@@ -51,6 +52,8 @@ export function computeClosure(attrs, fds) {
|
|
|
51
52
|
* column indices, then concatenate with the existing FDs. For a class
|
|
52
53
|
* `{c0, c1, ..., ck}` this emits `{ci} → {cj}` for every distinct ordered pair
|
|
53
54
|
* — enough for `computeClosure` to derive every member from any one of them.
|
|
55
|
+
* EC-derived FDs are pure value claims (`kind: 'determination'`) — an equality
|
|
56
|
+
* never implies row-uniqueness of either endpoint.
|
|
54
57
|
*/
|
|
55
58
|
export function expandEcsToFds(ecs, fds) {
|
|
56
59
|
const out = fds.slice();
|
|
@@ -61,7 +64,7 @@ export function expandEcsToFds(ecs, fds) {
|
|
|
61
64
|
for (let j = 0; j < cls.length; j++) {
|
|
62
65
|
if (i === j)
|
|
63
66
|
continue;
|
|
64
|
-
out.push({ determinants: [cls[i]], dependents: [cls[j]] });
|
|
67
|
+
out.push({ determinants: [cls[i]], dependents: [cls[j]], kind: 'determination' });
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
70
|
}
|
|
@@ -110,6 +113,9 @@ export function minimalCover(attrs, fds) {
|
|
|
110
113
|
// collapse to one in `addFd` / `mergeFds`. The first-merged source wins —
|
|
111
114
|
// table references merge declared-check contributions before hoisted
|
|
112
115
|
// assertion contributions, so `declared-check` is preferred on collisions.
|
|
116
|
+
// `kind` and `valueEquality` are likewise NOT compared; `addFd` reconciles
|
|
117
|
+
// `kind` on collisions with an "'unique' wins" rule (uniqueness is a property
|
|
118
|
+
// of the determinant set, so equal-determinant claims compose).
|
|
113
119
|
function fdsEqual(a, b) {
|
|
114
120
|
if (a.determinants.length !== b.determinants.length)
|
|
115
121
|
return false;
|
|
@@ -233,33 +239,52 @@ function dependentsSubset(sub, sup) {
|
|
|
233
239
|
* Guard-aware: FDs with different `guard` predicates are kept side-by-side
|
|
234
240
|
* even when their determinants/dependents match — they are logically distinct
|
|
235
241
|
* facts and may be activated by different surrounding predicates.
|
|
242
|
+
*
|
|
243
|
+
* Kind reconciliation: on a merge between entries with equal determinants and
|
|
244
|
+
* guards, the surviving entry's `kind` is `'unique'` when EITHER side claims
|
|
245
|
+
* it — uniqueness is a property of the determinant set, so equal-determinant
|
|
246
|
+
* claims compose. This includes upgrading a kept 'determination' entry in
|
|
247
|
+
* place when the subsumed newcomer is 'unique'. Equal-determinant entries with
|
|
248
|
+
* incomparable dependent sets both survive and each keeps its own kind (a
|
|
249
|
+
* sound under-claim). Object identity is preserved when nothing changes.
|
|
236
250
|
*/
|
|
237
251
|
export function addFd(fds, next, opts = {}) {
|
|
238
252
|
if (next.dependents.length === 0)
|
|
239
253
|
return fds.slice();
|
|
240
254
|
const result = [];
|
|
241
255
|
let subsumedByExisting = false;
|
|
256
|
+
// 'unique' wins on merge: a dropped-or-subsumed 'unique' twin upgrades the survivor.
|
|
257
|
+
let nextKind = next.kind;
|
|
242
258
|
for (const existing of fds) {
|
|
243
259
|
if (fdsEqual(existing, next)) {
|
|
244
260
|
subsumedByExisting = true;
|
|
245
|
-
result.push(existing
|
|
261
|
+
result.push(next.kind === 'unique' && existing.kind !== 'unique'
|
|
262
|
+
? { ...existing, kind: 'unique' }
|
|
263
|
+
: existing);
|
|
246
264
|
continue;
|
|
247
265
|
}
|
|
248
266
|
if (determinantsEqual(existing.determinants, next.determinants) &&
|
|
249
267
|
guardsEqual(existing.guard, next.guard)) {
|
|
250
268
|
// Same determinants and guard: keep whichever has the larger dependent set.
|
|
251
269
|
if (dependentsSubset(existing.dependents, next.dependents)) {
|
|
252
|
-
// existing ⊂ next, drop existing
|
|
270
|
+
// existing ⊂ next, drop existing — its uniqueness claim survives on next.
|
|
271
|
+
if (existing.kind === 'unique')
|
|
272
|
+
nextKind = 'unique';
|
|
253
273
|
continue;
|
|
254
274
|
}
|
|
255
275
|
if (dependentsSubset(next.dependents, existing.dependents)) {
|
|
256
276
|
subsumedByExisting = true;
|
|
277
|
+
result.push(next.kind === 'unique' && existing.kind !== 'unique'
|
|
278
|
+
? { ...existing, kind: 'unique' }
|
|
279
|
+
: existing);
|
|
280
|
+
continue;
|
|
257
281
|
}
|
|
258
282
|
}
|
|
259
283
|
result.push(existing);
|
|
260
284
|
}
|
|
261
|
-
if (!subsumedByExisting)
|
|
262
|
-
result.push(next);
|
|
285
|
+
if (!subsumedByExisting) {
|
|
286
|
+
result.push(nextKind === next.kind ? next : { ...next, kind: nextKind });
|
|
287
|
+
}
|
|
263
288
|
return enforceCap(result, opts);
|
|
264
289
|
}
|
|
265
290
|
function enforceCap(fds, opts) {
|
|
@@ -275,12 +300,19 @@ function enforceCap(fds, opts) {
|
|
|
275
300
|
};
|
|
276
301
|
const preferred = fds.filter(fd => isSubsetOfAnyKey(fd.determinants));
|
|
277
302
|
const other = fds.filter(fd => !isSubsetOfAnyKey(fd.determinants));
|
|
303
|
+
// Quality bias within each partition: keep 'unique' FDs ahead of plain
|
|
304
|
+
// determinations. Evicting a uniqueness witness can only cause downstream
|
|
305
|
+
// under-claims (sound), but it is cheap to avoid.
|
|
306
|
+
const uniqueFirst = (list) => [
|
|
307
|
+
...list.filter(fd => fd.kind === 'unique'),
|
|
308
|
+
...list.filter(fd => fd.kind !== 'unique'),
|
|
309
|
+
];
|
|
278
310
|
let kept;
|
|
279
311
|
if (preferred.length >= cap) {
|
|
280
|
-
kept = preferred.slice(0, cap);
|
|
312
|
+
kept = uniqueFirst(preferred).slice(0, cap);
|
|
281
313
|
}
|
|
282
314
|
else {
|
|
283
|
-
kept = preferred.concat(other.slice(0, cap - preferred.length));
|
|
315
|
+
kept = preferred.concat(uniqueFirst(other).slice(0, cap - preferred.length));
|
|
284
316
|
}
|
|
285
317
|
log('FD cap reached: dropped %d FD(s) from %d', fds.length - kept.length, fds.length);
|
|
286
318
|
return kept;
|
|
@@ -307,6 +339,14 @@ export function mergeFds(a, b, opts = {}) {
|
|
|
307
339
|
* Guarded FDs additionally require every column referenced in `guard.clauses`
|
|
308
340
|
* to be in the mapping — if any guard column is dropped the guard becomes
|
|
309
341
|
* unobservable and the FD can never be re-activated downstream.
|
|
342
|
+
*
|
|
343
|
+
* Rebuilds via spread so `kind` / `source` / `valueEquality` survive verbatim.
|
|
344
|
+
* Preserving `kind` is sound: a projection maps rows 1:1 (no merge, no
|
|
345
|
+
* duplication), so determinant row-uniqueness survives whenever the
|
|
346
|
+
* determinants survive — which the determinant-loss drop above already
|
|
347
|
+
* requires. The empty-determinant exception keeps its kind too: a 'unique'
|
|
348
|
+
* singleton stays ≤1-row under projection; a 'determination' constant pin
|
|
349
|
+
* stays a mere pin.
|
|
310
350
|
*/
|
|
311
351
|
export function projectFds(fds, mapping) {
|
|
312
352
|
const result = [];
|
|
@@ -339,8 +379,8 @@ export function projectFds(fds, mapping) {
|
|
|
339
379
|
newGuard = mappedGuard;
|
|
340
380
|
}
|
|
341
381
|
result.push(newGuard
|
|
342
|
-
? { determinants: newDet, dependents: newDep, guard: newGuard }
|
|
343
|
-
: { determinants: newDet, dependents: newDep });
|
|
382
|
+
? { ...fd, determinants: newDet, dependents: newDep, guard: newGuard }
|
|
383
|
+
: { ...fd, determinants: newDet, dependents: newDep });
|
|
344
384
|
}
|
|
345
385
|
return result;
|
|
346
386
|
}
|
|
@@ -395,12 +435,18 @@ function projectClause(clause, mapping) {
|
|
|
395
435
|
}
|
|
396
436
|
}
|
|
397
437
|
}
|
|
398
|
-
/**
|
|
438
|
+
/**
|
|
439
|
+
* Shift all column indices in `fds` (including any `guard` columns) by `offset`.
|
|
440
|
+
* Rebuilds via spread so `kind` / `source` / `valueEquality` survive verbatim —
|
|
441
|
+
* a shift is a pure column relabel, so every claim (uniqueness included) holds
|
|
442
|
+
* unchanged on the relabeled columns.
|
|
443
|
+
*/
|
|
399
444
|
export function shiftFds(fds, offset) {
|
|
400
445
|
if (offset === 0)
|
|
401
446
|
return fds.slice();
|
|
402
447
|
return fds.map(fd => {
|
|
403
448
|
const shifted = {
|
|
449
|
+
...fd,
|
|
404
450
|
determinants: fd.determinants.map(d => d + offset),
|
|
405
451
|
dependents: fd.dependents.map(d => d + offset),
|
|
406
452
|
};
|
|
@@ -428,14 +474,18 @@ function shiftClause(clause, offset) {
|
|
|
428
474
|
}
|
|
429
475
|
}
|
|
430
476
|
/**
|
|
431
|
-
* Return the unconditional twin of `fd` — drop the guard but keep
|
|
432
|
-
*
|
|
433
|
-
* entails the guard.
|
|
477
|
+
* Return the unconditional twin of `fd` — drop the guard but keep every other
|
|
478
|
+
* field (`kind` / `source` / `valueEquality` survive verbatim). Used by Filter
|
|
479
|
+
* activation when the surrounding predicate entails the guard. Preserving
|
|
480
|
+
* 'unique' is sound at the activating Filter: its rows all satisfy the guard,
|
|
481
|
+
* and filtering only shrinks the row set — fan-out hazards are handled by the
|
|
482
|
+
* join-side downgrade, not here.
|
|
434
483
|
*/
|
|
435
484
|
export function stripGuard(fd) {
|
|
436
485
|
if (fd.guard === undefined)
|
|
437
486
|
return fd;
|
|
438
|
-
|
|
487
|
+
const { guard: _guard, ...rest } = fd;
|
|
488
|
+
return rest;
|
|
439
489
|
}
|
|
440
490
|
/** Shift all column indices in `classes` by `offset`. */
|
|
441
491
|
export function shiftEquivClasses(classes, offset) {
|
|
@@ -491,6 +541,11 @@ export function addEquivalence(classes, a, b) {
|
|
|
491
541
|
* way to encode "K is a unique key on a relation": K determines every other
|
|
492
542
|
* output column. K = ∅ produces the "at-most-one-row" singleton FD.
|
|
493
543
|
*
|
|
544
|
+
* Emits `kind: 'unique'` — every caller passes a genuine key (declared or
|
|
545
|
+
* projected keys, fan-out-aware join `preservedKeys`, the aggregate group key,
|
|
546
|
+
* the set-op data-columns key, lens key obligations, TVF-declared keys), so
|
|
547
|
+
* the relation has at most one row per determinant tuple at the minting site.
|
|
548
|
+
*
|
|
494
549
|
* Returns undefined when K covers every column (the all-columns case has no
|
|
495
550
|
* non-trivial encoding — that case is communicated via `RelationType.isSet`
|
|
496
551
|
* instead).
|
|
@@ -504,14 +559,19 @@ export function superkeyToFd(key, columnCount) {
|
|
|
504
559
|
}
|
|
505
560
|
if (dependents.length === 0)
|
|
506
561
|
return undefined;
|
|
507
|
-
return { determinants: key.slice(), dependents };
|
|
562
|
+
return { determinants: key.slice(), dependents, kind: 'unique' };
|
|
508
563
|
}
|
|
509
564
|
/**
|
|
510
|
-
* True iff the closure of `attrs` under `fds` covers `{0..columnCount-1}
|
|
511
|
-
*
|
|
512
|
-
*
|
|
565
|
+
* True iff the closure of `attrs` under `fds` covers `{0..columnCount-1}`.
|
|
566
|
+
* COVERAGE ONLY — this is a pure value-determination claim and says NOTHING
|
|
567
|
+
* about row-uniqueness: over a bag, a determination-only closure path can
|
|
568
|
+
* cover every column while the relation still holds duplicate rows. For the
|
|
569
|
+
* uniqueness question ("at most one row per attrs-tuple?") use
|
|
570
|
+
* `isUniqueDeterminant`. (Renamed from `isSuperkey`, whose name read as a
|
|
571
|
+
* uniqueness claim and invited exactly that misuse — ticket
|
|
572
|
+
* `fd-determination-reader-side-rule`.)
|
|
513
573
|
*/
|
|
514
|
-
export function
|
|
574
|
+
export function closureCoversAll(attrs, fds, columnCount) {
|
|
515
575
|
if (columnCount <= 0)
|
|
516
576
|
return true;
|
|
517
577
|
const closure = computeClosure(attrs, fds ?? []);
|
|
@@ -521,16 +581,52 @@ export function isSuperkey(attrs, fds, columnCount) {
|
|
|
521
581
|
}
|
|
522
582
|
return true;
|
|
523
583
|
}
|
|
584
|
+
/**
|
|
585
|
+
* True iff `attrs` is provably row-unique on the relation: its FD closure
|
|
586
|
+
* covers every column AND uniqueness is reachable —
|
|
587
|
+
* - the relation is a set (two rows agreeing on `attrs` would agree on all
|
|
588
|
+
* columns = a duplicate, impossible in a set), or
|
|
589
|
+
* - some unguarded `kind: 'unique'` FD has determinants ⊆ closure(attrs)
|
|
590
|
+
* (rows agreeing on `attrs` agree on that unique determinant set; ≤1 row
|
|
591
|
+
* per its tuple ⇒ ≤1 row per attrs-tuple).
|
|
592
|
+
*
|
|
593
|
+
* Coverage alone (a determination-only closure path over a bag) proves
|
|
594
|
+
* nothing — that is the over-claim family the kind-aware readers exist to
|
|
595
|
+
* prevent (ticket `fd-determination-reader-side-rule`). This is the single
|
|
596
|
+
* reader-side uniqueness primitive; producers no longer gate determinations.
|
|
597
|
+
*
|
|
598
|
+
* Guarded FDs participate in neither branch: `computeClosure` skips them, and
|
|
599
|
+
* only UNguarded 'unique' FDs can witness (a guarded uniqueness claim holds
|
|
600
|
+
* only under its predicate, which this layer cannot see).
|
|
601
|
+
*/
|
|
602
|
+
export function isUniqueDeterminant(attrs, fds, columnCount, isSet) {
|
|
603
|
+
const fdList = fds ?? [];
|
|
604
|
+
const closure = computeClosure(attrs, fdList);
|
|
605
|
+
for (let i = 0; i < columnCount; i++) {
|
|
606
|
+
if (!closure.has(i))
|
|
607
|
+
return false;
|
|
608
|
+
}
|
|
609
|
+
if (isSet)
|
|
610
|
+
return true;
|
|
611
|
+
return fdList.some(fd => fd.guard === undefined &&
|
|
612
|
+
fd.kind === 'unique' &&
|
|
613
|
+
fd.determinants.every(d => closure.has(d)));
|
|
614
|
+
}
|
|
524
615
|
/**
|
|
525
616
|
* Enumerate the minimal full-cover key sets discoverable from `fds`: for each
|
|
526
|
-
* FD `K → Y`
|
|
527
|
-
*
|
|
617
|
+
* FD `K → Y` where `K` is a provably row-unique determinant
|
|
618
|
+
* (`isUniqueDeterminant` — coverage AND uniqueness reachability), return `K`
|
|
619
|
+
* (greedily minimized within `K`). Deduplicated by set equality.
|
|
528
620
|
*
|
|
529
|
-
*
|
|
530
|
-
*
|
|
531
|
-
*
|
|
621
|
+
* `minimalCover` preserves the closure, so the minimized key keeps both
|
|
622
|
+
* coverage and the unique witness (witness determinants ⊆ the unchanged
|
|
623
|
+
* closure).
|
|
624
|
+
*
|
|
625
|
+
* Excludes the trivial "all-columns is a key of a set" tautology — only FDs
|
|
626
|
+
* with `K ⊊ all_cols` are considered, since the all-cols case is encoded via
|
|
627
|
+
* `RelationType.isSet` (the `keysOf` fallback).
|
|
532
628
|
*/
|
|
533
|
-
export function deriveKeysFromFds(fds, columnCount) {
|
|
629
|
+
export function deriveKeysFromFds(fds, columnCount, isSet) {
|
|
534
630
|
if (!fds || fds.length === 0)
|
|
535
631
|
return [];
|
|
536
632
|
const results = [];
|
|
@@ -541,11 +637,9 @@ export function deriveKeysFromFds(fds, columnCount) {
|
|
|
541
637
|
if (fd.determinants.length >= columnCount)
|
|
542
638
|
continue;
|
|
543
639
|
const det = new Set(fd.determinants);
|
|
544
|
-
if (!
|
|
640
|
+
if (!isUniqueDeterminant(det, fds, columnCount, isSet))
|
|
545
641
|
continue;
|
|
546
642
|
const minimal = minimalCover(det, fds);
|
|
547
|
-
// Ensure the minimal cover still covers all columns (it should — minimalCover
|
|
548
|
-
// only drops attrs whose removal doesn't change closure).
|
|
549
643
|
const sorted = Array.from(minimal).sort((a, b) => a - b);
|
|
550
644
|
const key = sorted.join(',');
|
|
551
645
|
if (seen.has(key))
|
|
@@ -557,35 +651,42 @@ export function deriveKeysFromFds(fds, columnCount) {
|
|
|
557
651
|
}
|
|
558
652
|
/**
|
|
559
653
|
* True iff the FD set encodes any non-trivial key — i.e., there exists some
|
|
560
|
-
* FD whose determinants
|
|
561
|
-
*
|
|
562
|
-
* replacement for "the relation has a known unique key smaller
|
|
563
|
-
* column list" (the old `uniqueKeys.length > 0` check),
|
|
564
|
-
* tautological all-columns case which carries no information.
|
|
654
|
+
* FD whose determinants are a provably row-unique determinant set
|
|
655
|
+
* (`isUniqueDeterminant`) strictly smaller than all columns. This is the
|
|
656
|
+
* FD-surface replacement for "the relation has a known unique key smaller
|
|
657
|
+
* than its full column list" (the old `uniqueKeys.length > 0` check),
|
|
658
|
+
* excluding the tautological all-columns case which carries no information.
|
|
565
659
|
*/
|
|
566
|
-
export function hasAnyKey(fds, columnCount) {
|
|
660
|
+
export function hasAnyKey(fds, columnCount, isSet) {
|
|
567
661
|
if (!fds || fds.length === 0)
|
|
568
662
|
return false;
|
|
569
663
|
return fds.some(fd => fd.guard === undefined &&
|
|
570
664
|
fd.determinants.length < columnCount &&
|
|
571
|
-
|
|
665
|
+
isUniqueDeterminant(new Set(fd.determinants), fds, columnCount, isSet));
|
|
572
666
|
}
|
|
573
667
|
/**
|
|
574
|
-
* True iff the relation
|
|
575
|
-
*
|
|
576
|
-
*
|
|
668
|
+
* True iff the relation is provably at-most-one-row from its FD surface —
|
|
669
|
+
* `isUniqueDeterminant(∅, …)`: the closure of the empty set covers every
|
|
670
|
+
* column AND uniqueness is reachable (the relation is a set, or an unguarded
|
|
671
|
+
* 'unique' FD witnesses). Replaces the legacy `[[]]` singleton marker on
|
|
672
|
+
* `uniqueKeys`.
|
|
673
|
+
*
|
|
674
|
+
* On a bag, constant pins (`∅ → col` determinations from `where a = 1`) no
|
|
675
|
+
* longer over-claim ≤1-row; on a set, pinning every column IS a sound ≤1-row
|
|
676
|
+
* derivation. Zero-column relations return false — the `∅ → all_cols` FD is
|
|
677
|
+
* unrepresentable there, so the ≤1-row claim rides `estimatedRows` instead
|
|
678
|
+
* (see `characteristics.guaranteesUniqueRows`).
|
|
577
679
|
*/
|
|
578
|
-
export function hasSingletonFd(fds, columnCount) {
|
|
579
|
-
if (
|
|
680
|
+
export function hasSingletonFd(fds, columnCount, isSet) {
|
|
681
|
+
if (columnCount <= 0)
|
|
580
682
|
return false;
|
|
581
|
-
return
|
|
582
|
-
fd.determinants.length === 0 &&
|
|
583
|
-
isSuperkey(new Set(), fds, columnCount));
|
|
683
|
+
return isUniqueDeterminant(new Set(), fds, columnCount, isSet);
|
|
584
684
|
}
|
|
585
685
|
/**
|
|
586
686
|
* Build the singleton FD `∅ → {0..columnCount-1}` that encodes
|
|
587
|
-
* "at-most-one-row".
|
|
588
|
-
*
|
|
687
|
+
* "at-most-one-row". `kind: 'unique'` — ∅ row-unique ⟺ ≤1 row, which is
|
|
688
|
+
* exactly what every caller asserts. Returns undefined when
|
|
689
|
+
* `columnCount === 0` (no dependents).
|
|
589
690
|
*/
|
|
590
691
|
export function singletonFd(columnCount) {
|
|
591
692
|
if (columnCount <= 0)
|
|
@@ -593,39 +694,159 @@ export function singletonFd(columnCount) {
|
|
|
593
694
|
const dependents = [];
|
|
594
695
|
for (let i = 0; i < columnCount; i++)
|
|
595
696
|
dependents.push(i);
|
|
596
|
-
return { determinants: [], dependents };
|
|
697
|
+
return { determinants: [], dependents, kind: 'unique' };
|
|
597
698
|
}
|
|
598
699
|
/**
|
|
599
|
-
*
|
|
600
|
-
*
|
|
601
|
-
*
|
|
602
|
-
*
|
|
700
|
+
* Fold the singleton FD `∅ → {0..columnCount-1}` ("at-most-one-row") into `fds`
|
|
701
|
+
* via `addFd`. The canonical producer-side spelling of the ≤1-row fact — every
|
|
702
|
+
* `computePhysical` site that proves a relation emits ≤1 row should reach for
|
|
703
|
+
* this rather than open-coding `singletonFd` + `addFd`.
|
|
603
704
|
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
*
|
|
705
|
+
* A no-op returning a copy of `fds` when `columnCount === 0` (since
|
|
706
|
+
* `singletonFd(0)` is `undefined` — a zero-column relation cannot carry the
|
|
707
|
+
* marker). Pairs with the `hasSingletonFd` / `isAtMostOneRow` read surface.
|
|
607
708
|
*/
|
|
608
|
-
export function
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
709
|
+
export function addSingletonFd(fds, columnCount) {
|
|
710
|
+
const singleton = singletonFd(columnCount);
|
|
711
|
+
return singleton ? addFd(fds, singleton) : fds.slice();
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Normalize a list of candidate keys to the minimal, deduped set:
|
|
715
|
+
* - each key is sorted and de-duplicated internally,
|
|
716
|
+
* - duplicate keys collapse,
|
|
717
|
+
* - any key that is a (non-strict) superset of another retained key is
|
|
718
|
+
* dropped — only minimal keys survive.
|
|
719
|
+
*
|
|
720
|
+
* The empty key `[]` (proven ≤1-row) is a subset of every other key, so when
|
|
721
|
+
* present it subsumes them all and is the sole survivor.
|
|
722
|
+
*/
|
|
723
|
+
function normalizeKeys(keys) {
|
|
724
|
+
const sorted = keys.map(k => Array.from(new Set(k)).sort((a, b) => a - b));
|
|
725
|
+
const uniq = [];
|
|
726
|
+
const seen = new Set();
|
|
727
|
+
for (const k of sorted) {
|
|
728
|
+
const sig = k.join(',');
|
|
729
|
+
if (seen.has(sig))
|
|
623
730
|
continue;
|
|
624
|
-
|
|
625
|
-
|
|
731
|
+
seen.add(sig);
|
|
732
|
+
uniq.push(k);
|
|
733
|
+
}
|
|
734
|
+
const result = [];
|
|
735
|
+
for (const k of uniq) {
|
|
736
|
+
const kSet = new Set(k);
|
|
737
|
+
const subsumed = uniq.some(other => other !== k &&
|
|
738
|
+
other.length < k.length &&
|
|
739
|
+
other.every(c => kSet.has(c)));
|
|
740
|
+
if (!subsumed)
|
|
741
|
+
result.push(k);
|
|
742
|
+
}
|
|
743
|
+
return result;
|
|
744
|
+
}
|
|
745
|
+
function allColumns(columnCount) {
|
|
746
|
+
const cols = [];
|
|
747
|
+
for (let i = 0; i < columnCount; i++)
|
|
748
|
+
cols.push(i);
|
|
749
|
+
return cols;
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Canonical minimal candidate keys of a relation, each a sorted readonly
|
|
753
|
+
* `number[]` of output column indices, normalized and deduped. This is the
|
|
754
|
+
* single uniqueness read path — it reconciles all three surfaces a uniqueness
|
|
755
|
+
* fact can live on (declared `RelationType.keys`, the `PhysicalProperties.fds`
|
|
756
|
+
* FD set, and `RelationType.isSet`) so consumers never have to "check all
|
|
757
|
+
* three" by hand.
|
|
758
|
+
*
|
|
759
|
+
* Keys are gathered cheap → expensive:
|
|
760
|
+
* 1. Declared `keys` (mapped to column indices). The empty key `[]`
|
|
761
|
+
* (TableDee / ≤1-row) is preserved as an empty entry and subsumes all.
|
|
762
|
+
* 2. The `∅ → all_cols` FD (`hasSingletonFd`) ⇒ the empty key `[]`.
|
|
763
|
+
* 3. FD-derived keys via `deriveKeysFromFds`.
|
|
764
|
+
* 4. All-columns fallback: if nothing smaller was found AND the relation is
|
|
765
|
+
* a set (`getType().isSet`), the all-columns key `[0..n-1]`.
|
|
766
|
+
*
|
|
767
|
+
* Result is `[]` (no entries) ⟺ the relation is a bag (no provable key).
|
|
768
|
+
*
|
|
769
|
+
* **Enumeration bound (soundness vs completeness):** deriving minimal keys
|
|
770
|
+
* from a general FD set is the candidate-key enumeration problem (NP-hard in
|
|
771
|
+
* column count). We do NOT enumerate column subsets — `deriveKeysFromFds`
|
|
772
|
+
* seeds one candidate per existing FD and minimizes within it, and the
|
|
773
|
+
* declared keys + all-columns fallback are always emitted regardless of
|
|
774
|
+
* FD-enumeration cost. Over-capping here costs **completeness only** (a real
|
|
775
|
+
* key may go unlisted), never **soundness** (a listed key always holds). Use
|
|
776
|
+
* `isUnique` for the soundness-critical "is this set a superkey?" question —
|
|
777
|
+
* it additionally consults FD closure, which can prove a superkey absent from
|
|
778
|
+
* this minimal list.
|
|
779
|
+
*/
|
|
780
|
+
export function keysOf(rel) {
|
|
781
|
+
const type = rel.getType();
|
|
782
|
+
const columnCount = type.columns.length;
|
|
783
|
+
const fds = rel.physical?.fds;
|
|
784
|
+
const keys = [];
|
|
785
|
+
// 1. Declared keys (RelationType.keys). An empty ColRef[] ⇒ the empty key.
|
|
786
|
+
for (const key of type.keys) {
|
|
787
|
+
keys.push(key.map(ref => ref.index));
|
|
788
|
+
}
|
|
789
|
+
// 2. Provable ≤1-row (kind-aware) ⇒ the empty key.
|
|
790
|
+
if (hasSingletonFd(fds, columnCount, type.isSet)) {
|
|
791
|
+
keys.push([]);
|
|
792
|
+
}
|
|
793
|
+
// 3. FD-derived keys (already bounded to FDs with det.length < columnCount).
|
|
794
|
+
// `isSet` threads through so a determination-only covering determinant over
|
|
795
|
+
// a set (e.g. above a DISTINCT) derives a genuine key.
|
|
796
|
+
for (const k of deriveKeysFromFds(fds, columnCount, type.isSet)) {
|
|
797
|
+
keys.push(k);
|
|
798
|
+
}
|
|
799
|
+
const normalized = normalizeKeys(keys);
|
|
800
|
+
// 4. All-columns fallback, gated on set-ness. Only when nothing smaller was
|
|
801
|
+
// found — a set always has the all-columns key, but it is the weakest one.
|
|
802
|
+
if (normalized.length === 0 && type.isSet && columnCount > 0) {
|
|
803
|
+
return [allColumns(columnCount)];
|
|
804
|
+
}
|
|
805
|
+
return normalized;
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* True iff `cols` is a superkey of `rel` — i.e., the relation has at most one
|
|
809
|
+
* row per distinct `cols` tuple. The soundness-critical uniqueness predicate.
|
|
810
|
+
*
|
|
811
|
+
* Returns true iff any of:
|
|
812
|
+
* - `cols` is a (non-strict) superset of some `keysOf(rel)` entry (covers
|
|
813
|
+
* declared keys, the ≤1-row empty key, FD-derived keys, and the
|
|
814
|
+
* all-columns/set key), OR
|
|
815
|
+
* - `cols` is a provably row-unique determinant (`isUniqueDeterminant`:
|
|
816
|
+
* closure coverage AND uniqueness reachability) — this proves a superkey
|
|
817
|
+
* even when it is absent from the minimal `keysOf` list.
|
|
818
|
+
*
|
|
819
|
+
* No all-columns guard is needed on the closure branch: an all-columns probe
|
|
820
|
+
* on a bag fails `isUniqueDeterminant` on its own (no unique FD ⇒ false; if a
|
|
821
|
+
* unique FD exists the relation cannot hold duplicate rows, so true is
|
|
822
|
+
* correct).
|
|
823
|
+
*/
|
|
824
|
+
export function isUnique(cols, rel) {
|
|
825
|
+
const type = rel.getType();
|
|
826
|
+
const columnCount = type.columns.length;
|
|
827
|
+
const colSet = new Set(cols);
|
|
828
|
+
for (const key of keysOf(rel)) {
|
|
829
|
+
if (key.every(c => colSet.has(c)))
|
|
626
830
|
return true;
|
|
627
831
|
}
|
|
628
|
-
return
|
|
832
|
+
return isUniqueDeterminant(colSet, rel.physical?.fds, columnCount, type.isSet);
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* The single named spelling of the node-level "at-most-one-row" predicate:
|
|
836
|
+
* true iff `rel` is provably ≤1-row. Defined as `isUnique([], rel)` — the empty
|
|
837
|
+
* key is a subset of every column set, so a relation carrying it (via a declared
|
|
838
|
+
* empty key, the `∅ → all_cols` singleton FD, or any other channel `keysOf`
|
|
839
|
+
* reconciles) reports unique on the empty column list.
|
|
840
|
+
*
|
|
841
|
+
* Use this at node / rule level. The FD-only `hasSingletonFd` is the lower-level
|
|
842
|
+
* test `keysOf` itself calls; `isAtMostOneRow` is the surface consumers (joins,
|
|
843
|
+
* sort elimination) should reach for. Note it does **not** capture the
|
|
844
|
+
* zero-column `estimatedRows === 1` case — a zero-column relation has no
|
|
845
|
+
* representable empty key — so consumers needing that fallback keep their own
|
|
846
|
+
* check (see `characteristics.guaranteesUniqueRows`).
|
|
847
|
+
*/
|
|
848
|
+
export function isAtMostOneRow(rel) {
|
|
849
|
+
return isUnique([], rel);
|
|
629
850
|
}
|
|
630
851
|
/**
|
|
631
852
|
* Walk `predicate` (assumed to be a normalized conjunction) and extract FDs,
|
|
@@ -643,6 +864,19 @@ export function isAssertedKey(attrs, fds, columnCount) {
|
|
|
643
864
|
* equivalence pair `[col1, col2]`.
|
|
644
865
|
*
|
|
645
866
|
* Non-equality conjuncts contribute nothing.
|
|
867
|
+
*
|
|
868
|
+
* **Collation gate.** Every extracted fact is a VALUE-level claim (a pinned
|
|
869
|
+
* column has one value across rows; `col1 = col2` rows are value-equal), so a
|
|
870
|
+
* conjunct only contributes when its comparison is value-discriminating
|
|
871
|
+
* (`isValueDiscriminatingEquality`): for textual operands the effective
|
|
872
|
+
* comparison collation must be BINARY. A NOCASE/RTRIM comparison — via a
|
|
873
|
+
* `COLLATE` wrapper on either side or a non-BINARY declared column collation —
|
|
874
|
+
* passes value-DIFFERENT rows ('Bob' = 'bob' NOCASE), so its facts would
|
|
875
|
+
* over-claim (false ≤1-row keys, false EC-driven inferences, wrong insert
|
|
876
|
+
* defaults — ticket `collation-blind-equality-fact-extraction`). Declared-
|
|
877
|
+
* collation covered-key ≤1-row detection is NOT lost: it flows through the
|
|
878
|
+
* independent (and collation-sound) `extractConstraints` path in
|
|
879
|
+
* `FilterNode.computePhysical`.
|
|
646
880
|
*/
|
|
647
881
|
export function extractEqualityFds(predicate, attrIdToIndex) {
|
|
648
882
|
const fds = [];
|
|
@@ -660,6 +894,9 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
|
|
|
660
894
|
}
|
|
661
895
|
if (op !== '=')
|
|
662
896
|
continue;
|
|
897
|
+
// Value-level facts only from value-discriminating comparisons (see doc).
|
|
898
|
+
if (!isValueDiscriminatingEquality(n.left, n.right))
|
|
899
|
+
continue;
|
|
663
900
|
const lIsCol = n.left instanceof ColumnReferenceNode;
|
|
664
901
|
const rIsCol = n.right instanceof ColumnReferenceNode;
|
|
665
902
|
const lConst = constantValueOf(n.left);
|
|
@@ -668,8 +905,10 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
|
|
|
668
905
|
const lIdx = attrIdToIndex.get(n.left.attributeId);
|
|
669
906
|
const rIdx = attrIdToIndex.get(n.right.attributeId);
|
|
670
907
|
if (lIdx !== undefined && rIdx !== undefined && lIdx !== rIdx) {
|
|
671
|
-
|
|
672
|
-
|
|
908
|
+
// Mirror FDs from `col1 = col2` are pure value claims — equality
|
|
909
|
+
// never makes either endpoint row-unique.
|
|
910
|
+
fds.push({ determinants: [lIdx], dependents: [rIdx], kind: 'determination' });
|
|
911
|
+
fds.push({ determinants: [rIdx], dependents: [lIdx], kind: 'determination' });
|
|
673
912
|
equivPairs.push([lIdx, rIdx]);
|
|
674
913
|
}
|
|
675
914
|
continue;
|
|
@@ -677,7 +916,9 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
|
|
|
677
916
|
if (lIsCol && rConst !== undefined) {
|
|
678
917
|
const lIdx = attrIdToIndex.get(n.left.attributeId);
|
|
679
918
|
if (lIdx !== undefined) {
|
|
680
|
-
|
|
919
|
+
// `∅ → col` from a constant pin is deliberately 'determination': a
|
|
920
|
+
// pinned column does NOT imply the relation has at most one row.
|
|
921
|
+
fds.push({ determinants: [], dependents: [lIdx], kind: 'determination' });
|
|
681
922
|
constantBindings.push({ attrs: [lIdx], value: rConst });
|
|
682
923
|
}
|
|
683
924
|
continue;
|
|
@@ -685,7 +926,7 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
|
|
|
685
926
|
if (rIsCol && lConst !== undefined) {
|
|
686
927
|
const rIdx = attrIdToIndex.get(n.right.attributeId);
|
|
687
928
|
if (rIdx !== undefined) {
|
|
688
|
-
fds.push({ determinants: [], dependents: [rIdx] });
|
|
929
|
+
fds.push({ determinants: [], dependents: [rIdx], kind: 'determination' });
|
|
689
930
|
constantBindings.push({ attrs: [rIdx], value: lConst });
|
|
690
931
|
}
|
|
691
932
|
continue;
|
|
@@ -693,7 +934,44 @@ export function extractEqualityFds(predicate, attrIdToIndex) {
|
|
|
693
934
|
}
|
|
694
935
|
return { fds, equivPairs, constantBindings };
|
|
695
936
|
}
|
|
696
|
-
|
|
937
|
+
/**
|
|
938
|
+
* Collect per-column facts from a filter predicate for guard discharge.
|
|
939
|
+
*
|
|
940
|
+
* **Collation gate (per conjunct).** A fact may only discharge a guard when
|
|
941
|
+
* the filter's runtime comparison keeps filter-rows ⊆ guard-scope-rows. The
|
|
942
|
+
* guard predicate is evaluated under the column's *declared* collation at
|
|
943
|
+
* enforcement time — index maintenance for partial-UNIQUE guards, write-time
|
|
944
|
+
* CHECK evaluation for implication-form CHECK guards (constraint-builder
|
|
945
|
+
* threads declared collations into the CHECK scope types) — and guard
|
|
946
|
+
* recognition (`partial-unique-extraction.ts`, `check-extraction.ts`) only
|
|
947
|
+
* accepts bare column/literal AST shapes, so guard comparisons resolve to the
|
|
948
|
+
* declared collation. Hence:
|
|
949
|
+
*
|
|
950
|
+
* - `col = lit` / singleton-IN facts: sound when the conjunct's effective
|
|
951
|
+
* comparison collation is BINARY (value-equality implies equality under any
|
|
952
|
+
* collation) OR equals the column's declared collation (same comparison the
|
|
953
|
+
* guard scope uses; the strict `sqlValueEquals` literal match at discharge
|
|
954
|
+
* then under-claims at worst). The previous code stripped `CollateNode`
|
|
955
|
+
* from the literal side unconditionally, so `b = 'bob' collate nocase`
|
|
956
|
+
* discharged a BINARY `eq-literal{b,'bob'}` guard while admitting rows
|
|
957
|
+
* outside the partial-index scope (ticket
|
|
958
|
+
* `collation-blind-equality-fact-extraction`, repro 4).
|
|
959
|
+
* - `col1 = col2` facts: sound when both columns' contributed collations are
|
|
960
|
+
* equal — then any operand-resolution order (filter conjunct or guard
|
|
961
|
+
* spelling) lands on the same collation.
|
|
962
|
+
* - range facts over TEXT bounds: the discharge subset check
|
|
963
|
+
* (`filterRangeSubsetOfGuardRange`) compares bounds under BINARY, so the
|
|
964
|
+
* filter's effective collation AND the column's declared collation must
|
|
965
|
+
* both be BINARY (a BINARY bound comparison does not bound a NOCASE-ordered
|
|
966
|
+
* row set). Non-text bounds are collation-inert and stay ungated. This is
|
|
967
|
+
* deliberately stricter than the equality gate — a completeness loss for
|
|
968
|
+
* collated text ranges, never a soundness one.
|
|
969
|
+
* - plain `col IN (lits)`: the runtime (`emitIn`) compares under the
|
|
970
|
+
* condition operand's collation, which for the only recognized shape (a
|
|
971
|
+
* bare column) IS the declared collation; listed values' COLLATE wrappers
|
|
972
|
+
* are inert. Gated uniformly anyway for future-proofing.
|
|
973
|
+
*/
|
|
974
|
+
function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric, declaredCollationOf) {
|
|
697
975
|
const literalEqs = new Map();
|
|
698
976
|
const columnEqs = new Map();
|
|
699
977
|
const isNullCols = new Set();
|
|
@@ -722,6 +1000,13 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
|
|
|
722
1000
|
}
|
|
723
1001
|
return undefined;
|
|
724
1002
|
};
|
|
1003
|
+
// Equality-fact gate: BINARY, or matching the column's declared collation
|
|
1004
|
+
// (the collation guard scopes are evaluated under). See the function doc.
|
|
1005
|
+
const equalityCollationOk = (col, effColl) => effColl === 'BINARY' || effColl === normalizeCollationName(declaredCollationOf(col));
|
|
1006
|
+
// Range-fact gate for TEXT bounds: the discharge subset check is BINARY, so
|
|
1007
|
+
// both the filter comparison and the guard-scope (declared) collation must be.
|
|
1008
|
+
const rangeCollationOk = (col, effColl, bound) => typeof bound !== 'string'
|
|
1009
|
+
|| (effColl === 'BINARY' && normalizeCollationName(declaredCollationOf(col)) === 'BINARY');
|
|
725
1010
|
const tightenLowerBound = (col, value, inclusive) => {
|
|
726
1011
|
const cur = rangeBounds.get(col);
|
|
727
1012
|
if (!cur) {
|
|
@@ -792,18 +1077,23 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
|
|
|
792
1077
|
const lIdx = columnIndexOf(n.left);
|
|
793
1078
|
const rIdx = columnIndexOf(n.right);
|
|
794
1079
|
if (lIdx !== undefined && rIdx !== undefined) {
|
|
795
|
-
|
|
1080
|
+
// Both sides are bare column refs; require their contributed
|
|
1081
|
+
// collations to agree so any resolution order matches the guard's.
|
|
1082
|
+
if (operandCollation(n.left) === operandCollation(n.right)) {
|
|
1083
|
+
addColumnEq(lIdx, rIdx);
|
|
1084
|
+
}
|
|
796
1085
|
continue;
|
|
797
1086
|
}
|
|
1087
|
+
const effColl = effectiveComparisonCollation(n.left, n.right);
|
|
798
1088
|
if (lIdx !== undefined) {
|
|
799
1089
|
const lit = literalSqlValueOf(n.right);
|
|
800
|
-
if (lit !== undefined)
|
|
1090
|
+
if (lit !== undefined && equalityCollationOk(lIdx, effColl))
|
|
801
1091
|
literalEqs.set(lIdx, lit);
|
|
802
1092
|
continue;
|
|
803
1093
|
}
|
|
804
1094
|
if (rIdx !== undefined) {
|
|
805
1095
|
const lit = literalSqlValueOf(n.left);
|
|
806
|
-
if (lit !== undefined)
|
|
1096
|
+
if (lit !== undefined && equalityCollationOk(rIdx, effColl))
|
|
807
1097
|
literalEqs.set(rIdx, lit);
|
|
808
1098
|
}
|
|
809
1099
|
continue;
|
|
@@ -825,16 +1115,21 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
|
|
|
825
1115
|
if (op === '<' || op === '<=' || op === '>' || op === '>=') {
|
|
826
1116
|
const lIdx = columnIndexOf(n.left);
|
|
827
1117
|
const rIdx = columnIndexOf(n.right);
|
|
1118
|
+
const effColl = effectiveComparisonCollation(n.left, n.right);
|
|
828
1119
|
if (lIdx !== undefined && rIdx === undefined) {
|
|
829
1120
|
const lit = literalSqlValueOf(n.right);
|
|
830
1121
|
if (lit === undefined || lit === null)
|
|
831
1122
|
continue;
|
|
1123
|
+
if (!rangeCollationOk(lIdx, effColl, lit))
|
|
1124
|
+
continue;
|
|
832
1125
|
recordComparison(lIdx, op, lit);
|
|
833
1126
|
}
|
|
834
1127
|
else if (rIdx !== undefined && lIdx === undefined) {
|
|
835
1128
|
const lit = literalSqlValueOf(n.left);
|
|
836
1129
|
if (lit === undefined || lit === null)
|
|
837
1130
|
continue;
|
|
1131
|
+
if (!rangeCollationOk(rIdx, effColl, lit))
|
|
1132
|
+
continue;
|
|
838
1133
|
recordComparison(rIdx, flipComparison(op), lit);
|
|
839
1134
|
}
|
|
840
1135
|
continue;
|
|
@@ -849,10 +1144,15 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
|
|
|
849
1144
|
continue;
|
|
850
1145
|
const lo = literalSqlValueOf(n.lower);
|
|
851
1146
|
const hi = literalSqlValueOf(n.upper);
|
|
852
|
-
|
|
1147
|
+
// Per-bound effective collation (emitBetween: bound wins over expr).
|
|
1148
|
+
if (lo !== undefined && lo !== null
|
|
1149
|
+
&& rangeCollationOk(cIdx, effectiveBetweenBoundCollation(n.expr, n.lower), lo)) {
|
|
853
1150
|
tightenLowerBound(cIdx, lo, true);
|
|
854
|
-
|
|
1151
|
+
}
|
|
1152
|
+
if (hi !== undefined && hi !== null
|
|
1153
|
+
&& rangeCollationOk(cIdx, effectiveBetweenBoundCollation(n.expr, n.upper), hi)) {
|
|
855
1154
|
tightenUpperBound(cIdx, hi, true);
|
|
1155
|
+
}
|
|
856
1156
|
continue;
|
|
857
1157
|
}
|
|
858
1158
|
if (n instanceof UnaryOpNode) {
|
|
@@ -889,6 +1189,12 @@ function buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric) {
|
|
|
889
1189
|
const cIdx = columnIndexOf(n.condition);
|
|
890
1190
|
if (cIdx === undefined)
|
|
891
1191
|
continue;
|
|
1192
|
+
// emitIn resolves ONE collation through the provenance lattice over the
|
|
1193
|
+
// condition AND the listed values — a collate-wrapped element (folded
|
|
1194
|
+
// to a literal whose type carries rank-3 NOCASE) can outrank the bare
|
|
1195
|
+
// column recognized here, so this gate is load-bearing.
|
|
1196
|
+
if (!equalityCollationOk(cIdx, effectiveInCollation(n)))
|
|
1197
|
+
continue;
|
|
892
1198
|
const set = new Set();
|
|
893
1199
|
let allLiterals = true;
|
|
894
1200
|
for (const v of n.values) {
|
|
@@ -966,9 +1272,13 @@ function bindingForColumn(col, bindings) {
|
|
|
966
1272
|
* sound for numeric columns since the consumer matches `eq-literal{col, 0}`
|
|
967
1273
|
* via strict `sqlValueEquals`, which treats TEXT `''`, BLOB, and boolean
|
|
968
1274
|
* `false` as unequal to integer 0.
|
|
1275
|
+
*
|
|
1276
|
+
* `declaredCollationOf(col)` reports the source's output column collation
|
|
1277
|
+
* (normalized or not; `'BINARY'` when undeclared). Used by the per-conjunct
|
|
1278
|
+
* collation gate in `buildPredicateFacts` — see its doc.
|
|
969
1279
|
*/
|
|
970
|
-
export function predicateImpliesGuard(predicate, guard, ecs, bindings, attrIdToIndex, isColumnNonNullable, isColumnNumeric) {
|
|
971
|
-
const facts = buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric);
|
|
1280
|
+
export function predicateImpliesGuard(predicate, guard, ecs, bindings, attrIdToIndex, isColumnNonNullable, isColumnNumeric, declaredCollationOf) {
|
|
1281
|
+
const facts = buildPredicateFacts(predicate, attrIdToIndex, isColumnNumeric, declaredCollationOf);
|
|
972
1282
|
for (const clause of guard.clauses) {
|
|
973
1283
|
if (!clauseEntailed(clause, facts, ecs, bindings, isColumnNonNullable)) {
|
|
974
1284
|
return false;
|
|
@@ -1413,4 +1723,111 @@ export function shiftDomainConstraints(domains, offset) {
|
|
|
1413
1723
|
return domains.slice();
|
|
1414
1724
|
return domains.map(domain => ({ ...domain, column: domain.column + offset }));
|
|
1415
1725
|
}
|
|
1726
|
+
/**
|
|
1727
|
+
* Per-node cap on the number of INDs we materialize, mirroring
|
|
1728
|
+
* `MAX_FDS_PER_NODE`. A safety valve for pathological plans; truncations are
|
|
1729
|
+
* logged under the `quereus:planner:fd` logger like the FD/binding/domain caps.
|
|
1730
|
+
*/
|
|
1731
|
+
export const MAX_INDS_PER_NODE = 64;
|
|
1732
|
+
function sameOrderedList(a, b) {
|
|
1733
|
+
if (a.length !== b.length)
|
|
1734
|
+
return false;
|
|
1735
|
+
for (let i = 0; i < a.length; i++)
|
|
1736
|
+
if (a[i] !== b[i])
|
|
1737
|
+
return false;
|
|
1738
|
+
return true;
|
|
1739
|
+
}
|
|
1740
|
+
function indTargetsEqual(a, b) {
|
|
1741
|
+
if (a.kind !== b.kind)
|
|
1742
|
+
return false;
|
|
1743
|
+
if (a.kind === 'table' && b.kind === 'table') {
|
|
1744
|
+
return a.schema === b.schema && a.table === b.table && sameOrderedList(a.targetCols, b.targetCols);
|
|
1745
|
+
}
|
|
1746
|
+
if (a.kind === 'relation' && b.kind === 'relation') {
|
|
1747
|
+
return a.relationId === b.relationId && sameOrderedList(a.targetCols, b.targetCols);
|
|
1748
|
+
}
|
|
1749
|
+
return false;
|
|
1750
|
+
}
|
|
1751
|
+
/**
|
|
1752
|
+
* Structural equality for IND dedup. `cols` and `target.targetCols` are
|
|
1753
|
+
* compared as *ordered* lists — the positional pairing between them is
|
|
1754
|
+
* load-bearing (`cols[i]` is the child column matched to `targetCols[i]`), so a
|
|
1755
|
+
* reordering is a different fact and must not collapse. Stricter than
|
|
1756
|
+
* `fdsEqual`'s set comparison; over-keeping a reordered twin is harmless
|
|
1757
|
+
* (redundancy, capped), whereas collapsing distinct facts would lose an IND.
|
|
1758
|
+
*/
|
|
1759
|
+
function indsEqual(a, b) {
|
|
1760
|
+
return a.nullRejecting === b.nullRejecting
|
|
1761
|
+
&& sameOrderedList(a.cols, b.cols)
|
|
1762
|
+
&& indTargetsEqual(a.target, b.target);
|
|
1763
|
+
}
|
|
1764
|
+
/**
|
|
1765
|
+
* Add a single IND, skipping it when a structurally-equal entry (per
|
|
1766
|
+
* `indsEqual`) already exists. Enforces the per-node cap; truncations are
|
|
1767
|
+
* logged. Mirrors `addFd` minus the determinant-subsumption logic (an IND has
|
|
1768
|
+
* no determinant/dependent split to subsume).
|
|
1769
|
+
*/
|
|
1770
|
+
export function addInd(inds, next, opts = {}) {
|
|
1771
|
+
const result = inds.slice();
|
|
1772
|
+
if (!result.some(existing => indsEqual(existing, next))) {
|
|
1773
|
+
result.push(next);
|
|
1774
|
+
}
|
|
1775
|
+
return enforceIndCap(result, opts);
|
|
1776
|
+
}
|
|
1777
|
+
function enforceIndCap(inds, opts) {
|
|
1778
|
+
const cap = opts.cap ?? MAX_INDS_PER_NODE;
|
|
1779
|
+
if (inds.length <= cap)
|
|
1780
|
+
return inds;
|
|
1781
|
+
const kept = inds.slice(0, cap);
|
|
1782
|
+
log('IND cap reached: dropped %d IND(s) from %d', inds.length - kept.length, inds.length);
|
|
1783
|
+
return kept;
|
|
1784
|
+
}
|
|
1785
|
+
/** Merge two IND lists: concat with structural dedup via `addInd`, capped. */
|
|
1786
|
+
export function mergeInds(a, b, opts = {}) {
|
|
1787
|
+
let result = a.slice();
|
|
1788
|
+
for (const ind of b) {
|
|
1789
|
+
result = addInd(result, ind, opts);
|
|
1790
|
+
}
|
|
1791
|
+
return result;
|
|
1792
|
+
}
|
|
1793
|
+
/**
|
|
1794
|
+
* Project INDs through a column mapping (oldCol → newCol). An IND's `cols` is
|
|
1795
|
+
* **all-or-nothing**: drop the IND when ANY of its `cols` loses its mapping (the
|
|
1796
|
+
* relation no longer carries the witnessing columns) — there is no partial-
|
|
1797
|
+
* dependent survival as in `projectFds`. Survivors have their `cols` remapped to
|
|
1798
|
+
* output indices; `target.targetCols` index into the *target* relation, NOT this
|
|
1799
|
+
* relation's output, so they are NOT remapped. Result is deduped + capped.
|
|
1800
|
+
*/
|
|
1801
|
+
export function projectInds(inds, mapping) {
|
|
1802
|
+
const out = [];
|
|
1803
|
+
for (const ind of inds) {
|
|
1804
|
+
const newCols = [];
|
|
1805
|
+
let miss = false;
|
|
1806
|
+
for (const c of ind.cols) {
|
|
1807
|
+
const m = mapping.get(c);
|
|
1808
|
+
if (m === undefined) {
|
|
1809
|
+
miss = true;
|
|
1810
|
+
break;
|
|
1811
|
+
}
|
|
1812
|
+
newCols.push(m);
|
|
1813
|
+
}
|
|
1814
|
+
if (miss)
|
|
1815
|
+
continue;
|
|
1816
|
+
out.push({ cols: newCols, target: ind.target, nullRejecting: ind.nullRejecting });
|
|
1817
|
+
}
|
|
1818
|
+
return mergeInds([], out);
|
|
1819
|
+
}
|
|
1820
|
+
/**
|
|
1821
|
+
* Shift each IND's `cols` by `offset` (mirrors `shiftFds` for join column
|
|
1822
|
+
* translation). `target.targetCols` are target-relative ⇒ NOT shifted.
|
|
1823
|
+
*/
|
|
1824
|
+
export function shiftInds(inds, offset) {
|
|
1825
|
+
if (offset === 0)
|
|
1826
|
+
return inds.slice();
|
|
1827
|
+
return inds.map(ind => ({
|
|
1828
|
+
cols: ind.cols.map(c => c + offset),
|
|
1829
|
+
target: ind.target,
|
|
1830
|
+
nullRejecting: ind.nullRejecting,
|
|
1831
|
+
}));
|
|
1832
|
+
}
|
|
1416
1833
|
//# sourceMappingURL=fd-utils.js.map
|