@quereus/quereus 4.4.1 → 4.5.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 +1 -1
- package/dist/src/core/database-materialized-views-analysis.d.ts.map +1 -1
- package/dist/src/core/database-materialized-views-analysis.js +1 -0
- package/dist/src/core/database-materialized-views-analysis.js.map +1 -1
- package/dist/src/func/builtins/scalar.d.ts.map +1 -1
- package/dist/src/func/builtins/scalar.js +92 -3
- package/dist/src/func/builtins/scalar.js.map +1 -1
- package/dist/src/func/registration.d.ts +4 -0
- package/dist/src/func/registration.d.ts.map +1 -1
- package/dist/src/func/registration.js +1 -0
- package/dist/src/func/registration.js.map +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/planner/analysis/coarsened-key.d.ts +4 -3
- package/dist/src/planner/analysis/coarsened-key.d.ts.map +1 -1
- package/dist/src/planner/analysis/coarsened-key.js +37 -3
- package/dist/src/planner/analysis/coarsened-key.js.map +1 -1
- package/dist/src/planner/analysis/comparison-collation.d.ts +33 -3
- package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -1
- package/dist/src/planner/analysis/comparison-collation.js +36 -2
- package/dist/src/planner/analysis/comparison-collation.js.map +1 -1
- package/dist/src/planner/analysis/coverage-prover.d.ts +13 -2
- package/dist/src/planner/analysis/coverage-prover.d.ts.map +1 -1
- package/dist/src/planner/analysis/coverage-prover.js +10 -14
- package/dist/src/planner/analysis/coverage-prover.js.map +1 -1
- package/dist/src/planner/analysis/predicate-conjuncts.d.ts +10 -4
- package/dist/src/planner/analysis/predicate-conjuncts.d.ts.map +1 -1
- package/dist/src/planner/analysis/predicate-conjuncts.js +28 -7
- package/dist/src/planner/analysis/predicate-conjuncts.js.map +1 -1
- package/dist/src/planner/analysis/query-rewrite-matcher.d.ts.map +1 -1
- package/dist/src/planner/analysis/query-rewrite-matcher.js +8 -27
- package/dist/src/planner/analysis/query-rewrite-matcher.js.map +1 -1
- package/dist/src/planner/analysis/scalar-subqueries.d.ts +22 -3
- package/dist/src/planner/analysis/scalar-subqueries.d.ts.map +1 -1
- package/dist/src/planner/analysis/scalar-subqueries.js +32 -3
- package/dist/src/planner/analysis/scalar-subqueries.js.map +1 -1
- package/dist/src/planner/analysis/set-op-type-merge.d.ts +64 -0
- package/dist/src/planner/analysis/set-op-type-merge.d.ts.map +1 -0
- package/dist/src/planner/analysis/set-op-type-merge.js +97 -0
- package/dist/src/planner/analysis/set-op-type-merge.js.map +1 -0
- package/dist/src/planner/building/coercion.d.ts +78 -0
- package/dist/src/planner/building/coercion.d.ts.map +1 -0
- package/dist/src/planner/building/coercion.js +137 -0
- package/dist/src/planner/building/coercion.js.map +1 -0
- package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
- package/dist/src/planner/building/constraint-builder.js +5 -18
- package/dist/src/planner/building/constraint-builder.js.map +1 -1
- package/dist/src/planner/building/expression.d.ts.map +1 -1
- package/dist/src/planner/building/expression.js +1 -104
- 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 +8 -0
- package/dist/src/planner/building/function-call.js.map +1 -1
- package/dist/src/planner/building/select-compound.d.ts.map +1 -1
- package/dist/src/planner/building/select-compound.js +10 -6
- package/dist/src/planner/building/select-compound.js.map +1 -1
- package/dist/src/planner/cost/conjunct-cost.d.ts +42 -0
- package/dist/src/planner/cost/conjunct-cost.d.ts.map +1 -0
- package/dist/src/planner/cost/conjunct-cost.js +62 -0
- package/dist/src/planner/cost/conjunct-cost.js.map +1 -0
- package/dist/src/planner/mutation/propagate.d.ts.map +1 -1
- package/dist/src/planner/mutation/propagate.js +1 -0
- package/dist/src/planner/mutation/propagate.js.map +1 -1
- package/dist/src/planner/nodes/async-gather-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/async-gather-node.js +19 -8
- package/dist/src/planner/nodes/async-gather-node.js.map +1 -1
- package/dist/src/planner/nodes/bloom-join-node.d.ts +2 -0
- package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/bloom-join-node.js +10 -5
- package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
- package/dist/src/planner/nodes/join-node.d.ts +5 -0
- package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-node.js +8 -1
- package/dist/src/planner/nodes/join-node.js.map +1 -1
- package/dist/src/planner/nodes/join-utils.d.ts +57 -0
- package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-utils.js +47 -0
- package/dist/src/planner/nodes/join-utils.js.map +1 -1
- package/dist/src/planner/nodes/key-set-semi-join-node.d.ts +87 -0
- package/dist/src/planner/nodes/key-set-semi-join-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/key-set-semi-join-node.js +137 -0
- package/dist/src/planner/nodes/key-set-semi-join-node.js.map +1 -0
- package/dist/src/planner/nodes/merge-join-node.d.ts +2 -0
- package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/merge-join-node.js +14 -6
- package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.d.ts +1 -0
- package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.js +1 -0
- package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
- package/dist/src/planner/nodes/set-operation-node.d.ts +68 -16
- package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/set-operation-node.js +147 -26
- package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.d.ts +19 -1
- package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.js +13 -2
- package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
- package/dist/src/planner/optimizer.d.ts.map +1 -1
- package/dist/src/planner/optimizer.js +49 -0
- package/dist/src/planner/optimizer.js.map +1 -1
- package/dist/src/planner/rules/access/rule-key-set-seek.d.ts +68 -0
- package/dist/src/planner/rules/access/rule-key-set-seek.d.ts.map +1 -0
- package/dist/src/planner/rules/access/rule-key-set-seek.js +408 -0
- package/dist/src/planner/rules/access/rule-key-set-seek.js.map +1 -0
- package/dist/src/planner/rules/access/rule-monotonic-range-access.d.ts.map +1 -1
- package/dist/src/planner/rules/access/rule-monotonic-range-access.js +2 -2
- package/dist/src/planner/rules/access/rule-monotonic-range-access.js.map +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.d.ts +27 -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 +31 -11
- package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
- package/dist/src/planner/rules/join/equi-pair-extractor.d.ts +67 -41
- package/dist/src/planner/rules/join/equi-pair-extractor.d.ts.map +1 -1
- package/dist/src/planner/rules/join/equi-pair-extractor.js +72 -36
- package/dist/src/planner/rules/join/equi-pair-extractor.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-monotonic-merge-join.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-monotonic-merge-join.js +11 -1
- package/dist/src/planner/rules/join/rule-monotonic-merge-join.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts +1 -1
- package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +1 -1
- package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.d.ts +30 -0
- package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.d.ts.map +1 -0
- package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.js +63 -0
- package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.js.map +1 -0
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts +17 -1
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts.map +1 -1
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.js +206 -12
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts +3 -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 +13 -1
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -1
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.d.ts.map +1 -1
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +18 -3
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
- package/dist/src/planner/rules/shared/index-style-context.d.ts +17 -0
- package/dist/src/planner/rules/shared/index-style-context.d.ts.map +1 -1
- package/dist/src/planner/rules/shared/index-style-context.js +7 -0
- package/dist/src/planner/rules/shared/index-style-context.js.map +1 -1
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts +24 -6
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +175 -60
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
- package/dist/src/planner/stats/catalog-stats.d.ts +52 -0
- package/dist/src/planner/stats/catalog-stats.d.ts.map +1 -1
- package/dist/src/planner/stats/catalog-stats.js +151 -5
- package/dist/src/planner/stats/catalog-stats.js.map +1 -1
- package/dist/src/planner/stats/index.d.ts +15 -0
- 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/selectivity-combine.d.ts +53 -0
- package/dist/src/planner/stats/selectivity-combine.d.ts.map +1 -0
- package/dist/src/planner/stats/selectivity-combine.js +75 -0
- package/dist/src/planner/stats/selectivity-combine.js.map +1 -0
- package/dist/src/planner/util/column-origins.d.ts +58 -0
- package/dist/src/planner/util/column-origins.d.ts.map +1 -0
- package/dist/src/planner/util/column-origins.js +90 -0
- package/dist/src/planner/util/column-origins.js.map +1 -0
- package/dist/src/runtime/deferred-constraint-queue.d.ts +40 -0
- package/dist/src/runtime/deferred-constraint-queue.d.ts.map +1 -1
- package/dist/src/runtime/deferred-constraint-queue.js +90 -9
- package/dist/src/runtime/deferred-constraint-queue.js.map +1 -1
- package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/alter-table.js +6 -0
- package/dist/src/runtime/emit/alter-table.js.map +1 -1
- package/dist/src/runtime/emit/asof-scan.d.ts.map +1 -1
- package/dist/src/runtime/emit/asof-scan.js +8 -3
- package/dist/src/runtime/emit/asof-scan.js.map +1 -1
- package/dist/src/runtime/emit/between.d.ts.map +1 -1
- package/dist/src/runtime/emit/between.js +4 -38
- 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 +2 -23
- package/dist/src/runtime/emit/binary.js.map +1 -1
- package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -1
- package/dist/src/runtime/emit/bloom-join.js +6 -35
- package/dist/src/runtime/emit/bloom-join.js.map +1 -1
- package/dist/src/runtime/emit/case.d.ts.map +1 -1
- package/dist/src/runtime/emit/case.js +40 -6
- package/dist/src/runtime/emit/case.js.map +1 -1
- package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
- package/dist/src/runtime/emit/constraint-check.js +32 -8
- package/dist/src/runtime/emit/constraint-check.js.map +1 -1
- package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
- package/dist/src/runtime/emit/dml-executor.js +26 -23
- package/dist/src/runtime/emit/dml-executor.js.map +1 -1
- package/dist/src/runtime/emit/filter.d.ts +18 -0
- package/dist/src/runtime/emit/filter.d.ts.map +1 -1
- package/dist/src/runtime/emit/filter.js +52 -10
- package/dist/src/runtime/emit/filter.js.map +1 -1
- package/dist/src/runtime/emit/join-key-extractor.d.ts +46 -0
- package/dist/src/runtime/emit/join-key-extractor.d.ts.map +1 -0
- package/dist/src/runtime/emit/join-key-extractor.js +60 -0
- package/dist/src/runtime/emit/join-key-extractor.js.map +1 -0
- package/dist/src/runtime/emit/join.d.ts.map +1 -1
- package/dist/src/runtime/emit/join.js +36 -15
- package/dist/src/runtime/emit/join.js.map +1 -1
- package/dist/src/runtime/emit/key-set-semi-join.d.ts +29 -0
- package/dist/src/runtime/emit/key-set-semi-join.d.ts.map +1 -0
- package/dist/src/runtime/emit/key-set-semi-join.js +143 -0
- package/dist/src/runtime/emit/key-set-semi-join.js.map +1 -0
- package/dist/src/runtime/emit/merge-join.d.ts.map +1 -1
- package/dist/src/runtime/emit/merge-join.js +15 -8
- package/dist/src/runtime/emit/merge-join.js.map +1 -1
- package/dist/src/runtime/emit/operand-comparator.d.ts +40 -0
- package/dist/src/runtime/emit/operand-comparator.d.ts.map +1 -0
- package/dist/src/runtime/emit/operand-comparator.js +59 -0
- package/dist/src/runtime/emit/operand-comparator.js.map +1 -0
- package/dist/src/runtime/emit/scan.d.ts.map +1 -1
- package/dist/src/runtime/emit/scan.js +11 -2
- package/dist/src/runtime/emit/scan.js.map +1 -1
- package/dist/src/runtime/parallel-driver.d.ts +5 -2
- package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
- package/dist/src/runtime/parallel-driver.js +6 -2
- 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 +2 -0
- package/dist/src/runtime/register.js.map +1 -1
- package/dist/src/runtime/types.d.ts +7 -0
- package/dist/src/runtime/types.d.ts.map +1 -1
- package/dist/src/runtime/types.js.map +1 -1
- package/dist/src/schema/function.d.ts +9 -0
- package/dist/src/schema/function.d.ts.map +1 -1
- package/dist/src/schema/function.js.map +1 -1
- package/dist/src/types/builtin-types.d.ts.map +1 -1
- package/dist/src/types/builtin-types.js +30 -4
- package/dist/src/types/builtin-types.js.map +1 -1
- package/dist/src/util/comparison.d.ts +25 -0
- package/dist/src/util/comparison.d.ts.map +1 -1
- package/dist/src/util/comparison.js +31 -0
- package/dist/src/util/comparison.js.map +1 -1
- package/dist/src/vtab/best-access-plan.d.ts +87 -0
- package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
- package/dist/src/vtab/best-access-plan.js +87 -0
- package/dist/src/vtab/best-access-plan.js.map +1 -1
- package/dist/src/vtab/memory/layer/base.d.ts +6 -4
- package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/base.js +6 -4
- package/dist/src/vtab/memory/layer/base.js.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts +60 -18
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +100 -39
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.d.ts +15 -6
- package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.js +26 -11
- package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
- package/dist/src/vtab/memory/module.d.ts +14 -2
- package/dist/src/vtab/memory/module.d.ts.map +1 -1
- package/dist/src/vtab/memory/module.js +51 -39
- package/dist/src/vtab/memory/module.js.map +1 -1
- package/dist/src/vtab/memory/table.d.ts +1 -1
- package/dist/src/vtab/memory/table.d.ts.map +1 -1
- package/dist/src/vtab/memory/table.js +9 -2
- package/dist/src/vtab/memory/table.js.map +1 -1
- package/dist/src/vtab/table.d.ts +9 -1
- package/dist/src/vtab/table.d.ts.map +1 -1
- package/dist/src/vtab/table.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule: Key-set seek — materialize the semi-join key set, then seek the target with it
|
|
3
|
+
*
|
|
4
|
+
* Pattern (anchored on the physical hash semi join `join-physical-selection` builds):
|
|
5
|
+
*
|
|
6
|
+
* BloomJoinNode (semi, exactly one equi-pair, no residual)
|
|
7
|
+
* ├─ left: (FilterNode | trivial ProjectNode | AliasNode)*
|
|
8
|
+
* │ over SeqScan(fullScan) | ordering-only IndexScan(plan=0)
|
|
9
|
+
* └─ right: uncorrelated, deterministic, side-effect-free key source
|
|
10
|
+
*
|
|
11
|
+
* On a successful match the left chain is rebuilt with the leaf replaced by a
|
|
12
|
+
* `KeySetSemiJoinNode(leaf, right)` — the semi join slides below the peeled
|
|
13
|
+
* wrappers (a filter and a semi-filter commute; a trivial Project / Alias
|
|
14
|
+
* preserves rows and attribute ids):
|
|
15
|
+
*
|
|
16
|
+
* HashJoin(semi, Project(Filter(leaf)), right)
|
|
17
|
+
* → Project(Filter(KeySetSemiJoin(leaf, right)))
|
|
18
|
+
*
|
|
19
|
+
* The new node ALWAYS builds the key set and ALWAYS probes each target row
|
|
20
|
+
* against it — the runtime pushdown only changes how many rows the target
|
|
21
|
+
* emits, so a skipped or over-fetching seek can cost performance but never
|
|
22
|
+
* correctness. Every gate below exists to make an UNDER-fetch (rows the seek
|
|
23
|
+
* fails to return, which the probe cannot resurrect) impossible.
|
|
24
|
+
*
|
|
25
|
+
* The rule declines (returns null, keeping the hash semi join) on all of:
|
|
26
|
+
* - join type ≠ semi, >1 equi-pair, or a residual condition
|
|
27
|
+
* - a correlated, non-deterministic, or side-effect-bearing key source
|
|
28
|
+
* - side effects anywhere in the left chain
|
|
29
|
+
* - any non-peelable node between the join and the access leaf
|
|
30
|
+
* - a leaf that is not an unconstrained every-row walk — pushed constraints
|
|
31
|
+
* / limit / offset mean replacing its FilterInfo would silently drop the
|
|
32
|
+
* module-enforced predicates or directives
|
|
33
|
+
* (backlog/feat-key-set-seek-over-pushed-constraints)
|
|
34
|
+
* - a leaf whose emission order absorbed a SortNode (`orderingLoadBearing`):
|
|
35
|
+
* the dropped Sort's order now rides the leaf's walk order through the
|
|
36
|
+
* order-preserving hash join, and a pushed multi-seek would emit in
|
|
37
|
+
* seek-key order instead
|
|
38
|
+
* - target/key logical types that differ (a cross-type seek key can miss
|
|
39
|
+
* rows `=` considers equal — backlog/feat-key-set-seek-cross-type-keys)
|
|
40
|
+
* - a semantic-ordering key type ('PT1H' ≡ 'PT60M' but byte-distinct: a
|
|
41
|
+
* raw-value seek under-fetches)
|
|
42
|
+
* - a collation cover that is MISMATCH_UNSAFE (a finer index under-fetches;
|
|
43
|
+
* a BINARY join over a coarser index is admitted — the probe trims the
|
|
44
|
+
* over-fetch)
|
|
45
|
+
* - the module declining either runtime-set probe, naming different indexes
|
|
46
|
+
* across them, claiming a composite seek, attaching a JS residualFilter,
|
|
47
|
+
* or naming an index the engine cannot resolve / whose leading key column
|
|
48
|
+
* is not the seek column
|
|
49
|
+
* - the module answering a synthesized probe with a plan `validateAccessPlan`
|
|
50
|
+
* rejects (a module bug — logged, then declined like any other gate rather
|
|
51
|
+
* than failing a query the user's own predicate would have run fine)
|
|
52
|
+
* - a break-even of zero (the module's own costs say a scan wins at every
|
|
53
|
+
* key count)
|
|
54
|
+
*
|
|
55
|
+
* NOTE: the three `getBestAccessPlan` probes run on every qualifying hash semi
|
|
56
|
+
* join optimization, uncached. Cheap for both shipped modules; if a third-party
|
|
57
|
+
* module with an expensive planner ever shows up in optimization profiles,
|
|
58
|
+
* memoize by (table, seek column).
|
|
59
|
+
*
|
|
60
|
+
* NOTE: the `orderingLoadBearing` decline is conservative — a future enhancement
|
|
61
|
+
* could re-sort the pushed output by the leaf's advertised order, or push when
|
|
62
|
+
* the seek index IS the walk index (see
|
|
63
|
+
* `backlog/feat-key-set-seek-merge-semi-join`).
|
|
64
|
+
*/
|
|
65
|
+
import { createLogger } from '../../../common/logger.js';
|
|
66
|
+
import { isRelationalNode } from '../../nodes/plan-node.js';
|
|
67
|
+
import { BloomJoinNode } from '../../nodes/bloom-join-node.js';
|
|
68
|
+
import { KeySetSemiJoinNode, RUNTIME_SET_MAX_KEYS } from '../../nodes/key-set-semi-join-node.js';
|
|
69
|
+
import { SeqScanNode, IndexScanNode } from '../../nodes/table-access-nodes.js';
|
|
70
|
+
import { AliasNode } from '../../nodes/alias-node.js';
|
|
71
|
+
import { ProjectNode } from '../../nodes/project-node.js';
|
|
72
|
+
import { FilterNode } from '../../nodes/filter.js';
|
|
73
|
+
import { ColumnReferenceNode } from '../../nodes/reference.js';
|
|
74
|
+
import { PlanNodeCharacteristics } from '../../framework/characteristics.js';
|
|
75
|
+
import { isCorrelatedSubquery } from '../../cache/correlation-detector.js';
|
|
76
|
+
import { hasSemanticOrdering, normalizeCollationName } from '../../../util/comparison.js';
|
|
77
|
+
import { effectiveCollationOfTypes } from '../../analysis/comparison-collation.js';
|
|
78
|
+
import { classifyConstraintCover } from './rule-select-access-path.js';
|
|
79
|
+
import { resolveIndexDescriptor } from '../../../vtab/index-descriptor.js';
|
|
80
|
+
import { validateAccessPlan, } from '../../../vtab/best-access-plan.js';
|
|
81
|
+
const log = createLogger('optimizer:rule:key-set-seek');
|
|
82
|
+
/**
|
|
83
|
+
* A Project is "trivial" iff every projection is a bare ColumnReferenceNode —
|
|
84
|
+
* it preserves row count, order, and attribute ids, so the semi join commutes
|
|
85
|
+
* below it. Same predicate as `rule-monotonic-limit-pushdown`.
|
|
86
|
+
*/
|
|
87
|
+
function isTrivialProject(project) {
|
|
88
|
+
return project.projections.every(p => p.node instanceof ColumnReferenceNode);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Walk down from `chainRoot` toward the access leaf, descending only through
|
|
92
|
+
* Alias / trivial Project / Filter wrappers (each commutes with a semi join).
|
|
93
|
+
* Returns null when anything else appears before an admissible leaf.
|
|
94
|
+
*/
|
|
95
|
+
function peelToLeaf(chainRoot) {
|
|
96
|
+
let cursor = chainRoot;
|
|
97
|
+
let safety = 16;
|
|
98
|
+
while (safety-- > 0) {
|
|
99
|
+
if (cursor instanceof SeqScanNode || cursor instanceof IndexScanNode)
|
|
100
|
+
return cursor;
|
|
101
|
+
if (cursor instanceof AliasNode) {
|
|
102
|
+
cursor = cursor.source;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (cursor instanceof ProjectNode && isTrivialProject(cursor)) {
|
|
106
|
+
cursor = cursor.source;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (cursor instanceof FilterNode) {
|
|
110
|
+
cursor = cursor.source;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Rebuild the chain `chainRoot → … → oldLeaf` with `oldLeaf` replaced by
|
|
119
|
+
* `newLeaf`, reconstructing each intermediate node via `withChildren` (same
|
|
120
|
+
* shape as `rule-monotonic-limit-pushdown`'s rebuildChain).
|
|
121
|
+
*/
|
|
122
|
+
function rebuildChain(chainRoot, oldLeaf, newLeaf) {
|
|
123
|
+
if (chainRoot === oldLeaf) {
|
|
124
|
+
return newLeaf;
|
|
125
|
+
}
|
|
126
|
+
const newChildren = chainRoot.getChildren().map(child => isRelationalNode(child) ? rebuildChain(child, oldLeaf, newLeaf) : child);
|
|
127
|
+
return chainRoot.withChildren(newChildren);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Structural + purity admission of the join itself: a single-pair, residual-free
|
|
131
|
+
* hash SEMI join whose key source may be drained exactly once (uncorrelated,
|
|
132
|
+
* deterministic, pure) and whose probe chain carries no write.
|
|
133
|
+
*/
|
|
134
|
+
function admitJoin(node) {
|
|
135
|
+
if (node.joinType !== 'semi')
|
|
136
|
+
return false;
|
|
137
|
+
if (node.equiPairs.length !== 1)
|
|
138
|
+
return false;
|
|
139
|
+
if (node.residualCondition !== undefined)
|
|
140
|
+
return false;
|
|
141
|
+
// The key source is drained exactly once; a correlated, impure, or
|
|
142
|
+
// non-deterministic source must keep its per-execution semantics. Same
|
|
143
|
+
// admission test as the set probe and the decorrelation rule.
|
|
144
|
+
if (PlanNodeCharacteristics.subtreeHasSideEffects(node.right)) {
|
|
145
|
+
log('decline: key source has side effects');
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
if (!PlanNodeCharacteristics.isDeterministic(node.right)) {
|
|
149
|
+
log('decline: key source is non-deterministic');
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
if (isCorrelatedSubquery(node.right)) {
|
|
153
|
+
log('decline: key source is correlated');
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
// The left chain is re-rooted below its wrappers — refuse to touch a chain
|
|
157
|
+
// carrying a write.
|
|
158
|
+
if (PlanNodeCharacteristics.subtreeHasSideEffects(node.left)) {
|
|
159
|
+
log('decline: left chain has side effects');
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* The probe-side access leaf, when it is one whose `FilterInfo` may be replaced
|
|
166
|
+
* wholesale at runtime.
|
|
167
|
+
*
|
|
168
|
+
* It must read every row with nothing pushed into it: a plain full scan, or an
|
|
169
|
+
* ordering-only index walk (plan=0) — which reads every row exactly like a full
|
|
170
|
+
* scan and differs only in emission order, a property nothing above this hash
|
|
171
|
+
* join could depend on (BloomJoinNode propagates no ordering). A leaf already
|
|
172
|
+
* carrying pushed constraints had its residual Filter dropped on the module's
|
|
173
|
+
* promise to enforce them; replacing its FilterInfo with our multi-seek would
|
|
174
|
+
* silently drop those predicates
|
|
175
|
+
* (backlog/feat-key-set-seek-over-pushed-constraints). A pushed limit / offset
|
|
176
|
+
* is likewise a directive the multi-seek would not honor.
|
|
177
|
+
*/
|
|
178
|
+
function admitLeaf(left) {
|
|
179
|
+
const leaf = peelToLeaf(left);
|
|
180
|
+
if (!leaf) {
|
|
181
|
+
log('decline: left does not peel to an access leaf through Alias/Project/Filter');
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
const fi = leaf.filterInfo;
|
|
185
|
+
const isEveryRowWalk = fi.accessPath?.kind === 'fullScan'
|
|
186
|
+
|| (fi.accessPath?.kind === 'index' && fi.accessPath.plan === 'scan');
|
|
187
|
+
if (!isEveryRowWalk || fi.constraints.length !== 0
|
|
188
|
+
|| fi.limit !== undefined || fi.offset !== undefined) {
|
|
189
|
+
log('decline: leaf is not an unconstrained every-row walk');
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
// A leaf whose emission order absorbed a SortNode (sort absorption in
|
|
193
|
+
// rule-grow-retrieve, before this join existed) is the only thing producing
|
|
194
|
+
// the query's ORDER BY: the hash semi join preserves probe order at
|
|
195
|
+
// runtime, but a pushed multi-seek emits in seek-key order. Declining keeps
|
|
196
|
+
// the order-preserving hash join.
|
|
197
|
+
if (leaf instanceof IndexScanNode && leaf.orderingLoadBearing) {
|
|
198
|
+
log('decline: leaf emission order is load-bearing (absorbed a Sort)');
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
return leaf;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Resolve the equi-pair to a target column index, then apply the two type gates
|
|
205
|
+
* that keep a raw-value seek from under-fetching.
|
|
206
|
+
*/
|
|
207
|
+
function resolveSeekColumns(leaf, right, leftAttrId, rightAttrId) {
|
|
208
|
+
// Join key → table column index. A TableAccessNode's attributes are the
|
|
209
|
+
// table reference's, positionally 1:1 with tableSchema.columns.
|
|
210
|
+
const seekCol = leaf.getAttributeIndex().get(leftAttrId) ?? -1;
|
|
211
|
+
if (seekCol === -1) {
|
|
212
|
+
log('decline: join key attr %d is not a leaf column', leftAttrId);
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
const keyIdx = right.getAttributeIndex().get(rightAttrId) ?? -1;
|
|
216
|
+
if (keyIdx === -1) {
|
|
217
|
+
log('decline: join key attr %d is not a key-source column', rightAttrId);
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
const targetType = leaf.getAttributes()[seekCol].type;
|
|
221
|
+
const keyType = right.getAttributes()[keyIdx].type;
|
|
222
|
+
// Identical logical types only. A cross-type set (INTEGER column, REAL
|
|
223
|
+
// keys) would be encoded into seek keys that miss rows `=` considers equal,
|
|
224
|
+
// and the probe cannot resurrect a row the seek never returned.
|
|
225
|
+
if (targetType.logicalType.name !== keyType.logicalType.name) {
|
|
226
|
+
log('decline: logical types differ (%s vs %s)', targetType.logicalType.name, keyType.logicalType.name);
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
// Semantic-ordering types ('PT1H' equals 'PT60M' but is byte-distinct): a
|
|
230
|
+
// raw-value seek under-fetches. The store module declines these itself —
|
|
231
|
+
// gate in the engine too, so the guarantee does not depend on which module
|
|
232
|
+
// answered.
|
|
233
|
+
if (hasSemanticOrdering(targetType.logicalType) || hasSemanticOrdering(keyType.logicalType)) {
|
|
234
|
+
log('decline: semantic-ordering key type %s', targetType.logicalType.name);
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
return { seekCol, targetType, keyType };
|
|
238
|
+
}
|
|
239
|
+
/** Build the probe request `createIndexBasedAccess` would (identical `columns` mapping). */
|
|
240
|
+
function buildProbeRequest(tableSchema, tableRows, filters) {
|
|
241
|
+
return {
|
|
242
|
+
columns: tableSchema.columns.map((col, index) => ({
|
|
243
|
+
index,
|
|
244
|
+
name: col.name,
|
|
245
|
+
type: col.logicalType,
|
|
246
|
+
isPrimaryKey: col.primaryKey || false,
|
|
247
|
+
isUnique: col.primaryKey || false,
|
|
248
|
+
})),
|
|
249
|
+
filters,
|
|
250
|
+
estimatedRows: tableRows,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
/** A seek probe's claim, when the module accepted the runtime-set filter cleanly. */
|
|
254
|
+
function claimedIndex(plan, seekCol) {
|
|
255
|
+
if (plan.handledFilters[0] !== true)
|
|
256
|
+
return null;
|
|
257
|
+
if (!plan.indexName)
|
|
258
|
+
return null;
|
|
259
|
+
if (!plan.seekColumnIndexes || plan.seekColumnIndexes.length !== 1 || plan.seekColumnIndexes[0] !== seekCol) {
|
|
260
|
+
// A composite claim is declined too: sorting by single-column SQL value
|
|
261
|
+
// order equals index-key order only for a single key column.
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
// A module-supplied JS residual has no place to run in this path.
|
|
265
|
+
if (plan.residualFilter)
|
|
266
|
+
return null;
|
|
267
|
+
return plan.indexName;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* The module's answers to the three synthesized requests: its cost for a
|
|
271
|
+
* runtime-set seek at two key counts (2 and the engine ceiling) plus its plain
|
|
272
|
+
* scan cost. `maxCount` 2 rather than 1 keeps the two seek points distinct so
|
|
273
|
+
* the cost slope is well defined.
|
|
274
|
+
*
|
|
275
|
+
* These requests are the ENGINE's, not the user's: a module that answers one
|
|
276
|
+
* with a plan `validateAccessPlan` rejects gets logged and declined, leaving the
|
|
277
|
+
* hash semi join — the same disposition as every other gate. Failing the query
|
|
278
|
+
* instead would let a synthesized probe break a predicate that ran fine before.
|
|
279
|
+
*/
|
|
280
|
+
function probeModuleCosts(context, leaf, seekCol, keyRowsEstimate) {
|
|
281
|
+
const tableSchema = leaf.tableSchema;
|
|
282
|
+
const vtabModule = leaf.source.vtabModule;
|
|
283
|
+
const getBestAccessPlan = vtabModule.getBestAccessPlan;
|
|
284
|
+
if (typeof getBestAccessPlan !== 'function') {
|
|
285
|
+
log('decline: module has no getBestAccessPlan');
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
const tableRows = leaf.source.estimatedRows || undefined;
|
|
289
|
+
// Advisory count estimate, clamped into the ceiling `validateAccessPlanRequest` demands.
|
|
290
|
+
const runtimeSetFilter = (maxCount) => ({
|
|
291
|
+
columnIndex: seekCol,
|
|
292
|
+
op: 'IN',
|
|
293
|
+
usable: true,
|
|
294
|
+
runtimeSet: {
|
|
295
|
+
maxCount,
|
|
296
|
+
...(keyRowsEstimate !== undefined
|
|
297
|
+
? { estimatedCount: Math.min(maxCount, Math.max(0, Math.floor(keyRowsEstimate))) }
|
|
298
|
+
: {}),
|
|
299
|
+
},
|
|
300
|
+
});
|
|
301
|
+
const ask = (filters) => {
|
|
302
|
+
const request = buildProbeRequest(tableSchema, tableRows, filters);
|
|
303
|
+
const plan = getBestAccessPlan.call(vtabModule, context.db, tableSchema, request);
|
|
304
|
+
validateAccessPlan(request, plan);
|
|
305
|
+
return plan;
|
|
306
|
+
};
|
|
307
|
+
try {
|
|
308
|
+
return {
|
|
309
|
+
seekAt2: ask([runtimeSetFilter(2)]),
|
|
310
|
+
seekAtMax: ask([runtimeSetFilter(RUNTIME_SET_MAX_KEYS)]),
|
|
311
|
+
scan: ask([]),
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
catch (e) {
|
|
315
|
+
log('decline: module %s answered a synthesized runtime-set probe on %s with an invalid plan: %s', tableSchema.vtabModuleName, tableSchema.name, e instanceof Error ? e.message : String(e));
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Turn the module's probe answers into the runtime pushdown, or null when any
|
|
321
|
+
* claim gate fails.
|
|
322
|
+
*/
|
|
323
|
+
function planPushdown(context, leaf, right, cols) {
|
|
324
|
+
const costs = probeModuleCosts(context, leaf, cols.seekCol, right.estimatedRows);
|
|
325
|
+
if (!costs)
|
|
326
|
+
return null;
|
|
327
|
+
const indexAt2 = claimedIndex(costs.seekAt2, cols.seekCol);
|
|
328
|
+
const indexAtMax = claimedIndex(costs.seekAtMax, cols.seekCol);
|
|
329
|
+
if (!indexAt2 || !indexAtMax || indexAt2 !== indexAtMax) {
|
|
330
|
+
log('decline: module did not claim the runtime set on one index (A=%s, B=%s)', indexAt2, indexAtMax);
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
// Structured identity of the claimed index. An unresolved path declines —
|
|
334
|
+
// order-sensitive consumers (the isolation overlay merge) must be able to
|
|
335
|
+
// trust the accessPath this node stamps.
|
|
336
|
+
const descriptor = resolveIndexDescriptor(leaf.tableSchema, costs.seekAt2, indexAt2);
|
|
337
|
+
if (!descriptor) {
|
|
338
|
+
log('decline: index %s cannot be resolved to a descriptor', indexAt2);
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
if (descriptor.keyColumns[0].columnIndex !== cols.seekCol) {
|
|
342
|
+
// A module naming an index whose leading column is something else has
|
|
343
|
+
// answered a different question.
|
|
344
|
+
log('decline: index %s leading key column %d is not the seek column %d', indexAt2, descriptor.keyColumns[0].columnIndex, cols.seekCol);
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
// Collation cover: the join comparison collation (the same resolution
|
|
348
|
+
// emitBloomJoin makes, so the seek and the probe agree) against the index's
|
|
349
|
+
// leading key column collation. MATCH = exact seek; COARSER_SAFE (BINARY
|
|
350
|
+
// join over a non-BINARY index) over-fetches a superset the probe trims;
|
|
351
|
+
// MISMATCH_UNSAFE (a finer index) under-fetches — decline.
|
|
352
|
+
const joinCollation = normalizeCollationName(effectiveCollationOfTypes(cols.targetType, cols.keyType));
|
|
353
|
+
const indexCollation = normalizeCollationName(descriptor.keyColumns[0].collation ?? 'BINARY');
|
|
354
|
+
if (classifyConstraintCover(joinCollation, indexCollation, /*isEquality*/ true, false) === 'MISMATCH_UNSAFE') {
|
|
355
|
+
log('decline: collation cover unsafe (join %s vs index %s)', joinCollation, indexCollation);
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
const breakEvenKeys = interpolateBreakEven(costs);
|
|
359
|
+
if (breakEvenKeys < 1) {
|
|
360
|
+
log('decline: scan beats a seek at every key count (breakEven=%d)', breakEvenKeys);
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
return {
|
|
364
|
+
indexName: indexAt2,
|
|
365
|
+
accessPath: { kind: 'index', index: descriptor, plan: 'multiSeek' },
|
|
366
|
+
seekColumnIndex: cols.seekCol,
|
|
367
|
+
seekDescending: descriptor.keyColumns[0].desc === true,
|
|
368
|
+
maxKeys: RUNTIME_SET_MAX_KEYS,
|
|
369
|
+
breakEvenKeys,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* The distinct key count at which the module's own seek cost overtakes its scan
|
|
374
|
+
* cost. Interpolates the seek cost as a linear function of key count through the
|
|
375
|
+
* two probe points and solves against the scan cost. The linear fit is an
|
|
376
|
+
* approximation, but it is the MODULE's approximation — cost authority stays
|
|
377
|
+
* with the module rather than a second cost model living in the optimizer.
|
|
378
|
+
*
|
|
379
|
+
* A flat-or-falling seek cost (`slope <= 0`) never overtakes the scan, so the
|
|
380
|
+
* engine ceiling becomes the threshold. A scan cheaper than a two-key seek
|
|
381
|
+
* interpolates below 1 and the caller declines.
|
|
382
|
+
*/
|
|
383
|
+
function interpolateBreakEven(costs) {
|
|
384
|
+
const slope = (costs.seekAtMax.cost - costs.seekAt2.cost) / (RUNTIME_SET_MAX_KEYS - 2);
|
|
385
|
+
if (slope <= 0)
|
|
386
|
+
return RUNTIME_SET_MAX_KEYS;
|
|
387
|
+
return Math.max(0, Math.min(RUNTIME_SET_MAX_KEYS, Math.floor(2 + (costs.scan.cost - costs.seekAt2.cost) / slope)));
|
|
388
|
+
}
|
|
389
|
+
export function ruleKeySetSeek(node, context) {
|
|
390
|
+
if (!(node instanceof BloomJoinNode))
|
|
391
|
+
return null;
|
|
392
|
+
if (!admitJoin(node))
|
|
393
|
+
return null;
|
|
394
|
+
const leaf = admitLeaf(node.left);
|
|
395
|
+
if (!leaf)
|
|
396
|
+
return null;
|
|
397
|
+
const pair = node.equiPairs[0];
|
|
398
|
+
const cols = resolveSeekColumns(leaf, node.right, pair.leftAttrId, pair.rightAttrId);
|
|
399
|
+
if (!cols)
|
|
400
|
+
return null;
|
|
401
|
+
const pushdown = planPushdown(context, leaf, node.right, cols);
|
|
402
|
+
if (!pushdown)
|
|
403
|
+
return null;
|
|
404
|
+
const keySetJoin = new KeySetSemiJoinNode(node.scope, leaf, node.right, pair.leftAttrId, pair.rightAttrId, pushdown);
|
|
405
|
+
log('Replaced hash semi join with KeySetSemiJoin on %s.%s via %s (breakEven=%d)', leaf.tableSchema.name, leaf.tableSchema.columns[cols.seekCol]?.name, pushdown.indexName, pushdown.breakEvenKeys);
|
|
406
|
+
return rebuildChain(node.left, leaf, keySetJoin);
|
|
407
|
+
}
|
|
408
|
+
//# sourceMappingURL=rule-key-set-seek.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-key-set-seek.js","sourceRoot":"","sources":["../../../../../src/planner/rules/access/rule-key-set-seek.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-monotonic-range-access.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/access/rule-monotonic-range-access.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"rule-monotonic-range-access.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/access/rule-monotonic-range-access.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAqN7D,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,CAQ1F"}
|
|
@@ -83,7 +83,7 @@ function leafWithRangeBound(leaf, rb) {
|
|
|
83
83
|
return new SeqScanNode(leaf.scope, leaf.source, leaf.filterInfo, undefined, rb, leaf.suppressMonotonic);
|
|
84
84
|
}
|
|
85
85
|
if (leaf instanceof IndexScanNode) {
|
|
86
|
-
return new IndexScanNode(leaf.scope, leaf.source, leaf.filterInfo, leaf.indexName, leaf.providesOrdering, undefined, leaf.advertisement, rb, leaf.suppressMonotonic);
|
|
86
|
+
return new IndexScanNode(leaf.scope, leaf.source, leaf.filterInfo, leaf.indexName, leaf.providesOrdering, undefined, leaf.advertisement, rb, leaf.suppressMonotonic, leaf.orderingLoadBearing);
|
|
87
87
|
}
|
|
88
88
|
// IndexSeekNode
|
|
89
89
|
return new IndexSeekNode(leaf.scope, leaf.source, leaf.filterInfo, leaf.indexName, leaf.seekKeys, leaf.isRange, leaf.providesOrdering, undefined, leaf.advertisement, rb, leaf.suppressMonotonic);
|
|
@@ -94,7 +94,7 @@ function leafWithMonotonicSuppressed(leaf) {
|
|
|
94
94
|
return new SeqScanNode(leaf.scope, leaf.source, leaf.filterInfo, undefined, leaf.rangeBoundedOn, true);
|
|
95
95
|
}
|
|
96
96
|
if (leaf instanceof IndexScanNode) {
|
|
97
|
-
return new IndexScanNode(leaf.scope, leaf.source, leaf.filterInfo, leaf.indexName, leaf.providesOrdering, undefined, leaf.advertisement, leaf.rangeBoundedOn, true);
|
|
97
|
+
return new IndexScanNode(leaf.scope, leaf.source, leaf.filterInfo, leaf.indexName, leaf.providesOrdering, undefined, leaf.advertisement, leaf.rangeBoundedOn, true, leaf.orderingLoadBearing);
|
|
98
98
|
}
|
|
99
99
|
return new IndexSeekNode(leaf.scope, leaf.source, leaf.filterInfo, leaf.indexName, leaf.seekKeys, leaf.isRange, leaf.providesOrdering, undefined, leaf.advertisement, leaf.rangeBoundedOn, true);
|
|
100
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-monotonic-range-access.js","sourceRoot":"","sources":["../../../../../src/planner/rules/access/rule-monotonic-range-access.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"rule-monotonic-range-access.js","sourceRoot":"","sources":["../../../../../src/planner/rules/access/rule-monotonic-range-access.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,4 +13,31 @@
|
|
|
13
13
|
import type { PlanNode } from '../../nodes/plan-node.js';
|
|
14
14
|
import type { OptContext } from '../../framework/context.js';
|
|
15
15
|
export declare function ruleSelectAccessPath(node: PlanNode, context: OptContext): PlanNode | null;
|
|
16
|
+
/**
|
|
17
|
+
* Per-seek-constraint classification of how an index column's collation relates
|
|
18
|
+
* to the predicate's effective comparison collation. See {@link classifyConstraintCover}.
|
|
19
|
+
*
|
|
20
|
+
* - `MATCH` — collations equal; the seek fully satisfies the predicate.
|
|
21
|
+
* - `COARSER_SAFE` — equality op whose index collation is a provable superset of
|
|
22
|
+
* the predicate's (BINARY predicate over a non-BINARY index):
|
|
23
|
+
* the seek over-fetches a superset, so a residual recovers the
|
|
24
|
+
* exact matches.
|
|
25
|
+
* - `MISMATCH_UNSAFE` — anything else (a finer index that under-fetches, or any
|
|
26
|
+
* range/prefix mismatch that reorders the walked window): the
|
|
27
|
+
* seek cannot be made correct with a residual.
|
|
28
|
+
*/
|
|
29
|
+
type CollationCover = 'MATCH' | 'COARSER_SAFE' | 'MISMATCH_UNSAFE';
|
|
30
|
+
/**
|
|
31
|
+
* Cover relation for a single seek column. See {@link CollationCover}.
|
|
32
|
+
*
|
|
33
|
+
* `honorsCollatedRangeBounds` is the module's advertisement (off by default) that its
|
|
34
|
+
* runtime filters range bounds under the index collation rather than BINARY; it gates
|
|
35
|
+
* the non-BINARY range MATCH and is ignored for equality.
|
|
36
|
+
*
|
|
37
|
+
* Exported for `rule-key-set-seek`, which applies the same equality lattice to its
|
|
38
|
+
* runtime-materialized multi-seek (accepting MATCH and COARSER_SAFE, declining
|
|
39
|
+
* MISMATCH_UNSAFE) rather than restating it.
|
|
40
|
+
*/
|
|
41
|
+
export declare function classifyConstraintCover(predColl: string, indexColl: string, isEquality: boolean, honorsCollatedRangeBounds: boolean): CollationCover;
|
|
42
|
+
export {};
|
|
16
43
|
//# sourceMappingURL=rule-select-access-path.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-select-access-path.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/access/rule-select-access-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAkB,MAAM,0BAA0B,CAAC;AAEzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AA2H7D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"rule-select-access-path.d.ts","sourceRoot":"","sources":["../../../../../src/planner/rules/access/rule-select-access-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAkB,MAAM,0BAA0B,CAAC;AAEzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AA2H7D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,CAsFzF;AA0mCD;;;;;;;;;;;;GAYG;AACH,KAAK,cAAc,GAAG,OAAO,GAAG,cAAc,GAAG,iBAAiB,CAAC;AA+EnE;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,yBAAyB,EAAE,OAAO,GAAG,cAAc,CAuBpJ"}
|
|
@@ -115,11 +115,21 @@ export function ruleSelectAccessPath(node, context) {
|
|
|
115
115
|
// Always allow fallback to sequential scan to guarantee physicalization
|
|
116
116
|
// even when no specialized support is available.
|
|
117
117
|
// If grow-retrieve established an index-style context, reuse it directly
|
|
118
|
+
// NOTE: `retrieveNode.source` is intentionally NOT rebuilt on this path. Once an
|
|
119
|
+
// index-style moduleCtx exists it is the sole authority for what the access applies
|
|
120
|
+
// (accessPlan + handledFilters + residualPredicate); nothing this branch emits comes
|
|
121
|
+
// from `source`. A predicate written into `source` after the ctx is set is therefore
|
|
122
|
+
// silently lost — exactly the bug rule-predicate-pushdown's isIndexStyleContext guard
|
|
123
|
+
// prevents. Rebuilding from `source` here is NOT the fix: this branch also legitimately
|
|
124
|
+
// discards a Sort/LimitOffset that sort-absorption already elided, so rebuilding
|
|
125
|
+
// would resurrect them. `source` is still read elsewhere (rule-grow-retrieve's
|
|
126
|
+
// `collectBindingsInPlan` and `trySortAbsorbViaIndexOrdering`'s constraint sweep), so
|
|
127
|
+
// it is dead as an execution channel, not dead weight — do not stop populating it.
|
|
118
128
|
if (isIndexStyleContext(retrieveNode.moduleCtx)) {
|
|
119
129
|
log('Using index-style context provided by grow-retrieve');
|
|
120
130
|
const accessPlan = retrieveNode.moduleCtx.accessPlan;
|
|
121
131
|
const originalConstraints = retrieveNode.moduleCtx.originalConstraints;
|
|
122
|
-
const physicalLeaf = selectPhysicalNode(retrieveNode.tableRef, accessPlan, originalConstraints);
|
|
132
|
+
const physicalLeaf = selectPhysicalNode(retrieveNode.tableRef, accessPlan, originalConstraints, retrieveNode.moduleCtx.orderingLoadBearing === true);
|
|
123
133
|
if (retrieveNode.moduleCtx.residualPredicate) {
|
|
124
134
|
return new FilterNode(retrieveNode.scope, physicalLeaf, retrieveNode.moduleCtx.residualPredicate);
|
|
125
135
|
}
|
|
@@ -173,12 +183,14 @@ function createIndexBasedAccess(retrieveNode, context) {
|
|
|
173
183
|
let accessPlan;
|
|
174
184
|
let constraints;
|
|
175
185
|
let residualPredicate;
|
|
186
|
+
let orderingLoadBearing = false;
|
|
176
187
|
if (isIndexStyleContext(retrieveNode.moduleCtx)) {
|
|
177
188
|
// Use pre-computed access plan from grow rule
|
|
178
189
|
log('Using pre-computed access plan from grow rule');
|
|
179
190
|
accessPlan = retrieveNode.moduleCtx.accessPlan;
|
|
180
191
|
constraints = retrieveNode.moduleCtx.originalConstraints;
|
|
181
192
|
residualPredicate = retrieveNode.moduleCtx.residualPredicate;
|
|
193
|
+
orderingLoadBearing = retrieveNode.moduleCtx.orderingLoadBearing === true;
|
|
182
194
|
}
|
|
183
195
|
else {
|
|
184
196
|
// Extract constraints from grown pipeline in source using table instance key
|
|
@@ -200,7 +212,7 @@ function createIndexBasedAccess(retrieveNode, context) {
|
|
|
200
212
|
accessPlan = vtabModule.getBestAccessPlan(context.db, tableSchema, request);
|
|
201
213
|
}
|
|
202
214
|
// Choose physical node based on access plan
|
|
203
|
-
const physicalLeaf = selectPhysicalNode(retrieveNode.tableRef, accessPlan, constraints);
|
|
215
|
+
const physicalLeaf = selectPhysicalNode(retrieveNode.tableRef, accessPlan, constraints, orderingLoadBearing);
|
|
204
216
|
// If the Retrieve source contained a pipeline (e.g., Filter/Sort/Project), rebuild it above the physical leaf.
|
|
205
217
|
//
|
|
206
218
|
// NOTE: on this path (no index-style moduleCtx) an absorbed `Filter` in `source` is
|
|
@@ -280,9 +292,13 @@ function reattachUnconsumedConstraints(tableRef, accessPlan, constraints, consum
|
|
|
280
292
|
return new FilterNode(tableRef.scope, leaf, predicate);
|
|
281
293
|
}
|
|
282
294
|
/**
|
|
283
|
-
* Select the appropriate physical node based on access plan
|
|
295
|
+
* Select the appropriate physical node based on access plan.
|
|
296
|
+
*
|
|
297
|
+
* `orderingLoadBearing` records that a SortNode was dropped on the strength of
|
|
298
|
+
* this plan's `providesOrdering` (sort absorption) — lifted onto the
|
|
299
|
+
* ordering-only IndexScan leaf so emission-order-changing rewrites decline.
|
|
284
300
|
*/
|
|
285
|
-
function selectPhysicalNode(tableRef, accessPlan, constraints) {
|
|
301
|
+
function selectPhysicalNode(tableRef, accessPlan, constraints, orderingLoadBearing = false) {
|
|
286
302
|
// Empty result optimization (e.g., IS NULL on NOT NULL column)
|
|
287
303
|
if (accessPlan.rows === 0 && accessPlan.handledFilters.every(h => h)) {
|
|
288
304
|
log('Using empty result (impossible predicate detected)');
|
|
@@ -300,15 +316,15 @@ function selectPhysicalNode(tableRef, accessPlan, constraints) {
|
|
|
300
316
|
// --- Index-aware path: use module-provided index identity ---
|
|
301
317
|
// --- Legacy fallback: infer access method from constraints and PK definition ---
|
|
302
318
|
const leaf = (accessPlan.indexName && accessPlan.seekColumnIndexes && accessPlan.seekColumnIndexes.length > 0)
|
|
303
|
-
? selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInfo, providesOrdering, consumed)
|
|
304
|
-
: selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo, providesOrdering, consumed);
|
|
319
|
+
? selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInfo, providesOrdering, consumed, orderingLoadBearing)
|
|
320
|
+
: selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo, providesOrdering, consumed, orderingLoadBearing);
|
|
305
321
|
return reattachUnconsumedConstraints(tableRef, accessPlan, constraints, consumed, leaf);
|
|
306
322
|
}
|
|
307
323
|
/**
|
|
308
324
|
* Index-aware physical node selection using module-provided indexName and seekColumnIndexes.
|
|
309
325
|
* Works for both primary key and secondary indexes.
|
|
310
326
|
*/
|
|
311
|
-
function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInfo, providesOrdering, consumed) {
|
|
327
|
+
function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInfo, providesOrdering, consumed, orderingLoadBearing = false) {
|
|
312
328
|
const advertisement = extractAdvertisement(accessPlan);
|
|
313
329
|
// Whether this module's runtime honours the index collation for range bounds —
|
|
314
330
|
// gates the collation-matched non-BINARY range/prefix seek (see classifyConstraintCover).
|
|
@@ -686,7 +702,7 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
686
702
|
const orderingIdxStr = orderingIndexName === PRIMARY_PHYSICAL_INDEX_NAME ? PRIMARY_INDEX_NAME : orderingIndexName;
|
|
687
703
|
log('Using index scan (ordering provided by %s)', orderingIndexName);
|
|
688
704
|
const orderingFilterInfo = makeOrderedScanFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, orderingIdxStr);
|
|
689
|
-
return new IndexScanNode(tableRef.scope, tableRef, orderingFilterInfo, orderingIndexName, providesOrdering, accessPlan.cost, advertisement);
|
|
705
|
+
return new IndexScanNode(tableRef.scope, tableRef, orderingFilterInfo, orderingIndexName, providesOrdering, accessPlan.cost, advertisement, undefined, false, orderingLoadBearing);
|
|
690
706
|
}
|
|
691
707
|
// Fall back to sequential scan
|
|
692
708
|
log('Using sequential scan (index %s: no usable seek/range constraints)', physicalIndexName);
|
|
@@ -696,7 +712,7 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
696
712
|
* Legacy physical node selection for backward compatibility when module
|
|
697
713
|
* doesn't provide indexName/seekColumnIndexes (PK-based heuristics).
|
|
698
714
|
*/
|
|
699
|
-
function selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo, providesOrdering, consumed) {
|
|
715
|
+
function selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo, providesOrdering, consumed, orderingLoadBearing = false) {
|
|
700
716
|
const advertisement = extractAdvertisement(accessPlan);
|
|
701
717
|
const honorsCollatedRangeBounds = accessPlan.honorsCollatedRangeBounds === true;
|
|
702
718
|
// Analyze the access plan to determine node type
|
|
@@ -811,7 +827,7 @@ function selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo,
|
|
|
811
827
|
log('Using index scan (ordering provided by %s)', indexName);
|
|
812
828
|
const indexIdxStr = indexName === PRIMARY_PHYSICAL_INDEX_NAME ? PRIMARY_INDEX_NAME : indexName;
|
|
813
829
|
const orderingFilterInfo = makeOrderedScanFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, indexIdxStr);
|
|
814
|
-
return new IndexScanNode(tableRef.scope, tableRef, orderingFilterInfo, indexName, providesOrdering, accessPlan.cost, advertisement);
|
|
830
|
+
return new IndexScanNode(tableRef.scope, tableRef, orderingFilterInfo, indexName, providesOrdering, accessPlan.cost, advertisement, undefined, false, orderingLoadBearing);
|
|
815
831
|
}
|
|
816
832
|
log('Using sequential scan (no beneficial index access)');
|
|
817
833
|
return createSeqScan(tableRef, filterInfo, accessPlan.cost);
|
|
@@ -1032,8 +1048,12 @@ function primaryKeyCollationLookup(tableSchema) {
|
|
|
1032
1048
|
* `honorsCollatedRangeBounds` is the module's advertisement (off by default) that its
|
|
1033
1049
|
* runtime filters range bounds under the index collation rather than BINARY; it gates
|
|
1034
1050
|
* the non-BINARY range MATCH and is ignored for equality.
|
|
1051
|
+
*
|
|
1052
|
+
* Exported for `rule-key-set-seek`, which applies the same equality lattice to its
|
|
1053
|
+
* runtime-materialized multi-seek (accepting MATCH and COARSER_SAFE, declining
|
|
1054
|
+
* MISMATCH_UNSAFE) rather than restating it.
|
|
1035
1055
|
*/
|
|
1036
|
-
function classifyConstraintCover(predColl, indexColl, isEquality, honorsCollatedRangeBounds) {
|
|
1056
|
+
export function classifyConstraintCover(predColl, indexColl, isEquality, honorsCollatedRangeBounds) {
|
|
1037
1057
|
if (isEquality) {
|
|
1038
1058
|
if (predColl === indexColl)
|
|
1039
1059
|
return 'MATCH';
|