@quereus/quereus 0.1.0 → 0.2.1
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 +47 -23
- package/dist/src/common/types.d.ts +1 -0
- package/dist/src/common/types.d.ts.map +1 -1
- package/dist/src/core/database.d.ts +22 -4
- package/dist/src/core/database.d.ts.map +1 -1
- package/dist/src/core/database.js +44 -6
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/core/statement.d.ts +0 -7
- package/dist/src/core/statement.d.ts.map +1 -1
- package/dist/src/core/statement.js +1 -51
- package/dist/src/core/statement.js.map +1 -1
- package/dist/src/func/builtins/explain.d.ts.map +1 -1
- package/dist/src/func/builtins/explain.js +0 -11
- package/dist/src/func/builtins/explain.js.map +1 -1
- package/dist/src/index.d.ts +13 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/parser/ast.d.ts +10 -4
- package/dist/src/parser/ast.d.ts.map +1 -1
- package/dist/src/parser/parser.d.ts.map +1 -1
- package/dist/src/parser/parser.js +40 -44
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/src/planner/analysis/const-pass.d.ts.map +1 -1
- package/dist/src/planner/analysis/const-pass.js +12 -6
- package/dist/src/planner/analysis/const-pass.js.map +1 -1
- package/dist/src/planner/building/constraint-builder.d.ts +11 -0
- package/dist/src/planner/building/constraint-builder.d.ts.map +1 -0
- package/dist/src/planner/building/constraint-builder.js +79 -0
- package/dist/src/planner/building/constraint-builder.js.map +1 -0
- package/dist/src/planner/building/delete.d.ts.map +1 -1
- package/dist/src/planner/building/delete.js +7 -4
- package/dist/src/planner/building/delete.js.map +1 -1
- package/dist/src/planner/building/expression.d.ts +3 -0
- package/dist/src/planner/building/expression.d.ts.map +1 -1
- package/dist/src/planner/building/expression.js +33 -7
- package/dist/src/planner/building/expression.js.map +1 -1
- package/dist/src/planner/building/insert.d.ts.map +1 -1
- package/dist/src/planner/building/insert.js +5 -2
- package/dist/src/planner/building/insert.js.map +1 -1
- package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
- package/dist/src/planner/building/select-aggregates.js +46 -9
- package/dist/src/planner/building/select-aggregates.js.map +1 -1
- package/dist/src/planner/building/select-context.js +20 -11
- package/dist/src/planner/building/select-context.js.map +1 -1
- package/dist/src/planner/building/select-modifiers.d.ts +5 -3
- package/dist/src/planner/building/select-modifiers.d.ts.map +1 -1
- package/dist/src/planner/building/select-modifiers.js +29 -20
- package/dist/src/planner/building/select-modifiers.js.map +1 -1
- package/dist/src/planner/building/select-projections.d.ts +3 -1
- package/dist/src/planner/building/select-projections.d.ts.map +1 -1
- package/dist/src/planner/building/select-projections.js +15 -20
- 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 +25 -2
- package/dist/src/planner/building/select.d.ts.map +1 -1
- package/dist/src/planner/building/select.js +147 -24
- package/dist/src/planner/building/select.js.map +1 -1
- package/dist/src/planner/building/table.d.ts +0 -10
- package/dist/src/planner/building/table.d.ts.map +1 -1
- package/dist/src/planner/building/table.js +1 -35
- 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 +8 -5
- package/dist/src/planner/building/update.js.map +1 -1
- package/dist/src/planner/building/with.d.ts.map +1 -1
- package/dist/src/planner/building/with.js +7 -8
- package/dist/src/planner/building/with.js.map +1 -1
- package/dist/src/planner/cache/correlation-detector.d.ts +11 -0
- package/dist/src/planner/cache/correlation-detector.d.ts.map +1 -0
- package/dist/src/planner/cache/correlation-detector.js +73 -0
- package/dist/src/planner/cache/correlation-detector.js.map +1 -0
- package/dist/src/planner/cache/materialization-advisory.d.ts +12 -18
- package/dist/src/planner/cache/materialization-advisory.d.ts.map +1 -1
- package/dist/src/planner/cache/materialization-advisory.js +65 -46
- package/dist/src/planner/cache/materialization-advisory.js.map +1 -1
- package/dist/src/planner/cache/reference-graph.d.ts +14 -9
- package/dist/src/planner/cache/reference-graph.d.ts.map +1 -1
- package/dist/src/planner/cache/reference-graph.js +93 -84
- package/dist/src/planner/cache/reference-graph.js.map +1 -1
- package/dist/src/planner/debug.d.ts +25 -0
- package/dist/src/planner/debug.d.ts.map +1 -1
- package/dist/src/planner/debug.js +127 -0
- package/dist/src/planner/debug.js.map +1 -1
- package/dist/src/planner/framework/context.d.ts +11 -0
- package/dist/src/planner/framework/context.d.ts.map +1 -1
- package/dist/src/planner/framework/context.js +25 -2
- package/dist/src/planner/framework/context.js.map +1 -1
- package/dist/src/planner/framework/registry.d.ts +3 -7
- package/dist/src/planner/framework/registry.d.ts.map +1 -1
- package/dist/src/planner/framework/registry.js +20 -31
- package/dist/src/planner/framework/registry.js.map +1 -1
- package/dist/src/planner/nodes/add-constraint-node.d.ts +2 -1
- package/dist/src/planner/nodes/add-constraint-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/add-constraint-node.js +3 -0
- package/dist/src/planner/nodes/add-constraint-node.js.map +1 -1
- package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/aggregate-node.js +6 -4
- package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
- package/dist/src/planner/nodes/cache-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/cache-node.js +2 -2
- package/dist/src/planner/nodes/cache-node.js.map +1 -1
- package/dist/src/planner/nodes/constraint-check-node.d.ts +13 -6
- package/dist/src/planner/nodes/constraint-check-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/constraint-check-node.js +38 -12
- package/dist/src/planner/nodes/constraint-check-node.js.map +1 -1
- package/dist/src/planner/nodes/create-index-node.d.ts +2 -1
- package/dist/src/planner/nodes/create-index-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/create-index-node.js +3 -0
- package/dist/src/planner/nodes/create-index-node.js.map +1 -1
- package/dist/src/planner/nodes/create-table-node.d.ts +2 -1
- package/dist/src/planner/nodes/create-table-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/create-table-node.js +3 -0
- package/dist/src/planner/nodes/create-table-node.js.map +1 -1
- package/dist/src/planner/nodes/create-view-node.d.ts +2 -1
- package/dist/src/planner/nodes/create-view-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/create-view-node.js +3 -0
- package/dist/src/planner/nodes/create-view-node.js.map +1 -1
- package/dist/src/planner/nodes/cte-node.d.ts +1 -1
- package/dist/src/planner/nodes/cte-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/cte-node.js +33 -12
- package/dist/src/planner/nodes/cte-node.js.map +1 -1
- package/dist/src/planner/nodes/cte-reference-node.d.ts +18 -4
- package/dist/src/planner/nodes/cte-reference-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/cte-reference-node.js +40 -10
- package/dist/src/planner/nodes/cte-reference-node.js.map +1 -1
- package/dist/src/planner/nodes/delete-node.d.ts +4 -3
- package/dist/src/planner/nodes/delete-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/delete-node.js +20 -6
- package/dist/src/planner/nodes/delete-node.js.map +1 -1
- package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/distinct-node.js +2 -2
- 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/dml-executor-node.js +2 -2
- package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
- package/dist/src/planner/nodes/drop-table-node.d.ts +2 -1
- package/dist/src/planner/nodes/drop-table-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/drop-table-node.js +3 -0
- package/dist/src/planner/nodes/drop-table-node.js.map +1 -1
- package/dist/src/planner/nodes/drop-view-node.d.ts +2 -1
- package/dist/src/planner/nodes/drop-view-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/drop-view-node.js +3 -0
- package/dist/src/planner/nodes/drop-view-node.js.map +1 -1
- package/dist/src/planner/nodes/filter.d.ts.map +1 -1
- package/dist/src/planner/nodes/filter.js +3 -3
- package/dist/src/planner/nodes/filter.js.map +1 -1
- package/dist/src/planner/nodes/insert-node.d.ts +2 -1
- package/dist/src/planner/nodes/insert-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/insert-node.js +18 -5
- package/dist/src/planner/nodes/insert-node.js.map +1 -1
- package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts +28 -0
- package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js +69 -0
- package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js.map +1 -0
- package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-node.js +3 -3
- package/dist/src/planner/nodes/join-node.js.map +1 -1
- package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
- package/dist/src/planner/nodes/limit-offset.js +2 -2
- package/dist/src/planner/nodes/limit-offset.js.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.d.ts +1 -1
- package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.js +1 -1
- package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
- package/dist/src/planner/nodes/plan-node.d.ts +23 -0
- package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/plan-node.js +25 -2
- package/dist/src/planner/nodes/plan-node.js.map +1 -1
- package/dist/src/planner/nodes/project-node.d.ts +5 -1
- package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/project-node.js +39 -20
- 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 +20 -8
- package/dist/src/planner/nodes/recursive-cte-node.js.map +1 -1
- package/dist/src/planner/nodes/reference.d.ts.map +1 -1
- package/dist/src/planner/nodes/reference.js +4 -2
- package/dist/src/planner/nodes/reference.js.map +1 -1
- package/dist/src/planner/nodes/returning-node.d.ts +1 -1
- package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/returning-node.js +21 -13
- package/dist/src/planner/nodes/returning-node.js.map +1 -1
- package/dist/src/planner/nodes/scalar.d.ts +26 -2
- package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
- package/dist/src/planner/nodes/scalar.js +82 -10
- package/dist/src/planner/nodes/scalar.js.map +1 -1
- package/dist/src/planner/nodes/sequencing-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/sequencing-node.js +2 -2
- package/dist/src/planner/nodes/sequencing-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 -3
- package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
- package/dist/src/planner/nodes/single-row.d.ts +4 -2
- package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
- package/dist/src/planner/nodes/single-row.js +3 -0
- package/dist/src/planner/nodes/single-row.js.map +1 -1
- package/dist/src/planner/nodes/sink-node.d.ts +1 -1
- package/dist/src/planner/nodes/sink-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/sink-node.js +4 -4
- package/dist/src/planner/nodes/sink-node.js.map +1 -1
- package/dist/src/planner/nodes/sort.d.ts.map +1 -1
- package/dist/src/planner/nodes/sort.js +2 -2
- package/dist/src/planner/nodes/sort.js.map +1 -1
- package/dist/src/planner/nodes/stream-aggregate.d.ts +1 -0
- package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
- package/dist/src/planner/nodes/stream-aggregate.js +64 -11
- package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
- package/dist/src/planner/nodes/subquery.d.ts +4 -4
- package/dist/src/planner/nodes/subquery.d.ts.map +1 -1
- package/dist/src/planner/nodes/subquery.js +68 -23
- package/dist/src/planner/nodes/subquery.js.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.d.ts +83 -0
- package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -0
- package/dist/src/planner/nodes/table-access-nodes.js +226 -0
- package/dist/src/planner/nodes/table-access-nodes.js.map +1 -0
- package/dist/src/planner/nodes/update-node.d.ts +4 -2
- package/dist/src/planner/nodes/update-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/update-node.js +26 -13
- package/dist/src/planner/nodes/update-node.js.map +1 -1
- package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/window-node.js +25 -23
- package/dist/src/planner/nodes/window-node.js.map +1 -1
- package/dist/src/planner/optimizer.d.ts.map +1 -1
- package/dist/src/planner/optimizer.js +46 -50
- package/dist/src/planner/optimizer.js.map +1 -1
- package/dist/src/planner/planning-context.d.ts +13 -0
- package/dist/src/planner/planning-context.d.ts.map +1 -1
- package/dist/src/planner/planning-context.js.map +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.d.ts +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 +59 -53
- package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -1
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +62 -2
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
- package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts.map +1 -1
- package/dist/src/planner/rules/cache/rule-materialization-advisory.js +31 -24
- package/dist/src/planner/rules/cache/rule-materialization-advisory.js.map +1 -1
- package/dist/src/planner/scopes/base.d.ts +0 -10
- package/dist/src/planner/scopes/base.d.ts.map +1 -1
- package/dist/src/planner/scopes/base.js +0 -14
- package/dist/src/planner/scopes/base.js.map +1 -1
- package/dist/src/planner/scopes/empty.d.ts +0 -2
- package/dist/src/planner/scopes/empty.d.ts.map +1 -1
- package/dist/src/planner/scopes/empty.js +0 -8
- package/dist/src/planner/scopes/empty.js.map +1 -1
- package/dist/src/planner/scopes/multi.d.ts.map +1 -1
- package/dist/src/planner/scopes/multi.js +0 -1
- package/dist/src/planner/scopes/multi.js.map +1 -1
- package/dist/src/planner/scopes/param.d.ts.map +1 -1
- package/dist/src/planner/scopes/param.js +0 -1
- package/dist/src/planner/scopes/param.js.map +1 -1
- package/dist/src/planner/scopes/registered.d.ts +0 -10
- package/dist/src/planner/scopes/registered.d.ts.map +1 -1
- package/dist/src/planner/scopes/registered.js +1 -17
- package/dist/src/planner/scopes/registered.js.map +1 -1
- package/dist/src/planner/scopes/scope.d.ts +0 -8
- package/dist/src/planner/scopes/scope.d.ts.map +1 -1
- package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
- package/dist/src/planner/validation/plan-validator.js +1 -7
- package/dist/src/planner/validation/plan-validator.js.map +1 -1
- package/dist/src/runtime/context-helpers.d.ts +45 -0
- package/dist/src/runtime/context-helpers.d.ts.map +1 -0
- package/dist/src/runtime/context-helpers.js +139 -0
- package/dist/src/runtime/context-helpers.js.map +1 -0
- package/dist/src/runtime/emission-context.d.ts +1 -0
- package/dist/src/runtime/emission-context.d.ts.map +1 -1
- package/dist/src/runtime/emission-context.js +2 -1
- package/dist/src/runtime/emission-context.js.map +1 -1
- package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
- package/dist/src/runtime/emit/aggregate.js +119 -86
- package/dist/src/runtime/emit/aggregate.js.map +1 -1
- package/dist/src/runtime/emit/between.d.ts +5 -0
- package/dist/src/runtime/emit/between.d.ts.map +1 -0
- package/dist/src/runtime/emit/between.js +38 -0
- package/dist/src/runtime/emit/between.js.map +1 -0
- package/dist/src/runtime/emit/binary.d.ts +0 -1
- package/dist/src/runtime/emit/binary.d.ts.map +1 -1
- package/dist/src/runtime/emit/binary.js +0 -36
- package/dist/src/runtime/emit/binary.js.map +1 -1
- package/dist/src/runtime/emit/column-reference.d.ts.map +1 -1
- package/dist/src/runtime/emit/column-reference.js +2 -26
- package/dist/src/runtime/emit/column-reference.js.map +1 -1
- package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
- package/dist/src/runtime/emit/constraint-check.js +16 -123
- package/dist/src/runtime/emit/constraint-check.js.map +1 -1
- package/dist/src/runtime/emit/cte-reference.d.ts.map +1 -1
- package/dist/src/runtime/emit/cte-reference.js +16 -48
- package/dist/src/runtime/emit/cte-reference.js.map +1 -1
- package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
- package/dist/src/runtime/emit/distinct.js +2 -8
- package/dist/src/runtime/emit/distinct.js.map +1 -1
- package/dist/src/runtime/emit/filter.d.ts.map +1 -1
- package/dist/src/runtime/emit/filter.js +6 -13
- package/dist/src/runtime/emit/filter.js.map +1 -1
- package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts +5 -0
- package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts.map +1 -0
- package/dist/src/runtime/emit/internal-recursive-cte-ref.js +23 -0
- package/dist/src/runtime/emit/internal-recursive-cte-ref.js.map +1 -0
- package/dist/src/runtime/emit/join.d.ts.map +1 -1
- package/dist/src/runtime/emit/join.js +40 -40
- package/dist/src/runtime/emit/join.js.map +1 -1
- package/dist/src/runtime/emit/project.d.ts.map +1 -1
- package/dist/src/runtime/emit/project.js +13 -13
- 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 +3 -14
- 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 -14
- package/dist/src/runtime/emit/returning.js.map +1 -1
- package/dist/src/runtime/emit/scan.d.ts +5 -2
- package/dist/src/runtime/emit/scan.d.ts.map +1 -1
- package/dist/src/runtime/emit/scan.js +21 -17
- package/dist/src/runtime/emit/scan.js.map +1 -1
- package/dist/src/runtime/emit/sort.d.ts.map +1 -1
- package/dist/src/runtime/emit/sort.js +8 -11
- 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 +95 -40
- 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 +7 -22
- package/dist/src/runtime/emit/table-valued-function.js.map +1 -1
- package/dist/src/runtime/emit/update.d.ts.map +1 -1
- package/dist/src/runtime/emit/update.js +20 -27
- package/dist/src/runtime/emit/update.js.map +1 -1
- package/dist/src/runtime/emit/window.d.ts.map +1 -1
- package/dist/src/runtime/emit/window.js +55 -83
- 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 +49 -1
- 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 +5 -4
- package/dist/src/runtime/register.js.map +1 -1
- package/dist/src/runtime/scheduler.d.ts.map +1 -1
- package/dist/src/runtime/scheduler.js +47 -42
- package/dist/src/runtime/scheduler.js.map +1 -1
- package/dist/src/runtime/types.d.ts +34 -0
- package/dist/src/runtime/types.d.ts.map +1 -1
- package/dist/src/runtime/types.js +21 -0
- package/dist/src/runtime/types.js.map +1 -1
- package/dist/src/schema/manager.d.ts.map +1 -1
- package/dist/src/schema/manager.js +29 -16
- package/dist/src/schema/manager.js.map +1 -1
- package/dist/src/schema/table.d.ts +4 -4
- package/dist/src/schema/table.d.ts.map +1 -1
- package/dist/src/schema/table.js +10 -10
- package/dist/src/schema/table.js.map +1 -1
- package/dist/src/util/plugin-loader.d.ts +10 -1
- package/dist/src/util/plugin-loader.d.ts.map +1 -1
- package/dist/src/util/plugin-loader.js +56 -1
- package/dist/src/util/plugin-loader.js.map +1 -1
- package/dist/src/util/working-table-iterable.d.ts.map +1 -1
- package/dist/src/util/working-table-iterable.js +8 -8
- package/dist/src/util/working-table-iterable.js.map +1 -1
- package/dist/src/vtab/manifest.d.ts +36 -0
- package/dist/src/vtab/manifest.d.ts.map +1 -1
- package/dist/src/vtab/table.d.ts +1 -1
- package/dist/src/vtab/table.d.ts.map +1 -1
- package/package.json +8 -3
- package/src/common/types.ts +1 -0
- package/src/core/database.ts +48 -6
- package/src/core/statement.ts +1 -49
- package/src/func/builtins/explain.ts +0 -11
- package/src/index.ts +39 -5
- package/src/parser/ast.ts +12 -6
- package/src/parser/parser.ts +45 -52
- package/src/planner/analysis/const-pass.ts +281 -270
- package/src/planner/building/constraint-builder.ts +114 -0
- package/src/planner/building/delete.ts +18 -5
- package/src/planner/building/expression.ts +35 -7
- package/src/planner/building/insert.ts +16 -3
- package/src/planner/building/select-aggregates.ts +57 -11
- package/src/planner/building/select-context.ts +22 -12
- package/src/planner/building/select-modifiers.ts +35 -21
- package/src/planner/building/select-projections.ts +25 -26
- package/src/planner/building/select-window.ts +14 -9
- package/src/planner/building/select.ts +163 -31
- package/src/planner/building/table.ts +1 -40
- package/src/planner/building/update.ts +22 -7
- package/src/planner/building/with.ts +12 -13
- package/src/planner/cache/correlation-detector.ts +83 -0
- package/src/planner/cache/materialization-advisory.ts +71 -50
- package/src/planner/cache/reference-graph.ts +115 -91
- package/src/planner/debug.ts +163 -0
- package/src/planner/framework/context.ts +36 -2
- package/src/planner/framework/registry.ts +261 -274
- package/src/planner/nodes/add-constraint-node.ts +5 -1
- package/src/planner/nodes/aggregate-node.ts +6 -4
- package/src/planner/nodes/cache-node.ts +2 -2
- package/src/planner/nodes/constraint-check-node.ts +49 -15
- package/src/planner/nodes/create-index-node.ts +5 -1
- package/src/planner/nodes/create-table-node.ts +5 -1
- package/src/planner/nodes/create-view-node.ts +5 -1
- package/src/planner/nodes/cte-node.ts +45 -14
- package/src/planner/nodes/cte-reference-node.ts +49 -13
- package/src/planner/nodes/delete-node.ts +31 -7
- package/src/planner/nodes/distinct-node.ts +2 -2
- package/src/planner/nodes/dml-executor-node.ts +3 -3
- package/src/planner/nodes/drop-table-node.ts +5 -1
- package/src/planner/nodes/drop-view-node.ts +5 -1
- package/src/planner/nodes/filter.ts +3 -3
- package/src/planner/nodes/function.ts +93 -93
- package/src/planner/nodes/insert-node.ts +28 -5
- package/src/planner/nodes/internal-recursive-cte-ref-node.ts +76 -0
- package/src/planner/nodes/join-node.ts +3 -3
- package/src/planner/nodes/limit-offset.ts +2 -2
- package/src/planner/nodes/plan-node-type.ts +1 -1
- package/src/planner/nodes/plan-node.ts +39 -2
- package/src/planner/nodes/project-node.ts +39 -19
- package/src/planner/nodes/recursive-cte-node.ts +37 -9
- package/src/planner/nodes/reference.ts +4 -2
- package/src/planner/nodes/returning-node.ts +25 -13
- package/src/planner/nodes/scalar.ts +95 -11
- package/src/planner/nodes/sequencing-node.ts +2 -2
- package/src/planner/nodes/set-operation-node.ts +3 -3
- package/src/planner/nodes/single-row.ts +7 -2
- package/src/planner/nodes/sink-node.ts +5 -5
- package/src/planner/nodes/sort.ts +2 -2
- package/src/planner/nodes/stream-aggregate.ts +76 -12
- package/src/planner/nodes/subquery.ts +90 -27
- package/src/planner/nodes/{physical-access-nodes.ts → table-access-nodes.ts} +6 -6
- package/src/planner/nodes/update-node.ts +31 -13
- package/src/planner/nodes/window-node.ts +28 -22
- package/src/planner/optimizer.ts +257 -263
- package/src/planner/planning-context.ts +15 -0
- package/src/planner/rules/access/rule-select-access-path.ts +68 -64
- package/src/planner/rules/aggregate/rule-aggregate-streaming.ts +74 -2
- package/src/planner/rules/cache/rule-materialization-advisory.ts +31 -27
- package/src/planner/scopes/base.ts +0 -17
- package/src/planner/scopes/empty.ts +0 -10
- package/src/planner/scopes/multi.ts +0 -1
- package/src/planner/scopes/param.ts +0 -1
- package/src/planner/scopes/registered.ts +1 -20
- package/src/planner/scopes/scope.ts +0 -12
- package/src/planner/validation/plan-validator.ts +1 -8
- package/src/runtime/context-helpers.ts +191 -0
- package/src/runtime/emission-context.ts +5 -2
- package/src/runtime/emit/aggregate.ts +131 -85
- package/src/runtime/emit/between.ts +51 -0
- package/src/runtime/emit/binary.ts +0 -46
- package/src/runtime/emit/column-reference.ts +3 -36
- package/src/runtime/emit/constraint-check.ts +19 -144
- package/src/runtime/emit/cte-reference.ts +23 -60
- package/src/runtime/emit/distinct.ts +2 -7
- package/src/runtime/emit/filter.ts +6 -13
- package/src/runtime/emit/internal-recursive-cte-ref.ts +37 -0
- package/src/runtime/emit/join.ts +45 -43
- package/src/runtime/emit/project.ts +18 -12
- package/src/runtime/emit/recursive-cte.ts +3 -12
- package/src/runtime/emit/returning.ts +7 -14
- package/src/runtime/emit/scan.ts +25 -23
- package/src/runtime/emit/sort.ts +8 -11
- package/src/runtime/emit/subquery.ts +108 -48
- package/src/runtime/emit/table-valued-function.ts +7 -20
- package/src/runtime/emit/update.ts +22 -29
- package/src/runtime/emit/window.ts +74 -88
- package/src/runtime/emitters.ts +52 -1
- package/src/runtime/register.ts +5 -4
- package/src/runtime/scheduler.ts +54 -54
- package/src/runtime/types.ts +45 -0
- package/src/schema/manager.ts +34 -19
- package/src/schema/table.ts +8 -8
- package/src/util/plugin-loader.ts +78 -4
- package/src/util/working-table-iterable.ts +15 -7
- package/src/vtab/manifest.ts +42 -0
- package/src/vtab/table.ts +1 -1
- package/src/planner/nodes/scan.ts +0 -103
- package/src/planner/rules/physical/rule-mark-physical.ts +0 -37
- package/src/runtime/emit/table-reference.ts +0 -92
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Rule: Select Access Path
|
|
3
3
|
*
|
|
4
|
-
* Transforms:
|
|
4
|
+
* Transforms: TableReferenceNode → SeqScanNode | IndexScanNode | IndexSeekNode
|
|
5
5
|
* Conditions: When logical table access needs to be made physical
|
|
6
6
|
* Benefits: Enables cost-based access path selection and index utilization
|
|
7
7
|
*/
|
|
@@ -9,39 +9,36 @@
|
|
|
9
9
|
import { createLogger } from '../../../common/logger.js';
|
|
10
10
|
import type { PlanNode } from '../../nodes/plan-node.js';
|
|
11
11
|
import type { OptContext } from '../../framework/context.js';
|
|
12
|
-
import {
|
|
13
|
-
import { SeqScanNode, IndexScanNode, IndexSeekNode } from '../../nodes/
|
|
12
|
+
import { TableReferenceNode } from '../../nodes/reference.js';
|
|
13
|
+
import { SeqScanNode, IndexScanNode, IndexSeekNode } from '../../nodes/table-access-nodes.js';
|
|
14
14
|
import { seqScanCost } from '../../cost/index.js';
|
|
15
|
-
import type { ColumnMeta, PredicateConstraint, BestAccessPlanRequest, BestAccessPlanResult
|
|
15
|
+
import type { ColumnMeta, PredicateConstraint, BestAccessPlanRequest, BestAccessPlanResult } from '../../../vtab/best-access-plan.js';
|
|
16
|
+
import { FilterInfo } from '../../../vtab/filter-info.js';
|
|
17
|
+
import type { IndexConstraintUsage } from '../../../vtab/index-info.js';
|
|
16
18
|
|
|
17
19
|
const log = createLogger('optimizer:rule:select-access-path');
|
|
18
20
|
|
|
19
21
|
export function ruleSelectAccessPath(node: PlanNode, context: OptContext): PlanNode | null {
|
|
20
|
-
// Guard: only apply to
|
|
21
|
-
if (!(node instanceof
|
|
22
|
+
// Guard: only apply to TableReferenceNode
|
|
23
|
+
if (!(node instanceof TableReferenceNode)) {
|
|
22
24
|
return null;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
|
|
26
|
-
if (node.physical) {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
log('Selecting access path for table %s', node.source.tableSchema.name);
|
|
27
|
+
log('Selecting access path for table %s', node.tableSchema.name);
|
|
31
28
|
|
|
32
29
|
try {
|
|
33
30
|
// Get table schema and virtual table module
|
|
34
|
-
const tableSchema = node.
|
|
31
|
+
const tableSchema = node.tableSchema;
|
|
35
32
|
const vtabModule = tableSchema.vtabModule;
|
|
36
33
|
|
|
37
34
|
// If no virtual table module, fall back to sequential scan
|
|
38
35
|
if (!vtabModule || typeof vtabModule !== 'object' || !('getBestAccessPlan' in vtabModule)) {
|
|
39
36
|
log('No getBestAccessPlan support, using sequential scan for %s', tableSchema.name);
|
|
40
|
-
return createSeqScan(node);
|
|
37
|
+
return createSeqScan(node, undefined);
|
|
41
38
|
}
|
|
42
39
|
|
|
43
40
|
// Extract constraints from current filter info
|
|
44
|
-
const constraints =
|
|
41
|
+
const constraints: PredicateConstraint[] = []; // TODO: Extract from parent Filter node if any
|
|
45
42
|
|
|
46
43
|
// Build request for getBestAccessPlan
|
|
47
44
|
const request: BestAccessPlanRequest = {
|
|
@@ -53,7 +50,7 @@ export function ruleSelectAccessPath(node: PlanNode, context: OptContext): PlanN
|
|
|
53
50
|
isUnique: col.primaryKey || false // For now, assume only PK columns are unique
|
|
54
51
|
} as ColumnMeta)),
|
|
55
52
|
filters: constraints,
|
|
56
|
-
estimatedRows: node.
|
|
53
|
+
estimatedRows: node.estimatedRows
|
|
57
54
|
};
|
|
58
55
|
|
|
59
56
|
// Call getBestAccessPlan
|
|
@@ -68,58 +65,43 @@ export function ruleSelectAccessPath(node: PlanNode, context: OptContext): PlanN
|
|
|
68
65
|
return physicalNode;
|
|
69
66
|
|
|
70
67
|
} catch (error) {
|
|
71
|
-
log('Error selecting access path for %s: %s', node.
|
|
68
|
+
log('Error selecting access path for %s: %s', node.tableSchema.name, error);
|
|
72
69
|
// Fall back to sequential scan on error
|
|
73
70
|
return createSeqScan(node);
|
|
74
71
|
}
|
|
75
72
|
}
|
|
76
73
|
|
|
77
|
-
/**
|
|
78
|
-
* Extract predicate constraints from FilterInfo
|
|
79
|
-
*/
|
|
80
|
-
function extractConstraintsFromFilterInfo(node: TableScanNode, _tableSchema: any): PredicateConstraint[] {
|
|
81
|
-
const constraints: PredicateConstraint[] = [];
|
|
82
|
-
|
|
83
|
-
// Extract from FilterInfo.indexInfoOutput.aConstraint if available
|
|
84
|
-
const indexConstraints = node.filterInfo.indexInfoOutput.aConstraint;
|
|
85
|
-
if (indexConstraints) {
|
|
86
|
-
for (let i = 0; i < indexConstraints.length; i++) {
|
|
87
|
-
const constraint = indexConstraints[i];
|
|
88
|
-
|
|
89
|
-
if (constraint && constraint.usable) {
|
|
90
|
-
constraints.push({
|
|
91
|
-
columnIndex: constraint.iColumn,
|
|
92
|
-
op: mapConstraintOp(constraint.op),
|
|
93
|
-
usable: constraint.usable,
|
|
94
|
-
// Note: actual value would need to be extracted from args
|
|
95
|
-
value: undefined
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return constraints;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Map internal constraint op to public constraint op
|
|
106
|
-
*/
|
|
107
|
-
function mapConstraintOp(_internalOp: number): ConstraintOp {
|
|
108
|
-
// This mapping would need to be based on the actual constants used
|
|
109
|
-
// For now, assume equality - in a real implementation this would map
|
|
110
|
-
// from IndexConstraintOp constants to ConstraintOp
|
|
111
|
-
return '=';
|
|
112
|
-
}
|
|
113
|
-
|
|
114
74
|
/**
|
|
115
75
|
* Select the appropriate physical node based on access plan
|
|
116
76
|
*/
|
|
117
77
|
function selectPhysicalNode(
|
|
118
|
-
originalNode:
|
|
78
|
+
originalNode: TableReferenceNode,
|
|
119
79
|
accessPlan: BestAccessPlanResult,
|
|
120
80
|
constraints: PredicateConstraint[]
|
|
121
81
|
): SeqScanNode | IndexScanNode | IndexSeekNode {
|
|
122
82
|
|
|
83
|
+
// Create a default FilterInfo for the physical nodes
|
|
84
|
+
const filterInfo: FilterInfo = {
|
|
85
|
+
idxNum: 0,
|
|
86
|
+
idxStr: 'fullscan',
|
|
87
|
+
constraints: [],
|
|
88
|
+
args: [],
|
|
89
|
+
indexInfoOutput: {
|
|
90
|
+
nConstraint: 0,
|
|
91
|
+
aConstraint: [],
|
|
92
|
+
nOrderBy: 0,
|
|
93
|
+
aOrderBy: [],
|
|
94
|
+
aConstraintUsage: [] as IndexConstraintUsage[],
|
|
95
|
+
idxNum: 0,
|
|
96
|
+
idxStr: 'fullscan',
|
|
97
|
+
orderByConsumed: false,
|
|
98
|
+
estimatedCost: accessPlan.cost,
|
|
99
|
+
estimatedRows: BigInt(accessPlan.rows || 1000),
|
|
100
|
+
idxFlags: 0,
|
|
101
|
+
colUsed: 0n,
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
123
105
|
// Analyze the access plan to determine node type
|
|
124
106
|
const hasEqualityConstraints = constraints.some(c => c.op === '=' && accessPlan.handledFilters[constraints.indexOf(c)]);
|
|
125
107
|
const hasRangeConstraints = constraints.some(c => ['>', '>=', '<', '<='].includes(c.op) && accessPlan.handledFilters[constraints.indexOf(c)]);
|
|
@@ -136,8 +118,8 @@ function selectPhysicalNode(
|
|
|
136
118
|
log('Using index seek (equality constraint, small result)');
|
|
137
119
|
return new IndexSeekNode(
|
|
138
120
|
originalNode.scope,
|
|
139
|
-
originalNode
|
|
140
|
-
|
|
121
|
+
originalNode,
|
|
122
|
+
filterInfo,
|
|
141
123
|
'primary', // Default to primary index
|
|
142
124
|
[], // seekKeys would be populated from constraints
|
|
143
125
|
false, // not a range
|
|
@@ -149,8 +131,8 @@ function selectPhysicalNode(
|
|
|
149
131
|
log('Using index scan (range constraints or ordering)');
|
|
150
132
|
return new IndexScanNode(
|
|
151
133
|
originalNode.scope,
|
|
152
|
-
originalNode
|
|
153
|
-
|
|
134
|
+
originalNode,
|
|
135
|
+
filterInfo,
|
|
154
136
|
'primary', // Default to primary index
|
|
155
137
|
providesOrdering,
|
|
156
138
|
accessPlan.cost
|
|
@@ -158,21 +140,43 @@ function selectPhysicalNode(
|
|
|
158
140
|
} else {
|
|
159
141
|
// Fall back to sequential scan
|
|
160
142
|
log('Using sequential scan (no beneficial index access)');
|
|
161
|
-
return createSeqScan(originalNode, accessPlan.cost);
|
|
143
|
+
return createSeqScan(originalNode, filterInfo, accessPlan.cost);
|
|
162
144
|
}
|
|
163
145
|
}
|
|
164
146
|
|
|
165
147
|
/**
|
|
166
148
|
* Create a sequential scan node
|
|
167
149
|
*/
|
|
168
|
-
function createSeqScan(originalNode:
|
|
169
|
-
const tableRows = originalNode.
|
|
150
|
+
function createSeqScan(originalNode: TableReferenceNode, filterInfo?: FilterInfo, cost?: number): SeqScanNode {
|
|
151
|
+
const tableRows = originalNode.estimatedRows || 1000;
|
|
170
152
|
const scanCost = cost ?? seqScanCost(tableRows);
|
|
171
153
|
|
|
154
|
+
// Create default FilterInfo if not provided
|
|
155
|
+
const effectiveFilterInfo = filterInfo || {
|
|
156
|
+
idxNum: 0,
|
|
157
|
+
idxStr: 'fullscan',
|
|
158
|
+
constraints: [],
|
|
159
|
+
args: [],
|
|
160
|
+
indexInfoOutput: {
|
|
161
|
+
nConstraint: 0,
|
|
162
|
+
aConstraint: [],
|
|
163
|
+
nOrderBy: 0,
|
|
164
|
+
aOrderBy: [],
|
|
165
|
+
aConstraintUsage: [] as IndexConstraintUsage[],
|
|
166
|
+
idxNum: 0,
|
|
167
|
+
idxStr: 'fullscan',
|
|
168
|
+
orderByConsumed: false,
|
|
169
|
+
estimatedCost: scanCost,
|
|
170
|
+
estimatedRows: BigInt(tableRows),
|
|
171
|
+
idxFlags: 0,
|
|
172
|
+
colUsed: 0n,
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
172
176
|
const seqScan = new SeqScanNode(
|
|
173
177
|
originalNode.scope,
|
|
174
|
-
originalNode
|
|
175
|
-
|
|
178
|
+
originalNode,
|
|
179
|
+
effectiveFilterInfo,
|
|
176
180
|
scanCost
|
|
177
181
|
);
|
|
178
182
|
|
|
@@ -42,13 +42,49 @@ export function ruleAggregateStreaming(node: PlanNode, _context: OptContext): Pl
|
|
|
42
42
|
|
|
43
43
|
const sortNode = new SortNode(node.scope, source, sortKeys);
|
|
44
44
|
|
|
45
|
+
// Create combined attributes: AggregateNode attributes + source attributes
|
|
46
|
+
// This ensures both GROUP BY/aggregate AND source column attribute IDs are preserved
|
|
47
|
+
const aggregateAttrs = node.getAttributes();
|
|
48
|
+
const sourceAttrs = node.source.getAttributes();
|
|
49
|
+
|
|
50
|
+
// Deduplicate by column NAME to avoid duplicate columns like 'id'
|
|
51
|
+
// (The same logical column can have different attribute IDs between aggregate and source)
|
|
52
|
+
const seenNames = new Set<string>();
|
|
53
|
+
const combinedAttrs: typeof aggregateAttrs = [];
|
|
54
|
+
|
|
55
|
+
// Add aggregate attributes first (GROUP BY + aggregates)
|
|
56
|
+
for (const attr of aggregateAttrs) {
|
|
57
|
+
combinedAttrs.push(attr);
|
|
58
|
+
seenNames.add(attr.name);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Add source attributes that aren't already present by name
|
|
62
|
+
for (const attr of sourceAttrs) {
|
|
63
|
+
if (!seenNames.has(attr.name)) {
|
|
64
|
+
combinedAttrs.push(attr);
|
|
65
|
+
seenNames.add(attr.name);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Final safety-pass: filter duplicates that may have slipped through
|
|
70
|
+
const uniqueByName = new Set<string>();
|
|
71
|
+
const deduped: typeof combinedAttrs = [];
|
|
72
|
+
for (const attr of combinedAttrs) {
|
|
73
|
+
if (!uniqueByName.has(attr.name)) {
|
|
74
|
+
deduped.push(attr);
|
|
75
|
+
uniqueByName.add(attr.name);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const finalAttrs = deduped;
|
|
80
|
+
|
|
45
81
|
const result = new StreamAggregateNode(
|
|
46
82
|
node.scope,
|
|
47
83
|
sortNode,
|
|
48
84
|
node.groupBy,
|
|
49
85
|
node.aggregates,
|
|
50
86
|
undefined, // estimatedCostOverride
|
|
51
|
-
|
|
87
|
+
finalAttrs // unique list
|
|
52
88
|
);
|
|
53
89
|
|
|
54
90
|
// Let framework set physical properties via markPhysical()
|
|
@@ -58,13 +94,49 @@ export function ruleAggregateStreaming(node: PlanNode, _context: OptContext): Pl
|
|
|
58
94
|
return result;
|
|
59
95
|
} else {
|
|
60
96
|
// No GROUP BY - can stream aggregate without sorting
|
|
97
|
+
// Create combined attributes: AggregateNode attributes + source attributes
|
|
98
|
+
// This ensures both GROUP BY/aggregate AND source column attribute IDs are preserved
|
|
99
|
+
const aggregateAttrs = node.getAttributes();
|
|
100
|
+
const sourceAttrs = node.source.getAttributes();
|
|
101
|
+
|
|
102
|
+
// Deduplicate by column NAME to avoid duplicate columns like 'id'
|
|
103
|
+
// (The same logical column can have different attribute IDs between aggregate and source)
|
|
104
|
+
const seenNames = new Set<string>();
|
|
105
|
+
const combinedAttrs: typeof aggregateAttrs = [];
|
|
106
|
+
|
|
107
|
+
// Add aggregate attributes first (GROUP BY + aggregates)
|
|
108
|
+
for (const attr of aggregateAttrs) {
|
|
109
|
+
combinedAttrs.push(attr);
|
|
110
|
+
seenNames.add(attr.name);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Add source attributes that aren't already present by name
|
|
114
|
+
for (const attr of sourceAttrs) {
|
|
115
|
+
if (!seenNames.has(attr.name)) {
|
|
116
|
+
combinedAttrs.push(attr);
|
|
117
|
+
seenNames.add(attr.name);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Final safety-pass: filter duplicates that may have slipped through
|
|
122
|
+
const uniqueByName = new Set<string>();
|
|
123
|
+
const deduped: typeof combinedAttrs = [];
|
|
124
|
+
for (const attr of combinedAttrs) {
|
|
125
|
+
if (!uniqueByName.has(attr.name)) {
|
|
126
|
+
deduped.push(attr);
|
|
127
|
+
uniqueByName.add(attr.name);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const finalAttrs = deduped;
|
|
132
|
+
|
|
61
133
|
const result = new StreamAggregateNode(
|
|
62
134
|
node.scope,
|
|
63
135
|
source,
|
|
64
136
|
node.groupBy,
|
|
65
137
|
node.aggregates,
|
|
66
138
|
undefined, // estimatedCostOverride
|
|
67
|
-
|
|
139
|
+
finalAttrs // unique list
|
|
68
140
|
);
|
|
69
141
|
|
|
70
142
|
// Let framework set physical properties via markPhysical()
|
|
@@ -14,46 +14,50 @@ import { MaterializationAdvisory } from '../../cache/materialization-advisory.js
|
|
|
14
14
|
const log = createLogger('optimizer:rule:materialization-advisory');
|
|
15
15
|
|
|
16
16
|
export function ruleMaterializationAdvisory(node: PlanNode, context: OptContext): PlanNode | null {
|
|
17
|
-
//
|
|
18
|
-
//
|
|
17
|
+
// Apply this rule when we're at a non-relational node that has relational children
|
|
18
|
+
// This captures transitions into relational subtrees (queries, subqueries, CTEs, etc.)
|
|
19
19
|
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
// Check if this is a non-relational node
|
|
21
|
+
const nodeType = node.getType();
|
|
22
|
+
if (nodeType.typeClass === 'relation') {
|
|
23
|
+
// This is already a relational node, don't apply here
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
25
26
|
|
|
26
|
-
if
|
|
27
|
+
// Check if this node has any relational children
|
|
28
|
+
const relations = node.getRelations();
|
|
29
|
+
if (relations.length === 0) {
|
|
30
|
+
// No relational children, nothing to analyze
|
|
27
31
|
return null;
|
|
28
32
|
}
|
|
29
33
|
|
|
30
|
-
log('Applying materialization advisory
|
|
34
|
+
log('Applying materialization advisory at transition from %s to relational children', node.nodeType);
|
|
31
35
|
|
|
32
36
|
try {
|
|
33
37
|
// Create advisory with current tuning parameters
|
|
34
38
|
const advisory = new MaterializationAdvisory(context.tuning);
|
|
35
39
|
|
|
36
|
-
//
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// Count how many cache recommendations were made
|
|
40
|
-
const cacheCount = Array.from(recommendations.values())
|
|
41
|
-
.filter(rec => rec.shouldCache).length;
|
|
40
|
+
// We need to analyze and potentially transform each relational subtree
|
|
41
|
+
let anyTransformed = false;
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
// For each relational child, analyze and transform its entire subtree
|
|
44
|
+
for (const relation of relations) {
|
|
45
|
+
const transformedRelation = advisory.analyzeAndTransform(relation);
|
|
46
|
+
if (transformedRelation !== relation) {
|
|
47
|
+
anyTransformed = true;
|
|
48
|
+
log('Transformed relational subtree under %s', node.nodeType);
|
|
49
|
+
}
|
|
46
50
|
}
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
// If any relational children were transformed, we need to return a transformed node
|
|
53
|
+
// However, since we can't easily reconstruct the parent node with new relational children
|
|
54
|
+
// (as discussed in the earlier implementation), we'll analyze the entire node
|
|
55
|
+
if (anyTransformed) {
|
|
56
|
+
// Re-analyze the entire tree rooted at this node
|
|
57
|
+
const fullTransform = advisory.analyzeAndTransform(node);
|
|
58
|
+
if (fullTransform !== node) {
|
|
59
|
+
return fullTransform;
|
|
60
|
+
}
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
return null;
|
|
@@ -6,22 +6,5 @@ import { type Scope, Ambiguous } from './scope.js';
|
|
|
6
6
|
* Scope that tracks references.
|
|
7
7
|
*/
|
|
8
8
|
export abstract class BaseScope implements Scope {
|
|
9
|
-
/** References that have been resolved through this scope. */
|
|
10
|
-
private _references: PlanNode[] = [];
|
|
11
|
-
|
|
12
9
|
abstract resolveSymbol(symbolKey: string, expression: AST.Expression): PlanNode | typeof Ambiguous | undefined;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Returns all references that have been resolved through this scope.
|
|
16
|
-
* This includes references from both this scope and any parent scopes.
|
|
17
|
-
*
|
|
18
|
-
* @returns An array of all resolved references.
|
|
19
|
-
*/
|
|
20
|
-
getReferences(): readonly PlanNode[] {
|
|
21
|
-
return this._references;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
addReference(reference: PlanNode): void {
|
|
25
|
-
this._references.push(reference);
|
|
26
|
-
}
|
|
27
10
|
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { QuereusError } from '../../common/errors.js';
|
|
2
|
-
import { StatusCode } from '../../common/types.js';
|
|
3
1
|
import * as AST from '../../parser/ast.js';
|
|
4
2
|
import type { PlanNode } from '../nodes/plan-node.js';
|
|
5
3
|
import { type Scope, Ambiguous } from './scope.js';
|
|
@@ -10,13 +8,5 @@ export class EmptyScope implements Scope {
|
|
|
10
8
|
return undefined;
|
|
11
9
|
}
|
|
12
10
|
|
|
13
|
-
getReferences(): readonly PlanNode[] {
|
|
14
|
-
return [];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
addReference(_reference: PlanNode): void {
|
|
18
|
-
throw new QuereusError('EmptyScope does not support adding references.', StatusCode.MISUSE);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
11
|
static readonly instance = new EmptyScope();
|
|
22
12
|
}
|
|
@@ -10,9 +10,6 @@ import { type ReferenceCallback, type Scope, Ambiguous } from './scope.js';
|
|
|
10
10
|
* based on the current position in the PlanNode tree.
|
|
11
11
|
*/
|
|
12
12
|
export class RegisteredScope implements Scope {
|
|
13
|
-
/** References that have been resolved through this scope. */
|
|
14
|
-
private _references: PlanNode[] = [];
|
|
15
|
-
|
|
16
13
|
/** Symbols that have been registered in this scope. */
|
|
17
14
|
private registeredSymbols: Map<string, ReferenceCallback> = new Map();
|
|
18
15
|
|
|
@@ -43,9 +40,7 @@ export class RegisteredScope implements Scope {
|
|
|
43
40
|
resolveSymbol(symbolKey: string, expression: AST.Expression): PlanNode | typeof Ambiguous | undefined {
|
|
44
41
|
const reference = this.registeredSymbols.get(symbolKey.toLowerCase());
|
|
45
42
|
if (reference) {
|
|
46
|
-
|
|
47
|
-
this.addReference(node);
|
|
48
|
-
return node;
|
|
43
|
+
return reference(expression, this);
|
|
49
44
|
}
|
|
50
45
|
if (this.parent) {
|
|
51
46
|
return this.parent.resolveSymbol(symbolKey, expression);
|
|
@@ -53,20 +48,6 @@ export class RegisteredScope implements Scope {
|
|
|
53
48
|
return undefined;
|
|
54
49
|
}
|
|
55
50
|
|
|
56
|
-
/**
|
|
57
|
-
* Returns all references that have been resolved through this scope.
|
|
58
|
-
* This includes references from both this scope and any parent scopes.
|
|
59
|
-
*
|
|
60
|
-
* @returns An array of all resolved references.
|
|
61
|
-
*/
|
|
62
|
-
getReferences(): readonly PlanNode[] {
|
|
63
|
-
return this._references;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
addReference(reference: PlanNode): void {
|
|
67
|
-
this._references.push(reference);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
51
|
/**
|
|
71
52
|
* Returns all symbols that have been registered in this scope.
|
|
72
53
|
*
|
|
@@ -13,16 +13,4 @@ export type ReferenceCallback = (expression: AST.Expression, currentScope: Scope
|
|
|
13
13
|
*/
|
|
14
14
|
export interface Scope {
|
|
15
15
|
resolveSymbol(symbolKey: string, expression: AST.Expression): PlanNode | typeof Ambiguous | undefined;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Returns all references that have been resolved through this scope.
|
|
19
|
-
* This includes references from both this scope and any parent scopes.
|
|
20
|
-
*
|
|
21
|
-
* @returns An array of all resolved references.
|
|
22
|
-
*/
|
|
23
|
-
getReferences(): readonly PlanNode[];
|
|
24
|
-
|
|
25
|
-
addReference(reference: PlanNode): void;
|
|
26
16
|
}
|
|
27
|
-
|
|
28
|
-
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Validates that a plan tree meets all invariants before emission
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { PlanNode, type RelationalPlanNode } from '../nodes/plan-node.js';
|
|
6
|
+
import { isRelationalNode, PlanNode, type RelationalPlanNode } from '../nodes/plan-node.js';
|
|
7
7
|
import { PlanNodeType } from '../nodes/plan-node-type.js';
|
|
8
8
|
import { QuereusError } from '../../common/errors.js';
|
|
9
9
|
import { StatusCode } from '../../common/types.js';
|
|
@@ -299,13 +299,6 @@ function validateOrdering(ordering: any[], columnCount: number, nodePath: string
|
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
301
|
|
|
302
|
-
/**
|
|
303
|
-
* Check if a node is a relational node
|
|
304
|
-
*/
|
|
305
|
-
function isRelationalNode(node: PlanNode): boolean {
|
|
306
|
-
return 'getAttributes' in node && typeof (node as any).getAttributes === 'function';
|
|
307
|
-
}
|
|
308
|
-
|
|
309
302
|
/**
|
|
310
303
|
* Check if a node type is a DDL node that doesn't produce attributes
|
|
311
304
|
*/
|