@quereus/quereus 4.5.0 → 4.6.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 +4 -3
- package/dist/src/core/database-events.d.ts +99 -1
- package/dist/src/core/database-events.d.ts.map +1 -1
- package/dist/src/core/database-events.js +219 -3
- package/dist/src/core/database-events.js.map +1 -1
- package/dist/src/core/database-materialized-views-plan-builders.d.ts.map +1 -1
- package/dist/src/core/database-materialized-views-plan-builders.js +29 -2
- package/dist/src/core/database-materialized-views-plan-builders.js.map +1 -1
- package/dist/src/core/database-transaction.d.ts +9 -0
- package/dist/src/core/database-transaction.d.ts.map +1 -1
- package/dist/src/core/database-transaction.js +9 -0
- package/dist/src/core/database-transaction.js.map +1 -1
- package/dist/src/core/database.d.ts +7 -1
- package/dist/src/core/database.d.ts.map +1 -1
- package/dist/src/core/database.js +20 -5
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/func/builtins/aggregate.js +11 -11
- 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 +15 -85
- package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
- package/dist/src/func/builtins/conversion.d.ts.map +1 -1
- package/dist/src/func/builtins/conversion.js +10 -9
- package/dist/src/func/builtins/conversion.js.map +1 -1
- package/dist/src/func/builtins/datetime.d.ts.map +1 -1
- package/dist/src/func/builtins/datetime.js +28 -10
- package/dist/src/func/builtins/datetime.js.map +1 -1
- package/dist/src/func/builtins/json.d.ts.map +1 -1
- package/dist/src/func/builtins/json.js +23 -17
- package/dist/src/func/builtins/json.js.map +1 -1
- package/dist/src/func/builtins/mutation.js +2 -2
- package/dist/src/func/builtins/mutation.js.map +1 -1
- package/dist/src/func/builtins/return-types.d.ts +327 -0
- package/dist/src/func/builtins/return-types.d.ts.map +1 -0
- package/dist/src/func/builtins/return-types.js +43 -0
- package/dist/src/func/builtins/return-types.js.map +1 -0
- package/dist/src/func/builtins/scalar.d.ts.map +1 -1
- package/dist/src/func/builtins/scalar.js +138 -71
- package/dist/src/func/builtins/scalar.js.map +1 -1
- package/dist/src/func/builtins/schema.d.ts.map +1 -1
- package/dist/src/func/builtins/schema.js +11 -3
- package/dist/src/func/builtins/schema.js.map +1 -1
- package/dist/src/func/builtins/string.d.ts.map +1 -1
- package/dist/src/func/builtins/string.js +4 -2
- package/dist/src/func/builtins/string.js.map +1 -1
- package/dist/src/func/builtins/timespan.d.ts +3 -0
- package/dist/src/func/builtins/timespan.d.ts.map +1 -1
- package/dist/src/func/builtins/timespan.js +15 -11
- package/dist/src/func/builtins/timespan.js.map +1 -1
- package/dist/src/func/registration.d.ts +35 -1
- package/dist/src/func/registration.d.ts.map +1 -1
- package/dist/src/func/registration.js +235 -41
- package/dist/src/func/registration.js.map +1 -1
- package/dist/src/index.d.ts +11 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +12 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/parser/parser.d.ts +46 -0
- package/dist/src/parser/parser.d.ts.map +1 -1
- package/dist/src/parser/parser.js +160 -44
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/src/planner/analysis/check-extraction.d.ts.map +1 -1
- package/dist/src/planner/analysis/check-extraction.js +37 -4
- package/dist/src/planner/analysis/check-extraction.js.map +1 -1
- package/dist/src/planner/analysis/comparison-collation.d.ts +20 -22
- package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -1
- package/dist/src/planner/analysis/comparison-collation.js +29 -26
- package/dist/src/planner/analysis/comparison-collation.js.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.d.ts +0 -7
- package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.js +59 -59
- package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
- package/dist/src/planner/building/alter-table.d.ts.map +1 -1
- package/dist/src/planner/building/alter-table.js +65 -27
- package/dist/src/planner/building/alter-table.js.map +1 -1
- package/dist/src/planner/building/coercion.d.ts +21 -45
- package/dist/src/planner/building/coercion.d.ts.map +1 -1
- package/dist/src/planner/building/coercion.js +42 -91
- package/dist/src/planner/building/coercion.js.map +1 -1
- package/dist/src/planner/building/expression.d.ts +17 -0
- package/dist/src/planner/building/expression.d.ts.map +1 -1
- package/dist/src/planner/building/expression.js +28 -17
- package/dist/src/planner/building/expression.js.map +1 -1
- package/dist/src/planner/building/function-call.d.ts.map +1 -1
- package/dist/src/planner/building/function-call.js +7 -2
- package/dist/src/planner/building/function-call.js.map +1 -1
- package/dist/src/planner/building/select-aggregates.d.ts +1 -1
- package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
- package/dist/src/planner/building/select-aggregates.js +53 -2
- package/dist/src/planner/building/select-aggregates.js.map +1 -1
- package/dist/src/planner/building/select-context.d.ts +7 -0
- package/dist/src/planner/building/select-context.d.ts.map +1 -1
- package/dist/src/planner/building/select-context.js +10 -40
- package/dist/src/planner/building/select-context.js.map +1 -1
- package/dist/src/planner/building/select.d.ts +37 -1
- package/dist/src/planner/building/select.d.ts.map +1 -1
- package/dist/src/planner/building/select.js +112 -51
- package/dist/src/planner/building/select.js.map +1 -1
- package/dist/src/planner/cost/conjunct-cost.d.ts +40 -0
- package/dist/src/planner/cost/conjunct-cost.d.ts.map +1 -1
- package/dist/src/planner/cost/conjunct-cost.js +45 -0
- package/dist/src/planner/cost/conjunct-cost.js.map +1 -1
- package/dist/src/planner/cost/index.d.ts +10 -0
- package/dist/src/planner/cost/index.d.ts.map +1 -1
- package/dist/src/planner/cost/index.js +15 -0
- package/dist/src/planner/cost/index.js.map +1 -1
- package/dist/src/planner/nodes/aggregate-node.d.ts +6 -0
- package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/aggregate-node.js +10 -2
- 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 +2 -1
- package/dist/src/planner/nodes/alias-node.js.map +1 -1
- package/dist/src/planner/nodes/alter-table-node.d.ts +24 -8
- package/dist/src/planner/nodes/alter-table-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/alter-table-node.js.map +1 -1
- package/dist/src/planner/nodes/asof-scan-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/asof-scan-node.js +4 -1
- package/dist/src/planner/nodes/asof-scan-node.js.map +1 -1
- package/dist/src/planner/nodes/asserted-keys-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/asserted-keys-node.js +2 -1
- package/dist/src/planner/nodes/asserted-keys-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 +8 -3
- package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
- package/dist/src/planner/nodes/cache-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/cache-node.js +2 -1
- package/dist/src/planner/nodes/cache-node.js.map +1 -1
- package/dist/src/planner/nodes/distinct-node.d.ts +6 -0
- package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/distinct-node.js +10 -2
- package/dist/src/planner/nodes/distinct-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 -1
- package/dist/src/planner/nodes/eager-prefetch-node.js.map +1 -1
- package/dist/src/planner/nodes/fanout-lookup-join-node.d.ts +5 -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 +13 -6
- 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 +12 -5
- package/dist/src/planner/nodes/filter.js.map +1 -1
- package/dist/src/planner/nodes/hash-aggregate.d.ts +6 -0
- package/dist/src/planner/nodes/hash-aggregate.d.ts.map +1 -1
- package/dist/src/planner/nodes/hash-aggregate.js +10 -2
- package/dist/src/planner/nodes/hash-aggregate.js.map +1 -1
- package/dist/src/planner/nodes/join-node.d.ts +20 -1
- package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-node.js +30 -9
- package/dist/src/planner/nodes/join-node.js.map +1 -1
- package/dist/src/planner/nodes/join-utils.d.ts +21 -0
- package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-utils.js +26 -0
- package/dist/src/planner/nodes/join-utils.js.map +1 -1
- package/dist/src/planner/nodes/key-set-semi-join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/key-set-semi-join-node.js +5 -1
- package/dist/src/planner/nodes/key-set-semi-join-node.js.map +1 -1
- package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/lens-auxiliary-access-node.js +2 -1
- package/dist/src/planner/nodes/lens-auxiliary-access-node.js.map +1 -1
- package/dist/src/planner/nodes/limit-offset.d.ts +6 -0
- package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
- package/dist/src/planner/nodes/limit-offset.js +10 -2
- package/dist/src/planner/nodes/limit-offset.js.map +1 -1
- package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/merge-join-node.js +8 -3
- package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
- package/dist/src/planner/nodes/ordinal-slice-node.d.ts +5 -0
- package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/ordinal-slice-node.js +9 -2
- package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
- package/dist/src/planner/nodes/plan-node.d.ts +24 -0
- 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/project-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/project-node.js +2 -1
- 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 +3 -2
- 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 +2 -1
- package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
- package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
- package/dist/src/planner/nodes/scalar.js +5 -18
- package/dist/src/planner/nodes/scalar.js.map +1 -1
- package/dist/src/planner/nodes/sort.d.ts.map +1 -1
- package/dist/src/planner/nodes/sort.js +3 -1
- package/dist/src/planner/nodes/sort.js.map +1 -1
- package/dist/src/planner/nodes/stream-aggregate.d.ts +6 -0
- package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
- package/dist/src/planner/nodes/stream-aggregate.js +10 -2
- package/dist/src/planner/nodes/stream-aggregate.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 +5 -0
- package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
- package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
- package/dist/src/planner/nodes/window-function.js +8 -0
- package/dist/src/planner/nodes/window-function.js.map +1 -1
- package/dist/src/planner/nodes/window-node.d.ts +1 -1
- package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/window-node.js +3 -1
- package/dist/src/planner/nodes/window-node.js.map +1 -1
- package/dist/src/planner/optimizer.d.ts +9 -1
- package/dist/src/planner/optimizer.d.ts.map +1 -1
- package/dist/src/planner/optimizer.js +77 -6
- package/dist/src/planner/optimizer.js.map +1 -1
- package/dist/src/planner/rules/access/rule-key-set-seek.d.ts.map +1 -1
- package/dist/src/planner/rules/access/rule-key-set-seek.js +3 -68
- package/dist/src/planner/rules/access/rule-key-set-seek.js.map +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.d.ts +19 -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 +24 -3
- package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
- package/dist/src/planner/rules/cache/rule-cte-optimization.d.ts.map +1 -1
- package/dist/src/planner/rules/cache/rule-cte-optimization.js +9 -0
- package/dist/src/planner/rules/cache/rule-cte-optimization.js.map +1 -1
- package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.d.ts.map +1 -1
- package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.js +6 -4
- package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.js.map +1 -1
- package/dist/src/planner/rules/join/equi-pair-extractor.d.ts +5 -31
- package/dist/src/planner/rules/join/equi-pair-extractor.d.ts.map +1 -1
- package/dist/src/planner/rules/join/equi-pair-extractor.js +4 -44
- package/dist/src/planner/rules/join/equi-pair-extractor.js.map +1 -1
- package/dist/src/planner/rules/join/index-nested-loop.d.ts +49 -0
- package/dist/src/planner/rules/join/index-nested-loop.d.ts.map +1 -0
- package/dist/src/planner/rules/join/index-nested-loop.js +285 -0
- package/dist/src/planner/rules/join/index-nested-loop.js.map +1 -0
- package/dist/src/planner/rules/join/rule-fanout-batched-outer.js +8 -8
- package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts +10 -4
- 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 +83 -27
- package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -1
- package/dist/src/planner/rules/join/rule-monotonic-merge-join.js +4 -4
- package/dist/src/planner/rules/join/rule-monotonic-merge-join.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.d.ts +21 -8
- package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.d.ts.map +1 -1
- package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.js +70 -14
- package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts +42 -17
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts.map +1 -1
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.js +84 -154
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-join-predicate-pushdown.d.ts +73 -0
- package/dist/src/planner/rules/predicate/rule-join-predicate-pushdown.d.ts.map +1 -0
- package/dist/src/planner/rules/predicate/rule-join-predicate-pushdown.js +205 -0
- package/dist/src/planner/rules/predicate/rule-join-predicate-pushdown.js.map +1 -0
- package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts +14 -11
- 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 +21 -85
- package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts +7 -1
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts.map +1 -1
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js +7 -1
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -1
- package/dist/src/planner/rules/shared/access-leaf.d.ts +39 -0
- package/dist/src/planner/rules/shared/access-leaf.d.ts.map +1 -0
- package/dist/src/planner/rules/shared/access-leaf.js +79 -0
- package/dist/src/planner/rules/shared/access-leaf.js.map +1 -0
- 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 +18 -8
- 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 +3 -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 +27 -10
- 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 +69 -11
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
- package/dist/src/planner/rules/window/rule-monotonic-window.d.ts +17 -7
- package/dist/src/planner/rules/window/rule-monotonic-window.d.ts.map +1 -1
- package/dist/src/planner/rules/window/rule-monotonic-window.js +124 -87
- package/dist/src/planner/rules/window/rule-monotonic-window.js.map +1 -1
- package/dist/src/planner/scopes/aliased.d.ts.map +1 -1
- package/dist/src/planner/scopes/aliased.js +6 -0
- package/dist/src/planner/scopes/aliased.js.map +1 -1
- package/dist/src/planner/stats/catalog-stats.d.ts +44 -13
- package/dist/src/planner/stats/catalog-stats.d.ts.map +1 -1
- package/dist/src/planner/stats/catalog-stats.js +137 -61
- package/dist/src/planner/stats/catalog-stats.js.map +1 -1
- package/dist/src/planner/stats/conjunct-selectivity.d.ts +48 -0
- package/dist/src/planner/stats/conjunct-selectivity.d.ts.map +1 -0
- package/dist/src/planner/stats/conjunct-selectivity.js +168 -0
- package/dist/src/planner/stats/conjunct-selectivity.js.map +1 -0
- package/dist/src/planner/stats/index.d.ts +22 -3
- package/dist/src/planner/stats/index.d.ts.map +1 -1
- package/dist/src/planner/stats/index.js.map +1 -1
- package/dist/src/planner/stats/table-cardinality.d.ts +28 -0
- package/dist/src/planner/stats/table-cardinality.d.ts.map +1 -0
- package/dist/src/planner/stats/table-cardinality.js +29 -0
- package/dist/src/planner/stats/table-cardinality.js.map +1 -0
- package/dist/src/planner/util/column-origins.d.ts +29 -8
- package/dist/src/planner/util/column-origins.d.ts.map +1 -1
- package/dist/src/planner/util/column-origins.js +74 -14
- package/dist/src/planner/util/column-origins.js.map +1 -1
- package/dist/src/planner/util/fd-utils.d.ts +32 -8
- package/dist/src/planner/util/fd-utils.d.ts.map +1 -1
- package/dist/src/planner/util/fd-utils.js +46 -9
- package/dist/src/planner/util/fd-utils.js.map +1 -1
- package/dist/src/planner/util/ind-utils.d.ts +56 -17
- package/dist/src/planner/util/ind-utils.d.ts.map +1 -1
- package/dist/src/planner/util/ind-utils.js +82 -21
- package/dist/src/planner/util/ind-utils.js.map +1 -1
- package/dist/src/planner/util/key-utils.d.ts +20 -2
- package/dist/src/planner/util/key-utils.d.ts.map +1 -1
- package/dist/src/planner/util/key-utils.js +37 -3
- package/dist/src/planner/util/key-utils.js.map +1 -1
- package/dist/src/planner/util/row-estimates.d.ts +28 -0
- package/dist/src/planner/util/row-estimates.d.ts.map +1 -0
- package/dist/src/planner/util/row-estimates.js +40 -0
- package/dist/src/planner/util/row-estimates.js.map +1 -0
- package/dist/src/planner/util/row-population.d.ts +42 -0
- package/dist/src/planner/util/row-population.d.ts.map +1 -0
- package/dist/src/planner/util/row-population.js +71 -0
- package/dist/src/planner/util/row-population.js.map +1 -0
- package/dist/src/runtime/emit/add-constraint.d.ts.map +1 -1
- package/dist/src/runtime/emit/add-constraint.js +39 -1
- 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 +4 -4
- package/dist/src/runtime/emit/aggregate.js.map +1 -1
- package/dist/src/runtime/emit/alter-schema-event.d.ts +42 -0
- package/dist/src/runtime/emit/alter-schema-event.d.ts.map +1 -0
- package/dist/src/runtime/emit/alter-schema-event.js +28 -0
- package/dist/src/runtime/emit/alter-schema-event.js.map +1 -0
- package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/alter-table.js +380 -154
- 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 +35 -3
- package/dist/src/runtime/emit/analyze.js.map +1 -1
- package/dist/src/runtime/emit/cast.d.ts.map +1 -1
- package/dist/src/runtime/emit/cast.js +4 -19
- package/dist/src/runtime/emit/cast.js.map +1 -1
- package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
- package/dist/src/runtime/emit/dml-executor.js +64 -27
- package/dist/src/runtime/emit/dml-executor.js.map +1 -1
- package/dist/src/runtime/emit/drop-index.d.ts.map +1 -1
- package/dist/src/runtime/emit/drop-index.js +4 -3
- package/dist/src/runtime/emit/drop-index.js.map +1 -1
- package/dist/src/runtime/emit/hash-aggregate.d.ts.map +1 -1
- package/dist/src/runtime/emit/hash-aggregate.js +2 -2
- package/dist/src/runtime/emit/hash-aggregate.js.map +1 -1
- package/dist/src/runtime/emit/join.d.ts.map +1 -1
- package/dist/src/runtime/emit/join.js +8 -67
- package/dist/src/runtime/emit/join.js.map +1 -1
- package/dist/src/runtime/emit/key-set-semi-join.d.ts.map +1 -1
- package/dist/src/runtime/emit/key-set-semi-join.js +6 -0
- package/dist/src/runtime/emit/key-set-semi-join.js.map +1 -1
- package/dist/src/runtime/emit/operand-comparator.d.ts +30 -0
- package/dist/src/runtime/emit/operand-comparator.d.ts.map +1 -1
- package/dist/src/runtime/emit/operand-comparator.js +34 -0
- package/dist/src/runtime/emit/operand-comparator.js.map +1 -1
- package/dist/src/runtime/emit/schema-declarative.d.ts.map +1 -1
- package/dist/src/runtime/emit/schema-declarative.js +30 -0
- package/dist/src/runtime/emit/schema-declarative.js.map +1 -1
- package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
- package/dist/src/runtime/emit/subquery.js +153 -52
- package/dist/src/runtime/emit/subquery.js.map +1 -1
- package/dist/src/runtime/emit/window.js +36 -23
- package/dist/src/runtime/emit/window.js.map +1 -1
- package/dist/src/schema/catalog-persistability.d.ts +19 -16
- package/dist/src/schema/catalog-persistability.d.ts.map +1 -1
- package/dist/src/schema/catalog-persistability.js +76 -20
- package/dist/src/schema/catalog-persistability.js.map +1 -1
- package/dist/src/schema/catalog.d.ts +67 -2
- package/dist/src/schema/catalog.d.ts.map +1 -1
- package/dist/src/schema/catalog.js +194 -3
- package/dist/src/schema/catalog.js.map +1 -1
- package/dist/src/schema/column.d.ts +26 -3
- package/dist/src/schema/column.d.ts.map +1 -1
- package/dist/src/schema/column.js.map +1 -1
- package/dist/src/schema/ddl-generator.d.ts.map +1 -1
- package/dist/src/schema/ddl-generator.js +19 -6
- package/dist/src/schema/ddl-generator.js.map +1 -1
- package/dist/src/schema/function.d.ts +32 -1
- package/dist/src/schema/function.d.ts.map +1 -1
- package/dist/src/schema/function.js +10 -2
- package/dist/src/schema/function.js.map +1 -1
- package/dist/src/schema/manager.d.ts +84 -7
- package/dist/src/schema/manager.d.ts.map +1 -1
- package/dist/src/schema/manager.js +153 -53
- package/dist/src/schema/manager.js.map +1 -1
- package/dist/src/schema/schema-differ.d.ts.map +1 -1
- package/dist/src/schema/schema-differ.js +104 -28
- package/dist/src/schema/schema-differ.js.map +1 -1
- package/dist/src/schema/table.d.ts +149 -1
- package/dist/src/schema/table.d.ts.map +1 -1
- package/dist/src/schema/table.js +248 -1
- package/dist/src/schema/table.js.map +1 -1
- package/dist/src/schema/unique-enforcement.d.ts +5 -3
- package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
- package/dist/src/schema/unique-enforcement.js +5 -3
- package/dist/src/schema/unique-enforcement.js.map +1 -1
- package/dist/src/types/builtin-types.d.ts +16 -0
- package/dist/src/types/builtin-types.d.ts.map +1 -1
- package/dist/src/types/builtin-types.js +46 -8
- package/dist/src/types/builtin-types.js.map +1 -1
- package/dist/src/types/cast-semantics.d.ts +42 -0
- package/dist/src/types/cast-semantics.d.ts.map +1 -1
- package/dist/src/types/cast-semantics.js +64 -0
- package/dist/src/types/cast-semantics.js.map +1 -1
- package/dist/src/types/comparison-coercion.d.ts +101 -0
- package/dist/src/types/comparison-coercion.d.ts.map +1 -0
- package/dist/src/types/comparison-coercion.js +162 -0
- package/dist/src/types/comparison-coercion.js.map +1 -0
- package/dist/src/types/index.d.ts +2 -2
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js +2 -2
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/logical-type.d.ts +7 -0
- package/dist/src/types/logical-type.d.ts.map +1 -1
- package/dist/src/types/logical-type.js.map +1 -1
- package/dist/src/types/validation.d.ts +56 -0
- package/dist/src/types/validation.d.ts.map +1 -1
- package/dist/src/types/validation.js +68 -0
- package/dist/src/types/validation.js.map +1 -1
- package/dist/src/util/coercion.d.ts +8 -0
- package/dist/src/util/coercion.d.ts.map +1 -1
- package/dist/src/util/coercion.js +8 -0
- package/dist/src/util/coercion.js.map +1 -1
- package/dist/src/util/comparison.d.ts +16 -3
- package/dist/src/util/comparison.d.ts.map +1 -1
- package/dist/src/util/comparison.js +21 -5
- package/dist/src/util/comparison.js.map +1 -1
- package/dist/src/util/key-serializer.d.ts +46 -0
- package/dist/src/util/key-serializer.d.ts.map +1 -1
- package/dist/src/util/key-serializer.js +47 -0
- package/dist/src/util/key-serializer.js.map +1 -1
- package/dist/src/util/value-set.d.ts +21 -0
- package/dist/src/util/value-set.d.ts.map +1 -0
- package/dist/src/util/value-set.js +22 -0
- package/dist/src/util/value-set.js.map +1 -0
- package/dist/src/vtab/capabilities.d.ts +1 -1
- package/dist/src/vtab/events.d.ts +5 -1
- package/dist/src/vtab/events.d.ts.map +1 -1
- package/dist/src/vtab/events.js.map +1 -1
- package/dist/src/vtab/memory/layer/alter-column.d.ts +147 -0
- package/dist/src/vtab/memory/layer/alter-column.d.ts.map +1 -0
- package/dist/src/vtab/memory/layer/alter-column.js +214 -0
- package/dist/src/vtab/memory/layer/alter-column.js.map +1 -0
- package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/base.js +4 -3
- package/dist/src/vtab/memory/layer/base.js.map +1 -1
- package/dist/src/vtab/memory/layer/interface.d.ts +2 -2
- package/dist/src/vtab/memory/layer/interface.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts +176 -25
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +572 -495
- package/dist/src/vtab/memory/layer/manager.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 +32 -5
- package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.d.ts +101 -15
- package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.js +133 -45
- package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
- package/dist/src/vtab/memory/module.d.ts.map +1 -1
- package/dist/src/vtab/memory/module.js +2 -1
- 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 +11 -6
- package/dist/src/vtab/memory/table.js.map +1 -1
- package/dist/src/vtab/module.d.ts +51 -21
- package/dist/src/vtab/module.d.ts.map +1 -1
- package/dist/src/vtab/table.d.ts +1 -1
- package/dist/src/vtab/table.js +1 -1
- package/package.json +3 -3
|
@@ -3,12 +3,18 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Required Characteristics:
|
|
5
5
|
* - Node must be a logical JoinNode (not already a physical join)
|
|
6
|
-
* - Node must have an equi-join predicate for hash/merge
|
|
6
|
+
* - Node must have an equi-join predicate for hash/merge/index-NL consideration
|
|
7
|
+
* - Neither side may be correlated (a correlated side must keep the
|
|
8
|
+
* nested-loop driver — hash/merge drain a side outside any outer row's scope)
|
|
7
9
|
*
|
|
8
10
|
* Applied When:
|
|
9
|
-
* - Logical JoinNode with equi-join predicates where hash
|
|
11
|
+
* - Logical JoinNode with equi-join predicates where hash join, merge join, or
|
|
12
|
+
* an index-nested-loop (per-outer-row seek into the inner side, built by
|
|
13
|
+
* `index-nested-loop.ts`) is cheaper than the plain nested loop
|
|
10
14
|
*
|
|
11
|
-
* Benefits: Replaces O(n*m) nested loop with O(n+m) hash/merge join
|
|
15
|
+
* Benefits: Replaces the O(n*m) nested loop with an O(n+m) hash/merge join, or
|
|
16
|
+
* with an O(n·seek) index-nested-loop when the inner side's module can answer
|
|
17
|
+
* an equality seek on the join key
|
|
12
18
|
*/
|
|
13
19
|
import { createLogger } from '../../../common/logger.js';
|
|
14
20
|
import { JoinNode } from '../../nodes/join-node.js';
|
|
@@ -17,8 +23,11 @@ import { MergeJoinNode } from '../../nodes/merge-join-node.js';
|
|
|
17
23
|
import { SortNode } from '../../nodes/sort.js';
|
|
18
24
|
import { ColumnReferenceNode } from '../../nodes/reference.js';
|
|
19
25
|
import { nestedLoopJoinCost, hashJoinCost, mergeJoinCost } from '../../cost/index.js';
|
|
20
|
-
import { extractEquiPairs,
|
|
26
|
+
import { extractEquiPairs, isOrderedOnEquiPairs, reorderEquiPairsForMerge, } from './equi-pair-extractor.js';
|
|
21
27
|
import { PlanNodeCharacteristics } from '../../framework/characteristics.js';
|
|
28
|
+
import { isCorrelatedSubquery } from '../../cache/correlation-detector.js';
|
|
29
|
+
import { physicalSourceRows } from '../../util/row-estimates.js';
|
|
30
|
+
import { tryIndexNestedLoop } from './index-nested-loop.js';
|
|
22
31
|
const log = createLogger('optimizer:rule:join-physical-selection');
|
|
23
32
|
/**
|
|
24
33
|
* Create a SortNode that sorts a source on the equi-pair columns for this side.
|
|
@@ -40,15 +49,18 @@ function createSortForEquiPairs(source, equiPairs, side, scope) {
|
|
|
40
49
|
});
|
|
41
50
|
return new SortNode(scope, source, sortKeys);
|
|
42
51
|
}
|
|
43
|
-
export function ruleJoinPhysicalSelection(node,
|
|
52
|
+
export function ruleJoinPhysicalSelection(node, context) {
|
|
44
53
|
// Guard: only apply to logical JoinNode, not already-physical nodes
|
|
45
54
|
if (!(node instanceof JoinNode))
|
|
46
55
|
return null;
|
|
47
|
-
// A
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
|
|
56
|
+
// A correlated side must keep the nested-loop driver: hash and merge both
|
|
57
|
+
// drain a side once, outside any outer row's scope, so a subtree reading
|
|
58
|
+
// outer columns would resolve against no row (LATERAL is a parsed, supported
|
|
59
|
+
// join form, so `join lateral (…) on <equality>` reaches this rule with a
|
|
60
|
+
// correlated right side — converting it to a hash join raised "No row
|
|
61
|
+
// context found" at runtime). This is also what makes the index-nested-loop
|
|
62
|
+
// rewrite below idempotent: its own output has a correlated right side.
|
|
63
|
+
if (isCorrelatedSubquery(node.left) || isCorrelatedSubquery(node.right))
|
|
52
64
|
return null;
|
|
53
65
|
const joinType = node.joinType;
|
|
54
66
|
// Support INNER, LEFT, SEMI, and ANTI joins
|
|
@@ -59,20 +71,50 @@ export function ruleJoinPhysicalSelection(node, _context) {
|
|
|
59
71
|
const rightAttrs = node.right.getAttributes();
|
|
60
72
|
const leftAttrIds = new Set(leftAttrs.map(a => a.id));
|
|
61
73
|
const rightAttrIds = new Set(rightAttrs.map(a => a.id));
|
|
62
|
-
// Try to extract equi-join pairs from condition
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
extracted = extractEquiPairs(node.condition, leftAttrIds, rightAttrIds);
|
|
66
|
-
}
|
|
67
|
-
else if (node.usingColumns) {
|
|
68
|
-
extracted = extractEquiPairsFromUsing(node.usingColumns, leftAttrs, rightAttrs);
|
|
69
|
-
}
|
|
74
|
+
// Try to extract equi-join pairs from the condition. A USING join has one too —
|
|
75
|
+
// `buildUsingCondition` desugars it at build time — so there is no separate path.
|
|
76
|
+
const extracted = extractEquiPairs(node.condition, leftAttrIds, rightAttrIds);
|
|
70
77
|
if (!extracted || extracted.equiPairs.length === 0)
|
|
71
78
|
return null;
|
|
72
|
-
// Cost comparison: nested loop vs hash join vs merge join
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
// Cost comparison: nested loop vs hash join vs merge join vs index-nested-loop.
|
|
80
|
+
// Physical relay first: by PostOptimization both sides are physical access
|
|
81
|
+
// nodes (or wrappers over them) which declare no logical `estimatedRows`
|
|
82
|
+
// getter — the catalog-derived count lives in `physical.estimatedRows` (see
|
|
83
|
+
// planner/util/row-estimates.ts). `||` not `??`: 0 is the un-analyzed
|
|
84
|
+
// "unknown" sentinel, not "empty" (same collapse rule-select-access-path
|
|
85
|
+
// applies), so an un-analyzed table costs exactly as it did under the old
|
|
86
|
+
// logical-getter read (which yielded undefined → 100).
|
|
87
|
+
const leftRows = physicalSourceRows(node.left.physical, node.left) || 100;
|
|
88
|
+
const rightRows = physicalSourceRows(node.right.physical, node.right) || 100;
|
|
75
89
|
const nlCost = nestedLoopJoinCost(leftRows, rightRows);
|
|
90
|
+
// Index-nested-loop candidate: the logical JoinNode survives with its right
|
|
91
|
+
// leaf replaced by a per-outer-row correlated IndexSeek. Considered BEFORE
|
|
92
|
+
// the existence early-return below — index-NL keeps the nested-loop emitter
|
|
93
|
+
// (the only one that derives `exists … as` flag bits) and `withChildren`
|
|
94
|
+
// threads `existence` verbatim, so existence joins CAN take this path,
|
|
95
|
+
// unlike hash/merge which drop the appended flag column.
|
|
96
|
+
const indexNL = tryIndexNestedLoop(node, extracted.equiPairs, leftRows, context);
|
|
97
|
+
// Rebuild with the seek-bearing right side, KEEPING the ON condition on the
|
|
98
|
+
// join. It is redundant when the seek is exact, but it is the safety net
|
|
99
|
+
// when the seek over-fetches (a COARSER_SAFE collation cover, a module
|
|
100
|
+
// returning a superset) — and it costs one predicate evaluation per emitted
|
|
101
|
+
// row, not per scanned row.
|
|
102
|
+
const rebuildWithIndexNL = () => {
|
|
103
|
+
log('Selecting index-nested-loop join (cost=%.2f) for %d outer rows', indexNL.cost, leftRows);
|
|
104
|
+
return node.withChildren(node.condition
|
|
105
|
+
? [node.left, indexNL.newRight, node.condition]
|
|
106
|
+
: [node.left, indexNL.newRight]);
|
|
107
|
+
};
|
|
108
|
+
// A join exposing `exists … as` match flags stays the nested-loop JoinNode (the
|
|
109
|
+
// only emitter that derives the flag bit); the physical Bloom/Merge variants do
|
|
110
|
+
// not carry or emit the appended flag column, so converting would drop it. Read
|
|
111
|
+
// half: existence joins forgo hash/merge selection — documented limitation.
|
|
112
|
+
// Index-NL remains available (see above): only plain NL and index-NL compete.
|
|
113
|
+
if (node.hasExistenceColumns) {
|
|
114
|
+
if (indexNL && indexNL.cost < nlCost)
|
|
115
|
+
return rebuildWithIndexNL();
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
76
118
|
// Hash join cost: build side is the smaller input
|
|
77
119
|
const buildRows = Math.min(leftRows, rightRows);
|
|
78
120
|
const probeRows = Math.max(leftRows, rightRows);
|
|
@@ -102,21 +144,35 @@ export function ruleJoinPhysicalSelection(node, _context) {
|
|
|
102
144
|
const mergeCostValue = mergeAvailable
|
|
103
145
|
? mergeJoinCost(leftRows, rightRows, !leftOrdered, !rightOrdered)
|
|
104
146
|
: Infinity;
|
|
147
|
+
// Hash and merge each scan the inner side once, so the inner subtree's
|
|
148
|
+
// first-row latency is charged ONCE to each — locally here, not in the
|
|
149
|
+
// shared cost functions (which other callers use latency-free). Index-NL's
|
|
150
|
+
// formula charges it per outer row (per seek). Plain nested-loop's formula
|
|
151
|
+
// is deliberately left alone: it is the no-change fallback, and if it wins
|
|
152
|
+
// nothing is rewritten.
|
|
153
|
+
const rightLatencyMs = node.right.physical.expectedLatencyMs ?? 0;
|
|
105
154
|
let bestAlgo = 'nested-loop';
|
|
106
155
|
let bestCost = nlCost;
|
|
107
|
-
if (hashCostValue < bestCost) {
|
|
156
|
+
if (hashCostValue + rightLatencyMs < bestCost) {
|
|
108
157
|
bestAlgo = 'hash';
|
|
109
|
-
bestCost = hashCostValue;
|
|
158
|
+
bestCost = hashCostValue + rightLatencyMs;
|
|
110
159
|
}
|
|
111
|
-
if (mergeCostValue < bestCost) {
|
|
160
|
+
if (mergeCostValue + rightLatencyMs < bestCost) {
|
|
112
161
|
bestAlgo = 'merge';
|
|
113
|
-
bestCost = mergeCostValue;
|
|
162
|
+
bestCost = mergeCostValue + rightLatencyMs;
|
|
163
|
+
}
|
|
164
|
+
if (indexNL && indexNL.cost < bestCost) {
|
|
165
|
+
bestAlgo = 'index-nl';
|
|
166
|
+
bestCost = indexNL.cost;
|
|
114
167
|
}
|
|
115
168
|
if (bestAlgo === 'nested-loop') {
|
|
116
|
-
log('Nested loop cheapest (nl=%.2f, hash=%.2f, merge=%.2f) for %d x %d rows', nlCost, hashCostValue, mergeCostValue, leftRows, rightRows);
|
|
169
|
+
log('Nested loop cheapest (nl=%.2f, hash=%.2f, merge=%.2f, indexNL=%.2f) for %d x %d rows', nlCost, hashCostValue, mergeCostValue, indexNL?.cost ?? Infinity, leftRows, rightRows);
|
|
117
170
|
return null;
|
|
118
171
|
}
|
|
119
|
-
|
|
172
|
+
if (bestAlgo === 'index-nl') {
|
|
173
|
+
return rebuildWithIndexNL();
|
|
174
|
+
}
|
|
175
|
+
log('Selecting %s join (nl=%.2f, hash=%.2f, merge=%.2f, indexNL=%.2f) for %d x %d rows', bestAlgo, nlCost, hashCostValue, mergeCostValue, indexNL?.cost ?? Infinity, leftRows, rightRows);
|
|
120
176
|
// Preserve attribute IDs from the logical JoinNode
|
|
121
177
|
const preserveAttrs = node.getAttributes().slice();
|
|
122
178
|
if (bestAlgo === 'merge') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-join-physical-selection.js","sourceRoot":"","sources":["../../../../../src/planner/rules/join/rule-join-physical-selection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"rule-join-physical-selection.js","sourceRoot":"","sources":["../../../../../src/planner/rules/join/rule-join-physical-selection.ts"],"names":[],"mappings":"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"}
|
|
@@ -30,7 +30,7 @@ import { JoinNode } from '../../nodes/join-node.js';
|
|
|
30
30
|
import { MergeJoinNode } from '../../nodes/merge-join-node.js';
|
|
31
31
|
import { nestedLoopJoinCost, hashJoinCost, mergeJoinCost } from '../../cost/index.js';
|
|
32
32
|
import { PlanNodeCharacteristics } from '../../framework/characteristics.js';
|
|
33
|
-
import { extractEquiPairs,
|
|
33
|
+
import { extractEquiPairs, combineResidual, isMergeReadyOnAllPairs } from './equi-pair-extractor.js';
|
|
34
34
|
const log = createLogger('optimizer:rule:monotonic-merge-join');
|
|
35
35
|
export function ruleMonotonicMergeJoin(node, _context) {
|
|
36
36
|
if (!(node instanceof JoinNode))
|
|
@@ -46,9 +46,9 @@ export function ruleMonotonicMergeJoin(node, _context) {
|
|
|
46
46
|
const rightAttrs = node.right.getAttributes();
|
|
47
47
|
const leftAttrIds = new Set(leftAttrs.map(a => a.id));
|
|
48
48
|
const rightAttrIds = new Set(rightAttrs.map(a => a.id));
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
// A USING join carries a desugared condition (see `buildUsingCondition`), so the
|
|
50
|
+
// one extractor covers both spellings.
|
|
51
|
+
const extracted = extractEquiPairs(node.condition, leftAttrIds, rightAttrIds);
|
|
52
52
|
if (!extracted || extracted.equiPairs.length === 0)
|
|
53
53
|
return null;
|
|
54
54
|
// Defer to `rule-join-physical-selection` whenever both sides' physical
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-monotonic-merge-join.js","sourceRoot":"","sources":["../../../../../src/planner/rules/join/rule-monotonic-merge-join.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"rule-monotonic-merge-join.js","sourceRoot":"","sources":["../../../../../src/planner/rules/join/rule-monotonic-merge-join.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAErG,MAAM,GAAG,GAAG,YAAY,CAAC,qCAAqC,CAAC,CAAC;AAEhE,MAAM,UAAU,sBAAsB,CAAC,IAAc,EAAE,QAAoB;IAC1E,IAAI,CAAC,CAAC,IAAI,YAAY,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7C,+DAA+D;IAC/D,4EAA4E;IAC5E,IAAI,IAAI,CAAC,mBAAmB;QAAE,OAAO,IAAI,CAAC;IAE1C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAE3G,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;IAC5C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;IAC9C,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAExD,iFAAiF;IACjF,uCAAuC;IACvC,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IAC9E,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEhE,wEAAwE;IACxE,mEAAmE;IACnE,gEAAgE;IAChE,0EAA0E;IAC1E,0EAA0E;IAC1E,uEAAuE;IACvE,uEAAuE;IACvE,oEAAoE;IACpE,IAAI,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC;WACjD,sBAAsB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpF,MAAM,OAAO,GAAG,uBAAuB,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAG,uBAAuB,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE/D,uEAAuE;IACvE,yEAAyE;IACzE,8EAA8E;IAC9E,2EAA2E;IAC3E,qEAAqE;IACrE,2EAA2E;IAC3E,gFAAgF;IAChF,MAAM,cAAc,GAAa,EAAE,CAAC;IACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,SAAS;QACpC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC;QACnF,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,CAAC;QACrF,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,CAAC;IACD,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE7C,yEAAyE;IACzE,2EAA2E;IAC3E,yEAAyE;IACzE,2DAA2D;IAC3D,wEAAwE;IACxE,2EAA2E;IAC3E,MAAM,YAAY,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;IACvC,MAAM,OAAO,GAAmB,CAAC,SAAS,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;IAEpE,+EAA+E;IAC/E,yEAAyE;IACzE,kEAAkE;IAClE,wDAAwD;IACxD,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrD,IAAI,CAAC,KAAK,YAAY;YAAE,SAAS;QACjC,MAAM,IAAI,GAAG,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IACD,MAAM,QAAQ,GAAG,eAAe,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE7D,yEAAyE;IACzE,uCAAuC;IACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,IAAI,GAAG,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,GAAG,CAAC;IAClD,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;IACzF,MAAM,GAAG,GAAG,kBAAkB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACpD,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE,CAAC;QACnC,GAAG,CAAC,uFAAuF,EAC1F,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,GAAG,CAAC,oFAAoF,EACvF,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IAEpE,OAAO,IAAI,aAAa,CACvB,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,IAAI,EACT,IAAI,CAAC,KAAK,EACV,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,IAAI,CAAC,aAAa,EAAE,CAAC,KAAK,EAAiB,CAC3C,CAAC;AACH,CAAC"}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Rule: Filter Conjunct Ordering
|
|
3
3
|
*
|
|
4
|
-
* Reorders the top-level AND conjuncts of a FilterNode predicate
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* conjunct
|
|
4
|
+
* Reorders the top-level AND conjuncts of a FilterNode predicate so the
|
|
5
|
+
* emitter's conjunct early exit (runtime/emit/filter.ts) skips expensive
|
|
6
|
+
* conjuncts for every row an earlier conjunct already rejects. The sort key is
|
|
7
|
+
* `compareConjunctRank` (`cost/conjunct-cost.ts`): cost tier first, then —
|
|
8
|
+
* within a tier — estimated filtering bought per unit work,
|
|
9
|
+
* `(1 - selectivity) / cost` descending, with plain subtree cost breaking
|
|
10
|
+
* ratio ties.
|
|
11
|
+
*
|
|
12
|
+
* Selectivity comes from the shared per-conjunct estimator
|
|
13
|
+
* (`stats/conjunct-selectivity.ts`), gated on `statsOnlySelectivity` — real
|
|
14
|
+
* statistics only, never the NaiveStatsProvider's fabricated per-nodeType
|
|
15
|
+
* guess, whose numbers differ BY NODE KIND and would reorder conjuncts on no
|
|
16
|
+
* information at all. When no conjunct gets a real estimate the rule sorts
|
|
17
|
+
* with `compareConjunctCost` verbatim — an explicit branch, so a query with no
|
|
18
|
+
* ANALYZE'd statistics orders bit-identically to the cost-only rule.
|
|
8
19
|
*
|
|
9
20
|
* Soundness: SQL AND is commutative under three-valued logic, and a Filter
|
|
10
21
|
* rejects on both `false` and `NULL`, so any permutation of the conjuncts
|
|
@@ -20,11 +31,13 @@
|
|
|
20
31
|
* test/logic/07.7.4-where-conjunct-ordering.sqllogic), and a cheap guard
|
|
21
32
|
* already sorts first. It only becomes real if a scalar function that THROWS
|
|
22
33
|
* on bad input ships and a query guards it with a conjunct in a more expensive
|
|
23
|
-
* tier (e.g. `exists (...) and parse(x) > 0`).
|
|
24
|
-
*
|
|
25
|
-
*
|
|
34
|
+
* tier (e.g. `exists (...) and parse(x) > 0`). Selectivity adds a SECOND route
|
|
35
|
+
* past a guard: a statistics-strong conjunct can now sort ahead of a cheaper
|
|
36
|
+
* same-tier guard even where cost alone would have kept the guard first. At
|
|
37
|
+
* that point either gate the reorder on a per-function "may raise" trait or
|
|
38
|
+
* tell users to guard with CASE, as PostgreSQL does.
|
|
26
39
|
*/
|
|
27
40
|
import type { PlanNode } from '../../nodes/plan-node.js';
|
|
28
41
|
import type { OptContext } from '../../framework/context.js';
|
|
29
|
-
export declare function ruleFilterConjunctOrdering(node: PlanNode,
|
|
42
|
+
export declare function ruleFilterConjunctOrdering(node: PlanNode, context: OptContext): PlanNode | null;
|
|
30
43
|
//# sourceMappingURL=rule-filter-conjunct-ordering.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-filter-conjunct-ordering.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/predicate/rule-filter-conjunct-ordering.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"rule-filter-conjunct-ordering.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/predicate/rule-filter-conjunct-ordering.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAkB,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAc7D,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,CA8C/F"}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Rule: Filter Conjunct Ordering
|
|
3
3
|
*
|
|
4
|
-
* Reorders the top-level AND conjuncts of a FilterNode predicate
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* conjunct
|
|
4
|
+
* Reorders the top-level AND conjuncts of a FilterNode predicate so the
|
|
5
|
+
* emitter's conjunct early exit (runtime/emit/filter.ts) skips expensive
|
|
6
|
+
* conjuncts for every row an earlier conjunct already rejects. The sort key is
|
|
7
|
+
* `compareConjunctRank` (`cost/conjunct-cost.ts`): cost tier first, then —
|
|
8
|
+
* within a tier — estimated filtering bought per unit work,
|
|
9
|
+
* `(1 - selectivity) / cost` descending, with plain subtree cost breaking
|
|
10
|
+
* ratio ties.
|
|
11
|
+
*
|
|
12
|
+
* Selectivity comes from the shared per-conjunct estimator
|
|
13
|
+
* (`stats/conjunct-selectivity.ts`), gated on `statsOnlySelectivity` — real
|
|
14
|
+
* statistics only, never the NaiveStatsProvider's fabricated per-nodeType
|
|
15
|
+
* guess, whose numbers differ BY NODE KIND and would reorder conjuncts on no
|
|
16
|
+
* information at all. When no conjunct gets a real estimate the rule sorts
|
|
17
|
+
* with `compareConjunctCost` verbatim — an explicit branch, so a query with no
|
|
18
|
+
* ANALYZE'd statistics orders bit-identically to the cost-only rule.
|
|
8
19
|
*
|
|
9
20
|
* Soundness: SQL AND is commutative under three-valued logic, and a Filter
|
|
10
21
|
* rejects on both `false` and `NULL`, so any permutation of the conjuncts
|
|
@@ -20,18 +31,22 @@
|
|
|
20
31
|
* test/logic/07.7.4-where-conjunct-ordering.sqllogic), and a cheap guard
|
|
21
32
|
* already sorts first. It only becomes real if a scalar function that THROWS
|
|
22
33
|
* on bad input ships and a query guards it with a conjunct in a more expensive
|
|
23
|
-
* tier (e.g. `exists (...) and parse(x) > 0`).
|
|
24
|
-
*
|
|
25
|
-
*
|
|
34
|
+
* tier (e.g. `exists (...) and parse(x) > 0`). Selectivity adds a SECOND route
|
|
35
|
+
* past a guard: a statistics-strong conjunct can now sort ahead of a cheaper
|
|
36
|
+
* same-tier guard even where cost alone would have kept the guard first. At
|
|
37
|
+
* that point either gate the reorder on a per-function "may raise" trait or
|
|
38
|
+
* tell users to guard with CASE, as PostgreSQL does.
|
|
26
39
|
*/
|
|
27
40
|
import { createLogger } from '../../../common/logger.js';
|
|
28
41
|
import { PlanNodeType } from '../../nodes/plan-node-type.js';
|
|
29
42
|
import { FilterNode } from '../../nodes/filter.js';
|
|
30
43
|
import { PlanNodeCharacteristics } from '../../framework/characteristics.js';
|
|
31
44
|
import { splitConjuncts, combineConjuncts } from '../../analysis/predicate-conjuncts.js';
|
|
32
|
-
import { classifyConjunctCost, compareConjunctCost } from '../../cost/conjunct-cost.js';
|
|
45
|
+
import { classifyConjunctCost, compareConjunctCost, compareConjunctRank, UNKNOWN_CONJUNCT_SELECTIVITY, } from '../../cost/conjunct-cost.js';
|
|
46
|
+
import { collectColumnOrigins } from '../../util/column-origins.js';
|
|
47
|
+
import { estimateConjunctSelectivity } from '../../stats/conjunct-selectivity.js';
|
|
33
48
|
const log = createLogger('optimizer:rule:filter-conjunct-ordering');
|
|
34
|
-
export function ruleFilterConjunctOrdering(node,
|
|
49
|
+
export function ruleFilterConjunctOrdering(node, context) {
|
|
35
50
|
if (node.nodeType !== PlanNodeType.Filter)
|
|
36
51
|
return null;
|
|
37
52
|
const filter = node;
|
|
@@ -43,21 +58,62 @@ export function ruleFilterConjunctOrdering(node, _context) {
|
|
|
43
58
|
// side effect. This guard is what makes sideEffectMode 'safe' honest.
|
|
44
59
|
if (conjuncts.some(c => PlanNodeCharacteristics.subtreeHasSideEffects(c)))
|
|
45
60
|
return null;
|
|
46
|
-
const
|
|
47
|
-
|
|
61
|
+
const costs = conjuncts.map(classifyConjunctCost);
|
|
62
|
+
const selectivities = estimateSelectivities(filter, conjuncts, context);
|
|
63
|
+
// Array.prototype.sort is stable, so equal-key conjuncts keep source order —
|
|
48
64
|
// the determinism requirement.
|
|
49
|
-
|
|
65
|
+
let sorted;
|
|
66
|
+
if (selectivities === undefined) {
|
|
67
|
+
// No conjunct got a real estimate (or the provider has none to give):
|
|
68
|
+
// sort with the cost-only comparator verbatim, so the order is
|
|
69
|
+
// bit-identical to the pre-selectivity rule.
|
|
70
|
+
const ranked = conjuncts.map((conjunct, i) => ({ conjunct, cost: costs[i] }));
|
|
71
|
+
sorted = [...ranked].sort((a, b) => compareConjunctCost(a.cost, b.cost));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
const ranked = conjuncts.map((conjunct, i) => ({
|
|
75
|
+
conjunct,
|
|
76
|
+
cost: { ...costs[i], selectivity: selectivities[i] ?? UNKNOWN_CONJUNCT_SELECTIVITY },
|
|
77
|
+
}));
|
|
78
|
+
sorted = [...ranked].sort((a, b) => compareConjunctRank(a.cost, b.cost));
|
|
79
|
+
}
|
|
50
80
|
// Already ordered → null. This is not an optimization: it is the fixed point
|
|
51
81
|
// that stops the rewrite loop (an unconditional rebuild would flip conjunct
|
|
52
|
-
// order forever).
|
|
82
|
+
// order forever). The key depends only on the node and on `context.stats`,
|
|
83
|
+
// which is stable within one optimize(), so the sort is idempotent.
|
|
53
84
|
if (sorted.every((entry, i) => entry.conjunct === conjuncts[i]))
|
|
54
85
|
return null;
|
|
55
86
|
// length >= 2, so combineConjuncts cannot return null.
|
|
56
87
|
const reordered = combineConjuncts(sorted.map(entry => entry.conjunct));
|
|
57
|
-
log(`Reordered ${conjuncts.length} conjuncts
|
|
88
|
+
log(`Reordered ${conjuncts.length} conjuncts (${selectivities === undefined ? 'cost only' : 'cost + selectivity'})`);
|
|
58
89
|
// Construct directly rather than via withPredicate (which drops selectivity
|
|
59
90
|
// on any predicate change): reordering does not change the conjunct SET, so
|
|
60
91
|
// the estimate stamped by rule-filter-selectivity remains exactly as valid.
|
|
61
92
|
return new FilterNode(filter.scope, filter.source, reordered, undefined, filter.selectivity);
|
|
62
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Per-conjunct selectivities aligned with `conjuncts`, or undefined when the
|
|
96
|
+
* whole filter must fall back to cost-only ordering: the provider implements no
|
|
97
|
+
* `statsOnlySelectivity`, the source exposes no base-column origins (HAVING over
|
|
98
|
+
* an aggregate, a set operation, a `values` clause, …), or no conjunct could be
|
|
99
|
+
* estimated. The provider check comes first so the origins walk — a full pass
|
|
100
|
+
* over the source subtree — is skipped outright for a provider that omits the
|
|
101
|
+
* method.
|
|
102
|
+
*
|
|
103
|
+
* NOTE (tripwire): that short-circuit does NOT help the production
|
|
104
|
+
* `CatalogStatsProvider`, which always implements `statsOnlySelectivity`. A
|
|
105
|
+
* database with nothing ANALYZEd therefore still pays one origins walk per
|
|
106
|
+
* multi-conjunct Filter here, on top of the one `rule-filter-selectivity`
|
|
107
|
+
* already pays. Unmeasured; if it ever profiles hot, memoize the map per pass on
|
|
108
|
+
* OptContext keyed by the source node — the fix noted at that rule.
|
|
109
|
+
*/
|
|
110
|
+
function estimateSelectivities(filter, conjuncts, context) {
|
|
111
|
+
if (context.stats.statsOnlySelectivity == null)
|
|
112
|
+
return undefined;
|
|
113
|
+
const origins = collectColumnOrigins(filter.source);
|
|
114
|
+
if (origins.size === 0)
|
|
115
|
+
return undefined;
|
|
116
|
+
const estimates = conjuncts.map(c => estimateConjunctSelectivity(c, origins, context));
|
|
117
|
+
return estimates.some(e => e !== undefined) ? estimates : undefined;
|
|
118
|
+
}
|
|
63
119
|
//# sourceMappingURL=rule-filter-conjunct-ordering.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-filter-conjunct-ordering.js","sourceRoot":"","sources":["../../../../../src/planner/rules/predicate/rule-filter-conjunct-ordering.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"rule-filter-conjunct-ordering.js","sourceRoot":"","sources":["../../../../../src/planner/rules/predicate/rule-filter-conjunct-ordering.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,10 +4,25 @@
|
|
|
4
4
|
* Stamps a stats-derived selectivity onto a FilterNode so its `estimatedRows`
|
|
5
5
|
* reflects real column statistics instead of the flat DEFAULT_FILTER_SELECTIVITY.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* Registered TWICE, both bottom-up:
|
|
8
|
+
*
|
|
9
|
+
* - `filter-selectivity` (Physical pass), which fires AFTER the Structural pass —
|
|
10
|
+
* predicate-pushdown / grow-retrieve have already put the Filter in its final
|
|
11
|
+
* position over its final source, so the source subtree is settled (and may carry
|
|
12
|
+
* physical access nodes between the join and its table references). This stamp is
|
|
13
|
+
* what the physical and PostOptimization cost readers consult.
|
|
14
|
+
* - `filter-selectivity-restamp` (PostOptimization pass, registered first in that
|
|
15
|
+
* pass), which recovers the estimate for a Filter whose stamp was dropped by
|
|
16
|
+
* `FilterNode.withChildren` because PostOptimization rewrote something inside its
|
|
17
|
+
* predicate — `scalar-subquery-cache` wrapping an uncorrelated scalar subquery's
|
|
18
|
+
* inner re-mints every scalar ancestor up to the predicate. Without it, any query
|
|
19
|
+
* with a subquery in its `where` plans on the flat DEFAULT_FILTER_SELECTIVITY.
|
|
20
|
+
*
|
|
21
|
+
* The `selectivity !== undefined` guard below makes the second registration a no-op on
|
|
22
|
+
* every Filter whose stamp survived, so it only ever fills in, never overwrites. Both
|
|
23
|
+
* firings read a physical source subtree (`select-access-path` has already replaced
|
|
24
|
+
* Retrieve with an access node by the Physical pass's own bottom-up order);
|
|
25
|
+
* PostOptimization sources are the same shape or further lowered.
|
|
11
26
|
*
|
|
12
27
|
* Node-level accessors (`estimatedRows` / `computePhysical`) carry no OptContext,
|
|
13
28
|
* so a Filter cannot consult `context.stats` from inside itself. This rule holds
|
|
@@ -15,21 +30,31 @@
|
|
|
15
30
|
* flows through `estimatedRows` automatically.
|
|
16
31
|
*
|
|
17
32
|
* Two paths:
|
|
18
|
-
* - **single-table** — `
|
|
19
|
-
* Filter
|
|
20
|
-
* boolean structure itself.
|
|
21
|
-
* - **multi-relation** — the source spans several tables (a join)
|
|
22
|
-
* predicate into conjuncts, attribute each to the base
|
|
23
|
-
* come from, estimate per conjunct, and combine.
|
|
33
|
+
* - **single-table** — `extractRowSourceTableSchema` finds one base table under
|
|
34
|
+
* the Filter *whose rows are the ones arriving at it*; hand the whole predicate
|
|
35
|
+
* to the provider, which decomposes its boolean structure itself.
|
|
36
|
+
* - **multi-relation** — the source spans several tables (a join), or the strict
|
|
37
|
+
* walk declined. Split the predicate into conjuncts, attribute each to the base
|
|
38
|
+
* table(s) its columns come from, estimate per conjunct, and combine.
|
|
39
|
+
*
|
|
40
|
+
* The strict walk matters because an aggregate's output rows are a different
|
|
41
|
+
* population from its source's, so no fraction of the base table describes them at
|
|
42
|
+
* all: over `select cat, count(*) as ct from o group by cat having ct > 2` the
|
|
43
|
+
* permissive `extractTableSchema` reaches `o` through the aggregate, but `o`'s row
|
|
44
|
+
* count and column distributions say nothing about how many GROUPS survive `ct > 2`.
|
|
45
|
+
*
|
|
46
|
+
* Both paths hand the provider a {@link ColumnStatsResolver} built from
|
|
47
|
+
* `collectColumnOrigins`, so a column in the predicate is matched to statistics by
|
|
48
|
+
* ATTRIBUTE IDENTITY rather than by the name in its AST. `ProjectNode` forwards the
|
|
49
|
+
* source attribute id for a bare column reference and mints a fresh one for a
|
|
50
|
+
* computed expression, which is exactly the distinction wanted: `select cat as qty`
|
|
51
|
+
* still reads `o.cat`'s statistics, while `select id * 7 as qty` reads none rather
|
|
52
|
+
* than borrowing `o.qty`'s because the alias happens to collide. A CTE reference
|
|
53
|
+
* republishes its body's columns under per-reference relation instances, so a `with`
|
|
54
|
+
* clause estimates like the equivalent subquery while the two arms of a CTE self-join
|
|
55
|
+
* still count as two relations — see `column-origins.ts`.
|
|
24
56
|
*/
|
|
25
57
|
import type { PlanNode } from '../../nodes/plan-node.js';
|
|
26
58
|
import type { OptContext } from '../../framework/context.js';
|
|
27
|
-
/**
|
|
28
|
-
* Selectivity of an inequality (`<` `<=` `>` `>=`) comparing a column of one table
|
|
29
|
-
* to a column of another. The standard uniform-distribution estimate for a
|
|
30
|
-
* two-sided inequality is 1/3: there is no cross-table histogram, so nothing
|
|
31
|
-
* better than the uniform assumption is available here.
|
|
32
|
-
*/
|
|
33
|
-
export declare const CROSS_RELATION_INEQUALITY_SELECTIVITY: number;
|
|
34
59
|
export declare function ruleFilterSelectivity(node: PlanNode, context: OptContext): PlanNode | null;
|
|
35
60
|
//# sourceMappingURL=rule-filter-selectivity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-filter-selectivity.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/predicate/rule-filter-selectivity.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"rule-filter-selectivity.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/predicate/rule-filter-selectivity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAW7D,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,CAwC1F"}
|