@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,6 +1,6 @@
|
|
|
1
1
|
import type { WindowNode } from '../../planner/nodes/window-node.js';
|
|
2
2
|
import type { Instruction, RuntimeContext } from '../types.js';
|
|
3
|
-
import type { Row, SqlValue } from '../../common/types.js';
|
|
3
|
+
import type { OutputValue, Row, SqlValue } from '../../common/types.js';
|
|
4
4
|
import type { EmissionContext } from '../emission-context.js';
|
|
5
5
|
import { emitPlanNode, emitCallFromPlan } from '../emitters.js';
|
|
6
6
|
import { resolveWindowFunction } from '../../schema/window-function.js';
|
|
@@ -10,6 +10,7 @@ import { compareSqlValues, createOrderByComparatorFast, resolveCollation } from
|
|
|
10
10
|
import { createLogger } from '../../common/logger.js';
|
|
11
11
|
import { buildRowDescriptor } from '../../util/row-descriptor.js';
|
|
12
12
|
import { RowDescriptor } from '../../planner/nodes/plan-node.js';
|
|
13
|
+
import { withRowContext, withAsyncRowContext } from '../context-helpers.js';
|
|
13
14
|
|
|
14
15
|
const log = createLogger('runtime:emit:window');
|
|
15
16
|
|
|
@@ -45,7 +46,7 @@ export function emitWindow(plan: WindowNode, ctx: EmissionContext): Instruction
|
|
|
45
46
|
async function* run(
|
|
46
47
|
rctx: RuntimeContext,
|
|
47
48
|
source: AsyncIterable<Row>,
|
|
48
|
-
...callbacks: Array<(ctx: RuntimeContext) =>
|
|
49
|
+
...callbacks: Array<(ctx: RuntimeContext) => OutputValue>
|
|
49
50
|
): AsyncIterable<Row> {
|
|
50
51
|
log('Starting window function execution');
|
|
51
52
|
|
|
@@ -113,23 +114,22 @@ async function groupByPartitions(
|
|
|
113
114
|
const partitions = new Map<string, Row[]>();
|
|
114
115
|
|
|
115
116
|
for (const row of rows) {
|
|
116
|
-
rctx
|
|
117
|
-
try {
|
|
117
|
+
const partitionKey = await withAsyncRowContext(rctx, sourceRowDescriptor, () => row, async () => {
|
|
118
118
|
// Evaluate partition expressions
|
|
119
|
-
const partitionValues = partitionCallbacks.map(callback =>
|
|
119
|
+
const partitionValues = await Promise.all(partitionCallbacks.map(callback =>
|
|
120
|
+
callback(rctx)
|
|
121
|
+
));
|
|
120
122
|
|
|
121
123
|
// Create partition key
|
|
122
|
-
|
|
124
|
+
return partitionValues.map(val =>
|
|
123
125
|
val === null ? 'NULL' : String(val)
|
|
124
126
|
).join('|');
|
|
127
|
+
});
|
|
125
128
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
partitions.get(partitionKey)!.push(row);
|
|
130
|
-
} finally {
|
|
131
|
-
rctx.context.delete(sourceRowDescriptor);
|
|
129
|
+
if (!partitions.has(partitionKey)) {
|
|
130
|
+
partitions.set(partitionKey, []);
|
|
132
131
|
}
|
|
132
|
+
partitions.get(partitionKey)!.push(row);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
return partitions;
|
|
@@ -142,9 +142,9 @@ async function* processPartition(
|
|
|
142
142
|
rctx: RuntimeContext,
|
|
143
143
|
sourceRowDescriptor: RowDescriptor,
|
|
144
144
|
outputRowDescriptor: RowDescriptor,
|
|
145
|
-
partitionCallbacks: Array<(ctx: RuntimeContext) =>
|
|
146
|
-
orderByCallbacks: Array<(ctx: RuntimeContext) =>
|
|
147
|
-
funcArgCallbacks: Array<(
|
|
145
|
+
partitionCallbacks: Array<(ctx: RuntimeContext) => OutputValue>,
|
|
146
|
+
orderByCallbacks: Array<(ctx: RuntimeContext) => OutputValue>,
|
|
147
|
+
funcArgCallbacks: Array<(ctx: RuntimeContext) => OutputValue | null>
|
|
148
148
|
): AsyncIterable<Row> {
|
|
149
149
|
// Sort rows according to ORDER BY specification
|
|
150
150
|
const sortedRows = await sortRows(
|
|
@@ -158,8 +158,8 @@ async function* processPartition(
|
|
|
158
158
|
const outputRow = [...currentRow];
|
|
159
159
|
|
|
160
160
|
// Set up context for current row
|
|
161
|
-
rctx
|
|
162
|
-
|
|
161
|
+
const outputValues = await withRowContext(rctx, sourceRowDescriptor, () => currentRow, async () => {
|
|
162
|
+
const values: SqlValue[] = [];
|
|
163
163
|
// Compute each window function
|
|
164
164
|
for (let funcIndex = 0; funcIndex < plan.functions.length; funcIndex++) {
|
|
165
165
|
const func = plan.functions[funcIndex];
|
|
@@ -169,7 +169,7 @@ async function* processPartition(
|
|
|
169
169
|
let value: SqlValue;
|
|
170
170
|
|
|
171
171
|
if (schema.kind === 'ranking') {
|
|
172
|
-
value = computeRankingFunction(
|
|
172
|
+
value = await computeRankingFunction(
|
|
173
173
|
func.functionName, sortedRows, currentIndex,
|
|
174
174
|
orderByCallbacks, rctx, sourceRowDescriptor
|
|
175
175
|
);
|
|
@@ -186,26 +186,23 @@ async function* processPartition(
|
|
|
186
186
|
);
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
values.push(value);
|
|
190
190
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
return values;
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// Add computed values to output row
|
|
195
|
+
outputRow.push(...outputValues);
|
|
194
196
|
|
|
195
197
|
// Yield the output row
|
|
196
|
-
rctx
|
|
197
|
-
try {
|
|
198
|
-
yield outputRow as Row;
|
|
199
|
-
} finally {
|
|
200
|
-
rctx.context.delete(outputRowDescriptor);
|
|
201
|
-
}
|
|
198
|
+
yield await withRowContext(rctx, outputRowDescriptor, () => outputRow as Row, () => outputRow as Row);
|
|
202
199
|
}
|
|
203
200
|
}
|
|
204
201
|
|
|
205
202
|
async function sortRows(
|
|
206
203
|
rows: Row[],
|
|
207
204
|
orderBy: any[],
|
|
208
|
-
orderByCallbacks: Array<(ctx: RuntimeContext) =>
|
|
205
|
+
orderByCallbacks: Array<(ctx: RuntimeContext) => OutputValue>,
|
|
209
206
|
rctx: RuntimeContext,
|
|
210
207
|
sourceRowDescriptor: RowDescriptor
|
|
211
208
|
): Promise<Row[]> {
|
|
@@ -220,34 +217,29 @@ async function sortRows(
|
|
|
220
217
|
const collationFunc = resolveCollation('BINARY');
|
|
221
218
|
return createOrderByComparatorFast(
|
|
222
219
|
orderClause.direction,
|
|
223
|
-
|
|
220
|
+
orderClause.nulls,
|
|
224
221
|
collationFunc
|
|
225
222
|
);
|
|
226
223
|
});
|
|
227
224
|
|
|
228
|
-
|
|
225
|
+
// Pre-evaluate ORDER BY values for all rows to avoid async in sort
|
|
226
|
+
const rowsWithValues = await Promise.all(rows.map(async (row) => {
|
|
227
|
+
const values = await Promise.all(orderByCallbacks.map(async (callback) => {
|
|
228
|
+
return await withAsyncRowContext(rctx, sourceRowDescriptor, () => row, async () => {
|
|
229
|
+
const result = callback(rctx);
|
|
230
|
+
return await Promise.resolve(result);
|
|
231
|
+
});
|
|
232
|
+
}));
|
|
233
|
+
return { row, values };
|
|
234
|
+
}));
|
|
235
|
+
|
|
236
|
+
// Now sort using the pre-evaluated values
|
|
237
|
+
rowsWithValues.sort((a, b) => {
|
|
229
238
|
// Compare each ORDER BY expression in sequence
|
|
230
239
|
for (let i = 0; i < orderBy.length; i++) {
|
|
231
|
-
const callback = orderByCallbacks[i];
|
|
232
240
|
const comparator = orderByComparators[i];
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
rctx.context.set(sourceRowDescriptor, () => a);
|
|
236
|
-
let valueA: SqlValue;
|
|
237
|
-
try {
|
|
238
|
-
valueA = callback(rctx);
|
|
239
|
-
} finally {
|
|
240
|
-
rctx.context.delete(sourceRowDescriptor);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Evaluate expression for row B
|
|
244
|
-
rctx.context.set(sourceRowDescriptor, () => b);
|
|
245
|
-
let valueB: SqlValue;
|
|
246
|
-
try {
|
|
247
|
-
valueB = callback(rctx);
|
|
248
|
-
} finally {
|
|
249
|
-
rctx.context.delete(sourceRowDescriptor);
|
|
250
|
-
}
|
|
241
|
+
const valueA = a.values[i] as SqlValue;
|
|
242
|
+
const valueB = b.values[i] as SqlValue;
|
|
251
243
|
|
|
252
244
|
// Use pre-created optimized comparator
|
|
253
245
|
const comparison = comparator(valueA, valueB);
|
|
@@ -262,16 +254,19 @@ async function sortRows(
|
|
|
262
254
|
|
|
263
255
|
return 0; // All ORDER BY expressions are equal
|
|
264
256
|
});
|
|
257
|
+
|
|
258
|
+
// Extract just the rows in sorted order
|
|
259
|
+
return rowsWithValues.map(item => item.row);
|
|
265
260
|
}
|
|
266
261
|
|
|
267
|
-
function computeRankingFunction(
|
|
262
|
+
async function computeRankingFunction(
|
|
268
263
|
functionName: string,
|
|
269
264
|
sortedRows: Row[],
|
|
270
265
|
currentIndex: number,
|
|
271
266
|
orderByCallbacks: Array<(ctx: RuntimeContext) => any>,
|
|
272
267
|
rctx: RuntimeContext,
|
|
273
268
|
sourceRowDescriptor: RowDescriptor
|
|
274
|
-
): number {
|
|
269
|
+
): Promise<number> {
|
|
275
270
|
switch (functionName.toLowerCase()) {
|
|
276
271
|
case 'row_number':
|
|
277
272
|
return currentIndex + 1;
|
|
@@ -283,9 +278,9 @@ function computeRankingFunction(
|
|
|
283
278
|
|
|
284
279
|
for (let i = 0; i < currentIndex; i++) {
|
|
285
280
|
const prevRow = sortedRows[i];
|
|
286
|
-
if (!areRowsEqualInOrderBy(
|
|
281
|
+
if (!(await areRowsEqualInOrderBy(
|
|
287
282
|
prevRow, currentRow, orderByCallbacks, rctx, sourceRowDescriptor
|
|
288
|
-
)) {
|
|
283
|
+
))) {
|
|
289
284
|
rank = i + 2; // Rank is 1-based and accounts for ties
|
|
290
285
|
}
|
|
291
286
|
}
|
|
@@ -300,11 +295,11 @@ function computeRankingFunction(
|
|
|
300
295
|
|
|
301
296
|
for (let i = 0; i < currentIndex; i++) {
|
|
302
297
|
const prevRow = sortedRows[i];
|
|
303
|
-
if (!areRowsEqualInOrderBy(
|
|
298
|
+
if (!(await areRowsEqualInOrderBy(
|
|
304
299
|
prevRow, currentRow, orderByCallbacks, rctx, sourceRowDescriptor
|
|
305
|
-
)) {
|
|
300
|
+
))) {
|
|
306
301
|
// Create a key for this distinct set of ORDER BY values
|
|
307
|
-
const key = getOrderByKey(prevRow, orderByCallbacks, rctx, sourceRowDescriptor);
|
|
302
|
+
const key = await getOrderByKey(prevRow, orderByCallbacks, rctx, sourceRowDescriptor);
|
|
308
303
|
if (!seenValues.has(key)) {
|
|
309
304
|
seenValues.add(key);
|
|
310
305
|
denseRank++;
|
|
@@ -335,20 +330,20 @@ async function computeAggregateFunction(
|
|
|
335
330
|
// Determine frame bounds
|
|
336
331
|
const frameBounds = getFrameBounds(frame, sortedRows.length, currentIndex, hasOrderBy);
|
|
337
332
|
|
|
338
|
-
let accumulator = null;
|
|
333
|
+
let accumulator: any = null;
|
|
339
334
|
let rowCount = 0;
|
|
340
335
|
|
|
341
336
|
// Process rows within the frame
|
|
342
337
|
for (let i = frameBounds.start; i <= frameBounds.end; i++) {
|
|
343
338
|
const frameRow = sortedRows[i];
|
|
344
339
|
|
|
345
|
-
rctx
|
|
346
|
-
try {
|
|
340
|
+
await withAsyncRowContext(rctx, sourceRowDescriptor, () => frameRow, async () => {
|
|
347
341
|
let argValue: SqlValue = null;
|
|
348
342
|
|
|
349
343
|
// Get argument value if callback exists
|
|
350
344
|
if (argCallback) {
|
|
351
|
-
|
|
345
|
+
const result = argCallback(rctx);
|
|
346
|
+
argValue = await Promise.resolve(result);
|
|
352
347
|
}
|
|
353
348
|
|
|
354
349
|
// Apply aggregate step function
|
|
@@ -356,9 +351,7 @@ async function computeAggregateFunction(
|
|
|
356
351
|
accumulator = schema.step(accumulator, argValue);
|
|
357
352
|
rowCount++;
|
|
358
353
|
}
|
|
359
|
-
}
|
|
360
|
-
rctx.context.delete(sourceRowDescriptor);
|
|
361
|
-
}
|
|
354
|
+
});
|
|
362
355
|
}
|
|
363
356
|
|
|
364
357
|
// Apply final function
|
|
@@ -421,31 +414,25 @@ function getFrameBounds(
|
|
|
421
414
|
return { start, end };
|
|
422
415
|
}
|
|
423
416
|
|
|
424
|
-
function areRowsEqualInOrderBy(
|
|
417
|
+
async function areRowsEqualInOrderBy(
|
|
425
418
|
rowA: Row,
|
|
426
419
|
rowB: Row,
|
|
427
420
|
orderByCallbacks: Array<(ctx: RuntimeContext) => any>,
|
|
428
421
|
rctx: RuntimeContext,
|
|
429
422
|
sourceRowDescriptor: RowDescriptor
|
|
430
|
-
): boolean {
|
|
423
|
+
): Promise<boolean> {
|
|
431
424
|
for (const callback of orderByCallbacks) {
|
|
432
425
|
// Get value for row A
|
|
433
|
-
rctx
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
} finally {
|
|
438
|
-
rctx.context.delete(sourceRowDescriptor);
|
|
439
|
-
}
|
|
426
|
+
const valueA = await withAsyncRowContext(rctx, sourceRowDescriptor, () => rowA, async () => {
|
|
427
|
+
const result = callback(rctx);
|
|
428
|
+
return await Promise.resolve(result);
|
|
429
|
+
});
|
|
440
430
|
|
|
441
431
|
// Get value for row B
|
|
442
|
-
rctx
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
} finally {
|
|
447
|
-
rctx.context.delete(sourceRowDescriptor);
|
|
448
|
-
}
|
|
432
|
+
const valueB = await withAsyncRowContext(rctx, sourceRowDescriptor, () => rowB, async () => {
|
|
433
|
+
const result = callback(rctx);
|
|
434
|
+
return await Promise.resolve(result);
|
|
435
|
+
});
|
|
449
436
|
|
|
450
437
|
// If any ORDER BY expression differs, rows are not equal
|
|
451
438
|
if (compareSqlValues(valueA, valueB) !== 0) {
|
|
@@ -456,17 +443,16 @@ function areRowsEqualInOrderBy(
|
|
|
456
443
|
return true; // All ORDER BY expressions are equal
|
|
457
444
|
}
|
|
458
445
|
|
|
459
|
-
function getOrderByKey(
|
|
446
|
+
async function getOrderByKey(
|
|
460
447
|
row: Row,
|
|
461
448
|
orderByCallbacks: Array<(ctx: RuntimeContext) => any>,
|
|
462
449
|
rctx: RuntimeContext,
|
|
463
450
|
sourceRowDescriptor: RowDescriptor
|
|
464
|
-
): string {
|
|
465
|
-
rctx
|
|
466
|
-
|
|
467
|
-
|
|
451
|
+
): Promise<string> {
|
|
452
|
+
return await withAsyncRowContext(rctx, sourceRowDescriptor, () => row, async () => {
|
|
453
|
+
const values = await Promise.all(orderByCallbacks.map(callback =>
|
|
454
|
+
Promise.resolve(callback(rctx))
|
|
455
|
+
));
|
|
468
456
|
return values.map(val => val === null ? 'NULL' : String(val)).join('|');
|
|
469
|
-
}
|
|
470
|
-
rctx.context.delete(sourceRowDescriptor);
|
|
471
|
-
}
|
|
457
|
+
});
|
|
472
458
|
}
|
package/src/runtime/emitters.ts
CHANGED
|
@@ -61,12 +61,63 @@ export function getEmitterMeta(nodeType: PlanNodeType): EmitterMeta | undefined
|
|
|
61
61
|
return registration?.meta;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Wraps an instruction's run function with plan node stack tracking for debugging.
|
|
66
|
+
* Only adds overhead when tracing is enabled.
|
|
67
|
+
*/
|
|
68
|
+
function instrumentRunForTracing(plan: PlanNode, originalRun: InstructionRun): InstructionRun {
|
|
69
|
+
return function (ctx: RuntimeContext, ...args: any[]) {
|
|
70
|
+
const stack = (ctx.planStack = ctx.planStack || []);
|
|
71
|
+
stack.push(plan);
|
|
72
|
+
|
|
73
|
+
let result: any;
|
|
74
|
+
try {
|
|
75
|
+
result = originalRun(ctx, ...args);
|
|
76
|
+
} catch (err) {
|
|
77
|
+
// Synchronous error – pop immediately and re-throw
|
|
78
|
+
stack.pop();
|
|
79
|
+
throw err;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// If the result is an async iterable, defer the pop until iteration completes
|
|
83
|
+
if (result && typeof result === 'object' && Symbol.asyncIterator in result) {
|
|
84
|
+
const iterable = result as AsyncIterable<unknown>;
|
|
85
|
+
// Wrap iterable to pop stack in a finally block once iteration ends
|
|
86
|
+
return (async function* () {
|
|
87
|
+
try {
|
|
88
|
+
for await (const item of iterable) {
|
|
89
|
+
yield item;
|
|
90
|
+
}
|
|
91
|
+
} finally {
|
|
92
|
+
stack.pop();
|
|
93
|
+
}
|
|
94
|
+
})();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// If the result is a promise, pop once it settles
|
|
98
|
+
if (result && typeof (result as Promise<unknown>).then === 'function') {
|
|
99
|
+
return (result as Promise<unknown>).finally(() => {
|
|
100
|
+
stack.pop();
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Synchronous return value – pop immediately
|
|
105
|
+
stack.pop();
|
|
106
|
+
return result;
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
64
110
|
export function emitPlanNode(plan: PlanNode, ctx: EmissionContext): Instruction {
|
|
65
111
|
const registration = emitters.get(plan.nodeType);
|
|
66
112
|
if (!registration) {
|
|
67
113
|
throw new QuereusError(`No emitter registered for ${plan.nodeType}`, StatusCode.ERROR);
|
|
68
114
|
}
|
|
69
|
-
|
|
115
|
+
const instruction = registration.emitter(plan, ctx);
|
|
116
|
+
// Wrap with instrumentation for tracing
|
|
117
|
+
if (ctx.tracePlanStack) {
|
|
118
|
+
instruction.run = instrumentRunForTracing(plan, instruction.run);
|
|
119
|
+
}
|
|
120
|
+
return instruction;
|
|
70
121
|
}
|
|
71
122
|
|
|
72
123
|
/**
|
package/src/runtime/register.ts
CHANGED
|
@@ -13,7 +13,8 @@ import { emitDropTable } from './emit/drop-table.js';
|
|
|
13
13
|
import { emitCreateView } from './emit/create-view.js';
|
|
14
14
|
import { emitDropView } from './emit/drop-view.js';
|
|
15
15
|
import { emitCTE } from './emit/cte.js';
|
|
16
|
-
import {
|
|
16
|
+
import { emitCTEReference } from './emit/cte-reference.js';
|
|
17
|
+
import { emitInternalRecursiveCTERef } from './emit/internal-recursive-cte-ref.js';
|
|
17
18
|
import { emitInsert } from './emit/insert.js';
|
|
18
19
|
import { emitUpdate } from './emit/update.js';
|
|
19
20
|
import { emitDmlExecutor } from './emit/dml-executor.js';
|
|
@@ -45,7 +46,7 @@ import { emitLoopJoin } from './emit/join.js';
|
|
|
45
46
|
import { emitCache } from './emit/cache.js';
|
|
46
47
|
import { emitReturning } from './emit/returning.js';
|
|
47
48
|
import { emitSink } from './emit/sink.js';
|
|
48
|
-
import {
|
|
49
|
+
import { emitBetween } from './emit/between.js';
|
|
49
50
|
|
|
50
51
|
let registered = false;
|
|
51
52
|
|
|
@@ -67,14 +68,14 @@ export function registerEmitters() {
|
|
|
67
68
|
registerEmitter(PlanNodeType.CaseExpr, emitCaseExpr as EmitterFunc);
|
|
68
69
|
registerEmitter(PlanNodeType.Cast, emitCast as EmitterFunc);
|
|
69
70
|
registerEmitter(PlanNodeType.Collate, emitCollate as EmitterFunc);
|
|
71
|
+
registerEmitter(PlanNodeType.Between, emitBetween as EmitterFunc);
|
|
70
72
|
registerEmitter(PlanNodeType.ScalarSubquery, emitScalarSubquery as EmitterFunc);
|
|
71
73
|
registerEmitter(PlanNodeType.Exists, emitExists as EmitterFunc);
|
|
72
74
|
|
|
73
75
|
// Relational emitters (mix of logical and physical for now)
|
|
74
76
|
registerEmitter(PlanNodeType.Block, emitBlock as EmitterFunc);
|
|
75
|
-
registerEmitter(PlanNodeType.TableReference, emitTableReference as EmitterFunc);
|
|
76
77
|
registerEmitter(PlanNodeType.CTEReference, emitCTEReference as EmitterFunc);
|
|
77
|
-
registerEmitter(PlanNodeType.
|
|
78
|
+
registerEmitter(PlanNodeType.InternalRecursiveCTERef, emitInternalRecursiveCTERef as EmitterFunc);
|
|
78
79
|
|
|
79
80
|
// Physical access node emitters (Phase 1)
|
|
80
81
|
registerEmitter(PlanNodeType.SeqScan, emitSeqScan as EmitterFunc);
|
package/src/runtime/scheduler.ts
CHANGED
|
@@ -2,8 +2,10 @@ import type { Instruction, RuntimeContext, InstructionRuntimeStats } from "./typ
|
|
|
2
2
|
import type { OutputValue, RuntimeValue, Row } from "../common/types.js";
|
|
3
3
|
import { isAsyncIterable } from "./utils.js";
|
|
4
4
|
import { createLogger } from "../common/logger.js";
|
|
5
|
+
import { DefaultContextTracker } from './types.js';
|
|
5
6
|
|
|
6
7
|
const log = createLogger('runtime:metrics');
|
|
8
|
+
const contextLog = createLogger('runtime:context');
|
|
7
9
|
|
|
8
10
|
type ResultDestination = number | null;
|
|
9
11
|
|
|
@@ -71,13 +73,28 @@ export class Scheduler {
|
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
run(ctx: RuntimeContext): OutputValue {
|
|
76
|
+
// Initialize context tracker if not already present
|
|
77
|
+
if (!ctx.contextTracker) {
|
|
78
|
+
ctx.contextTracker = new DefaultContextTracker();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let result: OutputValue;
|
|
82
|
+
|
|
74
83
|
if (ctx.enableMetrics) {
|
|
75
|
-
|
|
84
|
+
result = this.runWithMetrics(ctx);
|
|
76
85
|
} else if (!ctx.tracer) {
|
|
77
|
-
|
|
86
|
+
result = this.runOptimized(ctx);
|
|
78
87
|
} else {
|
|
79
|
-
|
|
88
|
+
result = this.runWithTracing(ctx);
|
|
80
89
|
}
|
|
90
|
+
|
|
91
|
+
// Check for remaining contexts and warn rather than error
|
|
92
|
+
if (ctx.contextTracker && ctx.contextTracker.hasRemainingContexts()) {
|
|
93
|
+
const remaining = ctx.contextTracker.getRemainingContexts();
|
|
94
|
+
contextLog('Context leak detected - remaining contexts:', remaining.map(c => c.source));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return result;
|
|
81
98
|
}
|
|
82
99
|
|
|
83
100
|
private runOptimized(ctx: RuntimeContext): OutputValue {
|
|
@@ -164,7 +181,6 @@ export class Scheduler {
|
|
|
164
181
|
const args = instrArgs[i]!; // Guaranteed not to contain promises
|
|
165
182
|
instrArgs[i] = undefined; // Clear args as we go to minimize memory usage.
|
|
166
183
|
|
|
167
|
-
|
|
168
184
|
// Trace input
|
|
169
185
|
ctx.tracer!.traceInput(i, instruction, args as RuntimeValue[]);
|
|
170
186
|
|
|
@@ -386,12 +402,12 @@ export class Scheduler {
|
|
|
386
402
|
stats.elapsedNs += process.hrtime.bigint() - start;
|
|
387
403
|
throw error;
|
|
388
404
|
});
|
|
389
|
-
} else {
|
|
390
|
-
// Sync result
|
|
391
|
-
stats.out += this.countOutputs(result);
|
|
392
|
-
stats.elapsedNs += process.hrtime.bigint() - start;
|
|
393
|
-
return result;
|
|
394
405
|
}
|
|
406
|
+
|
|
407
|
+
stats.out += this.countOutputs(result);
|
|
408
|
+
stats.elapsedNs += process.hrtime.bigint() - start;
|
|
409
|
+
|
|
410
|
+
return result;
|
|
395
411
|
} catch (error) {
|
|
396
412
|
stats.elapsedNs += process.hrtime.bigint() - start;
|
|
397
413
|
throw error;
|
|
@@ -406,13 +422,10 @@ export class Scheduler {
|
|
|
406
422
|
stats.in += this.countInputs(args);
|
|
407
423
|
|
|
408
424
|
try {
|
|
409
|
-
const result = instruction.run(ctx, ...args);
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
stats.out += this.countOutputs(resolved);
|
|
425
|
+
const result = await instruction.run(ctx, ...args);
|
|
426
|
+
stats.out += this.countOutputs(result);
|
|
413
427
|
stats.elapsedNs += process.hrtime.bigint() - start;
|
|
414
|
-
|
|
415
|
-
return resolved;
|
|
428
|
+
return result;
|
|
416
429
|
} catch (error) {
|
|
417
430
|
stats.elapsedNs += process.hrtime.bigint() - start;
|
|
418
431
|
throw error;
|
|
@@ -420,65 +433,52 @@ export class Scheduler {
|
|
|
420
433
|
}
|
|
421
434
|
|
|
422
435
|
private countInputs(args: RuntimeValue[]): number {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
count += 1; // Count iterables as 1 (we can't know size without consuming)
|
|
436
|
+
return args.reduce((sum: number, arg) => {
|
|
437
|
+
if (isAsyncIterable(arg)) {
|
|
438
|
+
return sum + 1; // Count as 1 for async iterables (we don't know size)
|
|
439
|
+
} else if (Array.isArray(arg)) {
|
|
440
|
+
return sum + arg.length;
|
|
429
441
|
} else {
|
|
430
|
-
|
|
442
|
+
return sum + 1;
|
|
431
443
|
}
|
|
432
|
-
}
|
|
433
|
-
return count;
|
|
444
|
+
}, 0);
|
|
434
445
|
}
|
|
435
446
|
|
|
436
447
|
private countOutputs(result: OutputValue): number {
|
|
437
|
-
if (
|
|
448
|
+
if (isAsyncIterable(result)) {
|
|
449
|
+
return 1; // Count as 1 for async iterables (we don't know size)
|
|
450
|
+
} else if (Array.isArray(result)) {
|
|
438
451
|
return result.length;
|
|
439
|
-
} else if (isAsyncIterable(result)) {
|
|
440
|
-
return 1; // Count iterables as 1 (we can't know size without consuming)
|
|
441
452
|
} else {
|
|
442
453
|
return 1;
|
|
443
454
|
}
|
|
444
455
|
}
|
|
445
456
|
|
|
446
457
|
private logAggregateMetrics(): void {
|
|
447
|
-
if (
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
totalTime += stats.elapsedNs;
|
|
461
|
-
|
|
462
|
-
statsLog(' [%d] %s: %d exec, %d in, %d out, %.2fms',
|
|
463
|
-
i,
|
|
464
|
-
instruction.note || 'unknown',
|
|
465
|
-
stats.executions,
|
|
466
|
-
stats.in,
|
|
467
|
-
stats.out,
|
|
468
|
-
elapsedMs
|
|
469
|
-
);
|
|
458
|
+
if (log.enabled) {
|
|
459
|
+
let totalExecutions = 0;
|
|
460
|
+
let totalElapsed = 0n;
|
|
461
|
+
let totalIn = 0;
|
|
462
|
+
let totalOut = 0;
|
|
463
|
+
|
|
464
|
+
for (const instruction of this.instructions) {
|
|
465
|
+
if (instruction.runtimeStats) {
|
|
466
|
+
totalExecutions += instruction.runtimeStats.executions;
|
|
467
|
+
totalElapsed += instruction.runtimeStats.elapsedNs;
|
|
468
|
+
totalIn += instruction.runtimeStats.in;
|
|
469
|
+
totalOut += instruction.runtimeStats.out;
|
|
470
|
+
}
|
|
470
471
|
}
|
|
471
|
-
}
|
|
472
472
|
|
|
473
|
-
|
|
474
|
-
|
|
473
|
+
log(`Aggregate metrics: ${totalExecutions} executions, ${totalElapsed / 1000n}μs elapsed, ${totalIn} inputs, ${totalOut} outputs`);
|
|
474
|
+
}
|
|
475
475
|
}
|
|
476
476
|
|
|
477
477
|
/**
|
|
478
478
|
* Get runtime statistics for all instructions
|
|
479
479
|
*/
|
|
480
480
|
getMetrics(): InstructionRuntimeStats[] {
|
|
481
|
-
return this.instructions.map(
|
|
481
|
+
return this.instructions.map(instruction => instruction.runtimeStats || {
|
|
482
482
|
in: 0,
|
|
483
483
|
out: 0,
|
|
484
484
|
elapsedNs: 0n,
|
package/src/runtime/types.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { RowDescriptor, RowGetter, TableDescriptor, TableGetter } from "../
|
|
|
5
5
|
import type { Scheduler } from "./scheduler.js";
|
|
6
6
|
import type { EmissionContext } from "./emission-context.js";
|
|
7
7
|
import type { VirtualTableConnection } from "../vtab/connection.js";
|
|
8
|
+
import type { PlanNode } from '../planner/nodes/plan-node.js';
|
|
8
9
|
|
|
9
10
|
export type RuntimeContext = {
|
|
10
11
|
db: Database;
|
|
@@ -20,6 +21,10 @@ export type RuntimeContext = {
|
|
|
20
21
|
activeConnection?: VirtualTableConnection;
|
|
21
22
|
/** Whether to collect runtime execution metrics */
|
|
22
23
|
enableMetrics: boolean;
|
|
24
|
+
/** Context tracking for debugging context leaks */
|
|
25
|
+
contextTracker?: ContextTracker;
|
|
26
|
+
/** Stack of currently executing plan nodes (only when tracing enabled) */
|
|
27
|
+
planStack?: PlanNode[];
|
|
23
28
|
};
|
|
24
29
|
|
|
25
30
|
export type InstructionRun = (ctx: RuntimeContext, ...args: any[]) => OutputValue;
|
|
@@ -189,3 +194,43 @@ export class CollectingInstructionTracer implements InstructionTracer {
|
|
|
189
194
|
return value;
|
|
190
195
|
}
|
|
191
196
|
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Tracks context additions and removals for debugging context leaks
|
|
200
|
+
*/
|
|
201
|
+
export interface ContextTracker {
|
|
202
|
+
/** Record that a context was added */
|
|
203
|
+
addContext(descriptor: RowDescriptor, source: string): void;
|
|
204
|
+
/** Record that a context was removed */
|
|
205
|
+
removeContext(descriptor: RowDescriptor): void;
|
|
206
|
+
/** Get all remaining contexts with their sources */
|
|
207
|
+
getRemainingContexts(): Array<{ descriptor: RowDescriptor; source: string }>;
|
|
208
|
+
/** Check if there are any remaining contexts */
|
|
209
|
+
hasRemainingContexts(): boolean;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Default implementation of ContextTracker
|
|
214
|
+
*/
|
|
215
|
+
export class DefaultContextTracker implements ContextTracker {
|
|
216
|
+
private contexts = new Map<RowDescriptor, string>();
|
|
217
|
+
|
|
218
|
+
addContext(descriptor: RowDescriptor, source: string): void {
|
|
219
|
+
this.contexts.set(descriptor, source);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
removeContext(descriptor: RowDescriptor): void {
|
|
223
|
+
this.contexts.delete(descriptor);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
getRemainingContexts(): Array<{ descriptor: RowDescriptor; source: string }> {
|
|
227
|
+
return Array.from(this.contexts.entries()).map(([descriptor, source]) => ({
|
|
228
|
+
descriptor,
|
|
229
|
+
source
|
|
230
|
+
}));
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
hasRemainingContexts(): boolean {
|
|
234
|
+
return this.contexts.size > 0;
|
|
235
|
+
}
|
|
236
|
+
}
|