@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,5 +1,5 @@
|
|
|
1
1
|
import type { Scope } from '../scopes/scope.js';
|
|
2
|
-
import { PlanNode, type RelationalPlanNode, type Attribute } from './plan-node.js';
|
|
2
|
+
import { PlanNode, type RelationalPlanNode, type Attribute, isRelationalNode } from './plan-node.js';
|
|
3
3
|
import { PlanNodeType } from './plan-node-type.js';
|
|
4
4
|
import type { ScalarPlanNode } from './plan-node.js';
|
|
5
5
|
import type { RelationType } from '../../common/datatype.js';
|
|
@@ -150,25 +150,37 @@ export class ReturningNode extends PlanNode implements RelationalPlanNode {
|
|
|
150
150
|
return [this.executor];
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
getChildren(): readonly
|
|
154
|
-
|
|
153
|
+
getChildren(): readonly PlanNode[] {
|
|
154
|
+
// Return executor first, then all projection expressions
|
|
155
|
+
return [this.executor, ...this.projections.map(proj => proj.node)];
|
|
155
156
|
}
|
|
156
157
|
|
|
157
158
|
withChildren(newChildren: readonly PlanNode[]): PlanNode {
|
|
158
|
-
|
|
159
|
-
|
|
159
|
+
const expectedChildren = 1 + this.projections.length; // executor + projections
|
|
160
|
+
if (newChildren.length !== expectedChildren) {
|
|
161
|
+
throw new Error(`ReturningNode expects ${expectedChildren} children, got ${newChildren.length}`);
|
|
160
162
|
}
|
|
161
163
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
164
|
+
const [newExecutor, ...newProjectionNodes] = newChildren;
|
|
165
|
+
|
|
166
|
+
// Type check the executor
|
|
167
|
+
if (!isRelationalNode(newExecutor)) {
|
|
168
|
+
throw new Error('ReturningNode: first child must be a RelationalPlanNode (executor)');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Type check projection expressions
|
|
172
|
+
for (let i = 0; i < newProjectionNodes.length; i++) {
|
|
173
|
+
const expr = newProjectionNodes[i];
|
|
174
|
+
if (!('expression' in expr)) {
|
|
175
|
+
throw new Error(`ReturningNode: projection child ${i + 1} must be a ScalarPlanNode`);
|
|
166
176
|
}
|
|
167
177
|
}
|
|
168
178
|
|
|
169
179
|
// Check if anything changed
|
|
170
|
-
const
|
|
171
|
-
|
|
180
|
+
const executorChanged = newExecutor !== this.executor;
|
|
181
|
+
const projectionsChanged = newProjectionNodes.some((child, i) => child !== this.projections[i].node);
|
|
182
|
+
|
|
183
|
+
if (!executorChanged && !projectionsChanged) {
|
|
172
184
|
return this;
|
|
173
185
|
}
|
|
174
186
|
|
|
@@ -177,7 +189,7 @@ export class ReturningNode extends PlanNode implements RelationalPlanNode {
|
|
|
177
189
|
|
|
178
190
|
// Create new projections with preserved attribute IDs
|
|
179
191
|
const newProjections = this.projections.map((proj, i) => ({
|
|
180
|
-
node:
|
|
192
|
+
node: newProjectionNodes[i] as ScalarPlanNode,
|
|
181
193
|
alias: proj.alias,
|
|
182
194
|
attributeId: originalAttributes[i].id // Preserve original attribute ID
|
|
183
195
|
}));
|
|
@@ -185,7 +197,7 @@ export class ReturningNode extends PlanNode implements RelationalPlanNode {
|
|
|
185
197
|
// Create new instance with preserved attributes
|
|
186
198
|
return new ReturningNode(
|
|
187
199
|
this.scope,
|
|
188
|
-
|
|
200
|
+
newExecutor as RelationalPlanNode,
|
|
189
201
|
newProjections,
|
|
190
202
|
originalAttributes // Pass original attributes to preserve IDs
|
|
191
203
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ScalarType } from "../../common/datatype.js";
|
|
2
2
|
import { OutputValue, SqlDataType } from "../../common/types.js";
|
|
3
|
-
import { PlanNode, type ScalarPlanNode, type UnaryScalarNode, type NaryScalarNode, type ZeroAryScalarNode, type BinaryScalarNode, PhysicalProperties, type ConstantNode } from "./plan-node.js";
|
|
3
|
+
import { PlanNode, type ScalarPlanNode, type UnaryScalarNode, type NaryScalarNode, type ZeroAryScalarNode, type BinaryScalarNode, PhysicalProperties, type ConstantNode, type TernaryScalarNode } from "./plan-node.js";
|
|
4
4
|
import type * as AST from "../../parser/ast.js";
|
|
5
5
|
import type { Scope } from "../scopes/scope.js";
|
|
6
6
|
import { PlanNodeType } from "./plan-node-type.js";
|
|
@@ -150,7 +150,6 @@ export class BinaryOpNode extends PlanNode implements BinaryScalarNode {
|
|
|
150
150
|
case 'IS':
|
|
151
151
|
case 'IS NOT':
|
|
152
152
|
case 'IN':
|
|
153
|
-
case 'BETWEEN':
|
|
154
153
|
datatype = SqlDataType.INTEGER;
|
|
155
154
|
break;
|
|
156
155
|
case '||':
|
|
@@ -227,15 +226,28 @@ export class BinaryOpNode extends PlanNode implements BinaryScalarNode {
|
|
|
227
226
|
|
|
228
227
|
export class LiteralNode extends PlanNode implements ZeroAryScalarNode, ConstantNode {
|
|
229
228
|
readonly nodeType = PlanNodeType.Literal;
|
|
230
|
-
|
|
229
|
+
/**
|
|
230
|
+
* When constant folding replaces an expression with a literal, we still need to
|
|
231
|
+
* preserve the *type metadata* (affinity, collation, nullability, etc.).
|
|
232
|
+
*
|
|
233
|
+
* The optional `explicitType` allows the caller to override the
|
|
234
|
+
* automatically-derived type so that information (e.g. COLLATE NOCASE)
|
|
235
|
+
* survives the folding pass.
|
|
236
|
+
*/
|
|
231
237
|
constructor(
|
|
232
238
|
public readonly scope: Scope,
|
|
233
239
|
public readonly expression: AST.LiteralExpr,
|
|
240
|
+
private readonly explicitType?: ScalarType,
|
|
234
241
|
) {
|
|
235
242
|
super(scope, 0.001); // Minimal cost
|
|
236
243
|
}
|
|
237
244
|
|
|
238
245
|
getType(): ScalarType {
|
|
246
|
+
// If a caller supplied an explicit type (to preserve metadata such as
|
|
247
|
+
// collation) honour it verbatim.
|
|
248
|
+
if (this.explicitType) {
|
|
249
|
+
return this.explicitType;
|
|
250
|
+
}
|
|
239
251
|
const value = this.expression.value;
|
|
240
252
|
if (value === null) {
|
|
241
253
|
return {
|
|
@@ -667,7 +679,7 @@ export class CollateNode extends PlanNode implements UnaryScalarNode {
|
|
|
667
679
|
public readonly expression: AST.CollateExpr,
|
|
668
680
|
public readonly operand: ScalarPlanNode,
|
|
669
681
|
) {
|
|
670
|
-
super(scope, 0); //
|
|
682
|
+
super(scope, 0.001); // Minimal cost for COLLATE
|
|
671
683
|
this.cachedType = new Cached(this.generateType);
|
|
672
684
|
}
|
|
673
685
|
|
|
@@ -678,14 +690,9 @@ export class CollateNode extends PlanNode implements UnaryScalarNode {
|
|
|
678
690
|
generateType = (): ScalarType => {
|
|
679
691
|
const operandType = this.operand.getType();
|
|
680
692
|
|
|
681
|
-
// COLLATE preserves the operand type but changes the collation
|
|
682
693
|
return {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
nullable: operandType.nullable,
|
|
686
|
-
isReadOnly: operandType.isReadOnly,
|
|
687
|
-
datatype: operandType.datatype,
|
|
688
|
-
collationName: this.expression.collation.toUpperCase(),
|
|
694
|
+
...operandType,
|
|
695
|
+
collationName: this.expression.collation.toUpperCase()
|
|
689
696
|
};
|
|
690
697
|
}
|
|
691
698
|
|
|
@@ -734,3 +741,80 @@ export class CollateNode extends PlanNode implements UnaryScalarNode {
|
|
|
734
741
|
};
|
|
735
742
|
}
|
|
736
743
|
}
|
|
744
|
+
|
|
745
|
+
export class BetweenNode extends PlanNode implements TernaryScalarNode {
|
|
746
|
+
readonly nodeType = PlanNodeType.Between;
|
|
747
|
+
|
|
748
|
+
constructor(
|
|
749
|
+
public readonly scope: Scope,
|
|
750
|
+
public readonly expression: AST.BetweenExpr,
|
|
751
|
+
public readonly expr: ScalarPlanNode,
|
|
752
|
+
public readonly lower: ScalarPlanNode,
|
|
753
|
+
public readonly upper: ScalarPlanNode,
|
|
754
|
+
) {
|
|
755
|
+
super(scope, 0.03); // Cost for three comparisons
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
getType(): ScalarType {
|
|
759
|
+
// BETWEEN always returns INTEGER (0 or 1)
|
|
760
|
+
return {
|
|
761
|
+
typeClass: 'scalar',
|
|
762
|
+
affinity: SqlDataType.INTEGER,
|
|
763
|
+
nullable: false,
|
|
764
|
+
isReadOnly: true,
|
|
765
|
+
datatype: SqlDataType.INTEGER,
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
getChildren(): readonly [ScalarPlanNode, ScalarPlanNode, ScalarPlanNode] {
|
|
770
|
+
return [this.expr, this.lower, this.upper];
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
getRelations(): readonly [] {
|
|
774
|
+
return [];
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
withChildren(newChildren: readonly PlanNode[]): PlanNode {
|
|
778
|
+
if (newChildren.length !== 3) {
|
|
779
|
+
quereusError(`BetweenNode expects 3 children, got ${newChildren.length}`, StatusCode.INTERNAL);
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
const [newExpr, newLower, newUpper] = newChildren;
|
|
783
|
+
|
|
784
|
+
// Type check
|
|
785
|
+
for (const child of newChildren) {
|
|
786
|
+
if (!('expression' in child)) {
|
|
787
|
+
quereusError('BetweenNode: all children must be ScalarPlanNodes', StatusCode.INTERNAL);
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
// Return same instance if nothing changed
|
|
792
|
+
if (newExpr === this.expr && newLower === this.lower && newUpper === this.upper) {
|
|
793
|
+
return this;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// Create new instance
|
|
797
|
+
return new BetweenNode(
|
|
798
|
+
this.scope,
|
|
799
|
+
this.expression,
|
|
800
|
+
newExpr as ScalarPlanNode,
|
|
801
|
+
newLower as ScalarPlanNode,
|
|
802
|
+
newUpper as ScalarPlanNode
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
override toString(): string {
|
|
807
|
+
const notPrefix = this.expression.not ? 'NOT ' : '';
|
|
808
|
+
return `${formatExpression(this.expr)} ${notPrefix}BETWEEN ${formatExpression(this.lower)} AND ${formatExpression(this.upper)}`;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
override getLogicalAttributes(): Record<string, unknown> {
|
|
812
|
+
return {
|
|
813
|
+
expr: formatExpression(this.expr),
|
|
814
|
+
lower: formatExpression(this.lower),
|
|
815
|
+
upper: formatExpression(this.upper),
|
|
816
|
+
not: this.expression.not ?? false,
|
|
817
|
+
resultType: formatScalarType(this.getType())
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PlanNodeType } from './plan-node-type.js';
|
|
2
|
-
import { PlanNode, type Attribute, type RelationalPlanNode, type UnaryRelationalNode } from './plan-node.js';
|
|
2
|
+
import { isRelationalNode, PlanNode, type Attribute, type RelationalPlanNode, type UnaryRelationalNode } from './plan-node.js';
|
|
3
3
|
import type { RelationType } from '../../common/datatype.js';
|
|
4
4
|
import type { Scope } from '../scopes/scope.js';
|
|
5
5
|
import { Cached } from '../../util/cached.js';
|
|
@@ -79,7 +79,7 @@ export class SequencingNode extends PlanNode implements UnaryRelationalNode {
|
|
|
79
79
|
const [newSource] = newChildren;
|
|
80
80
|
|
|
81
81
|
// Type check
|
|
82
|
-
if (!(
|
|
82
|
+
if (!isRelationalNode(newSource)) {
|
|
83
83
|
throw new Error('SequencingNode: child must be a RelationalPlanNode');
|
|
84
84
|
}
|
|
85
85
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PlanNode } from './plan-node.js';
|
|
1
|
+
import { isRelationalNode, PlanNode } from './plan-node.js';
|
|
2
2
|
import type { RelationalPlanNode, Attribute, BinaryRelationalNode } from './plan-node.js';
|
|
3
3
|
import type { RelationType } from '../../common/datatype.js';
|
|
4
4
|
import { PlanNodeType } from './plan-node-type.js';
|
|
@@ -60,10 +60,10 @@ export class SetOperationNode extends PlanNode implements BinaryRelationalNode {
|
|
|
60
60
|
const [newLeft, newRight] = newChildren;
|
|
61
61
|
|
|
62
62
|
// Type check
|
|
63
|
-
if (!(
|
|
63
|
+
if (!isRelationalNode(newLeft)) {
|
|
64
64
|
quereusError('SetOperationNode: first child must be a RelationalPlanNode', StatusCode.INTERNAL);
|
|
65
65
|
}
|
|
66
|
-
if (!(
|
|
66
|
+
if (!isRelationalNode(newRight)) {
|
|
67
67
|
quereusError('SetOperationNode: second child must be a RelationalPlanNode', StatusCode.INTERNAL);
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { PlanNodeType } from './plan-node-type.js';
|
|
2
|
-
import { PlanNode, type ZeroAryRelationalNode, type Attribute, PhysicalProperties } from './plan-node.js';
|
|
2
|
+
import { PlanNode, type ZeroAryRelationalNode, type Attribute, PhysicalProperties, type ConstantNode } from './plan-node.js';
|
|
3
3
|
import type { RelationType } from '../../common/datatype.js';
|
|
4
4
|
import { EmptyScope } from '../scopes/empty.js';
|
|
5
5
|
import type { Scope } from '../scopes/scope.js';
|
|
6
|
+
import type { Row } from '../../common/types.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* A dummy relational node that produces a single row with no columns.
|
|
9
10
|
* Used as a source for SELECT statements without a FROM clause.
|
|
10
11
|
*/
|
|
11
|
-
export class SingleRowNode extends PlanNode implements ZeroAryRelationalNode {
|
|
12
|
+
export class SingleRowNode extends PlanNode implements ZeroAryRelationalNode, ConstantNode {
|
|
12
13
|
override readonly nodeType = PlanNodeType.SingleRow;
|
|
13
14
|
|
|
14
15
|
private static readonly singleInstance = new SingleRowNode(EmptyScope.instance); // HACK: null scope for singleton
|
|
@@ -77,4 +78,8 @@ export class SingleRowNode extends PlanNode implements ZeroAryRelationalNode {
|
|
|
77
78
|
constant: true,
|
|
78
79
|
};
|
|
79
80
|
}
|
|
81
|
+
|
|
82
|
+
async *getValue(): AsyncIterable<Row> {
|
|
83
|
+
yield [];
|
|
84
|
+
}
|
|
80
85
|
}
|
|
@@ -30,15 +30,15 @@ export class SinkNode extends PlanNode {
|
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
getChildren(): readonly
|
|
34
|
-
return [];
|
|
33
|
+
getChildren(): readonly [RelationalPlanNode] {
|
|
34
|
+
return [this.source];
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
withChildren(newChildren: readonly PlanNode[]): PlanNode {
|
|
38
|
-
if (newChildren.length !==
|
|
39
|
-
throw new Error(`SinkNode expects
|
|
38
|
+
if (newChildren.length !== 1) {
|
|
39
|
+
throw new Error(`SinkNode expects 1 child, got ${newChildren.length}`);
|
|
40
40
|
}
|
|
41
|
-
return
|
|
41
|
+
return new SinkNode(this.scope, newChildren[0] as RelationalPlanNode, this.operation);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
getRelations(): readonly [RelationalPlanNode] {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PlanNodeType } from './plan-node-type.js';
|
|
2
|
-
import { PlanNode, type RelationalPlanNode, type ScalarPlanNode, type UnaryRelationalNode, type PhysicalProperties, type Attribute } from './plan-node.js';
|
|
2
|
+
import { PlanNode, type RelationalPlanNode, type ScalarPlanNode, type UnaryRelationalNode, type PhysicalProperties, type Attribute, isRelationalNode } from './plan-node.js';
|
|
3
3
|
import type { RelationType } from '../../common/datatype.js';
|
|
4
4
|
import type { Scope } from '../scopes/scope.js';
|
|
5
5
|
import { formatSortKey } from '../../util/plan-formatter.js';
|
|
@@ -108,7 +108,7 @@ export class SortNode extends PlanNode implements UnaryRelationalNode {
|
|
|
108
108
|
const [newSource, ...newSortExpressions] = newChildren;
|
|
109
109
|
|
|
110
110
|
// Type check
|
|
111
|
-
if (!(
|
|
111
|
+
if (!isRelationalNode(newSource)) {
|
|
112
112
|
quereusError('SortNode: first child must be a RelationalPlanNode', StatusCode.INTERNAL);
|
|
113
113
|
}
|
|
114
114
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PlanNodeType } from './plan-node-type.js';
|
|
2
|
-
import { PlanNode, type RelationalPlanNode, type UnaryRelationalNode, type ScalarPlanNode, type PhysicalProperties, type Attribute } from './plan-node.js';
|
|
2
|
+
import { PlanNode, type RelationalPlanNode, type UnaryRelationalNode, type ScalarPlanNode, type PhysicalProperties, type Attribute, isRelationalNode } from './plan-node.js';
|
|
3
3
|
import type { RelationType } from '../../common/datatype.js';
|
|
4
4
|
import type { Scope } from '../scopes/scope.js';
|
|
5
5
|
import { Cached } from '../../util/cached.js';
|
|
@@ -31,15 +31,19 @@ export class StreamAggregateNode extends PlanNode implements UnaryRelationalNode
|
|
|
31
31
|
|
|
32
32
|
super(scope, estimatedCostOverride ?? (source.getTotalCost() + streamingCost));
|
|
33
33
|
|
|
34
|
+
|
|
35
|
+
|
|
34
36
|
this.attributesCache = new Cached(() => this.buildAttributes());
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
|
|
38
|
-
// If we have preserved attribute IDs, use them
|
|
39
|
+
private buildAttributes(): Attribute[] {
|
|
40
|
+
// If we have preserved attribute IDs, use them directly
|
|
41
|
+
// The optimizer rule now passes both aggregate AND source attributes
|
|
39
42
|
if (this.preserveAttributeIds) {
|
|
40
|
-
return this.preserveAttributeIds.slice();
|
|
43
|
+
return this.preserveAttributeIds.slice();
|
|
41
44
|
}
|
|
42
45
|
|
|
46
|
+
// Fallback: build attributes from scratch (used when not created via optimizer)
|
|
43
47
|
const attributes: Attribute[] = [];
|
|
44
48
|
|
|
45
49
|
// Group by columns come first
|
|
@@ -63,6 +67,18 @@ export class StreamAggregateNode extends PlanNode implements UnaryRelationalNode
|
|
|
63
67
|
});
|
|
64
68
|
});
|
|
65
69
|
|
|
70
|
+
// Add source attributes to support HAVING clauses
|
|
71
|
+
const sourceAttributes = this.source.getAttributes();
|
|
72
|
+
const existingAttrNames = new Set(attributes.map(attr => attr.name));
|
|
73
|
+
|
|
74
|
+
for (const sourceAttr of sourceAttributes) {
|
|
75
|
+
// Only add if not already present by name (avoid duplicates for GROUP BY columns)
|
|
76
|
+
if (!existingAttrNames.has(sourceAttr.name)) {
|
|
77
|
+
attributes.push(sourceAttr);
|
|
78
|
+
existingAttrNames.add(sourceAttr.name);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
66
82
|
return attributes;
|
|
67
83
|
}
|
|
68
84
|
|
|
@@ -78,21 +94,44 @@ export class StreamAggregateNode extends PlanNode implements UnaryRelationalNode
|
|
|
78
94
|
}
|
|
79
95
|
|
|
80
96
|
getType(): RelationType {
|
|
81
|
-
|
|
82
|
-
|
|
97
|
+
const columns = [];
|
|
98
|
+
|
|
99
|
+
// Start with preserved attributes if we have them, otherwise build GROUP BY + aggregates
|
|
100
|
+
if (this.preserveAttributeIds) {
|
|
101
|
+
// Use preserved attributes to match getAttributes() exactly
|
|
102
|
+
for (const attr of this.preserveAttributeIds) {
|
|
103
|
+
columns.push({
|
|
104
|
+
name: attr.name,
|
|
105
|
+
type: attr.type,
|
|
106
|
+
generated: false // Source attributes are not generated
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
83
110
|
// Group by columns come first
|
|
84
|
-
...this.groupBy.map((expr, index) => ({
|
|
111
|
+
columns.push(...this.groupBy.map((expr, index) => ({
|
|
85
112
|
name: this.getGroupByColumnName(expr, index),
|
|
86
113
|
type: expr.getType(),
|
|
87
114
|
generated: false
|
|
88
|
-
}))
|
|
115
|
+
})));
|
|
116
|
+
|
|
89
117
|
// Then aggregate columns
|
|
90
|
-
...this.aggregates.map(agg => ({
|
|
118
|
+
columns.push(...this.aggregates.map(agg => ({
|
|
91
119
|
name: agg.alias,
|
|
92
120
|
type: agg.expression.getType(),
|
|
93
121
|
generated: true
|
|
94
|
-
}))
|
|
95
|
-
|
|
122
|
+
})));
|
|
123
|
+
|
|
124
|
+
// Add all source columns to support HAVING clauses (consistent with getAttributes())
|
|
125
|
+
const sourceType = this.source.getType();
|
|
126
|
+
const existingNames = new Set(columns.map(col => col.name));
|
|
127
|
+
|
|
128
|
+
for (const sourceCol of sourceType.columns) {
|
|
129
|
+
// Only add if not already present (avoid duplicates for GROUP BY columns)
|
|
130
|
+
if (!existingNames.has(sourceCol.name)) {
|
|
131
|
+
columns.push(sourceCol);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
96
135
|
|
|
97
136
|
return {
|
|
98
137
|
typeClass: 'relation',
|
|
@@ -109,6 +148,31 @@ export class StreamAggregateNode extends PlanNode implements UnaryRelationalNode
|
|
|
109
148
|
return this.attributesCache.value;
|
|
110
149
|
}
|
|
111
150
|
|
|
151
|
+
getProducingExprs(): Map<number, ScalarPlanNode> {
|
|
152
|
+
const attributes = this.getAttributes();
|
|
153
|
+
const map = new Map<number, ScalarPlanNode>();
|
|
154
|
+
|
|
155
|
+
// Map GROUP BY expressions to their attribute IDs
|
|
156
|
+
for (let i = 0; i < this.groupBy.length; i++) {
|
|
157
|
+
const expr = this.groupBy[i];
|
|
158
|
+
const attr = attributes[i];
|
|
159
|
+
if (attr) {
|
|
160
|
+
map.set(attr.id, expr);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Map aggregate expressions to their attribute IDs
|
|
165
|
+
for (let i = 0; i < this.aggregates.length; i++) {
|
|
166
|
+
const agg = this.aggregates[i];
|
|
167
|
+
const attr = attributes[this.groupBy.length + i]; // Aggregates come after GROUP BY
|
|
168
|
+
if (attr) {
|
|
169
|
+
map.set(attr.id, agg.expression);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return map;
|
|
174
|
+
}
|
|
175
|
+
|
|
112
176
|
getChildren(): readonly PlanNode[] {
|
|
113
177
|
return [this.source, ...this.groupBy, ...this.aggregates.map(agg => agg.expression)];
|
|
114
178
|
}
|
|
@@ -193,7 +257,7 @@ export class StreamAggregateNode extends PlanNode implements UnaryRelationalNode
|
|
|
193
257
|
const newAggregateExpressions = restChildren.slice(this.groupBy.length);
|
|
194
258
|
|
|
195
259
|
// Type check
|
|
196
|
-
if (!(
|
|
260
|
+
if (!isRelationalNode(newSource)) {
|
|
197
261
|
quereusError('StreamAggregateNode: first child must be a RelationalPlanNode', StatusCode.INTERNAL);
|
|
198
262
|
}
|
|
199
263
|
|
|
@@ -7,6 +7,8 @@ import type { Scope } from "../scopes/scope.js";
|
|
|
7
7
|
import { compareSqlValues } from "../../util/comparison.js";
|
|
8
8
|
import type { Expression } from "../../parser/ast.js";
|
|
9
9
|
import { formatExpression, formatScalarType } from "../../util/plan-formatter.js";
|
|
10
|
+
import { quereusError } from "../../common/errors.js";
|
|
11
|
+
import { StatusCode } from "../../common/types.js";
|
|
10
12
|
|
|
11
13
|
export class ScalarSubqueryNode extends PlanNode implements ScalarPlanNode {
|
|
12
14
|
override readonly nodeType = PlanNodeType.ScalarSubquery;
|
|
@@ -36,8 +38,9 @@ export class ScalarSubqueryNode extends PlanNode implements ScalarPlanNode {
|
|
|
36
38
|
};
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
getChildren(): readonly [] {
|
|
40
|
-
|
|
41
|
+
getChildren(): readonly PlanNode[] {
|
|
42
|
+
// Include the subquery so the optimizer can visit it
|
|
43
|
+
return [this.subquery];
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
getRelations(): readonly [RelationalPlanNode] {
|
|
@@ -45,10 +48,28 @@ export class ScalarSubqueryNode extends PlanNode implements ScalarPlanNode {
|
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
withChildren(newChildren: readonly PlanNode[]): PlanNode {
|
|
48
|
-
if (newChildren.length !==
|
|
49
|
-
|
|
51
|
+
if (newChildren.length !== 1) {
|
|
52
|
+
quereusError(`ScalarSubqueryNode expects 1 child, got ${newChildren.length}`, StatusCode.INTERNAL);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const [newSubquery] = newChildren;
|
|
56
|
+
|
|
57
|
+
// Type check
|
|
58
|
+
if (newSubquery.getType().typeClass !== 'relation') {
|
|
59
|
+
quereusError('ScalarSubqueryNode: child must be a RelationalPlanNode', StatusCode.INTERNAL);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Check if anything changed
|
|
63
|
+
if (newSubquery === this.subquery) {
|
|
64
|
+
return this;
|
|
50
65
|
}
|
|
51
|
-
|
|
66
|
+
|
|
67
|
+
// Create new instance
|
|
68
|
+
return new ScalarSubqueryNode(
|
|
69
|
+
this.scope,
|
|
70
|
+
this.expression,
|
|
71
|
+
newSubquery as RelationalPlanNode
|
|
72
|
+
);
|
|
52
73
|
}
|
|
53
74
|
|
|
54
75
|
override toString(): string {
|
|
@@ -89,11 +110,16 @@ export class InNode extends PlanNode implements ScalarPlanNode {
|
|
|
89
110
|
}
|
|
90
111
|
}
|
|
91
112
|
|
|
92
|
-
getChildren(): readonly
|
|
113
|
+
getChildren(): readonly PlanNode[] {
|
|
114
|
+
// Include condition, values (if any), and source subquery (if any)
|
|
115
|
+
const children: PlanNode[] = [this.condition];
|
|
93
116
|
if (this.values) {
|
|
94
|
-
|
|
117
|
+
children.push(...this.values);
|
|
95
118
|
}
|
|
96
|
-
|
|
119
|
+
if (this.source) {
|
|
120
|
+
children.push(this.source);
|
|
121
|
+
}
|
|
122
|
+
return children;
|
|
97
123
|
}
|
|
98
124
|
|
|
99
125
|
getRelations(): readonly RelationalPlanNode[] {
|
|
@@ -104,29 +130,47 @@ export class InNode extends PlanNode implements ScalarPlanNode {
|
|
|
104
130
|
}
|
|
105
131
|
|
|
106
132
|
withChildren(newChildren: readonly PlanNode[]): PlanNode {
|
|
107
|
-
const expectedLength = this.values
|
|
133
|
+
const expectedLength = 1 + (this.values?.length ?? 0) + (this.source ? 1 : 0);
|
|
108
134
|
if (newChildren.length !== expectedLength) {
|
|
109
|
-
|
|
135
|
+
quereusError(`InNode expects ${expectedLength} children, got ${newChildren.length}`, StatusCode.INTERNAL);
|
|
110
136
|
}
|
|
111
137
|
|
|
112
|
-
|
|
138
|
+
let childIndex = 0;
|
|
139
|
+
const newCondition = newChildren[childIndex++];
|
|
113
140
|
|
|
114
|
-
// Type check
|
|
115
|
-
if (
|
|
116
|
-
|
|
141
|
+
// Type check condition
|
|
142
|
+
if (newCondition.getType().typeClass !== 'scalar') {
|
|
143
|
+
quereusError('InNode: condition must be a ScalarPlanNode', StatusCode.INTERNAL);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Extract new values if they exist
|
|
147
|
+
let newValues: ScalarPlanNode[] | undefined;
|
|
148
|
+
if (this.values) {
|
|
149
|
+
newValues = [];
|
|
150
|
+
for (let i = 0; i < this.values.length; i++) {
|
|
151
|
+
const value = newChildren[childIndex++];
|
|
152
|
+
if (value.getType().typeClass !== 'scalar') {
|
|
153
|
+
quereusError('InNode: values must be ScalarPlanNodes', StatusCode.INTERNAL);
|
|
154
|
+
}
|
|
155
|
+
newValues.push(value as ScalarPlanNode);
|
|
156
|
+
}
|
|
117
157
|
}
|
|
118
158
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
159
|
+
// Extract new source if it exists
|
|
160
|
+
let newSource: RelationalPlanNode | undefined;
|
|
161
|
+
if (this.source) {
|
|
162
|
+
newSource = newChildren[childIndex++] as RelationalPlanNode;
|
|
163
|
+
if (newSource.getType().typeClass !== 'relation') {
|
|
164
|
+
quereusError('InNode: source must be a RelationalPlanNode', StatusCode.INTERNAL);
|
|
122
165
|
}
|
|
123
166
|
}
|
|
124
167
|
|
|
125
168
|
// Check if anything changed
|
|
126
169
|
const conditionChanged = newCondition !== this.condition;
|
|
127
|
-
const valuesChanged = this.values && newValues.some((val, i) => val !== this.values![i]);
|
|
170
|
+
const valuesChanged = this.values && newValues && newValues.some((val, i) => val !== this.values![i]);
|
|
171
|
+
const sourceChanged = newSource !== this.source;
|
|
128
172
|
|
|
129
|
-
if (!conditionChanged && !valuesChanged) {
|
|
173
|
+
if (!conditionChanged && !valuesChanged && !sourceChanged) {
|
|
130
174
|
return this;
|
|
131
175
|
}
|
|
132
176
|
|
|
@@ -135,8 +179,8 @@ export class InNode extends PlanNode implements ScalarPlanNode {
|
|
|
135
179
|
this.scope,
|
|
136
180
|
this.expression,
|
|
137
181
|
newCondition as ScalarPlanNode,
|
|
138
|
-
|
|
139
|
-
|
|
182
|
+
newSource,
|
|
183
|
+
newValues
|
|
140
184
|
);
|
|
141
185
|
}
|
|
142
186
|
|
|
@@ -179,19 +223,38 @@ export class ExistsNode extends PlanNode implements ScalarPlanNode {
|
|
|
179
223
|
};
|
|
180
224
|
}
|
|
181
225
|
|
|
182
|
-
getChildren(): readonly [] {
|
|
183
|
-
|
|
226
|
+
getChildren(): readonly PlanNode[] {
|
|
227
|
+
// Include the subquery so the optimizer can visit it
|
|
228
|
+
return [this.subquery];
|
|
184
229
|
}
|
|
185
230
|
|
|
186
|
-
getRelations(): readonly [
|
|
231
|
+
getRelations(): readonly RelationalPlanNode[] {
|
|
187
232
|
return [this.subquery];
|
|
188
233
|
}
|
|
189
234
|
|
|
190
235
|
withChildren(newChildren: readonly PlanNode[]): PlanNode {
|
|
191
|
-
if (newChildren.length !==
|
|
192
|
-
|
|
236
|
+
if (newChildren.length !== 1) {
|
|
237
|
+
quereusError(`ExistsNode expects 1 child, got ${newChildren.length}`, StatusCode.INTERNAL);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const [newSubquery] = newChildren;
|
|
241
|
+
|
|
242
|
+
// Type check
|
|
243
|
+
if (newSubquery.getType().typeClass !== 'relation') {
|
|
244
|
+
quereusError('ExistsNode: child must be a RelationalPlanNode', StatusCode.INTERNAL);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Check if anything changed
|
|
248
|
+
if (newSubquery === this.subquery) {
|
|
249
|
+
return this;
|
|
193
250
|
}
|
|
194
|
-
|
|
251
|
+
|
|
252
|
+
// Create new instance
|
|
253
|
+
return new ExistsNode(
|
|
254
|
+
this.scope,
|
|
255
|
+
this.expression,
|
|
256
|
+
newSubquery as RelationalPlanNode
|
|
257
|
+
);
|
|
195
258
|
}
|
|
196
259
|
|
|
197
260
|
override toString(): string {
|