@quereus/quereus 0.2.1 → 0.4.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 +12 -1
- package/dist/src/common/errors.js.map +1 -1
- package/dist/src/common/json-types.d.ts +11 -0
- package/dist/src/common/json-types.d.ts.map +1 -0
- package/dist/src/common/json-types.js +3 -0
- package/dist/src/common/json-types.js.map +1 -0
- package/dist/src/common/types.d.ts +1 -0
- package/dist/src/common/types.d.ts.map +1 -1
- package/dist/src/core/database-options.d.ts +2 -2
- package/dist/src/core/database-options.d.ts.map +1 -1
- package/dist/src/core/database-options.js.map +1 -1
- package/dist/src/core/database.d.ts +61 -14
- package/dist/src/core/database.d.ts.map +1 -1
- package/dist/src/core/database.js +481 -54
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/core/statement.d.ts.map +1 -1
- package/dist/src/core/statement.js +3 -1
- package/dist/src/core/statement.js.map +1 -1
- package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
- package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
- package/dist/src/func/builtins/datetime.d.ts +2 -0
- package/dist/src/func/builtins/datetime.d.ts.map +1 -1
- package/dist/src/func/builtins/datetime.js +39 -0
- package/dist/src/func/builtins/datetime.js.map +1 -1
- package/dist/src/func/builtins/explain.d.ts +1 -0
- package/dist/src/func/builtins/explain.d.ts.map +1 -1
- package/dist/src/func/builtins/explain.js +159 -36
- package/dist/src/func/builtins/explain.js.map +1 -1
- package/dist/src/func/builtins/index.d.ts.map +1 -1
- package/dist/src/func/builtins/index.js +5 -2
- package/dist/src/func/builtins/index.js.map +1 -1
- package/dist/src/func/builtins/json-helpers.d.ts +8 -8
- package/dist/src/func/builtins/json-helpers.d.ts.map +1 -1
- package/dist/src/func/builtins/json-helpers.js +3 -3
- package/dist/src/func/builtins/json-helpers.js.map +1 -1
- package/dist/src/func/builtins/json-tvf.d.ts.map +1 -1
- package/dist/src/func/builtins/json-tvf.js +1 -1
- package/dist/src/func/builtins/json-tvf.js.map +1 -1
- package/dist/src/func/builtins/json.d.ts.map +1 -1
- package/dist/src/func/builtins/json.js +3 -2
- package/dist/src/func/builtins/json.js.map +1 -1
- package/dist/src/func/builtins/schema.d.ts.map +1 -1
- package/dist/src/func/builtins/schema.js +22 -1
- package/dist/src/func/builtins/schema.js.map +1 -1
- package/dist/src/func/context.d.ts.map +1 -1
- package/dist/src/func/context.js +5 -0
- package/dist/src/func/context.js.map +1 -1
- package/dist/src/func/registration.d.ts +2 -1
- package/dist/src/func/registration.d.ts.map +1 -1
- package/dist/src/func/registration.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- 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/parser/ast.d.ts +83 -4
- package/dist/src/parser/ast.d.ts.map +1 -1
- package/dist/src/parser/lexer.d.ts +11 -0
- package/dist/src/parser/lexer.d.ts.map +1 -1
- package/dist/src/parser/lexer.js +29 -21
- package/dist/src/parser/lexer.js.map +1 -1
- package/dist/src/parser/parser.d.ts +16 -0
- package/dist/src/parser/parser.d.ts.map +1 -1
- package/dist/src/parser/parser.js +542 -26
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/src/parser/visitor.d.ts.map +1 -1
- package/dist/src/parser/visitor.js +1 -0
- package/dist/src/parser/visitor.js.map +1 -1
- package/dist/src/planner/analysis/binding-collector.d.ts +5 -0
- package/dist/src/planner/analysis/binding-collector.d.ts.map +1 -0
- package/dist/src/planner/analysis/binding-collector.js +73 -0
- package/dist/src/planner/analysis/binding-collector.js.map +1 -0
- package/dist/src/planner/analysis/const-evaluator.js +1 -1
- package/dist/src/planner/analysis/const-evaluator.js.map +1 -1
- package/dist/src/planner/analysis/const-pass.d.ts.map +1 -1
- package/dist/src/planner/analysis/const-pass.js +1 -1
- package/dist/src/planner/analysis/const-pass.js.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.d.ts +67 -31
- package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.js +513 -84
- package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
- package/dist/src/planner/analysis/predicate-normalizer.d.ts +17 -0
- package/dist/src/planner/analysis/predicate-normalizer.d.ts.map +1 -0
- package/dist/src/planner/analysis/predicate-normalizer.js +222 -0
- package/dist/src/planner/analysis/predicate-normalizer.js.map +1 -0
- package/dist/src/planner/building/alter-table.d.ts.map +1 -1
- package/dist/src/planner/building/alter-table.js +5 -2
- package/dist/src/planner/building/alter-table.js.map +1 -1
- package/dist/src/planner/building/block.d.ts.map +1 -1
- package/dist/src/planner/building/block.js +16 -0
- package/dist/src/planner/building/block.js.map +1 -1
- package/dist/src/planner/building/constraint-builder.d.ts +1 -1
- package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
- package/dist/src/planner/building/constraint-builder.js +52 -3
- package/dist/src/planner/building/constraint-builder.js.map +1 -1
- package/dist/src/planner/building/create-assertion.d.ts +5 -0
- package/dist/src/planner/building/create-assertion.d.ts.map +1 -0
- package/dist/src/planner/building/create-assertion.js +5 -0
- package/dist/src/planner/building/create-assertion.js.map +1 -0
- package/dist/src/planner/building/declare-schema.d.ts +8 -0
- package/dist/src/planner/building/declare-schema.d.ts.map +1 -0
- package/dist/src/planner/building/declare-schema.js +14 -0
- package/dist/src/planner/building/declare-schema.js.map +1 -0
- package/dist/src/planner/building/delete.d.ts.map +1 -1
- package/dist/src/planner/building/delete.js +37 -5
- package/dist/src/planner/building/delete.js.map +1 -1
- package/dist/src/planner/building/drop-assertion.d.ts +5 -0
- package/dist/src/planner/building/drop-assertion.d.ts.map +1 -0
- package/dist/src/planner/building/drop-assertion.js +8 -0
- package/dist/src/planner/building/drop-assertion.js.map +1 -0
- package/dist/src/planner/building/expression.d.ts.map +1 -1
- package/dist/src/planner/building/expression.js +1 -0
- 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 +2 -1
- package/dist/src/planner/building/function-call.js.map +1 -1
- package/dist/src/planner/building/insert.d.ts.map +1 -1
- package/dist/src/planner/building/insert.js +67 -10
- package/dist/src/planner/building/insert.js.map +1 -1
- package/dist/src/planner/building/pragma.d.ts.map +1 -1
- package/dist/src/planner/building/pragma.js +1 -0
- package/dist/src/planner/building/pragma.js.map +1 -1
- package/dist/src/planner/building/schema-resolution.d.ts +2 -2
- package/dist/src/planner/building/schema-resolution.d.ts.map +1 -1
- package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
- package/dist/src/planner/building/select-aggregates.js +3 -2
- package/dist/src/planner/building/select-aggregates.js.map +1 -1
- package/dist/src/planner/building/select-compound.d.ts +2 -2
- package/dist/src/planner/building/select-compound.d.ts.map +1 -1
- package/dist/src/planner/building/select-compound.js +10 -1
- package/dist/src/planner/building/select-compound.js.map +1 -1
- package/dist/src/planner/building/select-context.d.ts +3 -3
- package/dist/src/planner/building/select-context.d.ts.map +1 -1
- package/dist/src/planner/building/select-context.js.map +1 -1
- package/dist/src/planner/building/select-modifiers.d.ts +6 -5
- package/dist/src/planner/building/select-modifiers.d.ts.map +1 -1
- package/dist/src/planner/building/select-modifiers.js +5 -4
- package/dist/src/planner/building/select-modifiers.js.map +1 -1
- package/dist/src/planner/building/select-projections.d.ts.map +1 -1
- package/dist/src/planner/building/select-projections.js +4 -5
- package/dist/src/planner/building/select-projections.js.map +1 -1
- package/dist/src/planner/building/select-window.d.ts.map +1 -1
- package/dist/src/planner/building/select-window.js +6 -3
- package/dist/src/planner/building/select-window.js.map +1 -1
- package/dist/src/planner/building/select.d.ts +3 -3
- package/dist/src/planner/building/select.d.ts.map +1 -1
- package/dist/src/planner/building/select.js +18 -8
- package/dist/src/planner/building/select.js.map +1 -1
- package/dist/src/planner/building/table-function.d.ts.map +1 -1
- package/dist/src/planner/building/table-function.js +1 -1
- package/dist/src/planner/building/table-function.js.map +1 -1
- package/dist/src/planner/building/table.d.ts +5 -3
- package/dist/src/planner/building/table.d.ts.map +1 -1
- package/dist/src/planner/building/table.js +7 -2
- package/dist/src/planner/building/table.js.map +1 -1
- package/dist/src/planner/building/update.d.ts.map +1 -1
- package/dist/src/planner/building/update.js +38 -6
- package/dist/src/planner/building/update.js.map +1 -1
- package/dist/src/planner/building/with.d.ts +3 -3
- package/dist/src/planner/building/with.d.ts.map +1 -1
- package/dist/src/planner/building/with.js.map +1 -1
- package/dist/src/planner/debug.d.ts.map +1 -1
- package/dist/src/planner/debug.js.map +1 -1
- package/dist/src/planner/framework/characteristics.d.ts +235 -0
- package/dist/src/planner/framework/characteristics.d.ts.map +1 -0
- package/dist/src/planner/framework/characteristics.js +299 -0
- package/dist/src/planner/framework/characteristics.js.map +1 -0
- package/dist/src/planner/framework/context.d.ts +16 -5
- package/dist/src/planner/framework/context.d.ts.map +1 -1
- package/dist/src/planner/framework/context.js +2 -0
- package/dist/src/planner/framework/context.js.map +1 -1
- package/dist/src/planner/framework/pass.d.ts +116 -0
- package/dist/src/planner/framework/pass.d.ts.map +1 -0
- package/dist/src/planner/framework/pass.js +236 -0
- package/dist/src/planner/framework/pass.js.map +1 -0
- package/dist/src/planner/nodes/aggregate-node.d.ts +16 -6
- package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/aggregate-node.js +40 -4
- package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
- package/dist/src/planner/nodes/array-index-node.js.map +1 -1
- package/dist/src/planner/nodes/cache-node.d.ts +5 -2
- package/dist/src/planner/nodes/cache-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/cache-node.js +6 -0
- package/dist/src/planner/nodes/cache-node.js.map +1 -1
- package/dist/src/planner/nodes/constraint-check-node.d.ts +10 -2
- package/dist/src/planner/nodes/constraint-check-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/constraint-check-node.js +12 -4
- package/dist/src/planner/nodes/constraint-check-node.js.map +1 -1
- package/dist/src/planner/nodes/create-assertion-node.d.ts +22 -0
- package/dist/src/planner/nodes/create-assertion-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/create-assertion-node.js +41 -0
- package/dist/src/planner/nodes/create-assertion-node.js.map +1 -0
- package/dist/src/planner/nodes/create-index-node.js +2 -2
- package/dist/src/planner/nodes/create-index-node.js.map +1 -1
- package/dist/src/planner/nodes/create-table-node.js +2 -2
- package/dist/src/planner/nodes/create-table-node.js.map +1 -1
- package/dist/src/planner/nodes/cte-node.d.ts +17 -2
- package/dist/src/planner/nodes/cte-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/cte-node.js +9 -1
- package/dist/src/planner/nodes/cte-node.js.map +1 -1
- package/dist/src/planner/nodes/cte-reference-node.js +1 -1
- package/dist/src/planner/nodes/cte-reference-node.js.map +1 -1
- package/dist/src/planner/nodes/declarative-schema.d.ts +62 -0
- package/dist/src/planner/nodes/declarative-schema.d.ts.map +1 -0
- package/dist/src/planner/nodes/declarative-schema.js +181 -0
- package/dist/src/planner/nodes/declarative-schema.js.map +1 -0
- package/dist/src/planner/nodes/delete-node.d.ts +8 -3
- package/dist/src/planner/nodes/delete-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/delete-node.js +10 -2
- package/dist/src/planner/nodes/delete-node.js.map +1 -1
- package/dist/src/planner/nodes/distinct-node.d.ts +3 -2
- package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/distinct-node.js +17 -4
- package/dist/src/planner/nodes/distinct-node.js.map +1 -1
- package/dist/src/planner/nodes/dml-executor-node.d.ts +1 -1
- package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/drop-assertion-node.d.ts +21 -0
- package/dist/src/planner/nodes/drop-assertion-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/drop-assertion-node.js +41 -0
- package/dist/src/planner/nodes/drop-assertion-node.js.map +1 -0
- package/dist/src/planner/nodes/drop-table-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/drop-table-node.js +1 -0
- package/dist/src/planner/nodes/drop-table-node.js.map +1 -1
- package/dist/src/planner/nodes/filter.d.ts +8 -3
- package/dist/src/planner/nodes/filter.d.ts.map +1 -1
- package/dist/src/planner/nodes/filter.js +44 -0
- package/dist/src/planner/nodes/filter.js.map +1 -1
- package/dist/src/planner/nodes/insert-node.d.ts +9 -3
- package/dist/src/planner/nodes/insert-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/insert-node.js +11 -2
- package/dist/src/planner/nodes/insert-node.js.map +1 -1
- package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts +3 -4
- 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 -16
- package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js.map +1 -1
- package/dist/src/planner/nodes/join-node.d.ts +12 -3
- package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-node.js +111 -2
- package/dist/src/planner/nodes/join-node.js.map +1 -1
- package/dist/src/planner/nodes/limit-offset.d.ts +7 -3
- package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
- package/dist/src/planner/nodes/limit-offset.js +15 -0
- package/dist/src/planner/nodes/limit-offset.js.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.d.ts +8 -0
- package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.js +8 -0
- package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
- package/dist/src/planner/nodes/plan-node.d.ts +9 -9
- package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/plan-node.js +3 -3
- package/dist/src/planner/nodes/plan-node.js.map +1 -1
- package/dist/src/planner/nodes/pragma.d.ts +2 -1
- package/dist/src/planner/nodes/pragma.d.ts.map +1 -1
- package/dist/src/planner/nodes/pragma.js +3 -1
- package/dist/src/planner/nodes/pragma.js.map +1 -1
- package/dist/src/planner/nodes/project-node.d.ts +16 -3
- package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/project-node.js +82 -2
- package/dist/src/planner/nodes/project-node.js.map +1 -1
- package/dist/src/planner/nodes/recursive-cte-node.d.ts +2 -2
- package/dist/src/planner/nodes/recursive-cte-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/recursive-cte-node.js +1 -1
- package/dist/src/planner/nodes/recursive-cte-node.js.map +1 -1
- package/dist/src/planner/nodes/reference.d.ts +13 -4
- package/dist/src/planner/nodes/reference.d.ts.map +1 -1
- package/dist/src/planner/nodes/reference.js +16 -0
- package/dist/src/planner/nodes/reference.js.map +1 -1
- package/dist/src/planner/nodes/remote-query-node.d.ts +37 -0
- package/dist/src/planner/nodes/remote-query-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/remote-query-node.js +63 -0
- package/dist/src/planner/nodes/remote-query-node.js.map +1 -0
- package/dist/src/planner/nodes/retrieve-node.d.ts +46 -0
- package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/retrieve-node.js +77 -0
- package/dist/src/planner/nodes/retrieve-node.js.map +1 -0
- package/dist/src/planner/nodes/returning-node.d.ts +4 -3
- package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/returning-node.js +44 -3
- package/dist/src/planner/nodes/returning-node.js.map +1 -1
- package/dist/src/planner/nodes/sequencing-node.d.ts +1 -1
- package/dist/src/planner/nodes/sequencing-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/sequencing-node.js.map +1 -1
- package/dist/src/planner/nodes/set-operation-node.d.ts +1 -1
- package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
- package/dist/src/planner/nodes/sort.d.ts +11 -2
- package/dist/src/planner/nodes/sort.d.ts.map +1 -1
- package/dist/src/planner/nodes/sort.js +23 -2
- package/dist/src/planner/nodes/sort.js.map +1 -1
- package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
- package/dist/src/planner/nodes/stream-aggregate.js +4 -1
- package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.d.ts +7 -1
- package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.js +22 -4
- package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
- package/dist/src/planner/nodes/table-function-call.d.ts +2 -1
- package/dist/src/planner/nodes/table-function-call.d.ts.map +1 -1
- package/dist/src/planner/nodes/table-function-call.js +12 -5
- package/dist/src/planner/nodes/table-function-call.js.map +1 -1
- package/dist/src/planner/nodes/transaction-node.js +2 -2
- package/dist/src/planner/nodes/transaction-node.js.map +1 -1
- package/dist/src/planner/nodes/update-node.d.ts +7 -1
- package/dist/src/planner/nodes/update-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/update-node.js +11 -2
- package/dist/src/planner/nodes/update-node.js.map +1 -1
- package/dist/src/planner/nodes/view-reference-node.js.map +1 -1
- package/dist/src/planner/nodes/window-function.js.map +1 -1
- package/dist/src/planner/nodes/window-node.js.map +1 -1
- package/dist/src/planner/optimizer-tuning.d.ts +11 -0
- package/dist/src/planner/optimizer-tuning.d.ts.map +1 -1
- package/dist/src/planner/optimizer-tuning.js +6 -0
- package/dist/src/planner/optimizer-tuning.js.map +1 -1
- package/dist/src/planner/optimizer.d.ts +17 -3
- package/dist/src/planner/optimizer.d.ts.map +1 -1
- package/dist/src/planner/optimizer.js +159 -67
- package/dist/src/planner/optimizer.js.map +1 -1
- package/dist/src/planner/planning-context.d.ts +5 -3
- package/dist/src/planner/planning-context.d.ts.map +1 -1
- package/dist/src/planner/planning-context.js +2 -0
- package/dist/src/planner/planning-context.js.map +1 -1
- package/dist/src/planner/resolve.d.ts +3 -2
- package/dist/src/planner/resolve.d.ts.map +1 -1
- package/dist/src/planner/resolve.js +6 -5
- package/dist/src/planner/resolve.js.map +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.d.ts +8 -3
- 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 +206 -47
- package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts +10 -3
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -1
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +95 -87
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
- package/dist/src/planner/rules/cache/rule-cte-optimization.d.ts +8 -2
- package/dist/src/planner/rules/cache/rule-cte-optimization.d.ts.map +1 -1
- package/dist/src/planner/rules/cache/rule-cte-optimization.js +24 -13
- package/dist/src/planner/rules/cache/rule-cte-optimization.js.map +1 -1
- package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts +9 -2
- package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts.map +1 -1
- package/dist/src/planner/rules/cache/rule-materialization-advisory.js +14 -7
- package/dist/src/planner/rules/cache/rule-materialization-advisory.js.map +1 -1
- package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.d.ts +9 -3
- package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.d.ts.map +1 -1
- package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js +34 -37
- package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js.map +1 -1
- package/dist/src/planner/rules/join/rule-join-greedy-commute.d.ts +14 -0
- package/dist/src/planner/rules/join/rule-join-greedy-commute.d.ts.map +1 -0
- package/dist/src/planner/rules/join/rule-join-greedy-commute.js +33 -0
- package/dist/src/planner/rules/join/rule-join-greedy-commute.js.map +1 -0
- package/dist/src/planner/rules/join/rule-join-key-inference.d.ts +11 -0
- package/dist/src/planner/rules/join/rule-join-key-inference.d.ts.map +1 -0
- package/dist/src/planner/rules/join/rule-join-key-inference.js +32 -0
- package/dist/src/planner/rules/join/rule-join-key-inference.js.map +1 -0
- package/dist/src/planner/rules/join/rule-quickpick-enumeration.d.ts +4 -0
- package/dist/src/planner/rules/join/rule-quickpick-enumeration.d.ts.map +1 -0
- package/dist/src/planner/rules/join/rule-quickpick-enumeration.js +233 -0
- package/dist/src/planner/rules/join/rule-quickpick-enumeration.js.map +1 -0
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts +21 -0
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts.map +1 -0
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js +125 -0
- package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -0
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.d.ts +21 -0
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.d.ts.map +1 -0
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +261 -0
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -0
- package/dist/src/planner/scopes/registered.d.ts +1 -0
- package/dist/src/planner/scopes/registered.d.ts.map +1 -1
- package/dist/src/planner/scopes/registered.js +7 -0
- package/dist/src/planner/scopes/registered.js.map +1 -1
- package/dist/src/planner/stats/index.d.ts +0 -17
- package/dist/src/planner/stats/index.d.ts.map +1 -1
- package/dist/src/planner/stats/index.js +0 -58
- package/dist/src/planner/stats/index.js.map +1 -1
- package/dist/src/planner/util/deferred-constraint.d.ts +14 -0
- package/dist/src/planner/util/deferred-constraint.d.ts.map +1 -0
- package/dist/src/planner/util/deferred-constraint.js +85 -0
- package/dist/src/planner/util/deferred-constraint.js.map +1 -0
- package/dist/src/planner/util/key-utils.d.ts +15 -0
- package/dist/src/planner/util/key-utils.d.ts.map +1 -0
- package/dist/src/planner/util/key-utils.js +43 -0
- package/dist/src/planner/util/key-utils.js.map +1 -0
- package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
- package/dist/src/planner/validation/plan-validator.js +1 -0
- package/dist/src/planner/validation/plan-validator.js.map +1 -1
- package/dist/src/runtime/deferred-constraint-queue.d.ts +33 -0
- package/dist/src/runtime/deferred-constraint-queue.d.ts.map +1 -0
- package/dist/src/runtime/deferred-constraint-queue.js +172 -0
- package/dist/src/runtime/deferred-constraint-queue.js.map +1 -0
- package/dist/src/runtime/emission-context.d.ts +9 -3
- package/dist/src/runtime/emission-context.d.ts.map +1 -1
- package/dist/src/runtime/emission-context.js +5 -1
- 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 +22 -4
- 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 +3 -2
- package/dist/src/runtime/emit/aggregate.js.map +1 -1
- package/dist/src/runtime/emit/array-index.js.map +1 -1
- package/dist/src/runtime/emit/binary.d.ts.map +1 -1
- package/dist/src/runtime/emit/binary.js +9 -2
- package/dist/src/runtime/emit/binary.js.map +1 -1
- package/dist/src/runtime/emit/cache.d.ts.map +1 -1
- package/dist/src/runtime/emit/cache.js +1 -1
- package/dist/src/runtime/emit/cache.js.map +1 -1
- package/dist/src/runtime/emit/cast.d.ts.map +1 -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 +110 -23
- package/dist/src/runtime/emit/constraint-check.js.map +1 -1
- package/dist/src/runtime/emit/create-assertion.d.ts +5 -0
- package/dist/src/runtime/emit/create-assertion.d.ts.map +1 -0
- package/dist/src/runtime/emit/create-assertion.js +70 -0
- package/dist/src/runtime/emit/create-assertion.js.map +1 -0
- package/dist/src/runtime/emit/cte-reference.d.ts.map +1 -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.map +1 -1
- package/dist/src/runtime/emit/distinct.d.ts.map +1 -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 +17 -9
- package/dist/src/runtime/emit/dml-executor.js.map +1 -1
- package/dist/src/runtime/emit/drop-assertion.d.ts +5 -0
- package/dist/src/runtime/emit/drop-assertion.d.ts.map +1 -0
- package/dist/src/runtime/emit/drop-assertion.js +30 -0
- package/dist/src/runtime/emit/drop-assertion.js.map +1 -0
- package/dist/src/runtime/emit/filter.d.ts.map +1 -1
- package/dist/src/runtime/emit/filter.js.map +1 -1
- package/dist/src/runtime/emit/join.d.ts.map +1 -1
- 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.map +1 -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.map +1 -1
- package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -1
- package/dist/src/runtime/emit/recursive-cte.js +1 -1
- package/dist/src/runtime/emit/recursive-cte.js.map +1 -1
- package/dist/src/runtime/emit/remote-query.d.ts +9 -0
- package/dist/src/runtime/emit/remote-query.d.ts.map +1 -0
- package/dist/src/runtime/emit/remote-query.js +30 -0
- package/dist/src/runtime/emit/remote-query.js.map +1 -0
- package/dist/src/runtime/emit/retrieve.d.ts +5 -0
- package/dist/src/runtime/emit/retrieve.d.ts.map +1 -0
- package/dist/src/runtime/emit/retrieve.js +9 -0
- package/dist/src/runtime/emit/retrieve.js.map +1 -0
- package/dist/src/runtime/emit/returning.d.ts.map +1 -1
- package/dist/src/runtime/emit/returning.js +1 -1
- 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.map +1 -1
- package/dist/src/runtime/emit/scan.d.ts.map +1 -1
- package/dist/src/runtime/emit/scan.js +20 -5
- package/dist/src/runtime/emit/scan.js.map +1 -1
- package/dist/src/runtime/emit/schema-declarative.d.ts +8 -0
- package/dist/src/runtime/emit/schema-declarative.d.ts.map +1 -0
- package/dist/src/runtime/emit/schema-declarative.js +163 -0
- package/dist/src/runtime/emit/schema-declarative.js.map +1 -0
- package/dist/src/runtime/emit/sequencing.d.ts.map +1 -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 -6
- package/dist/src/runtime/emit/set-operation.js.map +1 -1
- package/dist/src/runtime/emit/sort.d.ts.map +1 -1
- package/dist/src/runtime/emit/sort.js.map +1 -1
- package/dist/src/runtime/emit/subquery.d.ts +1 -1
- package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
- package/dist/src/runtime/emit/subquery.js +6 -6
- package/dist/src/runtime/emit/subquery.js.map +1 -1
- package/dist/src/runtime/emit/transaction.d.ts.map +1 -1
- package/dist/src/runtime/emit/transaction.js +48 -8
- package/dist/src/runtime/emit/transaction.js.map +1 -1
- package/dist/src/runtime/emit/values.d.ts.map +1 -1
- package/dist/src/runtime/emit/values.js.map +1 -1
- package/dist/src/runtime/emit/window.d.ts.map +1 -1
- package/dist/src/runtime/emit/window.js.map +1 -1
- package/dist/src/runtime/emitters.d.ts.map +1 -1
- package/dist/src/runtime/emitters.js +1 -0
- package/dist/src/runtime/emitters.js.map +1 -1
- package/dist/src/runtime/register.d.ts.map +1 -1
- package/dist/src/runtime/register.js +16 -2
- package/dist/src/runtime/register.js.map +1 -1
- package/dist/src/runtime/scheduler.js.map +1 -1
- package/dist/src/runtime/types.d.ts +2 -2
- package/dist/src/runtime/types.d.ts.map +1 -1
- package/dist/src/runtime/types.js +4 -1
- package/dist/src/runtime/types.js.map +1 -1
- package/dist/src/runtime/utils.d.ts +2 -2
- package/dist/src/runtime/utils.d.ts.map +1 -1
- package/dist/src/runtime/utils.js +1 -0
- package/dist/src/runtime/utils.js.map +1 -1
- package/dist/src/schema/assertion.d.ts +19 -0
- package/dist/src/schema/assertion.d.ts.map +1 -0
- package/dist/src/schema/assertion.js +2 -0
- package/dist/src/schema/assertion.js.map +1 -0
- package/dist/src/schema/catalog.d.ts +44 -0
- package/dist/src/schema/catalog.d.ts.map +1 -0
- package/dist/src/schema/catalog.js +148 -0
- package/dist/src/schema/catalog.js.map +1 -0
- package/dist/src/schema/change-events.d.ts +2 -2
- package/dist/src/schema/change-events.d.ts.map +1 -1
- package/dist/src/schema/column.d.ts +2 -0
- package/dist/src/schema/column.d.ts.map +1 -1
- package/dist/src/schema/column.js.map +1 -1
- package/dist/src/schema/declared-schema-manager.d.ts +42 -0
- package/dist/src/schema/declared-schema-manager.d.ts.map +1 -0
- package/dist/src/schema/declared-schema-manager.js +71 -0
- package/dist/src/schema/declared-schema-manager.js.map +1 -0
- package/dist/src/schema/function.d.ts +3 -2
- package/dist/src/schema/function.d.ts.map +1 -1
- package/dist/src/schema/function.js.map +1 -1
- package/dist/src/schema/manager.d.ts +8 -3
- package/dist/src/schema/manager.d.ts.map +1 -1
- package/dist/src/schema/manager.js +32 -3
- package/dist/src/schema/manager.js.map +1 -1
- package/dist/src/schema/schema-differ.d.ts +34 -0
- package/dist/src/schema/schema-differ.d.ts.map +1 -0
- package/dist/src/schema/schema-differ.js +157 -0
- package/dist/src/schema/schema-differ.js.map +1 -0
- package/dist/src/schema/schema-hasher.d.ts +10 -0
- package/dist/src/schema/schema-hasher.d.ts.map +1 -0
- package/dist/src/schema/schema-hasher.js +39 -0
- package/dist/src/schema/schema-hasher.js.map +1 -0
- package/dist/src/schema/schema.d.ts +7 -0
- package/dist/src/schema/schema.d.ts.map +1 -1
- package/dist/src/schema/schema.js +19 -0
- package/dist/src/schema/schema.js.map +1 -1
- package/dist/src/schema/table.d.ts +28 -3
- package/dist/src/schema/table.d.ts.map +1 -1
- package/dist/src/schema/table.js +17 -2
- package/dist/src/schema/table.js.map +1 -1
- package/dist/src/schema/window-function.d.ts.map +1 -1
- package/dist/src/schema/window-function.js.map +1 -1
- package/dist/src/util/ast-stringify.d.ts.map +1 -1
- package/dist/src/util/ast-stringify.js +116 -3
- package/dist/src/util/ast-stringify.js.map +1 -1
- package/dist/src/util/environment.js.map +1 -1
- package/dist/src/util/plugin-loader.d.ts +25 -0
- package/dist/src/util/plugin-loader.d.ts.map +1 -1
- package/dist/src/util/plugin-loader.js +137 -0
- package/dist/src/util/plugin-loader.js.map +1 -1
- package/dist/src/util/row-descriptor.d.ts +1 -1
- package/dist/src/util/row-descriptor.d.ts.map +1 -1
- package/dist/src/util/row-descriptor.js.map +1 -1
- package/dist/src/util/serialization.d.ts +3 -0
- package/dist/src/util/serialization.d.ts.map +1 -1
- package/dist/src/util/serialization.js +1 -0
- package/dist/src/util/serialization.js.map +1 -1
- package/dist/src/vtab/best-access-plan.d.ts +1 -1
- package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
- package/dist/src/vtab/best-access-plan.js +1 -0
- package/dist/src/vtab/best-access-plan.js.map +1 -1
- package/dist/src/vtab/manifest.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/base.js +2 -0
- package/dist/src/vtab/memory/layer/base.js.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts +2 -1
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +24 -6
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/dist/src/vtab/memory/layer/safe-iterate.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/safe-iterate.js.map +1 -1
- package/dist/src/vtab/memory/module.d.ts.map +1 -1
- package/dist/src/vtab/memory/module.js +5 -0
- package/dist/src/vtab/memory/module.js.map +1 -1
- package/dist/src/vtab/memory/table.d.ts +2 -1
- package/dist/src/vtab/memory/table.d.ts.map +1 -1
- package/dist/src/vtab/memory/table.js +3 -2
- package/dist/src/vtab/memory/table.js.map +1 -1
- package/dist/src/vtab/memory/utils/logging.d.ts +2 -2
- package/dist/src/vtab/memory/utils/logging.d.ts.map +1 -1
- package/dist/src/vtab/memory/utils/logging.js +6 -3
- package/dist/src/vtab/memory/utils/logging.js.map +1 -1
- package/dist/src/vtab/module.d.ts +25 -0
- package/dist/src/vtab/module.d.ts.map +1 -1
- package/dist/src/vtab/table.d.ts +17 -4
- package/dist/src/vtab/table.d.ts.map +1 -1
- package/dist/src/vtab/table.js.map +1 -1
- package/package.json +4 -2
- package/src/common/errors.ts +1 -1
- package/src/common/json-types.ts +16 -0
- package/src/common/types.ts +2 -0
- package/src/core/database-options.ts +8 -8
- package/src/core/database.ts +537 -71
- package/src/core/statement.ts +3 -1
- package/src/func/builtins/builtin-window-functions.ts +11 -10
- package/src/func/builtins/datetime.ts +42 -0
- package/src/func/builtins/explain.ts +186 -44
- package/src/func/builtins/index.ts +5 -2
- package/src/func/builtins/json-helpers.ts +21 -21
- package/src/func/builtins/json-tvf.ts +8 -9
- package/src/func/builtins/json.ts +10 -9
- package/src/func/builtins/schema.ts +24 -4
- package/src/func/context.ts +7 -0
- package/src/func/registration.ts +5 -1
- package/src/index.ts +2 -2
- package/src/parser/ast.ts +582 -481
- package/src/parser/lexer.ts +27 -21
- package/src/parser/parser.ts +3336 -2776
- package/src/parser/visitor.ts +1 -0
- package/src/planner/analysis/binding-collector.ts +83 -0
- package/src/planner/analysis/const-evaluator.ts +1 -1
- package/src/planner/analysis/const-pass.ts +3 -2
- package/src/planner/analysis/constraint-extractor.ts +610 -123
- package/src/planner/analysis/predicate-normalizer.ts +237 -0
- package/src/planner/building/alter-table.ts +3 -1
- package/src/planner/building/block.ts +93 -78
- package/src/planner/building/constraint-builder.ts +173 -114
- package/src/planner/building/create-assertion.ts +7 -0
- package/src/planner/building/declare-schema.ts +22 -0
- package/src/planner/building/delete.ts +214 -171
- package/src/planner/building/drop-assertion.ts +11 -0
- package/src/planner/building/expression.ts +1 -0
- package/src/planner/building/function-call.ts +6 -5
- package/src/planner/building/insert.ts +428 -349
- package/src/planner/building/pragma.ts +1 -0
- package/src/planner/building/schema-resolution.ts +176 -176
- package/src/planner/building/select-aggregates.ts +5 -3
- package/src/planner/building/select-compound.ts +22 -13
- package/src/planner/building/select-context.ts +6 -6
- package/src/planner/building/select-modifiers.ts +8 -7
- package/src/planner/building/select-projections.ts +177 -176
- package/src/planner/building/select-window.ts +259 -253
- package/src/planner/building/select.ts +531 -520
- package/src/planner/building/table-function.ts +49 -48
- package/src/planner/building/table.ts +9 -3
- package/src/planner/building/update.ts +319 -270
- package/src/planner/building/with.ts +7 -7
- package/src/planner/debug.ts +1 -0
- package/src/planner/framework/characteristics.ts +503 -0
- package/src/planner/framework/context.ts +23 -6
- package/src/planner/framework/pass.ts +354 -0
- package/src/planner/nodes/aggregate-node.ts +52 -7
- package/src/planner/nodes/array-index-node.ts +1 -1
- package/src/planner/nodes/cache-node.ts +11 -2
- package/src/planner/nodes/constraint-check-node.ts +14 -5
- package/src/planner/nodes/create-assertion-node.ts +51 -0
- package/src/planner/nodes/create-index-node.ts +2 -2
- package/src/planner/nodes/create-table-node.ts +2 -2
- package/src/planner/nodes/cte-node.ts +30 -4
- package/src/planner/nodes/cte-reference-node.ts +2 -2
- package/src/planner/nodes/declarative-schema.ts +221 -0
- package/src/planner/nodes/delete-node.ts +102 -96
- package/src/planner/nodes/distinct-node.ts +20 -6
- package/src/planner/nodes/dml-executor-node.ts +1 -1
- package/src/planner/nodes/drop-assertion-node.ts +50 -0
- package/src/planner/nodes/drop-table-node.ts +1 -0
- package/src/planner/nodes/filter.ts +56 -3
- package/src/planner/nodes/insert-node.ts +126 -120
- package/src/planner/nodes/internal-recursive-cte-ref-node.ts +5 -20
- package/src/planner/nodes/join-node.ts +122 -4
- package/src/planner/nodes/limit-offset.ts +132 -113
- package/src/planner/nodes/plan-node-type.ts +95 -87
- package/src/planner/nodes/plan-node.ts +8 -8
- package/src/planner/nodes/pragma.ts +6 -3
- package/src/planner/nodes/project-node.ts +101 -7
- package/src/planner/nodes/recursive-cte-node.ts +6 -6
- package/src/planner/nodes/reference.ts +334 -312
- package/src/planner/nodes/remote-query-node.ts +73 -0
- package/src/planner/nodes/retrieve-node.ts +86 -0
- package/src/planner/nodes/returning-node.ts +52 -10
- package/src/planner/nodes/sequencing-node.ts +2 -2
- package/src/planner/nodes/set-operation-node.ts +3 -3
- package/src/planner/nodes/sort.ts +33 -4
- package/src/planner/nodes/stream-aggregate.ts +5 -1
- package/src/planner/nodes/table-access-nodes.ts +31 -6
- package/src/planner/nodes/table-function-call.ts +134 -127
- package/src/planner/nodes/transaction-node.ts +2 -2
- package/src/planner/nodes/update-node.ts +138 -132
- package/src/planner/nodes/view-reference-node.ts +1 -1
- package/src/planner/nodes/window-function.ts +2 -2
- package/src/planner/nodes/window-node.ts +1 -1
- package/src/planner/optimizer-tuning.ts +18 -0
- package/src/planner/optimizer.ts +171 -96
- package/src/planner/planning-context.ts +10 -3
- package/src/planner/resolve.ts +10 -9
- package/src/planner/rules/README.md +96 -96
- package/src/planner/rules/access/rule-select-access-path.ts +384 -184
- package/src/planner/rules/aggregate/rule-aggregate-streaming.ts +118 -104
- package/src/planner/rules/cache/rule-cte-optimization.ts +29 -16
- package/src/planner/rules/cache/rule-materialization-advisory.ts +14 -7
- package/src/planner/rules/cache/rule-mutating-subquery-cache.ts +38 -44
- package/src/planner/rules/join/rule-join-greedy-commute.ts +48 -0
- package/src/planner/rules/join/rule-join-key-inference.ts +35 -0
- package/src/planner/rules/join/rule-quickpick-enumeration.ts +267 -0
- package/src/planner/rules/predicate/rule-predicate-pushdown.ts +144 -0
- package/src/planner/rules/retrieve/rule-grow-retrieve.ts +337 -0
- package/src/planner/scopes/registered.ts +8 -0
- package/src/planner/stats/index.ts +0 -65
- package/src/planner/util/key-utils.ts +46 -0
- package/src/planner/validation/plan-validator.ts +5 -3
- package/src/runtime/deferred-constraint-queue.ts +196 -0
- package/src/runtime/emission-context.ts +11 -5
- package/src/runtime/emit/add-constraint.ts +26 -5
- package/src/runtime/emit/aggregate.ts +9 -7
- package/src/runtime/emit/array-index.ts +2 -2
- package/src/runtime/emit/binary.ts +26 -8
- package/src/runtime/emit/cache.ts +2 -2
- package/src/runtime/emit/cast.ts +2 -2
- package/src/runtime/emit/constraint-check.ts +148 -26
- package/src/runtime/emit/create-assertion.ts +82 -0
- package/src/runtime/emit/cte-reference.ts +2 -2
- package/src/runtime/emit/cte.ts +2 -2
- package/src/runtime/emit/distinct.ts +2 -2
- package/src/runtime/emit/dml-executor.ts +20 -12
- package/src/runtime/emit/drop-assertion.ts +45 -0
- package/src/runtime/emit/filter.ts +4 -4
- package/src/runtime/emit/join.ts +8 -7
- package/src/runtime/emit/limit-offset.ts +2 -2
- package/src/runtime/emit/pragma.ts +2 -2
- package/src/runtime/emit/project.ts +2 -2
- package/src/runtime/emit/recursive-cte.ts +2 -2
- package/src/runtime/emit/remote-query.ts +47 -0
- package/src/runtime/emit/retrieve.ts +15 -0
- package/src/runtime/emit/returning.ts +4 -4
- package/src/runtime/emit/scalar-function.ts +2 -2
- package/src/runtime/emit/scan.ts +29 -13
- package/src/runtime/emit/schema-declarative.ts +205 -0
- package/src/runtime/emit/sequencing.ts +3 -3
- package/src/runtime/emit/set-operation.ts +7 -7
- package/src/runtime/emit/sort.ts +2 -2
- package/src/runtime/emit/subquery.ts +10 -10
- package/src/runtime/emit/transaction.ts +46 -8
- package/src/runtime/emit/values.ts +2 -2
- package/src/runtime/emit/window.ts +3 -3
- package/src/runtime/emitters.ts +1 -0
- package/src/runtime/register.ts +150 -135
- package/src/runtime/scheduler.ts +2 -2
- package/src/runtime/types.ts +10 -7
- package/src/runtime/utils.ts +3 -2
- package/src/schema/assertion.ts +21 -0
- package/src/schema/catalog.ts +208 -0
- package/src/schema/change-events.ts +2 -2
- package/src/schema/column.ts +2 -0
- package/src/schema/declared-schema-manager.ts +82 -0
- package/src/schema/function.ts +5 -2
- package/src/schema/manager.ts +742 -709
- package/src/schema/schema-differ.ts +214 -0
- package/src/schema/schema-hasher.ts +44 -0
- package/src/schema/schema.ts +23 -0
- package/src/schema/table.ts +398 -364
- package/src/schema/window-function.ts +2 -0
- package/src/util/ast-stringify.ts +869 -764
- package/src/util/environment.ts +2 -2
- package/src/util/plugin-loader.ts +184 -0
- package/src/util/row-descriptor.ts +1 -1
- package/src/util/serialization.ts +2 -0
- package/src/vtab/best-access-plan.ts +2 -1
- package/src/vtab/manifest.ts +1 -0
- package/src/vtab/memory/index.ts +178 -178
- package/src/vtab/memory/layer/base.ts +275 -273
- package/src/vtab/memory/layer/interface.ts +47 -47
- package/src/vtab/memory/layer/manager.ts +33 -11
- package/src/vtab/memory/layer/safe-iterate.ts +3 -3
- package/src/vtab/memory/layer/transaction.ts +229 -229
- package/src/vtab/memory/module.ts +24 -18
- package/src/vtab/memory/table.ts +256 -253
- package/src/vtab/memory/utils/logging.ts +6 -3
- package/src/vtab/module.ts +170 -140
- package/src/vtab/table.ts +162 -143
|
@@ -1,73 +1,167 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Constraint extraction utilities for predicate analysis and
|
|
2
|
+
* Constraint extraction utilities for predicate analysis and pushdown optimization
|
|
3
3
|
* Converts scalar expressions into constraints that can be pushed down to virtual tables
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { ScalarPlanNode } from '../nodes/plan-node.js';
|
|
6
|
+
import type { ScalarPlanNode, RelationalPlanNode, PlanNode } from '../nodes/plan-node.js';
|
|
7
7
|
import { PlanNodeType } from '../nodes/plan-node-type.js';
|
|
8
8
|
import type { ColumnReferenceNode } from '../nodes/reference.js';
|
|
9
|
-
import
|
|
10
|
-
import { LiteralNode } from '../nodes/scalar.js';
|
|
9
|
+
import { BinaryOpNode, BetweenNode } from '../nodes/scalar.js';
|
|
10
|
+
import type { LiteralNode } from '../nodes/scalar.js';
|
|
11
|
+
import { InNode } from '../nodes/subquery.js';
|
|
12
|
+
import type { Row, SqlValue } from '../../common/types.js';
|
|
13
|
+
import { createLogger } from '../../common/logger.js';
|
|
14
|
+
import type * as AST from '../../parser/ast.js';
|
|
15
|
+
import { getSyncLiteral } from '../../parser/utils.js';
|
|
16
|
+
import type { ConstraintOp, PredicateConstraint as VtabPredicateConstraint } from '../../vtab/best-access-plan.js';
|
|
17
|
+
import { TableReferenceNode, ColumnReferenceNode as _ColumnRef } from '../nodes/reference.js';
|
|
18
|
+
import { CapabilityDetectors } from '../framework/characteristics.js';
|
|
11
19
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export type ConstraintOp = '=' | '>' | '>=' | '<' | '<=' | 'MATCH' | 'LIKE' | 'GLOB' | 'IS NULL' | 'IS NOT NULL';
|
|
20
|
+
const log = createLogger('planner:analysis:constraint-extractor');
|
|
21
|
+
|
|
22
|
+
// ConstraintOp is imported from vtab/best-access-plan.ts
|
|
16
23
|
|
|
17
24
|
/**
|
|
18
25
|
* A constraint extracted from a predicate expression
|
|
26
|
+
* Extends the vtab PredicateConstraint with additional metadata for the planner
|
|
19
27
|
*/
|
|
20
|
-
export interface PredicateConstraint {
|
|
21
|
-
/** Index of the column in the table schema */
|
|
22
|
-
columnIndex: number;
|
|
28
|
+
export interface PredicateConstraint extends VtabPredicateConstraint {
|
|
23
29
|
/** Attribute ID of the column reference */
|
|
24
30
|
attributeId: number;
|
|
25
|
-
/** Constraint operator */
|
|
26
|
-
op: ConstraintOp;
|
|
27
|
-
/** Constant value for the constraint (if applicable) */
|
|
28
|
-
value?: SqlValue;
|
|
29
|
-
/** Whether this constraint can be used by the virtual table */
|
|
30
|
-
usable: boolean;
|
|
31
31
|
/** Original expression node for debugging */
|
|
32
32
|
sourceExpression: ScalarPlanNode;
|
|
33
|
+
/** Target table relation (for multi-table predicates) */
|
|
34
|
+
targetRelation?: string;
|
|
35
|
+
/** Dynamic value expression for parameterized/correlated constraints (or IN lists) */
|
|
36
|
+
valueExpr?: ScalarPlanNode | ScalarPlanNode[];
|
|
37
|
+
/** Binding kind describing how value is supplied */
|
|
38
|
+
bindingKind?: 'literal' | 'parameter' | 'correlated' | 'expression' | 'mixed';
|
|
33
39
|
}
|
|
34
40
|
|
|
35
41
|
/**
|
|
36
42
|
* Result of constraint extraction
|
|
37
43
|
*/
|
|
38
44
|
export interface ConstraintExtractionResult {
|
|
39
|
-
/** Extracted constraints */
|
|
40
|
-
|
|
45
|
+
/** Extracted constraints grouped by target table relation */
|
|
46
|
+
constraintsByTable: Map<string, PredicateConstraint[]>;
|
|
41
47
|
/** Residual predicate that couldn't be converted to constraints */
|
|
42
48
|
residualPredicate?: ScalarPlanNode;
|
|
49
|
+
/** All constraints in a flat list */
|
|
50
|
+
allConstraints: PredicateConstraint[];
|
|
51
|
+
/** Predicate comprised only of supported fragments for a specific table (optional) */
|
|
52
|
+
supportedPredicateByTable?: Map<string, ScalarPlanNode>;
|
|
53
|
+
/** For each table, which unique key(s) are fully covered by equality constraints (by column indexes). Empty if none. */
|
|
54
|
+
coveredKeysByTable?: Map<string, number[][]>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Table information for constraint mapping
|
|
59
|
+
*/
|
|
60
|
+
export interface TableInfo {
|
|
61
|
+
relationName: string; // human-readable (e.g., schema.table)
|
|
62
|
+
relationKey: string; // instance-unique (e.g., schema.table#<nodeId>)
|
|
63
|
+
attributes: Array<{ id: number; name: string }>;
|
|
64
|
+
columnIndexMap: Map<number, number>; // attributeId -> columnIndex
|
|
65
|
+
/** Logical unique keys for the relation, expressed as output column indexes */
|
|
66
|
+
uniqueKeys?: number[][];
|
|
43
67
|
}
|
|
44
68
|
|
|
45
69
|
/**
|
|
46
70
|
* Extract constraints from a scalar predicate expression
|
|
47
|
-
*
|
|
71
|
+
* Handles binary comparisons, boolean logic (AND/OR), and complex expressions
|
|
48
72
|
*/
|
|
49
73
|
export function extractConstraints(
|
|
50
74
|
predicate: ScalarPlanNode,
|
|
51
|
-
|
|
75
|
+
tableInfos: TableInfo[] = []
|
|
52
76
|
): ConstraintExtractionResult {
|
|
53
|
-
const
|
|
77
|
+
const constraintsByTable = new Map<string, PredicateConstraint[]>();
|
|
78
|
+
const allConstraints: PredicateConstraint[] = [];
|
|
54
79
|
const residualExpressions: ScalarPlanNode[] = [];
|
|
55
80
|
|
|
56
|
-
|
|
57
|
-
|
|
81
|
+
log('Extracting constraints from predicate: %s', predicate.toString());
|
|
82
|
+
|
|
83
|
+
// Build attribute-to-table mapping for quick lookups
|
|
84
|
+
const tableByAttribute = new Map<number, TableInfo>();
|
|
85
|
+
for (const tableInfo of tableInfos) {
|
|
86
|
+
for (const attr of tableInfo.attributes) {
|
|
87
|
+
tableByAttribute.set(attr.id, tableInfo);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Start extraction process & build supported fragments per table
|
|
92
|
+
const perTableParts = new Map<string, ScalarPlanNode[]>();
|
|
93
|
+
extractFromExpression(predicate, allConstraints, residualExpressions, tableByAttribute, perTableParts);
|
|
94
|
+
|
|
95
|
+
// Group constraints by table instance key
|
|
96
|
+
for (const constraint of allConstraints) {
|
|
97
|
+
if (constraint.targetRelation) {
|
|
98
|
+
if (!constraintsByTable.has(constraint.targetRelation)) {
|
|
99
|
+
constraintsByTable.set(constraint.targetRelation, []);
|
|
100
|
+
}
|
|
101
|
+
constraintsByTable.get(constraint.targetRelation)!.push(constraint);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
58
104
|
|
|
59
|
-
// Build residual predicate from unmatched expressions
|
|
105
|
+
// Build residual predicate from unmatched expressions (combine with AND)
|
|
60
106
|
let residualPredicate: ScalarPlanNode | undefined;
|
|
61
107
|
if (residualExpressions.length === 1) {
|
|
62
108
|
residualPredicate = residualExpressions[0];
|
|
63
109
|
} else if (residualExpressions.length > 1) {
|
|
64
|
-
|
|
65
|
-
|
|
110
|
+
let acc = residualExpressions[0];
|
|
111
|
+
for (let i = 1; i < residualExpressions.length; i++) {
|
|
112
|
+
const right = residualExpressions[i];
|
|
113
|
+
const ast: AST.BinaryExpr = { type: 'binary', operator: 'AND', left: (acc as any).expression, right: (right as any).expression };
|
|
114
|
+
acc = new BinaryOpNode((acc as any).scope, ast, acc, right);
|
|
115
|
+
}
|
|
116
|
+
residualPredicate = acc;
|
|
66
117
|
}
|
|
67
118
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
119
|
+
log('Extracted %d constraints across %d tables, %d residual expressions',
|
|
120
|
+
allConstraints.length, constraintsByTable.size, residualExpressions.length);
|
|
121
|
+
|
|
122
|
+
const supportedPredicateByTable = new Map<string, ScalarPlanNode>();
|
|
123
|
+
for (const [rel, parts] of perTableParts) {
|
|
124
|
+
const combined = combineParts(parts);
|
|
125
|
+
if (combined) supportedPredicateByTable.set(rel, combined);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Compute covered keys per table: collect equality constraints and check against table unique keys
|
|
129
|
+
const coveredKeysByTable = new Map<string, number[][]>();
|
|
130
|
+
for (const [rel, constraints] of constraintsByTable) {
|
|
131
|
+
const tInfo = tableInfos.find(t => t.relationKey === rel || t.relationName === rel);
|
|
132
|
+
if (!tInfo || !tInfo.uniqueKeys || tInfo.uniqueKeys.length === 0) {
|
|
133
|
+
coveredKeysByTable.set(rel, []);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const eqCols = new Set<number>();
|
|
137
|
+
for (const c of constraints) {
|
|
138
|
+
if (c.op === '=') {
|
|
139
|
+
eqCols.add(c.columnIndex);
|
|
140
|
+
}
|
|
141
|
+
// Single-value IN could be treated as equality
|
|
142
|
+
if (c.op === 'IN' && Array.isArray(c.value) && (c.value as unknown[]).length === 1) {
|
|
143
|
+
eqCols.add(c.columnIndex);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const covered: number[][] = [];
|
|
147
|
+
for (const key of tInfo.uniqueKeys) {
|
|
148
|
+
if (key.length === 0) {
|
|
149
|
+
// Zero-length key means at most one row; trivially covered
|
|
150
|
+
covered.push([]);
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
const allCovered = key.every(idx => eqCols.has(idx));
|
|
154
|
+
if (allCovered) covered.push([...key]);
|
|
155
|
+
}
|
|
156
|
+
coveredKeysByTable.set(rel, covered);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
constraintsByTable,
|
|
161
|
+
residualPredicate,
|
|
162
|
+
allConstraints,
|
|
163
|
+
supportedPredicateByTable,
|
|
164
|
+
coveredKeysByTable
|
|
71
165
|
};
|
|
72
166
|
}
|
|
73
167
|
|
|
@@ -78,123 +172,316 @@ function extractFromExpression(
|
|
|
78
172
|
expr: ScalarPlanNode,
|
|
79
173
|
constraints: PredicateConstraint[],
|
|
80
174
|
residual: ScalarPlanNode[],
|
|
81
|
-
|
|
175
|
+
attributeToTableMap: Map<number, TableInfo>,
|
|
176
|
+
perTableParts: Map<string, ScalarPlanNode[]>
|
|
82
177
|
): void {
|
|
83
178
|
// Handle AND expressions - recurse on both sides
|
|
84
179
|
if (isAndExpression(expr)) {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
180
|
+
const binaryOp = expr as BinaryOpNode;
|
|
181
|
+
extractFromExpression(binaryOp.left, constraints, residual, attributeToTableMap, perTableParts);
|
|
182
|
+
extractFromExpression(binaryOp.right, constraints, residual, attributeToTableMap, perTableParts);
|
|
183
|
+
return;
|
|
91
184
|
}
|
|
92
185
|
|
|
93
|
-
//
|
|
94
|
-
|
|
186
|
+
// Handle OR expressions - for now, treat as residual (could be enhanced later)
|
|
187
|
+
if (isOrExpression(expr)) {
|
|
188
|
+
log('OR expression found, treating as residual: %s', expr.toString());
|
|
189
|
+
residual.push(expr);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// BETWEEN → range constraints
|
|
194
|
+
if (expr.nodeType === PlanNodeType.Between) {
|
|
195
|
+
const c = extractBetweenConstraints(expr as BetweenNode, attributeToTableMap);
|
|
196
|
+
if (c) {
|
|
197
|
+
constraints.push(...c);
|
|
198
|
+
addSupportedPart(expr, attributeToTableMap, perTableParts);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// IN list → IN constraint (literals only)
|
|
204
|
+
if (expr.nodeType === PlanNodeType.In) {
|
|
205
|
+
const c = extractInConstraint(expr as InNode, attributeToTableMap);
|
|
206
|
+
if (c) {
|
|
207
|
+
constraints.push(c);
|
|
208
|
+
addSupportedPart(expr, attributeToTableMap, perTableParts);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Try to extract constraint from binary comparison
|
|
214
|
+
const constraint = extractBinaryConstraint(expr, attributeToTableMap);
|
|
95
215
|
if (constraint) {
|
|
96
216
|
constraints.push(constraint);
|
|
217
|
+
addSupportedPart(expr, attributeToTableMap, perTableParts);
|
|
218
|
+
log('Extracted constraint: %s %s %s (table: %s)',
|
|
219
|
+
constraint.attributeId, constraint.op, constraint.value, constraint.targetRelation);
|
|
97
220
|
} else {
|
|
98
221
|
// Cannot convert to constraint - add to residual
|
|
222
|
+
log('Cannot extract constraint from expression, adding to residual: %s', expr.toString());
|
|
99
223
|
residual.push(expr);
|
|
100
224
|
}
|
|
101
225
|
}
|
|
102
226
|
|
|
227
|
+
function addSupportedPart(expr: ScalarPlanNode, attributeToTableMap: Map<number, TableInfo>, perTableParts: Map<string, ScalarPlanNode[]>): void {
|
|
228
|
+
// Determine target table by first column reference in expr; if absent, skip
|
|
229
|
+
const relKey = findTargetRelationKey(expr, attributeToTableMap);
|
|
230
|
+
if (!relKey) return;
|
|
231
|
+
if (!perTableParts.has(relKey)) perTableParts.set(relKey, []);
|
|
232
|
+
perTableParts.get(relKey)!.push(expr);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function findTargetRelationKey(expr: ScalarPlanNode, attributeToTableMap: Map<number, TableInfo>): string | undefined {
|
|
236
|
+
let found: string | undefined;
|
|
237
|
+
const stack: ScalarPlanNode[] = [expr];
|
|
238
|
+
while (stack.length) {
|
|
239
|
+
const n = stack.pop()!;
|
|
240
|
+
if (n.nodeType === PlanNodeType.ColumnReference) {
|
|
241
|
+
const attrId = (n as unknown as _ColumnRef).attributeId;
|
|
242
|
+
const info = attributeToTableMap.get(attrId);
|
|
243
|
+
if (info) return info.relationKey ?? info.relationName;
|
|
244
|
+
}
|
|
245
|
+
for (const c of n.getChildren()) {
|
|
246
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
247
|
+
stack.push(c as any);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return found;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function combineParts(parts: ScalarPlanNode[]): ScalarPlanNode | undefined {
|
|
254
|
+
if (parts.length === 0) return undefined;
|
|
255
|
+
if (parts.length === 1) return parts[0];
|
|
256
|
+
// Combine with AND
|
|
257
|
+
let acc = parts[0];
|
|
258
|
+
for (let i = 1; i < parts.length; i++) {
|
|
259
|
+
const right = parts[i];
|
|
260
|
+
const ast: AST.BinaryExpr = { type: 'binary', operator: 'AND', left: (acc as any).expression, right: (right as any).expression };
|
|
261
|
+
acc = new BinaryOpNode((acc as any).scope, ast, acc, right);
|
|
262
|
+
}
|
|
263
|
+
return acc;
|
|
264
|
+
}
|
|
265
|
+
|
|
103
266
|
/**
|
|
104
267
|
* Extract constraint from binary comparison expression
|
|
105
268
|
*/
|
|
106
269
|
function extractBinaryConstraint(
|
|
107
270
|
expr: ScalarPlanNode,
|
|
108
|
-
|
|
271
|
+
attributeToTableMap: Map<number, TableInfo>
|
|
109
272
|
): PredicateConstraint | null {
|
|
110
|
-
|
|
111
|
-
if (
|
|
273
|
+
// Must be a binary operation
|
|
274
|
+
if (expr.nodeType !== PlanNodeType.BinaryOp) {
|
|
112
275
|
return null;
|
|
113
276
|
}
|
|
114
277
|
|
|
115
|
-
const
|
|
278
|
+
const binaryOp = expr as BinaryOpNode;
|
|
279
|
+
const { left, right } = binaryOp;
|
|
280
|
+
const operator = binaryOp.expression.operator;
|
|
116
281
|
|
|
117
282
|
// Try column-constant pattern (column op constant)
|
|
118
283
|
let columnRef: ColumnReferenceNode | null = null;
|
|
119
284
|
let constant: SqlValue | undefined;
|
|
120
|
-
|
|
285
|
+
let finalOp: ConstraintOp | null = null;
|
|
121
286
|
|
|
122
|
-
|
|
287
|
+
if (isColumnReference(left) && (isLiteralConstant(right) || isDynamicValue(right))) {
|
|
123
288
|
columnRef = left;
|
|
124
|
-
|
|
125
|
-
|
|
289
|
+
if (isLiteralConstant(right)) {
|
|
290
|
+
constant = getLiteralValue(right);
|
|
291
|
+
}
|
|
292
|
+
finalOp = mapOperatorToConstraint(operator, constant);
|
|
293
|
+
} else if ((isLiteralConstant(left) || isDynamicValue(left)) && isColumnReference(right)) {
|
|
126
294
|
// Reverse pattern (constant op column) - flip operator
|
|
127
295
|
columnRef = right;
|
|
128
|
-
|
|
129
|
-
|
|
296
|
+
if (isLiteralConstant(left)) {
|
|
297
|
+
constant = getLiteralValue(left);
|
|
298
|
+
}
|
|
299
|
+
const baseOp = mapOperatorToConstraint(operator, constant);
|
|
300
|
+
finalOp = baseOp ? flipOperator(baseOp) : null;
|
|
130
301
|
}
|
|
131
302
|
|
|
132
|
-
|
|
303
|
+
if (!columnRef || !finalOp) {
|
|
304
|
+
log('No column-constant pattern found in binary expression');
|
|
133
305
|
return null;
|
|
134
306
|
}
|
|
135
307
|
|
|
136
|
-
// Map attribute ID to column index
|
|
137
|
-
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
columnIndex = mappedIndex;
|
|
142
|
-
}
|
|
308
|
+
// Map attribute ID to table and column index
|
|
309
|
+
const tableInfo = attributeToTableMap.get(columnRef.attributeId);
|
|
310
|
+
if (!tableInfo) {
|
|
311
|
+
log('No table mapping found for attribute ID %d', columnRef.attributeId);
|
|
312
|
+
return null;
|
|
143
313
|
}
|
|
144
314
|
|
|
145
|
-
|
|
315
|
+
const columnIndex = tableInfo.columnIndexMap.get(columnRef.attributeId);
|
|
316
|
+
if (columnIndex === undefined) {
|
|
317
|
+
log('No column index found for attribute ID %d', columnRef.attributeId);
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const result: PredicateConstraint = {
|
|
146
322
|
columnIndex,
|
|
147
323
|
attributeId: columnRef.attributeId,
|
|
148
|
-
op:
|
|
324
|
+
op: finalOp,
|
|
149
325
|
value: constant,
|
|
150
|
-
usable:
|
|
151
|
-
sourceExpression: expr
|
|
152
|
-
|
|
326
|
+
usable: true, // Usable since we found table mapping
|
|
327
|
+
sourceExpression: expr,
|
|
328
|
+
targetRelation: tableInfo.relationKey
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
// Attach dynamic binding metadata when RHS/LHS is not a literal
|
|
332
|
+
const rhs = (expr as BinaryOpNode).right;
|
|
333
|
+
const lhs = (expr as BinaryOpNode).left;
|
|
334
|
+
const nonLiteral = !isLiteralConstant(lhs) || !isLiteralConstant(rhs);
|
|
335
|
+
if (nonLiteral) {
|
|
336
|
+
// Determine which side is the value side
|
|
337
|
+
const valueSide = (columnRef === lhs ? rhs : lhs) as ScalarPlanNode;
|
|
338
|
+
if (!isLiteralConstant(valueSide)) {
|
|
339
|
+
result.valueExpr = valueSide;
|
|
340
|
+
if (valueSide.nodeType === PlanNodeType.ParameterReference) {
|
|
341
|
+
result.bindingKind = 'parameter';
|
|
342
|
+
} else if (valueSide.nodeType === PlanNodeType.ColumnReference) {
|
|
343
|
+
const rhsAttrId = (valueSide as unknown as ColumnReferenceNode).attributeId;
|
|
344
|
+
const sameTable = tableInfo.columnIndexMap.has(rhsAttrId);
|
|
345
|
+
result.bindingKind = sameTable ? 'expression' : 'correlated';
|
|
346
|
+
} else {
|
|
347
|
+
result.bindingKind = 'expression';
|
|
348
|
+
}
|
|
349
|
+
} else {
|
|
350
|
+
result.bindingKind = 'literal';
|
|
351
|
+
}
|
|
352
|
+
} else {
|
|
353
|
+
result.bindingKind = 'literal';
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
return result;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function extractBetweenConstraints(
|
|
360
|
+
expr: BetweenNode,
|
|
361
|
+
attributeToTableMap: Map<number, TableInfo>
|
|
362
|
+
): PredicateConstraint[] | null {
|
|
363
|
+
// Only support column BETWEEN literal AND literal
|
|
364
|
+
const col = expr.expr;
|
|
365
|
+
const low = expr.lower;
|
|
366
|
+
const up = expr.upper;
|
|
367
|
+
const not = !!expr.expression.not;
|
|
368
|
+
|
|
369
|
+
if (col.nodeType !== PlanNodeType.ColumnReference) return null;
|
|
370
|
+
if (!isLiteralConstant(low) || !isLiteralConstant(up)) return null;
|
|
371
|
+
|
|
372
|
+
const columnRef = col as unknown as ColumnReferenceNode;
|
|
373
|
+
const tableInfo = attributeToTableMap.get(columnRef.attributeId);
|
|
374
|
+
if (!tableInfo) return null;
|
|
375
|
+
const columnIndex = tableInfo.columnIndexMap.get(columnRef.attributeId);
|
|
376
|
+
if (columnIndex === undefined) return null;
|
|
377
|
+
|
|
378
|
+
if (not) {
|
|
379
|
+
// NOT BETWEEN not expressible as single contiguous range; leave as residual
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const lowVal = getLiteralValue(low);
|
|
384
|
+
const upVal = getLiteralValue(up);
|
|
385
|
+
return [
|
|
386
|
+
{
|
|
387
|
+
columnIndex,
|
|
388
|
+
attributeId: columnRef.attributeId,
|
|
389
|
+
op: '>=',
|
|
390
|
+
value: lowVal,
|
|
391
|
+
usable: true,
|
|
392
|
+
sourceExpression: expr,
|
|
393
|
+
targetRelation: tableInfo.relationKey
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
columnIndex,
|
|
397
|
+
attributeId: columnRef.attributeId,
|
|
398
|
+
op: '<=',
|
|
399
|
+
value: upVal,
|
|
400
|
+
usable: true,
|
|
401
|
+
sourceExpression: expr,
|
|
402
|
+
targetRelation: tableInfo.relationKey
|
|
403
|
+
}
|
|
404
|
+
];
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function extractInConstraint(
|
|
408
|
+
expr: InNode,
|
|
409
|
+
attributeToTableMap: Map<number, TableInfo>
|
|
410
|
+
): PredicateConstraint | null {
|
|
411
|
+
// Only support column IN (literal, ...)
|
|
412
|
+
if (expr.source) return null;
|
|
413
|
+
if (!expr.values || expr.values.length === 0) return null;
|
|
414
|
+
const col = expr.condition;
|
|
415
|
+
if (col.nodeType !== PlanNodeType.ColumnReference) return null;
|
|
416
|
+
|
|
417
|
+
// Ensure all are literals
|
|
418
|
+
if (!expr.values.every(v => isLiteralConstant(v))) return null;
|
|
419
|
+
|
|
420
|
+
const columnRef = col as unknown as ColumnReferenceNode;
|
|
421
|
+
const tableInfo = attributeToTableMap.get(columnRef.attributeId);
|
|
422
|
+
if (!tableInfo) return null;
|
|
423
|
+
const columnIndex = tableInfo.columnIndexMap.get(columnRef.attributeId);
|
|
424
|
+
if (columnIndex === undefined) return null;
|
|
425
|
+
|
|
426
|
+
// Virtual table IN constraint can carry a single array value or multiple equality constraints.
|
|
427
|
+
// Our API supports op 'IN' with value array.
|
|
428
|
+
const values = expr.values.map(v => getLiteralValue(v));
|
|
429
|
+
return {
|
|
430
|
+
columnIndex,
|
|
431
|
+
attributeId: columnRef.attributeId,
|
|
432
|
+
op: 'IN',
|
|
433
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
434
|
+
value: values as any,
|
|
435
|
+
usable: true,
|
|
436
|
+
sourceExpression: expr,
|
|
437
|
+
targetRelation: tableInfo.relationKey
|
|
438
|
+
};
|
|
153
439
|
}
|
|
154
440
|
|
|
155
441
|
/**
|
|
156
|
-
*
|
|
442
|
+
* Map AST operators to constraint operators
|
|
157
443
|
*/
|
|
158
|
-
function
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
444
|
+
function mapOperatorToConstraint(operator: string, rightValue?: SqlValue): ConstraintOp | null {
|
|
445
|
+
switch (operator) {
|
|
446
|
+
case '=': return '=';
|
|
447
|
+
case '>': return '>';
|
|
448
|
+
case '>=': return '>=';
|
|
449
|
+
case '<': return '<';
|
|
450
|
+
case '<=': return '<=';
|
|
451
|
+
case 'LIKE': return 'LIKE';
|
|
452
|
+
case 'GLOB': return 'GLOB';
|
|
453
|
+
case 'MATCH': return 'MATCH';
|
|
454
|
+
case 'IN': return 'IN';
|
|
455
|
+
case 'NOT IN': return 'NOT IN';
|
|
456
|
+
case 'IS':
|
|
457
|
+
return rightValue === null ? 'IS NULL' : null;
|
|
458
|
+
case 'IS NOT':
|
|
459
|
+
return rightValue === null ? 'IS NOT NULL' : null;
|
|
460
|
+
default: return null;
|
|
461
|
+
}
|
|
172
462
|
}
|
|
173
463
|
|
|
174
464
|
/**
|
|
175
465
|
* Check if expression is an AND operation
|
|
176
466
|
*/
|
|
177
467
|
function isAndExpression(expr: ScalarPlanNode): boolean {
|
|
178
|
-
|
|
179
|
-
|
|
468
|
+
return expr.nodeType === PlanNodeType.BinaryOp &&
|
|
469
|
+
(expr as BinaryOpNode).expression.operator === 'AND';
|
|
180
470
|
}
|
|
181
471
|
|
|
182
472
|
/**
|
|
183
|
-
*
|
|
473
|
+
* Check if expression is an OR operation
|
|
184
474
|
*/
|
|
185
|
-
function
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
} | null {
|
|
189
|
-
// Simplified - would need actual implementation
|
|
190
|
-
return null;
|
|
475
|
+
function isOrExpression(expr: ScalarPlanNode): boolean {
|
|
476
|
+
return expr.nodeType === PlanNodeType.BinaryOp &&
|
|
477
|
+
(expr as BinaryOpNode).expression.operator === 'OR';
|
|
191
478
|
}
|
|
192
479
|
|
|
193
480
|
/**
|
|
194
481
|
* Check if node is a column reference
|
|
195
482
|
*/
|
|
196
483
|
function isColumnReference(node: ScalarPlanNode): node is ColumnReferenceNode {
|
|
197
|
-
return node
|
|
484
|
+
return CapabilityDetectors.isColumnReference(node);
|
|
198
485
|
}
|
|
199
486
|
|
|
200
487
|
/**
|
|
@@ -204,12 +491,17 @@ function isLiteralConstant(node: ScalarPlanNode): node is LiteralNode {
|
|
|
204
491
|
return node.nodeType === PlanNodeType.Literal;
|
|
205
492
|
}
|
|
206
493
|
|
|
494
|
+
function isDynamicValue(node: ScalarPlanNode): boolean {
|
|
495
|
+
// Parameter or column reference from any table (correlation handled later)
|
|
496
|
+
return node.nodeType === PlanNodeType.ParameterReference || node.nodeType === PlanNodeType.ColumnReference;
|
|
497
|
+
}
|
|
498
|
+
|
|
207
499
|
/**
|
|
208
500
|
* Get literal value from literal node
|
|
209
501
|
*/
|
|
210
|
-
function getLiteralValue(
|
|
211
|
-
|
|
212
|
-
return
|
|
502
|
+
function getLiteralValue(node: ScalarPlanNode): SqlValue {
|
|
503
|
+
const literalNode = node as LiteralNode;
|
|
504
|
+
return getSyncLiteral(literalNode.expression);
|
|
213
505
|
}
|
|
214
506
|
|
|
215
507
|
/**
|
|
@@ -222,17 +514,230 @@ function flipOperator(op: ConstraintOp): ConstraintOp {
|
|
|
222
514
|
case '>': return '<';
|
|
223
515
|
case '>=': return '<=';
|
|
224
516
|
case '=': return '=';
|
|
517
|
+
case 'LIKE': return 'LIKE'; // Not flippable
|
|
518
|
+
case 'GLOB': return 'GLOB'; // Not flippable
|
|
519
|
+
case 'MATCH': return 'MATCH'; // Not flippable
|
|
520
|
+
case 'IN': return 'IN'; // Not flippable in this context
|
|
521
|
+
case 'NOT IN': return 'NOT IN'; // Not flippable in this context
|
|
225
522
|
default: return op;
|
|
226
523
|
}
|
|
227
524
|
}
|
|
228
525
|
|
|
229
526
|
/**
|
|
230
|
-
*
|
|
527
|
+
* Extract constraints for a specific table from a relational plan
|
|
528
|
+
* Analyzes all Filter nodes and join conditions that reference the table
|
|
231
529
|
*/
|
|
232
|
-
function
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
530
|
+
export function extractConstraintsForTable(
|
|
531
|
+
plan: RelationalPlanNode,
|
|
532
|
+
targetTableRelationKey: string
|
|
533
|
+
): PredicateConstraint[] {
|
|
534
|
+
const constraints: PredicateConstraint[] = [];
|
|
535
|
+
|
|
536
|
+
// Walk the plan tree looking for filter predicates
|
|
537
|
+
walkPlanForPredicates(plan, (predicate, sourceNode) => {
|
|
538
|
+
// Create table info for the target table only
|
|
539
|
+
const tableInfos = createTableInfosFromPlan(plan).filter(
|
|
540
|
+
info => info.relationKey === targetTableRelationKey
|
|
541
|
+
);
|
|
542
|
+
|
|
543
|
+
if (tableInfos.length > 0) {
|
|
544
|
+
const result = extractConstraints(predicate, tableInfos);
|
|
545
|
+
const tableConstraints = result.constraintsByTable.get(targetTableRelationKey);
|
|
546
|
+
if (tableConstraints) {
|
|
547
|
+
constraints.push(...tableConstraints);
|
|
548
|
+
log('Found %d constraints for table %s from %s',
|
|
549
|
+
tableConstraints.length, targetTableRelationKey, sourceNode);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
return constraints;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Extract constraints and combined residual predicate for a specific table
|
|
559
|
+
*/
|
|
560
|
+
export function extractConstraintsAndResidualForTable(
|
|
561
|
+
plan: RelationalPlanNode,
|
|
562
|
+
targetTableRelationKey: string
|
|
563
|
+
): { constraints: PredicateConstraint[]; residualPredicate?: ScalarPlanNode } {
|
|
564
|
+
const constraints: PredicateConstraint[] = [];
|
|
565
|
+
const residuals: ScalarPlanNode[] = [];
|
|
566
|
+
|
|
567
|
+
walkPlanForPredicates(plan, (predicate) => {
|
|
568
|
+
const tableInfos = createTableInfosFromPlan(plan).filter(
|
|
569
|
+
info => info.relationKey === targetTableRelationKey
|
|
570
|
+
);
|
|
571
|
+
if (tableInfos.length === 0) return;
|
|
572
|
+
const result = extractConstraints(predicate, tableInfos);
|
|
573
|
+
const tableConstraints = result.constraintsByTable.get(targetTableRelationKey);
|
|
574
|
+
if (tableConstraints && tableConstraints.length) {
|
|
575
|
+
constraints.push(...tableConstraints);
|
|
576
|
+
}
|
|
577
|
+
if (result.residualPredicate) {
|
|
578
|
+
residuals.push(result.residualPredicate);
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
return { constraints, residualPredicate: combineResiduals(residuals) };
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Compute which unique keys are fully covered by equality constraints for a table within a plan.
|
|
587
|
+
* Returns a list of covered keys (each key is a list of column indexes in the table output order).
|
|
588
|
+
*/
|
|
589
|
+
export function extractCoveredKeysForTable(
|
|
590
|
+
plan: RelationalPlanNode,
|
|
591
|
+
targetTableRelationKey: string
|
|
592
|
+
): number[][] {
|
|
593
|
+
const constraints: PredicateConstraint[] = extractConstraintsForTable(plan, targetTableRelationKey);
|
|
594
|
+
const tInfos = createTableInfosFromPlan(plan).filter(info => info.relationKey === targetTableRelationKey);
|
|
595
|
+
if (tInfos.length === 0) return [];
|
|
596
|
+
const uniqueKeys = tInfos[0].uniqueKeys ?? [];
|
|
597
|
+
return computeCoveredKeysForConstraints(constraints, uniqueKeys);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Given a set of constraints and a table's unique keys, compute which keys are fully covered by equality.
|
|
602
|
+
*/
|
|
603
|
+
export function computeCoveredKeysForConstraints(
|
|
604
|
+
constraints: readonly PredicateConstraint[],
|
|
605
|
+
tableUniqueKeys: readonly number[][]
|
|
606
|
+
): number[][] {
|
|
607
|
+
const eqCols = new Set<number>();
|
|
608
|
+
for (const c of constraints) {
|
|
609
|
+
if (c.op === '=') {
|
|
610
|
+
eqCols.add(c.columnIndex);
|
|
611
|
+
}
|
|
612
|
+
if (c.op === 'IN' && Array.isArray(c.value) && (c.value as unknown[]).length === 1) {
|
|
613
|
+
eqCols.add(c.columnIndex);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
const covered: number[][] = [];
|
|
617
|
+
for (const key of tableUniqueKeys) {
|
|
618
|
+
if (key.length === 0) {
|
|
619
|
+
covered.push([]);
|
|
620
|
+
continue;
|
|
621
|
+
}
|
|
622
|
+
const allCovered = key.every(idx => eqCols.has(idx));
|
|
623
|
+
if (allCovered) covered.push([...key]);
|
|
624
|
+
}
|
|
625
|
+
return covered;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Analyze plan to classify each TableReference instance as 'row' (row-specific) or 'global'.
|
|
630
|
+
* Row-specific means equality constraints fully cover at least one unique key at that reference.
|
|
631
|
+
*/
|
|
632
|
+
export function analyzeRowSpecific(
|
|
633
|
+
plan: RelationalPlanNode | PlanNode
|
|
634
|
+
): Map<string, 'row' | 'global'> {
|
|
635
|
+
const result = new Map<string, 'row' | 'global'>();
|
|
636
|
+
const infos = createTableInfosFromPlan(plan as RelationalPlanNode);
|
|
637
|
+
for (const info of infos) {
|
|
638
|
+
const covered = extractCoveredKeysForTable(plan as RelationalPlanNode, info.relationKey);
|
|
639
|
+
result.set(info.relationKey, covered.length > 0 ? 'row' : 'global');
|
|
640
|
+
}
|
|
641
|
+
return result;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
function combineResiduals(predicates: ScalarPlanNode[]): ScalarPlanNode | undefined {
|
|
645
|
+
if (predicates.length === 0) return undefined;
|
|
646
|
+
if (predicates.length === 1) return predicates[0];
|
|
647
|
+
let acc = predicates[0];
|
|
648
|
+
for (let i = 1; i < predicates.length; i++) {
|
|
649
|
+
const right = predicates[i];
|
|
650
|
+
const ast: AST.BinaryExpr = { type: 'binary', operator: 'AND', left: (acc as any).expression, right: (right as any).expression };
|
|
651
|
+
acc = new BinaryOpNode((acc as any).scope, ast, acc, right);
|
|
652
|
+
}
|
|
653
|
+
return acc;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Walk a plan tree and call callback for each predicate found
|
|
658
|
+
*/
|
|
659
|
+
function walkPlanForPredicates(
|
|
660
|
+
plan: PlanNode,
|
|
661
|
+
callback: (predicate: ScalarPlanNode, sourceNode: string) => void
|
|
662
|
+
): void {
|
|
663
|
+
if (!plan) return;
|
|
664
|
+
// If node exposes predicates via characteristic, collect them
|
|
665
|
+
if (CapabilityDetectors.isPredicateSource(plan as any)) {
|
|
666
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
667
|
+
const preds = (plan as any).getPredicates() as ReadonlyArray<ScalarPlanNode>;
|
|
668
|
+
for (const p of preds) {
|
|
669
|
+
callback(p, 'PredicateSource');
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
// Recurse into all children (scalar and relational)
|
|
674
|
+
for (const child of plan.getChildren()) {
|
|
675
|
+
walkPlanForPredicates(child as unknown as PlanNode, callback);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Create table information from a relational plan
|
|
681
|
+
*/
|
|
682
|
+
function createTableInfosFromPlan(plan: RelationalPlanNode | PlanNode): TableInfo[] {
|
|
683
|
+
const tableInfos: TableInfo[] = [];
|
|
684
|
+
|
|
685
|
+
const seen = new Set<string>();
|
|
686
|
+
|
|
687
|
+
function visitAny(node: PlanNode): void {
|
|
688
|
+
const id = (node as any).id ?? null;
|
|
689
|
+
if (id !== null) {
|
|
690
|
+
const k = String(id);
|
|
691
|
+
if (seen.has(k)) return;
|
|
692
|
+
seen.add(k);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
if (node instanceof TableReferenceNode) {
|
|
696
|
+
const tr = node as unknown as { tableSchema: { schemaName: string; name: string } };
|
|
697
|
+
tableInfos.push(createTableInfoFromNode(node as unknown as RelationalPlanNode, `${tr.tableSchema.schemaName}.${tr.tableSchema.name}`));
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
for (const rel of node.getRelations()) {
|
|
701
|
+
visitAny(rel as unknown as PlanNode);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
for (const child of node.getChildren()) {
|
|
705
|
+
visitAny(child as unknown as PlanNode);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
visitAny(plan as unknown as PlanNode);
|
|
710
|
+
return tableInfos;
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Utility to create table info from a table reference node
|
|
715
|
+
*/
|
|
716
|
+
export function createTableInfoFromNode(node: RelationalPlanNode, relationName?: string): TableInfo {
|
|
717
|
+
const attributes = node.getAttributes();
|
|
718
|
+
const columnIndexMap = new Map<number, number>();
|
|
719
|
+
|
|
720
|
+
// Map attribute IDs to column indices
|
|
721
|
+
attributes.forEach((attr, index) => {
|
|
722
|
+
columnIndexMap.set(attr.id, index);
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
// Extract logical unique keys from relation type, map ColRef[] to plain column indexes
|
|
726
|
+
const relType = (node as unknown as { getType: () => { keys: { index: number }[][] } }).getType();
|
|
727
|
+
const uniqueKeys: number[][] | undefined = Array.isArray(relType?.keys)
|
|
728
|
+
? relType.keys.map(key => key.map(ref => ref.index))
|
|
729
|
+
: undefined;
|
|
730
|
+
|
|
731
|
+
const relName = relationName || node.toString();
|
|
732
|
+
const relationKey = `${relName}#${(node as any).id ?? 'unknown'}`;
|
|
733
|
+
|
|
734
|
+
return {
|
|
735
|
+
relationName: relName,
|
|
736
|
+
relationKey,
|
|
737
|
+
attributes: attributes.map(attr => ({ id: attr.id, name: attr.name })),
|
|
738
|
+
columnIndexMap,
|
|
739
|
+
uniqueKeys
|
|
740
|
+
};
|
|
236
741
|
}
|
|
237
742
|
|
|
238
743
|
/**
|
|
@@ -242,36 +747,18 @@ function combineWithAnd(expressions: ScalarPlanNode[]): ScalarPlanNode {
|
|
|
242
747
|
export function createResidualFilter(
|
|
243
748
|
originalPredicate: ScalarPlanNode,
|
|
244
749
|
handledConstraints: PredicateConstraint[]
|
|
245
|
-
): ((row:
|
|
246
|
-
// If
|
|
750
|
+
): ((row: Row) => boolean) | undefined {
|
|
751
|
+
// If no constraints were handled, return undefined (original predicate still needed)
|
|
247
752
|
if (handledConstraints.length === 0) {
|
|
248
|
-
|
|
249
|
-
// This is a placeholder - real implementation would need to compile the predicate
|
|
250
|
-
return (_row: any) => true;
|
|
753
|
+
return undefined;
|
|
251
754
|
}
|
|
252
755
|
|
|
253
|
-
//
|
|
254
|
-
//
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Utility to map table schema columns to attribute IDs
|
|
260
|
-
* Used when extracting constraints for specific tables
|
|
261
|
-
*/
|
|
262
|
-
export function createColumnMapping(
|
|
263
|
-
tableColumns: Array<{ name: string }>,
|
|
264
|
-
nodeAttributes: Array<{ id: number; name: string }>
|
|
265
|
-
): Map<number, number> {
|
|
266
|
-
const mapping = new Map<number, number>();
|
|
267
|
-
|
|
268
|
-
// Simple name-based mapping
|
|
269
|
-
for (const attr of nodeAttributes) {
|
|
270
|
-
const columnIndex = tableColumns.findIndex(col => col.name === attr.name);
|
|
271
|
-
if (columnIndex >= 0) {
|
|
272
|
-
mapping.set(attr.id, columnIndex);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
756
|
+
// TODO: Implement sophisticated residual filter construction
|
|
757
|
+
// This would need to:
|
|
758
|
+
// 1. Identify which parts of the original predicate were handled
|
|
759
|
+
// 2. Construct a new predicate with only the unhandled parts
|
|
760
|
+
// 3. Compile that predicate to a runtime function
|
|
275
761
|
|
|
276
|
-
|
|
762
|
+
log('Residual filter construction not yet implemented - using original predicate');
|
|
763
|
+
return undefined;
|
|
277
764
|
}
|