@quereus/quereus 4.3.1 → 4.3.2
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 +25 -7
- package/dist/src/common/types.d.ts +9 -59
- package/dist/src/common/types.d.ts.map +1 -1
- package/dist/src/common/types.js.map +1 -1
- package/dist/src/core/database-assertions.d.ts +2 -2
- package/dist/src/core/database-assertions.d.ts.map +1 -1
- package/dist/src/core/database-assertions.js +4 -3
- package/dist/src/core/database-assertions.js.map +1 -1
- package/dist/src/core/database-external-changes.d.ts +1 -1
- package/dist/src/core/database-external-changes.js +1 -1
- package/dist/src/core/database-internal.d.ts.map +1 -1
- package/dist/src/core/database-materialized-views-analysis.d.ts +199 -0
- package/dist/src/core/database-materialized-views-analysis.d.ts.map +1 -0
- package/dist/src/core/database-materialized-views-analysis.js +502 -0
- package/dist/src/core/database-materialized-views-analysis.js.map +1 -0
- package/dist/src/core/database-materialized-views-apply.d.ts +280 -0
- package/dist/src/core/database-materialized-views-apply.d.ts.map +1 -0
- package/dist/src/core/database-materialized-views-apply.js +624 -0
- package/dist/src/core/database-materialized-views-apply.js.map +1 -0
- package/dist/src/core/database-materialized-views-plan-builders.d.ts +203 -0
- package/dist/src/core/database-materialized-views-plan-builders.d.ts.map +1 -0
- package/dist/src/core/database-materialized-views-plan-builders.js +1084 -0
- package/dist/src/core/database-materialized-views-plan-builders.js.map +1 -0
- package/dist/src/core/database-materialized-views-plans.d.ts +417 -0
- package/dist/src/core/database-materialized-views-plans.d.ts.map +1 -0
- package/dist/src/core/database-materialized-views-plans.js +13 -0
- package/dist/src/core/database-materialized-views-plans.js.map +1 -0
- package/dist/src/core/database-materialized-views.d.ts +11 -819
- package/dist/src/core/database-materialized-views.d.ts.map +1 -1
- package/dist/src/core/database-materialized-views.js +60 -2069
- package/dist/src/core/database-materialized-views.js.map +1 -1
- package/dist/src/core/database-transaction.d.ts +10 -1
- package/dist/src/core/database-transaction.d.ts.map +1 -1
- package/dist/src/core/database-transaction.js +16 -4
- package/dist/src/core/database-transaction.js.map +1 -1
- package/dist/src/core/database-watchers.d.ts.map +1 -1
- package/dist/src/core/database-watchers.js +2 -1
- package/dist/src/core/database-watchers.js.map +1 -1
- package/dist/src/core/database.d.ts +99 -13
- package/dist/src/core/database.d.ts.map +1 -1
- package/dist/src/core/database.js +250 -33
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/core/derived-row-validator.d.ts +1 -1
- package/dist/src/core/derived-row-validator.d.ts.map +1 -1
- package/dist/src/core/derived-row-validator.js +5 -3
- package/dist/src/core/derived-row-validator.js.map +1 -1
- package/dist/src/core/statement.d.ts +8 -0
- package/dist/src/core/statement.d.ts.map +1 -1
- package/dist/src/core/statement.js +98 -18
- package/dist/src/core/statement.js.map +1 -1
- package/dist/src/emit/ast-stringify.d.ts.map +1 -1
- package/dist/src/emit/ast-stringify.js +24 -13
- package/dist/src/emit/ast-stringify.js.map +1 -1
- package/dist/src/func/builtins/explain.d.ts.map +1 -1
- package/dist/src/func/builtins/explain.js +2 -1
- package/dist/src/func/builtins/explain.js.map +1 -1
- package/dist/src/func/builtins/json.d.ts.map +1 -1
- package/dist/src/func/builtins/json.js +2 -1
- package/dist/src/func/builtins/json.js.map +1 -1
- package/dist/src/func/builtins/mutation.d.ts.map +1 -1
- package/dist/src/func/builtins/mutation.js +3 -2
- package/dist/src/func/builtins/mutation.js.map +1 -1
- package/dist/src/index.d.ts +16 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +33 -7
- package/dist/src/index.js.map +1 -1
- package/dist/src/parser/ast.d.ts +2 -2
- package/dist/src/parser/lexer.d.ts +11 -1
- package/dist/src/parser/lexer.d.ts.map +1 -1
- package/dist/src/parser/lexer.js +40 -34
- package/dist/src/parser/lexer.js.map +1 -1
- package/dist/src/parser/parser.d.ts.map +1 -1
- package/dist/src/parser/parser.js +16 -9
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/src/planner/analysis/authored-inverse.js +1 -1
- package/dist/src/planner/analysis/comparison-collation.d.ts +52 -0
- package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -1
- package/dist/src/planner/analysis/comparison-collation.js +84 -7
- package/dist/src/planner/analysis/comparison-collation.js.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.js +64 -17
- package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
- package/dist/src/planner/analysis/coverage-prover.d.ts +1 -1
- package/dist/src/planner/analysis/coverage-prover.js +1 -1
- package/dist/src/planner/analysis/sat-checker.d.ts +8 -1
- package/dist/src/planner/analysis/sat-checker.d.ts.map +1 -1
- package/dist/src/planner/analysis/sat-checker.js +117 -22
- package/dist/src/planner/analysis/sat-checker.js.map +1 -1
- package/dist/src/planner/analysis/scalar-invertibility.d.ts +13 -4
- package/dist/src/planner/analysis/scalar-invertibility.d.ts.map +1 -1
- package/dist/src/planner/analysis/scalar-invertibility.js +12 -3
- package/dist/src/planner/analysis/scalar-invertibility.js.map +1 -1
- package/dist/src/planner/analysis/update-lineage.d.ts +1 -1
- package/dist/src/planner/analysis/update-lineage.js +1 -1
- package/dist/src/planner/analysis/update-lineage.js.map +1 -1
- package/dist/src/planner/analysis/view-complement.d.ts +2 -2
- package/dist/src/planner/building/delete.js +2 -2
- package/dist/src/planner/building/delete.js.map +1 -1
- package/dist/src/planner/building/dml-target.d.ts +2 -2
- package/dist/src/planner/building/dml-target.js +2 -2
- package/dist/src/planner/building/insert.d.ts.map +1 -1
- package/dist/src/planner/building/insert.js +53 -2
- package/dist/src/planner/building/insert.js.map +1 -1
- package/dist/src/planner/building/schema-resolution.d.ts +3 -0
- package/dist/src/planner/building/schema-resolution.d.ts.map +1 -1
- package/dist/src/planner/building/schema-resolution.js +4 -5
- package/dist/src/planner/building/schema-resolution.js.map +1 -1
- package/dist/src/planner/building/select.js +3 -3
- package/dist/src/planner/building/select.js.map +1 -1
- package/dist/src/planner/building/update.js +2 -2
- package/dist/src/planner/building/update.js.map +1 -1
- package/dist/src/planner/building/view-mutation-builder.js +7 -7
- package/dist/src/planner/building/view-mutation-builder.js.map +1 -1
- package/dist/src/planner/cache/materialization-advisory.d.ts +1 -2
- package/dist/src/planner/cache/materialization-advisory.d.ts.map +1 -1
- package/dist/src/planner/cache/materialization-advisory.js +21 -14
- package/dist/src/planner/cache/materialization-advisory.js.map +1 -1
- package/dist/src/planner/cache/reference-graph.d.ts +14 -1
- package/dist/src/planner/cache/reference-graph.d.ts.map +1 -1
- package/dist/src/planner/cache/reference-graph.js +26 -26
- package/dist/src/planner/cache/reference-graph.js.map +1 -1
- package/dist/src/planner/cost/index.d.ts +7 -3
- package/dist/src/planner/cost/index.d.ts.map +1 -1
- package/dist/src/planner/cost/index.js.map +1 -1
- package/dist/src/planner/debug.d.ts +3 -2
- package/dist/src/planner/debug.d.ts.map +1 -1
- package/dist/src/planner/debug.js +9 -3
- package/dist/src/planner/debug.js.map +1 -1
- package/dist/src/planner/framework/characteristics.d.ts +46 -19
- package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
- package/dist/src/planner/framework/characteristics.js +50 -134
- package/dist/src/planner/framework/characteristics.js.map +1 -1
- package/dist/src/planner/framework/context.d.ts +8 -44
- package/dist/src/planner/framework/context.d.ts.map +1 -1
- package/dist/src/planner/framework/context.js +0 -91
- package/dist/src/planner/framework/context.js.map +1 -1
- package/dist/src/planner/framework/pass.d.ts +7 -0
- package/dist/src/planner/framework/pass.d.ts.map +1 -1
- package/dist/src/planner/framework/pass.js +84 -0
- package/dist/src/planner/framework/pass.js.map +1 -1
- package/dist/src/planner/framework/registry.d.ts +13 -42
- package/dist/src/planner/framework/registry.d.ts.map +1 -1
- package/dist/src/planner/framework/registry.js +14 -182
- package/dist/src/planner/framework/registry.js.map +1 -1
- package/dist/src/planner/mutation/backward-body.d.ts +2 -2
- package/dist/src/planner/mutation/cte-flatten.js +1 -1
- package/dist/src/planner/mutation/decomposition.d.ts +2 -2
- package/dist/src/planner/mutation/decomposition.js +1 -1
- package/dist/src/planner/mutation/lens-enforcement.d.ts.map +1 -1
- package/dist/src/planner/mutation/lens-enforcement.js +2 -1
- package/dist/src/planner/mutation/lens-enforcement.js.map +1 -1
- package/dist/src/planner/mutation/multi-source.d.ts +8 -8
- package/dist/src/planner/mutation/multi-source.js +11 -11
- package/dist/src/planner/mutation/multi-source.js.map +1 -1
- package/dist/src/planner/mutation/propagate.d.ts +1 -1
- package/dist/src/planner/mutation/propagate.js +1 -1
- package/dist/src/planner/mutation/scope-transform.d.ts +2 -2
- package/dist/src/planner/mutation/scope-transform.js +3 -3
- package/dist/src/planner/mutation/scope-transform.js.map +1 -1
- package/dist/src/planner/mutation/set-op.d.ts +1 -1
- package/dist/src/planner/mutation/set-op.d.ts.map +1 -1
- package/dist/src/planner/mutation/set-op.js +3 -2
- package/dist/src/planner/mutation/set-op.js.map +1 -1
- package/dist/src/planner/mutation/single-source.d.ts +3 -3
- package/dist/src/planner/mutation/single-source.js +9 -9
- package/dist/src/planner/mutation/single-source.js.map +1 -1
- package/dist/src/planner/nodes/aggregate-function.d.ts +3 -1
- package/dist/src/planner/nodes/aggregate-function.d.ts.map +1 -1
- package/dist/src/planner/nodes/aggregate-function.js +1 -0
- package/dist/src/planner/nodes/aggregate-function.js.map +1 -1
- package/dist/src/planner/nodes/aggregate-node.d.ts +1 -0
- package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/aggregate-node.js +8 -1
- 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 +3 -1
- package/dist/src/planner/nodes/alias-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 +3 -2
- package/dist/src/planner/nodes/asof-scan-node.js.map +1 -1
- package/dist/src/planner/nodes/asserted-keys-node.d.ts +1 -1
- package/dist/src/planner/nodes/asserted-keys-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/asserted-keys-node.js +5 -2
- package/dist/src/planner/nodes/asserted-keys-node.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 +3 -1
- package/dist/src/planner/nodes/async-gather-node.js.map +1 -1
- package/dist/src/planner/nodes/block.js +3 -3
- package/dist/src/planner/nodes/block.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 +5 -1
- package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
- package/dist/src/planner/nodes/cache-node.d.ts +1 -0
- package/dist/src/planner/nodes/cache-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/cache-node.js +1 -0
- package/dist/src/planner/nodes/cache-node.js.map +1 -1
- package/dist/src/planner/nodes/cte-node.d.ts +1 -0
- package/dist/src/planner/nodes/cte-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/cte-node.js +4 -1
- package/dist/src/planner/nodes/cte-node.js.map +1 -1
- package/dist/src/planner/nodes/distinct-node.js +3 -3
- package/dist/src/planner/nodes/distinct-node.js.map +1 -1
- package/dist/src/planner/nodes/dml-executor-node.d.ts +21 -0
- package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
- package/dist/src/planner/nodes/envelope-scan-node.d.ts +1 -1
- package/dist/src/planner/nodes/envelope-scan-node.js +1 -1
- package/dist/src/planner/nodes/fanout-lookup-join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/fanout-lookup-join-node.js +4 -2
- package/dist/src/planner/nodes/fanout-lookup-join-node.js.map +1 -1
- package/dist/src/planner/nodes/filter.d.ts +10 -2
- package/dist/src/planner/nodes/filter.d.ts.map +1 -1
- package/dist/src/planner/nodes/filter.js +81 -14
- package/dist/src/planner/nodes/filter.js.map +1 -1
- package/dist/src/planner/nodes/hash-aggregate.d.ts +12 -1
- package/dist/src/planner/nodes/hash-aggregate.d.ts.map +1 -1
- package/dist/src/planner/nodes/hash-aggregate.js +28 -1
- package/dist/src/planner/nodes/hash-aggregate.js.map +1 -1
- package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts +3 -1
- package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js +1 -0
- package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js.map +1 -1
- package/dist/src/planner/nodes/join-node.d.ts +3 -1
- package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-node.js +5 -5
- package/dist/src/planner/nodes/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 +4 -1
- package/dist/src/planner/nodes/lens-auxiliary-access-node.js.map +1 -1
- package/dist/src/planner/nodes/limit-offset.d.ts +1 -0
- package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
- package/dist/src/planner/nodes/limit-offset.js +4 -3
- package/dist/src/planner/nodes/limit-offset.js.map +1 -1
- 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 +6 -1
- package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
- package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/ordinal-slice-node.js +3 -1
- package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
- package/dist/src/planner/nodes/plan-node.d.ts +68 -5
- package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/plan-node.js +137 -24
- package/dist/src/planner/nodes/plan-node.js.map +1 -1
- package/dist/src/planner/nodes/project-node.d.ts +3 -2
- package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/project-node.js +1 -0
- package/dist/src/planner/nodes/project-node.js.map +1 -1
- package/dist/src/planner/nodes/recursive-cte-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/recursive-cte-node.js +8 -2
- package/dist/src/planner/nodes/recursive-cte-node.js.map +1 -1
- package/dist/src/planner/nodes/reference.d.ts +5 -1
- package/dist/src/planner/nodes/reference.d.ts.map +1 -1
- package/dist/src/planner/nodes/reference.js +3 -0
- package/dist/src/planner/nodes/reference.js.map +1 -1
- package/dist/src/planner/nodes/remote-query-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/remote-query-node.js +3 -1
- package/dist/src/planner/nodes/remote-query-node.js.map +1 -1
- package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/retrieve-node.js +3 -1
- package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
- package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/set-operation-node.js +3 -1
- package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
- package/dist/src/planner/nodes/sink-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/sink-node.js +3 -1
- package/dist/src/planner/nodes/sink-node.js.map +1 -1
- package/dist/src/planner/nodes/sort.d.ts +2 -1
- package/dist/src/planner/nodes/sort.d.ts.map +1 -1
- package/dist/src/planner/nodes/sort.js +9 -5
- package/dist/src/planner/nodes/sort.js.map +1 -1
- package/dist/src/planner/nodes/stream-aggregate.d.ts +12 -1
- package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
- package/dist/src/planner/nodes/stream-aggregate.js +32 -3
- package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.d.ts +2 -1
- package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.js +2 -0
- package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
- package/dist/src/planner/nodes/view-mutation-node.d.ts +2 -2
- package/dist/src/planner/nodes/view-mutation-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/view-mutation-node.js +5 -1
- package/dist/src/planner/nodes/view-mutation-node.js.map +1 -1
- package/dist/src/planner/nodes/window-function.d.ts +3 -1
- package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
- package/dist/src/planner/nodes/window-function.js +1 -0
- package/dist/src/planner/nodes/window-function.js.map +1 -1
- package/dist/src/planner/optimizer.d.ts +52 -8
- package/dist/src/planner/optimizer.d.ts.map +1 -1
- package/dist/src/planner/optimizer.js +885 -894
- package/dist/src/planner/optimizer.js.map +1 -1
- 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 +235 -202
- package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
- package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts +2 -2
- package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js +2 -2
- package/dist/src/planner/rules/cache/rule-scalar-cse.d.ts +1 -1
- package/dist/src/planner/rules/cache/rule-scalar-cse.js +1 -1
- package/dist/src/planner/rules/join/rule-fanout-batched-outer.d.ts +1 -1
- package/dist/src/planner/rules/join/rule-fanout-batched-outer.js +1 -1
- package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts +1 -1
- package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js +1 -1
- package/dist/src/planner/rules/join/rule-join-elimination.d.ts +1 -1
- package/dist/src/planner/rules/join/rule-join-elimination.js +1 -1
- package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js +5 -6
- package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.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-contradiction.d.ts +2 -2
- package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts.map +1 -1
- package/dist/src/planner/rules/predicate/rule-filter-contradiction.js +4 -3
- package/dist/src/planner/rules/predicate/rule-filter-contradiction.js.map +1 -1
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts +19 -0
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts.map +1 -0
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.js +48 -0
- package/dist/src/planner/rules/predicate/rule-filter-selectivity.js.map +1 -0
- package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.js +12 -1
- package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.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 +22 -20
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
- package/dist/src/planner/rules/shared/index-style-context.d.ts +39 -0
- package/dist/src/planner/rules/shared/index-style-context.d.ts.map +1 -0
- package/dist/src/planner/rules/shared/index-style-context.js +26 -0
- package/dist/src/planner/rules/shared/index-style-context.js.map +1 -0
- package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts +1 -1
- package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js +1 -1
- package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts +1 -1
- package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js +1 -1
- package/dist/src/planner/stats/analyze.d.ts.map +1 -1
- package/dist/src/planner/stats/analyze.js +2 -20
- package/dist/src/planner/stats/analyze.js.map +1 -1
- package/dist/src/planner/stats/histogram.d.ts.map +1 -1
- package/dist/src/planner/stats/histogram.js +4 -0
- package/dist/src/planner/stats/histogram.js.map +1 -1
- package/dist/src/planner/util/fd-utils.d.ts +2 -3
- package/dist/src/planner/util/fd-utils.d.ts.map +1 -1
- package/dist/src/planner/util/fd-utils.js +2 -3
- package/dist/src/planner/util/fd-utils.js.map +1 -1
- package/dist/src/planner/validation/plan-validator.d.ts +16 -0
- package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
- package/dist/src/planner/validation/plan-validator.js +36 -0
- package/dist/src/planner/validation/plan-validator.js.map +1 -1
- package/dist/src/runtime/async-util.d.ts +26 -0
- package/dist/src/runtime/async-util.d.ts.map +1 -1
- package/dist/src/runtime/async-util.js +139 -55
- package/dist/src/runtime/async-util.js.map +1 -1
- package/dist/src/runtime/context-helpers.d.ts +32 -4
- package/dist/src/runtime/context-helpers.d.ts.map +1 -1
- package/dist/src/runtime/context-helpers.js +26 -9
- package/dist/src/runtime/context-helpers.js.map +1 -1
- package/dist/src/runtime/deferred-constraint-queue.d.ts.map +1 -1
- package/dist/src/runtime/deferred-constraint-queue.js +2 -1
- package/dist/src/runtime/deferred-constraint-queue.js.map +1 -1
- package/dist/src/runtime/emission-context.d.ts +27 -3
- package/dist/src/runtime/emission-context.d.ts.map +1 -1
- package/dist/src/runtime/emission-context.js +38 -7
- package/dist/src/runtime/emission-context.js.map +1 -1
- package/dist/src/runtime/emit/add-constraint.d.ts.map +1 -1
- package/dist/src/runtime/emit/add-constraint.js +7 -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 +17 -13
- package/dist/src/runtime/emit/aggregate.js.map +1 -1
- package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/alter-table.js +98 -9
- package/dist/src/runtime/emit/alter-table.js.map +1 -1
- package/dist/src/runtime/emit/analyze.d.ts.map +1 -1
- package/dist/src/runtime/emit/analyze.js +2 -1
- package/dist/src/runtime/emit/analyze.js.map +1 -1
- package/dist/src/runtime/emit/asof-scan.d.ts.map +1 -1
- package/dist/src/runtime/emit/asof-scan.js +13 -10
- package/dist/src/runtime/emit/asof-scan.js.map +1 -1
- package/dist/src/runtime/emit/async-gather.d.ts.map +1 -1
- package/dist/src/runtime/emit/async-gather.js +4 -3
- package/dist/src/runtime/emit/async-gather.js.map +1 -1
- package/dist/src/runtime/emit/between.d.ts.map +1 -1
- package/dist/src/runtime/emit/between.js +2 -1
- 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 +122 -14
- package/dist/src/runtime/emit/binary.js.map +1 -1
- package/dist/src/runtime/emit/block.d.ts.map +1 -1
- package/dist/src/runtime/emit/block.js +2 -1
- package/dist/src/runtime/emit/block.js.map +1 -1
- package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -1
- package/dist/src/runtime/emit/bloom-join.js +20 -8
- package/dist/src/runtime/emit/bloom-join.js.map +1 -1
- package/dist/src/runtime/emit/cache.d.ts.map +1 -1
- package/dist/src/runtime/emit/cache.js +2 -1
- package/dist/src/runtime/emit/cache.js.map +1 -1
- package/dist/src/runtime/emit/case.d.ts.map +1 -1
- package/dist/src/runtime/emit/case.js +66 -45
- package/dist/src/runtime/emit/case.js.map +1 -1
- package/dist/src/runtime/emit/cast.d.ts.map +1 -1
- package/dist/src/runtime/emit/cast.js +2 -1
- package/dist/src/runtime/emit/cast.js.map +1 -1
- package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
- package/dist/src/runtime/emit/constraint-check.js +13 -7
- package/dist/src/runtime/emit/constraint-check.js.map +1 -1
- package/dist/src/runtime/emit/create-assertion.d.ts.map +1 -1
- package/dist/src/runtime/emit/create-assertion.js +2 -1
- package/dist/src/runtime/emit/create-assertion.js.map +1 -1
- package/dist/src/runtime/emit/create-index.d.ts.map +1 -1
- package/dist/src/runtime/emit/create-index.js +12 -1
- package/dist/src/runtime/emit/create-index.js.map +1 -1
- package/dist/src/runtime/emit/create-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/create-table.js +12 -1
- package/dist/src/runtime/emit/create-table.js.map +1 -1
- package/dist/src/runtime/emit/cte-reference.d.ts.map +1 -1
- package/dist/src/runtime/emit/cte-reference.js +2 -1
- package/dist/src/runtime/emit/cte-reference.js.map +1 -1
- package/dist/src/runtime/emit/cte.d.ts.map +1 -1
- package/dist/src/runtime/emit/cte.js +2 -1
- package/dist/src/runtime/emit/cte.js.map +1 -1
- package/dist/src/runtime/emit/ddl-transaction-policy.d.ts +50 -0
- package/dist/src/runtime/emit/ddl-transaction-policy.d.ts.map +1 -0
- package/dist/src/runtime/emit/ddl-transaction-policy.js +69 -0
- package/dist/src/runtime/emit/ddl-transaction-policy.js.map +1 -0
- package/dist/src/runtime/emit/delete.d.ts.map +1 -1
- package/dist/src/runtime/emit/delete.js +2 -1
- package/dist/src/runtime/emit/delete.js.map +1 -1
- package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
- package/dist/src/runtime/emit/distinct.js +2 -1
- package/dist/src/runtime/emit/distinct.js.map +1 -1
- package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
- package/dist/src/runtime/emit/dml-executor.js +70 -31
- package/dist/src/runtime/emit/dml-executor.js.map +1 -1
- package/dist/src/runtime/emit/drop-assertion.d.ts.map +1 -1
- package/dist/src/runtime/emit/drop-assertion.js +2 -1
- package/dist/src/runtime/emit/drop-assertion.js.map +1 -1
- package/dist/src/runtime/emit/drop-index.d.ts.map +1 -1
- package/dist/src/runtime/emit/drop-index.js +17 -1
- package/dist/src/runtime/emit/drop-index.js.map +1 -1
- package/dist/src/runtime/emit/drop-table.d.ts.map +1 -1
- package/dist/src/runtime/emit/drop-table.js +11 -1
- package/dist/src/runtime/emit/drop-table.js.map +1 -1
- package/dist/src/runtime/emit/eager-prefetch.d.ts.map +1 -1
- package/dist/src/runtime/emit/eager-prefetch.js +2 -1
- package/dist/src/runtime/emit/eager-prefetch.js.map +1 -1
- package/dist/src/runtime/emit/envelope-scan.d.ts.map +1 -1
- package/dist/src/runtime/emit/envelope-scan.js +2 -1
- package/dist/src/runtime/emit/envelope-scan.js.map +1 -1
- package/dist/src/runtime/emit/fanout-lookup-join.d.ts.map +1 -1
- package/dist/src/runtime/emit/fanout-lookup-join.js +3 -2
- package/dist/src/runtime/emit/fanout-lookup-join.js.map +1 -1
- package/dist/src/runtime/emit/filter.d.ts.map +1 -1
- package/dist/src/runtime/emit/filter.js +8 -3
- package/dist/src/runtime/emit/filter.js.map +1 -1
- package/dist/src/runtime/emit/hash-aggregate.d.ts.map +1 -1
- package/dist/src/runtime/emit/hash-aggregate.js +16 -11
- package/dist/src/runtime/emit/hash-aggregate.js.map +1 -1
- package/dist/src/runtime/emit/insert.d.ts.map +1 -1
- package/dist/src/runtime/emit/insert.js +2 -1
- package/dist/src/runtime/emit/insert.js.map +1 -1
- package/dist/src/runtime/emit/join.d.ts.map +1 -1
- package/dist/src/runtime/emit/join.js +20 -6
- package/dist/src/runtime/emit/join.js.map +1 -1
- package/dist/src/runtime/emit/limit-offset.d.ts.map +1 -1
- package/dist/src/runtime/emit/limit-offset.js +2 -1
- package/dist/src/runtime/emit/limit-offset.js.map +1 -1
- package/dist/src/runtime/emit/literal.d.ts.map +1 -1
- package/dist/src/runtime/emit/literal.js +2 -1
- package/dist/src/runtime/emit/literal.js.map +1 -1
- package/dist/src/runtime/emit/materialized-view-helpers.d.ts +22 -0
- package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -1
- package/dist/src/runtime/emit/materialized-view-helpers.js +123 -12
- package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -1
- package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -1
- package/dist/src/runtime/emit/materialized-view.js +6 -0
- package/dist/src/runtime/emit/materialized-view.js.map +1 -1
- package/dist/src/runtime/emit/merge-join.d.ts.map +1 -1
- package/dist/src/runtime/emit/merge-join.js +14 -4
- package/dist/src/runtime/emit/merge-join.js.map +1 -1
- package/dist/src/runtime/emit/ordinal-slice.d.ts.map +1 -1
- package/dist/src/runtime/emit/ordinal-slice.js +2 -1
- package/dist/src/runtime/emit/ordinal-slice.js.map +1 -1
- package/dist/src/runtime/emit/pragma.d.ts.map +1 -1
- package/dist/src/runtime/emit/pragma.js +2 -1
- package/dist/src/runtime/emit/pragma.js.map +1 -1
- package/dist/src/runtime/emit/project.d.ts.map +1 -1
- package/dist/src/runtime/emit/project.js +7 -2
- package/dist/src/runtime/emit/project.js.map +1 -1
- package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -1
- package/dist/src/runtime/emit/recursive-cte.js +2 -1
- package/dist/src/runtime/emit/recursive-cte.js.map +1 -1
- package/dist/src/runtime/emit/returning.d.ts.map +1 -1
- package/dist/src/runtime/emit/returning.js +7 -2
- package/dist/src/runtime/emit/returning.js.map +1 -1
- package/dist/src/runtime/emit/scalar-function.d.ts.map +1 -1
- package/dist/src/runtime/emit/scalar-function.js +2 -1
- package/dist/src/runtime/emit/scalar-function.js.map +1 -1
- package/dist/src/runtime/emit/scan.d.ts.map +1 -1
- package/dist/src/runtime/emit/scan.js +55 -17
- package/dist/src/runtime/emit/scan.js.map +1 -1
- package/dist/src/runtime/emit/schema-declarative.d.ts.map +1 -1
- package/dist/src/runtime/emit/schema-declarative.js +6 -5
- package/dist/src/runtime/emit/schema-declarative.js.map +1 -1
- package/dist/src/runtime/emit/sequencing.d.ts.map +1 -1
- package/dist/src/runtime/emit/sequencing.js +2 -1
- package/dist/src/runtime/emit/sequencing.js.map +1 -1
- package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
- package/dist/src/runtime/emit/set-operation.js +6 -5
- package/dist/src/runtime/emit/set-operation.js.map +1 -1
- package/dist/src/runtime/emit/sink.d.ts.map +1 -1
- package/dist/src/runtime/emit/sink.js +2 -1
- package/dist/src/runtime/emit/sink.js.map +1 -1
- package/dist/src/runtime/emit/sort.d.ts.map +1 -1
- package/dist/src/runtime/emit/sort.js +2 -1
- package/dist/src/runtime/emit/sort.js.map +1 -1
- package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
- package/dist/src/runtime/emit/subquery.js +42 -23
- package/dist/src/runtime/emit/subquery.js.map +1 -1
- package/dist/src/runtime/emit/table-valued-function.d.ts.map +1 -1
- package/dist/src/runtime/emit/table-valued-function.js +2 -1
- package/dist/src/runtime/emit/table-valued-function.js.map +1 -1
- package/dist/src/runtime/emit/temporal-arithmetic.d.ts.map +1 -1
- package/dist/src/runtime/emit/temporal-arithmetic.js +2 -1
- package/dist/src/runtime/emit/temporal-arithmetic.js.map +1 -1
- package/dist/src/runtime/emit/transaction.d.ts.map +1 -1
- package/dist/src/runtime/emit/transaction.js +2 -1
- package/dist/src/runtime/emit/transaction.js.map +1 -1
- package/dist/src/runtime/emit/unary.d.ts.map +1 -1
- package/dist/src/runtime/emit/unary.js +2 -1
- package/dist/src/runtime/emit/unary.js.map +1 -1
- package/dist/src/runtime/emit/update.d.ts.map +1 -1
- package/dist/src/runtime/emit/update.js +2 -1
- package/dist/src/runtime/emit/update.js.map +1 -1
- package/dist/src/runtime/emit/values.d.ts.map +1 -1
- package/dist/src/runtime/emit/values.js +2 -1
- package/dist/src/runtime/emit/values.js.map +1 -1
- package/dist/src/runtime/emit/view-mutation.d.ts +1 -1
- package/dist/src/runtime/emit/view-mutation.d.ts.map +1 -1
- package/dist/src/runtime/emit/view-mutation.js +6 -3
- package/dist/src/runtime/emit/view-mutation.js.map +1 -1
- package/dist/src/runtime/emit/window.d.ts.map +1 -1
- package/dist/src/runtime/emit/window.js +26 -9
- package/dist/src/runtime/emit/window.js.map +1 -1
- package/dist/src/runtime/emitters.d.ts +11 -3
- package/dist/src/runtime/emitters.d.ts.map +1 -1
- package/dist/src/runtime/emitters.js +13 -22
- package/dist/src/runtime/emitters.js.map +1 -1
- package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
- package/dist/src/runtime/foreign-key-actions.js +39 -13
- package/dist/src/runtime/foreign-key-actions.js.map +1 -1
- package/dist/src/runtime/parallel-driver.d.ts +18 -4
- package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
- package/dist/src/runtime/parallel-driver.js +72 -18
- package/dist/src/runtime/parallel-driver.js.map +1 -1
- package/dist/src/runtime/scheduler.d.ts +56 -7
- package/dist/src/runtime/scheduler.d.ts.map +1 -1
- package/dist/src/runtime/scheduler.js +223 -200
- package/dist/src/runtime/scheduler.js.map +1 -1
- package/dist/src/runtime/strict-flags.d.ts +22 -0
- package/dist/src/runtime/strict-flags.d.ts.map +1 -0
- package/dist/src/runtime/strict-flags.js +26 -0
- package/dist/src/runtime/strict-flags.js.map +1 -0
- package/dist/src/runtime/strict-fork.d.ts +4 -4
- package/dist/src/runtime/strict-fork.d.ts.map +1 -1
- package/dist/src/runtime/strict-fork.js +175 -31
- package/dist/src/runtime/strict-fork.js.map +1 -1
- package/dist/src/runtime/types.d.ts +66 -4
- package/dist/src/runtime/types.d.ts.map +1 -1
- package/dist/src/runtime/types.js +37 -0
- package/dist/src/runtime/types.js.map +1 -1
- package/dist/src/runtime/utils.d.ts.map +1 -1
- package/dist/src/runtime/utils.js +8 -17
- package/dist/src/runtime/utils.js.map +1 -1
- package/dist/src/schema/column.d.ts +8 -0
- 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.js +5 -0
- package/dist/src/schema/ddl-generator.js.map +1 -1
- package/dist/src/schema/lens-compiler.js +2 -2
- package/dist/src/schema/lens-compiler.js.map +1 -1
- package/dist/src/schema/lens-prover.d.ts.map +1 -1
- package/dist/src/schema/lens-prover.js +2 -3
- package/dist/src/schema/lens-prover.js.map +1 -1
- package/dist/src/schema/lens.d.ts +1 -1
- package/dist/src/schema/manager.d.ts.map +1 -1
- package/dist/src/schema/manager.js +7 -2
- package/dist/src/schema/manager.js.map +1 -1
- package/dist/src/schema/rename-rewriter.d.ts +61 -0
- package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
- package/dist/src/schema/rename-rewriter.js +77 -0
- package/dist/src/schema/rename-rewriter.js.map +1 -1
- package/dist/src/schema/table.d.ts +36 -8
- package/dist/src/schema/table.d.ts.map +1 -1
- package/dist/src/schema/table.js +61 -11
- package/dist/src/schema/table.js.map +1 -1
- package/dist/src/schema/unique-enforcement.d.ts +28 -5
- package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
- package/dist/src/schema/unique-enforcement.js +37 -5
- package/dist/src/schema/unique-enforcement.js.map +1 -1
- package/dist/src/schema/view.d.ts +1 -1
- package/dist/src/schema/view.js +1 -1
- package/dist/src/types/json-type.d.ts.map +1 -1
- package/dist/src/types/json-type.js +18 -8
- package/dist/src/types/json-type.js.map +1 -1
- package/dist/src/types/logical-type.d.ts +26 -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/util/comparison.d.ts +83 -59
- package/dist/src/util/comparison.d.ts.map +1 -1
- package/dist/src/util/comparison.js +191 -131
- package/dist/src/util/comparison.js.map +1 -1
- package/dist/src/util/json-canonical.d.ts +34 -0
- package/dist/src/util/json-canonical.d.ts.map +1 -0
- package/dist/src/util/json-canonical.js +32 -0
- package/dist/src/util/json-canonical.js.map +1 -0
- package/dist/src/util/key-serializer.d.ts +10 -3
- package/dist/src/util/key-serializer.d.ts.map +1 -1
- package/dist/src/util/key-serializer.js +43 -17
- package/dist/src/util/key-serializer.js.map +1 -1
- package/dist/src/util/key-tuple-codec.d.ts +37 -0
- package/dist/src/util/key-tuple-codec.d.ts.map +1 -0
- package/dist/src/util/key-tuple-codec.js +65 -0
- package/dist/src/util/key-tuple-codec.js.map +1 -0
- package/dist/src/util/latches.d.ts +29 -3
- package/dist/src/util/latches.d.ts.map +1 -1
- package/dist/src/util/latches.js +60 -6
- package/dist/src/util/latches.js.map +1 -1
- package/dist/src/util/patterns.d.ts +22 -8
- package/dist/src/util/patterns.d.ts.map +1 -1
- package/dist/src/util/patterns.js +87 -16
- package/dist/src/util/patterns.js.map +1 -1
- package/dist/src/util/qualified-name.d.ts +10 -0
- package/dist/src/util/qualified-name.d.ts.map +1 -0
- package/dist/src/util/qualified-name.js +15 -0
- package/dist/src/util/qualified-name.js.map +1 -0
- package/dist/src/vtab/backing-host.d.ts +8 -1
- package/dist/src/vtab/backing-host.d.ts.map +1 -1
- package/dist/src/vtab/backing-host.js +7 -0
- package/dist/src/vtab/backing-host.js.map +1 -1
- package/dist/src/vtab/best-access-plan.d.ts +18 -0
- package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
- package/dist/src/vtab/best-access-plan.js +15 -0
- package/dist/src/vtab/best-access-plan.js.map +1 -1
- package/dist/src/vtab/capabilities.d.ts +44 -0
- package/dist/src/vtab/capabilities.d.ts.map +1 -1
- package/dist/src/vtab/filter-info.d.ts +42 -0
- package/dist/src/vtab/filter-info.d.ts.map +1 -1
- package/dist/src/vtab/filter-info.js +137 -1
- package/dist/src/vtab/filter-info.js.map +1 -1
- package/dist/src/vtab/idx-str.d.ts +62 -0
- package/dist/src/vtab/idx-str.d.ts.map +1 -0
- package/dist/src/vtab/idx-str.js +130 -0
- package/dist/src/vtab/idx-str.js.map +1 -0
- package/dist/src/vtab/index-descriptor.d.ts +122 -0
- package/dist/src/vtab/index-descriptor.d.ts.map +1 -0
- package/dist/src/vtab/index-descriptor.js +104 -0
- package/dist/src/vtab/index-descriptor.js.map +1 -0
- package/dist/src/vtab/mapping-advertisement.d.ts +1 -1
- package/dist/src/vtab/memory/index.d.ts +12 -4
- package/dist/src/vtab/memory/index.d.ts.map +1 -1
- package/dist/src/vtab/memory/index.js +17 -9
- package/dist/src/vtab/memory/index.js.map +1 -1
- package/dist/src/vtab/memory/layer/base.d.ts +85 -31
- package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/base.js +127 -86
- package/dist/src/vtab/memory/layer/base.js.map +1 -1
- package/dist/src/vtab/memory/layer/connection.d.ts +27 -0
- package/dist/src/vtab/memory/layer/connection.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/connection.js +36 -1
- package/dist/src/vtab/memory/layer/connection.js.map +1 -1
- package/dist/src/vtab/memory/layer/interface.d.ts +24 -4
- package/dist/src/vtab/memory/layer/interface.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts +212 -16
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +754 -170
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/dist/src/vtab/memory/layer/plan-filter.d.ts +26 -1
- package/dist/src/vtab/memory/layer/plan-filter.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/plan-filter.js +29 -11
- package/dist/src/vtab/memory/layer/plan-filter.js.map +1 -1
- package/dist/src/vtab/memory/layer/safe-iterate.d.ts +2 -2
- package/dist/src/vtab/memory/layer/safe-iterate.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/safe-iterate.js +2 -2
- package/dist/src/vtab/memory/layer/safe-iterate.js.map +1 -1
- package/dist/src/vtab/memory/layer/scan-layer.d.ts +5 -1
- package/dist/src/vtab/memory/layer/scan-layer.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/scan-layer.js +38 -22
- package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
- package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/scan-plan.js +13 -21
- package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.d.ts +169 -7
- package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.js +334 -9
- package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
- package/dist/src/vtab/memory/module.d.ts +11 -4
- package/dist/src/vtab/memory/module.d.ts.map +1 -1
- package/dist/src/vtab/memory/module.js +35 -16
- package/dist/src/vtab/memory/module.js.map +1 -1
- package/dist/src/vtab/memory/table.d.ts +30 -4
- package/dist/src/vtab/memory/table.d.ts.map +1 -1
- package/dist/src/vtab/memory/table.js +63 -15
- package/dist/src/vtab/memory/table.js.map +1 -1
- package/dist/src/vtab/memory/utils/predicate.d.ts +9 -1
- package/dist/src/vtab/memory/utils/predicate.d.ts.map +1 -1
- package/dist/src/vtab/memory/utils/predicate.js +35 -14
- package/dist/src/vtab/memory/utils/predicate.js.map +1 -1
- package/dist/src/vtab/memory/utils/primary-key-encode.d.ts.map +1 -1
- package/dist/src/vtab/memory/utils/primary-key-encode.js +12 -6
- package/dist/src/vtab/memory/utils/primary-key-encode.js.map +1 -1
- package/dist/src/vtab/memory/utils/primary-key.d.ts +6 -1
- package/dist/src/vtab/memory/utils/primary-key.d.ts.map +1 -1
- package/dist/src/vtab/memory/utils/primary-key.js +12 -8
- package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
- package/dist/src/vtab/module.d.ts +38 -14
- package/dist/src/vtab/module.d.ts.map +1 -1
- package/dist/src/vtab/table.d.ts +41 -2
- package/dist/src/vtab/table.d.ts.map +1 -1
- package/dist/src/vtab/table.js +19 -0
- package/dist/src/vtab/table.js.map +1 -1
- package/package.json +5 -4
- package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts +0 -18
- package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts.map +0 -1
- package/dist/src/planner/rules/cache/rule-materialization-advisory.js +0 -65
- package/dist/src/planner/rules/cache/rule-materialization-advisory.js.map +0 -1
|
@@ -16,6 +16,9 @@ import { RetrieveNode } from '../../nodes/retrieve-node.js';
|
|
|
16
16
|
import { RemoteQueryNode } from '../../nodes/remote-query-node.js';
|
|
17
17
|
import { SeqScanNode, IndexScanNode, IndexSeekNode, EmptyResultNode } from '../../nodes/table-access-nodes.js';
|
|
18
18
|
import { seqScanCost } from '../../cost/index.js';
|
|
19
|
+
import { makeEmptyFilterInfo, makeFullScanFilterInfo } from '../../../vtab/filter-info.js';
|
|
20
|
+
import { PRIMARY_INDEX_NAME, PRIMARY_PHYSICAL_INDEX_NAME, resolveIndexDescriptor } from '../../../vtab/index-descriptor.js';
|
|
21
|
+
import { encodeIdxStr, makeIdxStrSpec } from '../../../vtab/idx-str.js';
|
|
19
22
|
import { compareSqlValues, normalizeCollationName } from '../../../util/comparison.js';
|
|
20
23
|
import { FilterNode } from '../../nodes/filter.js';
|
|
21
24
|
import { extractConstraintsForTable, createTableInfoFromNode } from '../../analysis/constraint-extractor.js';
|
|
@@ -23,7 +26,64 @@ import { LiteralNode, BinaryOpNode, BetweenNode } from '../../nodes/scalar.js';
|
|
|
23
26
|
import { InNode } from '../../nodes/subquery.js';
|
|
24
27
|
import { effectiveBetweenBoundCollation, effectiveComparisonCollation, effectiveInCollation } from '../../analysis/comparison-collation.js';
|
|
25
28
|
import { IndexConstraintOp } from '../../../common/constants.js';
|
|
29
|
+
import { isIndexStyleContext } from '../shared/index-style-context.js';
|
|
26
30
|
const log = createLogger('optimizer:rule:select-access-path');
|
|
31
|
+
const warnLog = createLogger('optimizer:rule:select-access-path').extend('warn');
|
|
32
|
+
/**
|
|
33
|
+
* Resolve the structured {@link AccessPath} for an index arm.
|
|
34
|
+
*
|
|
35
|
+
* `indexName` is the name that lands in `idxStr` — `accessPlan.indexName` for a seek,
|
|
36
|
+
* `accessPlan.orderingIndexName` for an ordering-only walk, `_primary_` for the legacy
|
|
37
|
+
* arms. When the engine cannot resolve it (a per-plan alias the module minted without
|
|
38
|
+
* supplying an `indexDescriptor`) we record `unresolvedIndex` and warn, rather than
|
|
39
|
+
* guessing: an order-sensitive consumer must be able to refuse the plan.
|
|
40
|
+
*/
|
|
41
|
+
function buildIndexAccessPath(tableSchema, accessPlan, indexName, plan) {
|
|
42
|
+
const index = resolveIndexDescriptor(tableSchema, accessPlan, indexName);
|
|
43
|
+
if (index)
|
|
44
|
+
return { kind: 'index', index, plan };
|
|
45
|
+
warnLog('access plan for table %s named index %s which the engine cannot resolve; module should return indexDescriptor', tableSchema.name, indexName);
|
|
46
|
+
return { kind: 'unresolvedIndex', indexName, plan };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Derive a seek/scan FilterInfo from the arm's shared `base`: the encoded `idxStr` and
|
|
50
|
+
* the structured `accessPath` are both projections of the same (indexName, plan, params)
|
|
51
|
+
* triple, so they cannot drift.
|
|
52
|
+
*/
|
|
53
|
+
function makeIndexFilterInfo(base, tableSchema, accessPlan, indexName, plan, constraints, params) {
|
|
54
|
+
const idxStr = encodeIdxStr(makeIdxStrSpec(indexName, plan, params));
|
|
55
|
+
return {
|
|
56
|
+
...base,
|
|
57
|
+
constraints,
|
|
58
|
+
idxStr,
|
|
59
|
+
accessPath: buildIndexAccessPath(tableSchema, accessPlan, indexName, plan),
|
|
60
|
+
indexInfoOutput: {
|
|
61
|
+
...base.indexInfoOutput,
|
|
62
|
+
idxStr,
|
|
63
|
+
// Reflect the seek's consumed constraints so EXPLAIN's matchedClauses
|
|
64
|
+
// counts them; `base` is seeded from a full scan and carries none.
|
|
65
|
+
aConstraintUsage: constraints.map(c => ({ argvIndex: c.argvIndex, omit: true })),
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Derive the FilterInfo for an ordering-only index walk (`plan=0`). Unlike a seek this
|
|
71
|
+
* also stamps `indexInfoOutput.idxStr` and `orderByConsumed`, because the runtime reads
|
|
72
|
+
* the consumed-ordering flag off the IndexInfo rather than the FilterInfo.
|
|
73
|
+
*/
|
|
74
|
+
function makeOrderedScanFilterInfo(base, tableSchema, accessPlan, indexName) {
|
|
75
|
+
const idxStr = encodeIdxStr(makeIdxStrSpec(indexName, 'scan'));
|
|
76
|
+
return {
|
|
77
|
+
...base,
|
|
78
|
+
idxStr,
|
|
79
|
+
accessPath: buildIndexAccessPath(tableSchema, accessPlan, indexName, 'scan'),
|
|
80
|
+
indexInfoOutput: {
|
|
81
|
+
...base.indexInfoOutput,
|
|
82
|
+
idxStr,
|
|
83
|
+
orderByConsumed: true,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
27
87
|
/**
|
|
28
88
|
* Extract the monotonic-ordering advertisement from a `BestAccessPlanResult`,
|
|
29
89
|
* or return undefined when nothing is advertised. The result is forwarded to
|
|
@@ -117,7 +177,7 @@ function createIndexBasedAccess(retrieveNode, context) {
|
|
|
117
177
|
// Use pre-computed access plan from grow rule
|
|
118
178
|
log('Using pre-computed access plan from grow rule');
|
|
119
179
|
accessPlan = retrieveNode.moduleCtx.accessPlan;
|
|
120
|
-
constraints = retrieveNode.moduleCtx.originalConstraints
|
|
180
|
+
constraints = retrieveNode.moduleCtx.originalConstraints;
|
|
121
181
|
residualPredicate = retrieveNode.moduleCtx.residualPredicate;
|
|
122
182
|
}
|
|
123
183
|
else {
|
|
@@ -141,7 +201,14 @@ function createIndexBasedAccess(retrieveNode, context) {
|
|
|
141
201
|
}
|
|
142
202
|
// Choose physical node based on access plan
|
|
143
203
|
const physicalLeaf = selectPhysicalNode(retrieveNode.tableRef, accessPlan, constraints);
|
|
144
|
-
// If the Retrieve source contained a pipeline (e.g., Filter/Sort/Project), rebuild it above the physical leaf
|
|
204
|
+
// If the Retrieve source contained a pipeline (e.g., Filter/Sort/Project), rebuild it above the physical leaf.
|
|
205
|
+
//
|
|
206
|
+
// NOTE: on this path (no index-style moduleCtx) an absorbed `Filter` in `source` is
|
|
207
|
+
// preserved verbatim, so a constraint that `reattachUnconsumedConstraints` recovers is
|
|
208
|
+
// already applied above — the reattached `Filter` is then redundant, not wrong. Only
|
|
209
|
+
// reachable for a module exposing BOTH `supports()` (declining here) and
|
|
210
|
+
// `getBestAccessPlan()`. If that ever shows up as a duplicated predicate in EXPLAIN,
|
|
211
|
+
// pass the consumed set out and skip the reattach when `source !== tableRef`.
|
|
145
212
|
let rebuiltPipeline = physicalLeaf;
|
|
146
213
|
if (retrieveNode.source !== retrieveNode.tableRef) {
|
|
147
214
|
log('Rebuilding Retrieve pipeline above physical access node');
|
|
@@ -173,6 +240,45 @@ function rebuildPipelineWithNewLeaf(pipelineRoot, oldLeaf, newLeaf) {
|
|
|
173
240
|
});
|
|
174
241
|
return pipelineRoot.withChildren(newChildren);
|
|
175
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* The constraint operators this rule can turn into seek bounds, and therefore the
|
|
245
|
+
* only ones {@link reattachUnconsumedConstraints} can recover when a module claims
|
|
246
|
+
* a filter the rule never consumes.
|
|
247
|
+
*
|
|
248
|
+
* NOTE: ops outside this set (IS NULL / IS NOT NULL / LIKE / GLOB / MATCH / NOT IN) are never
|
|
249
|
+
* pushed into FilterInfo by this rule, so a module claiming one is taken at its word.
|
|
250
|
+
* Sound today: the only such claim is memory's tautological IS NOT NULL on a NOT NULL
|
|
251
|
+
* column. If a module ever claims a non-tautological non-seek op, its predicate is lost
|
|
252
|
+
* — widen this set, or make grow-retrieve refuse the claim.
|
|
253
|
+
*/
|
|
254
|
+
const RECLAIMABLE_OPS = new Set(['=', 'IN', '>', '>=', '<', '<=', 'OR_RANGE']);
|
|
255
|
+
/**
|
|
256
|
+
* `handledFilters[i] === true` is a module's promise that filter `i` will be enforced
|
|
257
|
+
* somewhere else — and the only "somewhere else" available is `FilterInfo.constraints`
|
|
258
|
+
* (the seek bounds this rule builds). This rule consumes at most one constraint per
|
|
259
|
+
* column per role: the first `=`/`IN`, the first lower bound, the first upper bound.
|
|
260
|
+
* A module that claims a redundant same-column same-role filter (`v > 10 and v > 30`)
|
|
261
|
+
* therefore hands the planner a predicate that is seeked nowhere and — because
|
|
262
|
+
* `rule-grow-retrieve` residualizes only *unhandled* constraints — filtered nowhere.
|
|
263
|
+
*
|
|
264
|
+
* Reattach those as a residual `Filter` so an over-claiming module costs a redundant
|
|
265
|
+
* predicate evaluation, never a wrong answer. Skipped for an `EmptyResultNode` leaf
|
|
266
|
+
* (filtering an empty relation is dead weight) and restricted to {@link RECLAIMABLE_OPS}.
|
|
267
|
+
*/
|
|
268
|
+
function reattachUnconsumedConstraints(tableRef, accessPlan, constraints, consumed, leaf) {
|
|
269
|
+
if (leaf instanceof EmptyResultNode)
|
|
270
|
+
return leaf;
|
|
271
|
+
const lost = constraints.filter((c, i) => accessPlan.handledFilters[i] === true
|
|
272
|
+
&& !consumed.has(c)
|
|
273
|
+
&& RECLAIMABLE_OPS.has(c.op));
|
|
274
|
+
if (lost.length === 0)
|
|
275
|
+
return leaf;
|
|
276
|
+
const predicate = combineResidualExpressions(lost.map(c => c.sourceExpression));
|
|
277
|
+
if (!predicate)
|
|
278
|
+
return leaf;
|
|
279
|
+
log('Reattaching %d handled-but-unconsumed constraint(s) as a residual filter', lost.length);
|
|
280
|
+
return new FilterNode(tableRef.scope, leaf, predicate);
|
|
281
|
+
}
|
|
176
282
|
/**
|
|
177
283
|
* Select the appropriate physical node based on access plan
|
|
178
284
|
*/
|
|
@@ -182,51 +288,34 @@ function selectPhysicalNode(tableRef, accessPlan, constraints) {
|
|
|
182
288
|
log('Using empty result (impossible predicate detected)');
|
|
183
289
|
return createEmptyResultNode(tableRef);
|
|
184
290
|
}
|
|
185
|
-
//
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
idxStr: 'fullscan',
|
|
189
|
-
constraints: [],
|
|
190
|
-
args: [],
|
|
191
|
-
indexInfoOutput: {
|
|
192
|
-
nConstraint: 0,
|
|
193
|
-
aConstraint: [],
|
|
194
|
-
nOrderBy: 0,
|
|
195
|
-
aOrderBy: [],
|
|
196
|
-
aConstraintUsage: [],
|
|
197
|
-
idxNum: 0,
|
|
198
|
-
idxStr: 'fullscan',
|
|
199
|
-
orderByConsumed: false,
|
|
200
|
-
estimatedCost: accessPlan.cost,
|
|
201
|
-
estimatedRows: BigInt(accessPlan.rows || 1000),
|
|
202
|
-
idxFlags: 0,
|
|
203
|
-
colUsed: 0n,
|
|
204
|
-
}
|
|
205
|
-
};
|
|
291
|
+
// Default FilterInfo for the physical nodes. Each index arm below spreads this and
|
|
292
|
+
// overrides `idxStr` / `accessPath` for the index it chose.
|
|
293
|
+
const filterInfo = makeFullScanFilterInfo(accessPlan.cost, accessPlan.rows || 1000);
|
|
206
294
|
// Convert OrderingSpec[] to the format expected by physical nodes
|
|
207
295
|
const providesOrdering = accessPlan.providesOrdering?.map(spec => ({
|
|
208
296
|
column: spec.columnIndex,
|
|
209
297
|
desc: spec.desc
|
|
210
298
|
}));
|
|
299
|
+
const consumed = new Set();
|
|
211
300
|
// --- Index-aware path: use module-provided index identity ---
|
|
212
|
-
if (accessPlan.indexName && accessPlan.seekColumnIndexes && accessPlan.seekColumnIndexes.length > 0) {
|
|
213
|
-
return selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInfo, providesOrdering);
|
|
214
|
-
}
|
|
215
301
|
// --- Legacy fallback: infer access method from constraints and PK definition ---
|
|
216
|
-
|
|
302
|
+
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);
|
|
305
|
+
return reattachUnconsumedConstraints(tableRef, accessPlan, constraints, consumed, leaf);
|
|
217
306
|
}
|
|
218
307
|
/**
|
|
219
308
|
* Index-aware physical node selection using module-provided indexName and seekColumnIndexes.
|
|
220
309
|
* Works for both primary key and secondary indexes.
|
|
221
310
|
*/
|
|
222
|
-
function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInfo, providesOrdering) {
|
|
311
|
+
function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInfo, providesOrdering, consumed) {
|
|
223
312
|
const advertisement = extractAdvertisement(accessPlan);
|
|
224
313
|
// Whether this module's runtime honours the index collation for range bounds —
|
|
225
314
|
// gates the collation-matched non-BINARY range/prefix seek (see classifyConstraintCover).
|
|
226
315
|
const honorsCollatedRangeBounds = accessPlan.honorsCollatedRangeBounds === true;
|
|
227
316
|
const seekCols = accessPlan.seekColumnIndexes;
|
|
228
317
|
// Map accessPlan.indexName to physical node indexName ('_primary_' → 'primary')
|
|
229
|
-
const physicalIndexName = accessPlan.indexName ===
|
|
318
|
+
const physicalIndexName = accessPlan.indexName === PRIMARY_INDEX_NAME ? PRIMARY_PHYSICAL_INDEX_NAME : accessPlan.indexName;
|
|
230
319
|
// idxStr uses the raw name (scan-plan builder maps '_primary_' → 'primary')
|
|
231
320
|
const idxStrName = accessPlan.indexName;
|
|
232
321
|
// Build a map of constraints by column index for quick lookup
|
|
@@ -242,6 +331,14 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
242
331
|
if (accessPlan.handledFilters[i] === true)
|
|
243
332
|
handledByCol.add(c.columnIndex);
|
|
244
333
|
});
|
|
334
|
+
// Per-column, per-role pickers. Each returns the FIRST constraint in `constraints`
|
|
335
|
+
// order filling that role — the positional contract module authors must claim
|
|
336
|
+
// against (see docs/module-authoring.md). Redundant same-role duplicates are never
|
|
337
|
+
// picked and are recovered by `reattachUnconsumedConstraints`.
|
|
338
|
+
const isHandled = (c) => handledByCol.has(c.columnIndex);
|
|
339
|
+
const findPrefixEq = (colIdx) => (constraintsByCol.get(colIdx) ?? []).find(c => (c.op === '=' || (c.op === 'IN' && Array.isArray(c.value) && c.value.length === 1)) && isHandled(c));
|
|
340
|
+
const findLower = (colIdx) => (constraintsByCol.get(colIdx) ?? []).find(c => (c.op === '>' || c.op === '>=') && isHandled(c));
|
|
341
|
+
const findUpper = (colIdx) => (constraintsByCol.get(colIdx) ?? []).find(c => (c.op === '<' || c.op === '<=') && isHandled(c));
|
|
245
342
|
// Check if all seek columns have equality constraints (=, single-value IN, or multi-value IN)
|
|
246
343
|
const eqBySeekCol = new Map();
|
|
247
344
|
let allEquality = true;
|
|
@@ -258,6 +355,11 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
258
355
|
}
|
|
259
356
|
}
|
|
260
357
|
if (allEquality && eqBySeekCol.size === seekCols.length) {
|
|
358
|
+
// Every arm below returns, and each consumes exactly the per-seek-column
|
|
359
|
+
// equality constraints — as seek keys, or (on a collation decline) as the
|
|
360
|
+
// residual re-applied above the scan.
|
|
361
|
+
for (const c of eqBySeekCol.values())
|
|
362
|
+
consumed.add(c);
|
|
261
363
|
// Collation-cover analysis: a seek over an index whose per-column collation
|
|
262
364
|
// differs from the predicate's effective comparison collation is NOT a
|
|
263
365
|
// complete substitute for the predicate. Decline (scan + residual) on an
|
|
@@ -302,11 +404,7 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
302
404
|
constraint: { iColumn: colIdx, op: IndexConstraintOp.EQ, usable: true },
|
|
303
405
|
argvIndex: i + 1,
|
|
304
406
|
}));
|
|
305
|
-
const fi =
|
|
306
|
-
...filterInfo,
|
|
307
|
-
constraints: inConstraints,
|
|
308
|
-
idxStr: `idx=${idxStrName}(0);plan=5;inCount=${seekKeys.length}`,
|
|
309
|
-
};
|
|
407
|
+
const fi = makeIndexFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, idxStrName, 'multiSeek', inConstraints, new Map([['inCount', String(seekKeys.length)]]));
|
|
310
408
|
log('Using index multi-seek on %s (IN with %d values)', physicalIndexName, seekKeys.length);
|
|
311
409
|
return finishSeek(new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, false, providesOrdering, accessPlan.cost, advertisement));
|
|
312
410
|
}
|
|
@@ -357,11 +455,7 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
357
455
|
constraint: { iColumn: seekCols[i % seekWidth], op: IndexConstraintOp.EQ, usable: true },
|
|
358
456
|
argvIndex: i + 1,
|
|
359
457
|
}));
|
|
360
|
-
const fi =
|
|
361
|
-
...filterInfo,
|
|
362
|
-
constraints: seekConstraints,
|
|
363
|
-
idxStr: `idx=${idxStrName}(0);plan=5;inCount=${effectiveTuples.length};seekWidth=${seekWidth}`,
|
|
364
|
-
};
|
|
458
|
+
const fi = makeIndexFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, idxStrName, 'multiSeek', seekConstraints, new Map([['inCount', String(effectiveTuples.length)], ['seekWidth', String(seekWidth)]]));
|
|
365
459
|
log('Using composite index multi-seek on %s (cross-product of %d distinct non-null seeks, width %d)', physicalIndexName, effectiveTuples.length, seekWidth);
|
|
366
460
|
return finishSeek(new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, false, providesOrdering, accessPlan.cost, advertisement));
|
|
367
461
|
}
|
|
@@ -381,11 +475,7 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
381
475
|
constraint: { iColumn: seekCols[i % seekWidth], op: IndexConstraintOp.EQ, usable: true },
|
|
382
476
|
argvIndex: i + 1,
|
|
383
477
|
}));
|
|
384
|
-
const fi =
|
|
385
|
-
...filterInfo,
|
|
386
|
-
constraints: seekConstraints,
|
|
387
|
-
idxStr: `idx=${idxStrName}(0);plan=5;inCount=${crossProduct.length};seekWidth=${seekWidth}`,
|
|
388
|
-
};
|
|
478
|
+
const fi = makeIndexFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, idxStrName, 'multiSeek', seekConstraints, new Map([['inCount', String(crossProduct.length)], ['seekWidth', String(seekWidth)]]));
|
|
389
479
|
log('Using composite index multi-seek on %s (cross-product of %d seeks, width %d)', physicalIndexName, crossProduct.length, seekWidth);
|
|
390
480
|
return finishSeek(new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, false, providesOrdering, accessPlan.cost, advertisement));
|
|
391
481
|
}
|
|
@@ -403,11 +493,7 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
403
493
|
constraint: { iColumn: colIdx, op: IndexConstraintOp.EQ, usable: true },
|
|
404
494
|
argvIndex: i + 1,
|
|
405
495
|
}));
|
|
406
|
-
const fi =
|
|
407
|
-
...filterInfo,
|
|
408
|
-
constraints: eqConstraints,
|
|
409
|
-
idxStr: `idx=${idxStrName}(0);plan=2`,
|
|
410
|
-
};
|
|
496
|
+
const fi = makeIndexFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, idxStrName, 'eqSeek', eqConstraints);
|
|
411
497
|
log('Using index seek on %s (equality)', physicalIndexName);
|
|
412
498
|
return finishSeek(new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, false, providesOrdering, accessPlan.cost, advertisement));
|
|
413
499
|
}
|
|
@@ -416,31 +502,34 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
416
502
|
const prefixEqCols = [];
|
|
417
503
|
let trailingRangeCol;
|
|
418
504
|
for (const colIdx of seekCols) {
|
|
419
|
-
|
|
420
|
-
const eqConstraint = colConstraints.find(c => (c.op === '=' || (c.op === 'IN' && Array.isArray(c.value) && c.value.length === 1)) &&
|
|
421
|
-
handledByCol.has(c.columnIndex));
|
|
422
|
-
if (eqConstraint) {
|
|
505
|
+
if (findPrefixEq(colIdx)) {
|
|
423
506
|
prefixEqCols.push(colIdx);
|
|
424
507
|
}
|
|
425
508
|
else {
|
|
426
|
-
|
|
427
|
-
if (hasRange)
|
|
509
|
+
if (findLower(colIdx) || findUpper(colIdx))
|
|
428
510
|
trailingRangeCol = colIdx;
|
|
429
511
|
break;
|
|
430
512
|
}
|
|
431
513
|
}
|
|
432
514
|
if (prefixEqCols.length > 0 && trailingRangeCol !== undefined) {
|
|
515
|
+
const prefixConstraints = prefixEqCols.map(colIdx => ({ colIdx, constraint: findPrefixEq(colIdx) }));
|
|
516
|
+
const lower = findLower(trailingRangeCol);
|
|
517
|
+
const upper = findUpper(trailingRangeCol);
|
|
518
|
+
// Every arm below returns, consuming the prefix equalities plus the first
|
|
519
|
+
// lower/upper trailing bound — as seek keys, or (on a collation decline) as
|
|
520
|
+
// the residual re-applied above the scan.
|
|
521
|
+
for (const { constraint } of prefixConstraints)
|
|
522
|
+
consumed.add(constraint);
|
|
523
|
+
if (lower)
|
|
524
|
+
consumed.add(lower);
|
|
525
|
+
if (upper)
|
|
526
|
+
consumed.add(upper);
|
|
433
527
|
// A literal NULL in any prefix-equality column makes every row-value
|
|
434
528
|
// comparison UNKNOWN ⇒ no match. Emit an empty result rather than relying
|
|
435
529
|
// on the runtime prefix walk breaking on the first row. Part A does not
|
|
436
530
|
// cover this path (it walks via `equalityPrefix`, not `equalityKey`), so
|
|
437
531
|
// the plan-time check is the robustness guarantee here.
|
|
438
|
-
|
|
439
|
-
const c = (constraintsByCol.get(colIdx) ?? []).find(c => (c.op === '=' || (c.op === 'IN' && Array.isArray(c.value) && c.value.length === 1)) &&
|
|
440
|
-
handledByCol.has(c.columnIndex));
|
|
441
|
-
return c !== undefined && isLiteralNullEquality(c);
|
|
442
|
-
});
|
|
443
|
-
if (prefixHasLiteralNull) {
|
|
532
|
+
if (prefixConstraints.some(({ constraint }) => isLiteralNullEquality(constraint))) {
|
|
444
533
|
log('Prefix-range seek on %s has a literal NULL prefix key — using empty result', physicalIndexName);
|
|
445
534
|
return createEmptyResultNode(tableRef);
|
|
446
535
|
}
|
|
@@ -448,20 +537,12 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
448
537
|
// the walked index window (it is no longer a contiguous superset), so it
|
|
449
538
|
// cannot be salvaged with a residual — decline to a scan + residual.
|
|
450
539
|
{
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
const trailing = constraintsByCol.get(trailingRangeCol) ?? [];
|
|
458
|
-
const lo = trailing.find(c => (c.op === '>' || c.op === '>=') && handledByCol.has(c.columnIndex));
|
|
459
|
-
const hi = trailing.find(c => (c.op === '<' || c.op === '<=') && handledByCol.has(c.columnIndex));
|
|
460
|
-
if (lo)
|
|
461
|
-
consumed.push({ colIdx: trailingRangeCol, constraint: lo });
|
|
462
|
-
if (hi)
|
|
463
|
-
consumed.push({ colIdx: trailingRangeCol, constraint: hi });
|
|
464
|
-
const cover = classifyCollationCover(consumed, false, indexColumnCollationLookup(tableRef.tableSchema, accessPlan), honorsCollatedRangeBounds);
|
|
540
|
+
const coverConstraints = [...prefixConstraints];
|
|
541
|
+
if (lower)
|
|
542
|
+
coverConstraints.push({ colIdx: trailingRangeCol, constraint: lower });
|
|
543
|
+
if (upper)
|
|
544
|
+
coverConstraints.push({ colIdx: trailingRangeCol, constraint: upper });
|
|
545
|
+
const cover = classifyCollationCover(coverConstraints, false, indexColumnCollationLookup(tableRef.tableSchema, accessPlan), honorsCollatedRangeBounds);
|
|
465
546
|
if (!cover.useIndex) {
|
|
466
547
|
log('Declining prefix-range seek on %s (collation mismatch) — sequential scan + residual', physicalIndexName);
|
|
467
548
|
const scan = createSeqScan(tableRef);
|
|
@@ -472,17 +553,12 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
472
553
|
const allConstraints = [];
|
|
473
554
|
let argv = 1;
|
|
474
555
|
// Add prefix equality values
|
|
475
|
-
for (const colIdx of
|
|
476
|
-
|
|
477
|
-
handledByCol.has(c.columnIndex));
|
|
478
|
-
seekKeys.push(equalitySeekKey(tableRef.scope, c));
|
|
556
|
+
for (const { colIdx, constraint } of prefixConstraints) {
|
|
557
|
+
seekKeys.push(equalitySeekKey(tableRef.scope, constraint));
|
|
479
558
|
allConstraints.push({ constraint: { iColumn: colIdx, op: IndexConstraintOp.EQ, usable: true }, argvIndex: argv });
|
|
480
559
|
argv++;
|
|
481
560
|
}
|
|
482
561
|
// Add trailing range values
|
|
483
|
-
const trailingConstraints = constraintsByCol.get(trailingRangeCol) ?? [];
|
|
484
|
-
const lower = trailingConstraints.find(c => (c.op === '>' || c.op === '>=') && handledByCol.has(c.columnIndex));
|
|
485
|
-
const upper = trailingConstraints.find(c => (c.op === '<' || c.op === '<=') && handledByCol.has(c.columnIndex));
|
|
486
562
|
if (lower) {
|
|
487
563
|
allConstraints.push({ constraint: { iColumn: trailingRangeCol, op: opToIndexOp(lower.op), usable: true }, argvIndex: argv });
|
|
488
564
|
seekKeys.push(lower.valueExpr && !Array.isArray(lower.valueExpr) ? lower.valueExpr : literalFromValue(tableRef.scope, lower.value));
|
|
@@ -493,35 +569,43 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
493
569
|
seekKeys.push(upper.valueExpr && !Array.isArray(upper.valueExpr) ? upper.valueExpr : literalFromValue(tableRef.scope, upper.value));
|
|
494
570
|
argv++;
|
|
495
571
|
}
|
|
496
|
-
const fi =
|
|
497
|
-
...filterInfo,
|
|
498
|
-
constraints: allConstraints,
|
|
499
|
-
idxStr: `idx=${idxStrName}(0);plan=7;prefixLen=${prefixEqCols.length}`,
|
|
500
|
-
};
|
|
572
|
+
const fi = makeIndexFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, idxStrName, 'prefixRangeSeek', allConstraints, new Map([['prefixLen', String(prefixEqCols.length)]]));
|
|
501
573
|
log('Using index prefix-range seek on %s (prefix=%d cols)', physicalIndexName, prefixEqCols.length);
|
|
502
574
|
return new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, true, providesOrdering, accessPlan.cost, advertisement);
|
|
503
575
|
}
|
|
504
576
|
}
|
|
505
|
-
// Check for range constraints on the seek
|
|
506
|
-
//
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
577
|
+
// Check for range constraints on the LEADING seek column only. A standalone range
|
|
578
|
+
// seek emits its bounds positionally into `seekKeys` and the runtime applies them to
|
|
579
|
+
// the index's leading column, so a range on a *later* seek column is usable only via
|
|
580
|
+
// the prefix-range path above — which requires every preceding seek column to be
|
|
581
|
+
// pinned by a single-valued equality. Picking a later column here would bound the
|
|
582
|
+
// leading column with the wrong value and silently drop rows (`a in (1,2) and b > 15`
|
|
583
|
+
// over an index on `(a, b)`: the multi-value IN is not a prefix key, so `b`'s bound
|
|
584
|
+
// would be seeked against `a`). When the leading column carries no bound we decline;
|
|
585
|
+
// `reattachUnconsumedConstraints` re-applies the claimed range as a residual.
|
|
586
|
+
const leadingSeekCol = seekCols[0];
|
|
587
|
+
const rangeCol = (leadingSeekCol !== undefined && (findLower(leadingSeekCol) || findUpper(leadingSeekCol)))
|
|
588
|
+
? leadingSeekCol
|
|
589
|
+
: undefined;
|
|
511
590
|
if (rangeCol !== undefined) {
|
|
512
|
-
const
|
|
513
|
-
const
|
|
514
|
-
|
|
591
|
+
const lower = findLower(rangeCol);
|
|
592
|
+
const upper = findUpper(rangeCol);
|
|
593
|
+
// Both arms below return, consuming the first lower/upper bound — as seek
|
|
594
|
+
// bounds, or (on a collation decline) as the residual above the scan.
|
|
595
|
+
if (lower)
|
|
596
|
+
consumed.add(lower);
|
|
597
|
+
if (upper)
|
|
598
|
+
consumed.add(upper);
|
|
515
599
|
// Collation-cover: a range seek under a collation that differs from the
|
|
516
600
|
// predicate's reorders the index window, so it is never a superset — decline
|
|
517
601
|
// to a scan + residual on any mismatch.
|
|
518
602
|
{
|
|
519
|
-
const
|
|
603
|
+
const coverConstraints = [];
|
|
520
604
|
if (lower)
|
|
521
|
-
|
|
605
|
+
coverConstraints.push({ colIdx: rangeCol, constraint: lower });
|
|
522
606
|
if (upper)
|
|
523
|
-
|
|
524
|
-
const cover = classifyCollationCover(
|
|
607
|
+
coverConstraints.push({ colIdx: rangeCol, constraint: upper });
|
|
608
|
+
const cover = classifyCollationCover(coverConstraints, false, indexColumnCollationLookup(tableRef.tableSchema, accessPlan), honorsCollatedRangeBounds);
|
|
525
609
|
if (!cover.useIndex) {
|
|
526
610
|
log('Declining range seek on %s (collation mismatch) — sequential scan + residual', physicalIndexName);
|
|
527
611
|
const scan = createSeqScan(tableRef);
|
|
@@ -541,11 +625,7 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
541
625
|
seekKeys.push(upper.valueExpr && !Array.isArray(upper.valueExpr) ? upper.valueExpr : literalFromValue(tableRef.scope, upper.value));
|
|
542
626
|
argv++;
|
|
543
627
|
}
|
|
544
|
-
const fi =
|
|
545
|
-
...filterInfo,
|
|
546
|
-
constraints: rangeConstraints,
|
|
547
|
-
idxStr: `idx=${idxStrName}(0);plan=3`,
|
|
548
|
-
};
|
|
628
|
+
const fi = makeIndexFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, idxStrName, 'rangeSeek', rangeConstraints);
|
|
549
629
|
log('Using index seek (range) on %s', physicalIndexName);
|
|
550
630
|
return new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, true, providesOrdering, accessPlan.cost, advertisement);
|
|
551
631
|
}
|
|
@@ -554,6 +634,9 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
554
634
|
seekCols.includes(c.columnIndex) && handledByCol.has(c.columnIndex));
|
|
555
635
|
if (orRangeConstraint && orRangeConstraint.ranges) {
|
|
556
636
|
const ranges = orRangeConstraint.ranges;
|
|
637
|
+
// Both arms below return, consuming this OR_RANGE — as the multi-range seek's
|
|
638
|
+
// bounds, or (on a collation decline) as the residual above the scan.
|
|
639
|
+
consumed.add(orRangeConstraint);
|
|
557
640
|
// Collation-cover: an OR_RANGE seek walks multiple index windows whose order
|
|
558
641
|
// follows the index collation; any mismatch makes them non-supersets, so
|
|
559
642
|
// decline to a scan + residual.
|
|
@@ -589,28 +672,16 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
589
672
|
constraint: { iColumn: orRangeConstraint.columnIndex, op: IndexConstraintOp.GE, usable: true },
|
|
590
673
|
argvIndex: i + 1,
|
|
591
674
|
}));
|
|
592
|
-
const fi =
|
|
593
|
-
...filterInfo,
|
|
594
|
-
constraints: orRangeConstraints,
|
|
595
|
-
idxStr: `idx=${idxStrName}(0);plan=6;rangeCount=${ranges.length};rangeOps=${rangeOps.join(',')}`,
|
|
596
|
-
};
|
|
675
|
+
const fi = makeIndexFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, idxStrName, 'multiRangeSeek', orRangeConstraints, new Map([['rangeCount', String(ranges.length)], ['rangeOps', rangeOps.join(',')]]));
|
|
597
676
|
log('Using index multi-range seek on %s (%d ranges)', physicalIndexName, ranges.length);
|
|
598
677
|
return new IndexSeekNode(tableRef.scope, tableRef, fi, physicalIndexName, seekKeys, true, providesOrdering, accessPlan.cost, advertisement);
|
|
599
678
|
}
|
|
600
679
|
// Ordering-only index scan
|
|
601
680
|
if (providesOrdering) {
|
|
602
681
|
const orderingIndexName = accessPlan.orderingIndexName ?? physicalIndexName;
|
|
603
|
-
const orderingIdxStr = orderingIndexName ===
|
|
682
|
+
const orderingIdxStr = orderingIndexName === PRIMARY_PHYSICAL_INDEX_NAME ? PRIMARY_INDEX_NAME : orderingIndexName;
|
|
604
683
|
log('Using index scan (ordering provided by %s)', orderingIndexName);
|
|
605
|
-
const orderingFilterInfo =
|
|
606
|
-
...filterInfo,
|
|
607
|
-
idxStr: `idx=${orderingIdxStr}(0);plan=0`,
|
|
608
|
-
indexInfoOutput: {
|
|
609
|
-
...filterInfo.indexInfoOutput,
|
|
610
|
-
idxStr: `idx=${orderingIdxStr}(0);plan=0`,
|
|
611
|
-
orderByConsumed: true,
|
|
612
|
-
}
|
|
613
|
-
};
|
|
684
|
+
const orderingFilterInfo = makeOrderedScanFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, orderingIdxStr);
|
|
614
685
|
return new IndexScanNode(tableRef.scope, tableRef, orderingFilterInfo, orderingIndexName, providesOrdering, accessPlan.cost, advertisement);
|
|
615
686
|
}
|
|
616
687
|
// Fall back to sequential scan
|
|
@@ -621,7 +692,7 @@ function selectPhysicalNodeFromPlan(tableRef, accessPlan, constraints, filterInf
|
|
|
621
692
|
* Legacy physical node selection for backward compatibility when module
|
|
622
693
|
* doesn't provide indexName/seekColumnIndexes (PK-based heuristics).
|
|
623
694
|
*/
|
|
624
|
-
function selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo, providesOrdering) {
|
|
695
|
+
function selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo, providesOrdering, consumed) {
|
|
625
696
|
const advertisement = extractAdvertisement(accessPlan);
|
|
626
697
|
const honorsCollatedRangeBounds = accessPlan.honorsCollatedRangeBounds === true;
|
|
627
698
|
// Analyze the access plan to determine node type
|
|
@@ -630,17 +701,27 @@ function selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo,
|
|
|
630
701
|
if (accessPlan.handledFilters[i] === true)
|
|
631
702
|
handledByCol.add(c.columnIndex);
|
|
632
703
|
});
|
|
633
|
-
|
|
634
|
-
|
|
704
|
+
// Every '=' constraint, handled or not: an unhandled one still makes a sound seek key
|
|
705
|
+
// (grow-retrieve keeps it in the residual), so it may complete a PK cover.
|
|
706
|
+
const eqConstraints = constraints.filter(c => c.op === '=');
|
|
707
|
+
const hasEqualityConstraints = eqConstraints.length > 0;
|
|
635
708
|
const hasRangeConstraints = constraints.some(c => ['>', '>=', '<', '<='].includes(c.op) && handledByCol.has(c.columnIndex));
|
|
636
709
|
const maybeRows = accessPlan.rows || 0;
|
|
637
710
|
const pkCols = tableRef.tableSchema.primaryKeyDefinition ?? [];
|
|
711
|
+
// FIRST '=' per column, matching the positional contract the index-aware path and
|
|
712
|
+
// `docs/module-authoring.md` state. Keeping the last would seek on a constraint a
|
|
713
|
+
// module claiming positionally never expected to be consumed.
|
|
638
714
|
const eqByCol = new Map();
|
|
639
|
-
for (const c of
|
|
640
|
-
eqByCol.
|
|
715
|
+
for (const c of eqConstraints)
|
|
716
|
+
if (!eqByCol.has(c.columnIndex))
|
|
717
|
+
eqByCol.set(c.columnIndex, c);
|
|
641
718
|
const coversPk = pkCols.length > 0 && pkCols.every(pk => eqByCol.has(pk.index));
|
|
642
719
|
const treatAsHandledPk = coversPk && pkCols.every(pk => handledByCol.has(pk.index) || eqByCol.has(pk.index));
|
|
643
720
|
if ((hasEqualityConstraints && coversPk || treatAsHandledPk) && maybeRows <= 10) {
|
|
721
|
+
// Every arm below returns, consuming the per-PK-column equality — as a seek
|
|
722
|
+
// key, or (on a collation decline) as the residual re-applied above the scan.
|
|
723
|
+
for (const pk of pkCols)
|
|
724
|
+
consumed.add(eqByCol.get(pk.index));
|
|
644
725
|
// A literal NULL in any PK column makes the point-seek UNKNOWN ⇒ no row can
|
|
645
726
|
// match. Emit an empty result instead of a doomed seek (mirrors the
|
|
646
727
|
// index-aware path; the scan-layer runtime guard covers the dynamic case).
|
|
@@ -665,31 +746,38 @@ function selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo,
|
|
|
665
746
|
constraint: { iColumn: pk.index, op: IndexConstraintOp.EQ, usable: true },
|
|
666
747
|
argvIndex: i + 1,
|
|
667
748
|
}));
|
|
668
|
-
const fi =
|
|
669
|
-
...filterInfo,
|
|
670
|
-
constraints: eqConstraints,
|
|
671
|
-
idxStr: 'idx=_primary_(0);plan=2',
|
|
672
|
-
};
|
|
749
|
+
const fi = makeIndexFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, PRIMARY_INDEX_NAME, 'eqSeek', eqConstraints);
|
|
673
750
|
log('Using index seek on primary key (legacy)');
|
|
674
751
|
const pkSeek = new IndexSeekNode(tableRef.scope, tableRef, fi, 'primary', seekKeys, false, providesOrdering, accessPlan.cost, advertisement);
|
|
675
752
|
return cover.residual ? new FilterNode(tableRef.scope, pkSeek, cover.residual) : pkSeek;
|
|
676
753
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
754
|
+
const rangeCols = constraints
|
|
755
|
+
.filter(c => ['>', '>=', '<', '<='].includes(c.op) && handledByCol.has(c.columnIndex))
|
|
756
|
+
.sort((a, b) => a.columnIndex - b.columnIndex);
|
|
757
|
+
const primaryFirstCol = (tableRef.tableSchema.primaryKeyDefinition?.[0]?.index) ?? (rangeCols[0]?.columnIndex ?? 0);
|
|
758
|
+
const lower = rangeCols.find(c => c.columnIndex === primaryFirstCol && (c.op === '>' || c.op === '>='));
|
|
759
|
+
const upper = rangeCols.find(c => c.columnIndex === primaryFirstCol && (c.op === '<' || c.op === '<='));
|
|
760
|
+
// A PK range seek needs at least one bound on the LEADING PK column: seek keys are
|
|
761
|
+
// positional and the runtime walks the primary key. When every handled range sits on
|
|
762
|
+
// a later PK column there is nothing to seek with, and a zero-key `IndexSeekNode`
|
|
763
|
+
// would be a full index walk dressed up as a seek. Decline instead — the claimed
|
|
764
|
+
// range comes back as a residual via `reattachUnconsumedConstraints`.
|
|
765
|
+
if (hasRangeConstraints && (lower || upper)) {
|
|
766
|
+
// Both arms below return, consuming the first lower/upper bound on the leading
|
|
767
|
+
// PK column — as seek bounds, or (on a collation decline) as the scan residual.
|
|
768
|
+
if (lower)
|
|
769
|
+
consumed.add(lower);
|
|
770
|
+
if (upper)
|
|
771
|
+
consumed.add(upper);
|
|
684
772
|
// Collation-cover: a PK range seek under a mismatched collation reorders the
|
|
685
773
|
// walked window, so decline to a scan + residual on any mismatch.
|
|
686
774
|
{
|
|
687
|
-
const
|
|
775
|
+
const coverConstraints = [];
|
|
688
776
|
if (lower)
|
|
689
|
-
|
|
777
|
+
coverConstraints.push({ colIdx: primaryFirstCol, constraint: lower });
|
|
690
778
|
if (upper)
|
|
691
|
-
|
|
692
|
-
const cover = classifyCollationCover(
|
|
779
|
+
coverConstraints.push({ colIdx: primaryFirstCol, constraint: upper });
|
|
780
|
+
const cover = classifyCollationCover(coverConstraints, false, primaryKeyCollationLookup(tableRef.tableSchema), honorsCollatedRangeBounds);
|
|
693
781
|
if (!cover.useIndex) {
|
|
694
782
|
log('Declining PK range seek (collation mismatch) — sequential scan + residual (legacy)');
|
|
695
783
|
const scan = createSeqScan(tableRef);
|
|
@@ -709,36 +797,20 @@ function selectPhysicalNodeLegacy(tableRef, accessPlan, constraints, filterInfo,
|
|
|
709
797
|
seekKeys.push(upper.valueExpr && !Array.isArray(upper.valueExpr) ? upper.valueExpr : literalFromValue(tableRef.scope, upper.value));
|
|
710
798
|
argv++;
|
|
711
799
|
}
|
|
712
|
-
const fi =
|
|
713
|
-
...filterInfo,
|
|
714
|
-
constraints: rangeConstraints,
|
|
715
|
-
idxStr: 'idx=_primary_(0);plan=3',
|
|
716
|
-
};
|
|
800
|
+
const fi = makeIndexFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, PRIMARY_INDEX_NAME, 'rangeSeek', rangeConstraints);
|
|
717
801
|
log('Using index seek (range) on primary key (legacy)');
|
|
718
802
|
return new IndexSeekNode(tableRef.scope, tableRef, fi, 'primary', seekKeys, true, providesOrdering, accessPlan.cost, advertisement);
|
|
719
803
|
}
|
|
720
804
|
if (providesOrdering) {
|
|
721
|
-
const indexName = accessPlan.orderingIndexName ??
|
|
805
|
+
const indexName = accessPlan.orderingIndexName ?? PRIMARY_PHYSICAL_INDEX_NAME;
|
|
722
806
|
log('Using index scan (ordering provided by %s)', indexName);
|
|
723
|
-
const indexIdxStr = indexName ===
|
|
724
|
-
const orderingFilterInfo =
|
|
725
|
-
...filterInfo,
|
|
726
|
-
idxStr: `idx=${indexIdxStr}(0);plan=0`,
|
|
727
|
-
indexInfoOutput: {
|
|
728
|
-
...filterInfo.indexInfoOutput,
|
|
729
|
-
idxStr: `idx=${indexIdxStr}(0);plan=0`,
|
|
730
|
-
orderByConsumed: true,
|
|
731
|
-
}
|
|
732
|
-
};
|
|
807
|
+
const indexIdxStr = indexName === PRIMARY_PHYSICAL_INDEX_NAME ? PRIMARY_INDEX_NAME : indexName;
|
|
808
|
+
const orderingFilterInfo = makeOrderedScanFilterInfo(filterInfo, tableRef.tableSchema, accessPlan, indexIdxStr);
|
|
733
809
|
return new IndexScanNode(tableRef.scope, tableRef, orderingFilterInfo, indexName, providesOrdering, accessPlan.cost, advertisement);
|
|
734
810
|
}
|
|
735
811
|
log('Using sequential scan (no beneficial index access)');
|
|
736
812
|
return createSeqScan(tableRef, filterInfo, accessPlan.cost);
|
|
737
813
|
}
|
|
738
|
-
// Narrow module context originating from grow-retrieve index-style fallback
|
|
739
|
-
function isIndexStyleContext(ctx) {
|
|
740
|
-
return !!ctx && typeof ctx === 'object' && ctx.kind === 'index-style';
|
|
741
|
-
}
|
|
742
814
|
/**
|
|
743
815
|
* Create a sequential scan node
|
|
744
816
|
*/
|
|
@@ -746,26 +818,7 @@ function createSeqScan(tableRef, filterInfo, cost) {
|
|
|
746
818
|
const tableRows = tableRef.estimatedRows || 1000;
|
|
747
819
|
const scanCost = cost ?? seqScanCost(tableRows);
|
|
748
820
|
// Create default FilterInfo if not provided
|
|
749
|
-
const effectiveFilterInfo = filterInfo
|
|
750
|
-
idxNum: 0,
|
|
751
|
-
idxStr: 'fullscan',
|
|
752
|
-
constraints: [],
|
|
753
|
-
args: [],
|
|
754
|
-
indexInfoOutput: {
|
|
755
|
-
nConstraint: 0,
|
|
756
|
-
aConstraint: [],
|
|
757
|
-
nOrderBy: 0,
|
|
758
|
-
aOrderBy: [],
|
|
759
|
-
aConstraintUsage: [],
|
|
760
|
-
idxNum: 0,
|
|
761
|
-
idxStr: 'fullscan',
|
|
762
|
-
orderByConsumed: false,
|
|
763
|
-
estimatedCost: scanCost,
|
|
764
|
-
estimatedRows: BigInt(tableRows),
|
|
765
|
-
idxFlags: 0,
|
|
766
|
-
colUsed: 0n,
|
|
767
|
-
}
|
|
768
|
-
};
|
|
821
|
+
const effectiveFilterInfo = filterInfo ?? makeFullScanFilterInfo(scanCost, tableRows);
|
|
769
822
|
const seqScan = new SeqScanNode(tableRef.scope, tableRef, effectiveFilterInfo, scanCost);
|
|
770
823
|
return seqScan;
|
|
771
824
|
}
|
|
@@ -824,27 +877,7 @@ function equalitySeekKey(scope, c) {
|
|
|
824
877
|
* the literal-IN reduction below.
|
|
825
878
|
*/
|
|
826
879
|
function createEmptyResultNode(tableRef) {
|
|
827
|
-
|
|
828
|
-
idxNum: 0,
|
|
829
|
-
idxStr: 'empty',
|
|
830
|
-
constraints: [],
|
|
831
|
-
args: [],
|
|
832
|
-
indexInfoOutput: {
|
|
833
|
-
nConstraint: 0,
|
|
834
|
-
aConstraint: [],
|
|
835
|
-
nOrderBy: 0,
|
|
836
|
-
aOrderBy: [],
|
|
837
|
-
aConstraintUsage: [],
|
|
838
|
-
idxNum: 0,
|
|
839
|
-
idxStr: 'empty',
|
|
840
|
-
orderByConsumed: false,
|
|
841
|
-
estimatedCost: 0,
|
|
842
|
-
estimatedRows: 0n,
|
|
843
|
-
idxFlags: 0,
|
|
844
|
-
colUsed: 0n,
|
|
845
|
-
}
|
|
846
|
-
};
|
|
847
|
-
return new EmptyResultNode(tableRef.scope, tableRef, emptyFilterInfo, 0);
|
|
880
|
+
return new EmptyResultNode(tableRef.scope, tableRef, makeEmptyFilterInfo(), 0);
|
|
848
881
|
}
|
|
849
882
|
/**
|
|
850
883
|
* True when an equality constraint resolves to a *literal* SQL NULL — `col = null`
|