@quereus/quereus 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -23
- 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 +9 -2
- 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 +6 -3
- 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 +4 -1
- 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 +7 -4
- 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 +11 -4
- 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.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 +14 -121
- 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/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/package.json +8 -3
- 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 +11 -2
- package/src/parser/parser.ts +40 -47
- package/src/planner/analysis/const-pass.ts +281 -270
- package/src/planner/building/constraint-builder.ts +114 -0
- package/src/planner/building/delete.ts +16 -3
- package/src/planner/building/expression.ts +35 -7
- package/src/planner/building/insert.ts +14 -1
- 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 +19 -4
- 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 +47 -13
- 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 +2 -2
- 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 +17 -142
- 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/util/plugin-loader.ts +78 -4
- package/src/util/working-table-iterable.ts +15 -7
- package/src/vtab/manifest.ts +42 -0
- 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
|
@@ -43,6 +43,17 @@ export function buildWindowPhase(
|
|
|
43
43
|
// For now, proceed with WindowNode
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
// CRITICAL: Build window specification expressions using the INPUT scope
|
|
47
|
+
// This ensures expressions reference the correct input attribute IDs,
|
|
48
|
+
// not premature output attribute IDs that don't exist in the runtime context
|
|
49
|
+
const partitionExpressions = windowSpec.partitionBy.map(expr =>
|
|
50
|
+
buildExpression(selectContext, expr, false)
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const orderByExpressions = windowSpec.orderBy.map(orderClause =>
|
|
54
|
+
buildExpression(selectContext, orderClause.expr, false)
|
|
55
|
+
);
|
|
56
|
+
|
|
46
57
|
// Create new WindowFunctionCallNode instances with alias information
|
|
47
58
|
const windowFuncsWithAlias = functions.map(({ func, alias }) =>
|
|
48
59
|
new WindowFunctionCallNode(
|
|
@@ -54,17 +65,9 @@ export function buildWindowPhase(
|
|
|
54
65
|
)
|
|
55
66
|
);
|
|
56
67
|
|
|
57
|
-
// Build expressions for window specification
|
|
58
|
-
const partitionExpressions = windowSpec.partitionBy.map(expr =>
|
|
59
|
-
buildExpression(selectContext, expr, false)
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
const orderByExpressions = windowSpec.orderBy.map(orderClause =>
|
|
63
|
-
buildExpression(selectContext, orderClause.expr, false)
|
|
64
|
-
);
|
|
65
|
-
|
|
66
68
|
const functionArguments = buildWindowFunctionArguments(windowFuncsWithAlias, selectContext);
|
|
67
69
|
|
|
70
|
+
// Now create the WindowNode with pre-compiled expressions
|
|
68
71
|
currentInput = new WindowNode(
|
|
69
72
|
selectContext.scope,
|
|
70
73
|
currentInput,
|
|
@@ -246,3 +249,5 @@ function compareWindowSpecs(originalWindow: any, funcWindow: any): boolean {
|
|
|
246
249
|
originalOrder === funcOrder &&
|
|
247
250
|
originalFrame === funcFrame;
|
|
248
251
|
}
|
|
252
|
+
|
|
253
|
+
|
|
@@ -4,7 +4,7 @@ import { QuereusError } from '../../common/errors.js';
|
|
|
4
4
|
import { StatusCode } from '../../common/types.js';
|
|
5
5
|
import type { PlanningContext } from '../planning-context.js';
|
|
6
6
|
import { SingleRowNode } from '../nodes/single-row.js';
|
|
7
|
-
import {
|
|
7
|
+
import { buildTableReference } from './table.js';
|
|
8
8
|
import { AliasedScope } from '../scopes/aliased.js';
|
|
9
9
|
import { RegisteredScope } from '../scopes/registered.js';
|
|
10
10
|
import type { Scope } from '../scopes/scope.js';
|
|
@@ -14,10 +14,12 @@ import { buildExpression } from './expression.js';
|
|
|
14
14
|
import { FilterNode } from '../nodes/filter.js';
|
|
15
15
|
import { buildTableFunctionCall } from './table-function.js';
|
|
16
16
|
import { CTEReferenceNode } from '../nodes/cte-reference-node.js';
|
|
17
|
+
import { InternalRecursiveCTERefNode } from '../nodes/internal-recursive-cte-ref-node.js';
|
|
17
18
|
import type { CTEPlanNode } from '../nodes/cte-node.js';
|
|
18
19
|
import { JoinNode } from '../nodes/join-node.js';
|
|
19
20
|
import { ColumnReferenceNode } from '../nodes/reference.js';
|
|
20
21
|
import { ValuesNode } from '../nodes/values-node.js';
|
|
22
|
+
import { createLogger } from '../../common/logger.js';
|
|
21
23
|
|
|
22
24
|
// Import decomposed functionality
|
|
23
25
|
import { buildWithContext } from './select-context.js';
|
|
@@ -26,16 +28,19 @@ import { analyzeSelectColumns, buildStarProjections } from './select-projections
|
|
|
26
28
|
import { buildAggregatePhase, buildFinalAggregateProjections } from './select-aggregates.js';
|
|
27
29
|
import { buildWindowPhase } from './select-window.js';
|
|
28
30
|
import { buildFinalProjections, applyDistinct, applyOrderBy, applyLimitOffset } from './select-modifiers.js';
|
|
31
|
+
import { SortNode, type SortKey } from '../nodes/sort.js';
|
|
29
32
|
|
|
30
33
|
import { buildInsertStmt } from './insert.js';
|
|
31
34
|
import { buildUpdateStmt } from './update.js';
|
|
32
35
|
import { buildDeleteStmt } from './delete.js';
|
|
33
36
|
|
|
37
|
+
const logger = createLogger('planner:cte');
|
|
38
|
+
|
|
34
39
|
/**
|
|
35
40
|
* Creates an initial logical query plan for a SELECT statement.
|
|
36
41
|
*
|
|
37
42
|
* For this initial version, it only supports simple "SELECT ... FROM one_table" queries,
|
|
38
|
-
* effectively returning a
|
|
43
|
+
* effectively returning a TableReferenceNode for that table.
|
|
39
44
|
*
|
|
40
45
|
* @param stmt The AST.SelectStmt to plan.
|
|
41
46
|
* @param ctx The parent planning context for this SELECT statement.
|
|
@@ -46,7 +51,14 @@ import { buildDeleteStmt } from './delete.js';
|
|
|
46
51
|
export function buildSelectStmt(
|
|
47
52
|
ctx: PlanningContext,
|
|
48
53
|
stmt: AST.SelectStmt,
|
|
49
|
-
parentCTEs: Map<string, CTEPlanNode> = new Map()
|
|
54
|
+
parentCTEs: Map<string, CTEPlanNode> = new Map(),
|
|
55
|
+
/**
|
|
56
|
+
* Whether ProjectNodes inside this SELECT should forward all input columns that are not explicitly
|
|
57
|
+
* listed in the projection list. This is desirable for top-level queries (helps ORDER BY, window
|
|
58
|
+
* functions, etc.) but must be switched off for scalar/IN/EXISTS sub-queries which are required to
|
|
59
|
+
* expose only their declared columns.
|
|
60
|
+
*/
|
|
61
|
+
preserveInputColumns: boolean = true
|
|
50
62
|
): PlanNode {
|
|
51
63
|
|
|
52
64
|
// Phase 0: Handle WITH clause if present
|
|
@@ -119,25 +131,82 @@ export function buildSelectStmt(
|
|
|
119
131
|
// Build final projections if needed
|
|
120
132
|
if (aggregateResult.needsFinalProjection) {
|
|
121
133
|
const finalProjections = buildFinalAggregateProjections(stmt, selectContext, aggregateResult.aggregateScope);
|
|
122
|
-
input = new ProjectNode(selectScope, input, finalProjections);
|
|
134
|
+
input = new ProjectNode(selectScope, input, finalProjections, undefined, undefined, preserveInputColumns);
|
|
123
135
|
}
|
|
124
136
|
}
|
|
125
137
|
|
|
126
|
-
|
|
127
|
-
|
|
138
|
+
// Handle window functions if present
|
|
139
|
+
if (hasWindowFunctions) {
|
|
140
|
+
// Check if ORDER BY references columns not in SELECT before applying window functions
|
|
141
|
+
let preWindowSort = false;
|
|
142
|
+
if (stmt.orderBy) {
|
|
143
|
+
const selectedColumns = new Set<string>();
|
|
144
|
+
for (const column of stmt.columns) {
|
|
145
|
+
if (column.type === 'column' && column.expr.type === 'column') {
|
|
146
|
+
selectedColumns.add(column.expr.name.toLowerCase());
|
|
147
|
+
}
|
|
148
|
+
if (column.type === 'column' && column.alias) {
|
|
149
|
+
selectedColumns.add(column.alias.toLowerCase());
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Check if ORDER BY references columns not in SELECT
|
|
154
|
+
for (const orderByClause of stmt.orderBy) {
|
|
155
|
+
if (orderByClause.expr.type === 'column') {
|
|
156
|
+
const orderColumn = orderByClause.expr.name.toLowerCase();
|
|
157
|
+
if (!selectedColumns.has(orderColumn)) {
|
|
158
|
+
// Apply ORDER BY before window projections
|
|
159
|
+
const sortKeys: SortKey[] = stmt.orderBy.map(orderBy => ({
|
|
160
|
+
expression: buildExpression(selectContext, orderBy.expr),
|
|
161
|
+
direction: orderBy.direction,
|
|
162
|
+
nulls: orderBy.nulls
|
|
163
|
+
}));
|
|
164
|
+
input = new SortNode(selectContext.scope, input, sortKeys);
|
|
165
|
+
preWindowSort = true;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
input = buildWindowPhase(input, windowFunctions, selectContext, stmt);
|
|
173
|
+
|
|
174
|
+
// Update context to include window output columns
|
|
175
|
+
const windowOutputScope = new RegisteredScope(selectContext.scope);
|
|
176
|
+
const windowAttributes = input.getAttributes();
|
|
177
|
+
input.getType().columns.forEach((col, index) => {
|
|
178
|
+
const attr = windowAttributes[index];
|
|
179
|
+
windowOutputScope.registerSymbol(col.name.toLowerCase(), (exp, s) =>
|
|
180
|
+
new ColumnReferenceNode(s, exp as AST.ColumnExpr, col.type, attr.id, index));
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Create combined scope that includes both original columns and window output
|
|
184
|
+
const combinedScope = new MultiScope([windowOutputScope, selectScope]);
|
|
185
|
+
selectContext = { ...selectContext, scope: combinedScope };
|
|
128
186
|
|
|
129
|
-
|
|
187
|
+
// Don't apply ORDER BY again if we already did it
|
|
188
|
+
if (preWindowSort) {
|
|
189
|
+
preAggregateSort = true;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Handle final projections for non-aggregate, non-window cases
|
|
130
194
|
if (!hasAggregates && !hasWindowFunctions) {
|
|
131
|
-
const finalResult = buildFinalProjections(input, projections, selectScope, stmt, selectContext);
|
|
195
|
+
const finalResult = buildFinalProjections(input, projections, selectScope, stmt, selectContext, preserveInputColumns);
|
|
132
196
|
input = finalResult.output;
|
|
133
197
|
selectContext = finalResult.finalContext;
|
|
134
198
|
preAggregateSort = finalResult.preAggregateSort;
|
|
135
|
-
}
|
|
136
199
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
200
|
+
// Apply final modifiers with projection scope for column alias resolution
|
|
201
|
+
input = applyDistinct(input, stmt, selectScope);
|
|
202
|
+
input = applyOrderBy(input, stmt, selectContext, preAggregateSort, finalResult.projectionScope);
|
|
203
|
+
input = applyLimitOffset(input, stmt, selectContext, finalResult.projectionScope);
|
|
204
|
+
} else {
|
|
205
|
+
// Apply final modifiers without projection scope for aggregate/window cases
|
|
206
|
+
input = applyDistinct(input, stmt, selectScope);
|
|
207
|
+
input = applyOrderBy(input, stmt, selectContext, preAggregateSort);
|
|
208
|
+
input = applyLimitOffset(input, stmt, selectContext);
|
|
209
|
+
}
|
|
141
210
|
|
|
142
211
|
return input;
|
|
143
212
|
}
|
|
@@ -162,6 +231,22 @@ export function buildValuesStmt(
|
|
|
162
231
|
return new ValuesNode(ctx.scope, rows);
|
|
163
232
|
}
|
|
164
233
|
|
|
234
|
+
/**
|
|
235
|
+
* Processes a FROM clause item into a relational plan node.
|
|
236
|
+
*
|
|
237
|
+
* Handles different types of FROM items:
|
|
238
|
+
* - Table references - creates a TableReferenceNode
|
|
239
|
+
* - Subqueries - plans the subquery
|
|
240
|
+
* - Joins - builds the join structure
|
|
241
|
+
* - Table functions - creates a table function call node
|
|
242
|
+
*
|
|
243
|
+
* For a simple table reference, this calls buildTableReference which
|
|
244
|
+
* returns a TableReferenceNode for that table.
|
|
245
|
+
*
|
|
246
|
+
* @param fromClause The FROM clause AST node to process
|
|
247
|
+
* @param ctx The planning context
|
|
248
|
+
* @returns A relational plan node representing the FROM clause
|
|
249
|
+
*/
|
|
165
250
|
export function buildFrom(fromClause: AST.FromClause, parentContext: PlanningContext, cteNodes: Map<string, CTEPlanNode> = new Map()): RelationalPlanNode {
|
|
166
251
|
let fromTable: RelationalPlanNode;
|
|
167
252
|
let columnScope: Scope;
|
|
@@ -169,27 +254,74 @@ export function buildFrom(fromClause: AST.FromClause, parentContext: PlanningCon
|
|
|
169
254
|
if (fromClause.type === 'table') {
|
|
170
255
|
const tableName = fromClause.table.name.toLowerCase();
|
|
171
256
|
|
|
172
|
-
|
|
257
|
+
// Check if this is a CTE reference
|
|
173
258
|
if (cteNodes.has(tableName)) {
|
|
174
259
|
const cteNode = cteNodes.get(tableName)!;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
260
|
+
|
|
261
|
+
// Check if this is an internal recursive CTE reference
|
|
262
|
+
if (cteNode instanceof InternalRecursiveCTERefNode) {
|
|
263
|
+
// For internal recursive references, use the node directly
|
|
264
|
+
fromTable = cteNode;
|
|
265
|
+
|
|
266
|
+
// Create scope for internal recursive CTE columns
|
|
267
|
+
const internalScope = new RegisteredScope(parentContext.scope);
|
|
268
|
+
const internalAttributes = cteNode.getAttributes();
|
|
269
|
+
cteNode.getType().columns.forEach((c, i) => {
|
|
270
|
+
const attr = internalAttributes[i];
|
|
271
|
+
internalScope.registerSymbol(c.name.toLowerCase(), (exp, s) =>
|
|
272
|
+
new ColumnReferenceNode(s, exp as AST.ColumnExpr, c.type, attr.id, i));
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
if (fromClause.alias) {
|
|
276
|
+
columnScope = new AliasedScope(internalScope, tableName, fromClause.alias.toLowerCase());
|
|
277
|
+
} else {
|
|
278
|
+
columnScope = new AliasedScope(internalScope, tableName, tableName);
|
|
279
|
+
}
|
|
188
280
|
} else {
|
|
189
|
-
|
|
190
|
-
|
|
281
|
+
// Regular CTE reference - cache by CTE name + alias to ensure consistent attribute IDs
|
|
282
|
+
const cacheKey = `${tableName}:${fromClause.alias || tableName}`;
|
|
283
|
+
|
|
284
|
+
// Initialize cache if not exists
|
|
285
|
+
if (!parentContext.cteReferenceCache) {
|
|
286
|
+
parentContext.cteReferenceCache = new Map();
|
|
287
|
+
}
|
|
191
288
|
|
|
192
|
-
|
|
289
|
+
let cteRefNode: CTEReferenceNode;
|
|
290
|
+
if (parentContext.cteReferenceCache.has(cacheKey)) {
|
|
291
|
+
cteRefNode = parentContext.cteReferenceCache.get(cacheKey)!;
|
|
292
|
+
const attrs = cteRefNode.getAttributes();
|
|
293
|
+
logger(`Using cached CTE reference ${cacheKey}, attrs=[${attrs.map(a => a.id).join(',')}]`);
|
|
294
|
+
} else {
|
|
295
|
+
cteRefNode = new CTEReferenceNode(parentContext.scope, cteNode, fromClause.alias);
|
|
296
|
+
parentContext.cteReferenceCache.set(cacheKey, cteRefNode);
|
|
297
|
+
const attrs = cteRefNode.getAttributes();
|
|
298
|
+
logger(`Created new CTE reference ${cacheKey}, attrs=[${attrs.map(a => a.id).join(',')}]`);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Create scope for CTE columns using attributes from the reference node
|
|
302
|
+
// CRITICAL: Use a closure to capture the reference node's attributes
|
|
303
|
+
// This ensures all column references use the same attribute IDs
|
|
304
|
+
const cteScope = new RegisteredScope(parentContext.scope);
|
|
305
|
+
const refAttrs = cteRefNode.getAttributes();
|
|
306
|
+
cteRefNode.getType().columns.forEach((c, i) => {
|
|
307
|
+
const attr = refAttrs[i];
|
|
308
|
+
cteScope.registerSymbol(c.name.toLowerCase(), (exp, s) => {
|
|
309
|
+
// Always use the cached reference node's attribute ID
|
|
310
|
+
return new ColumnReferenceNode(s, exp as AST.ColumnExpr, c.type, attr.id, i);
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
if (fromClause.alias) {
|
|
315
|
+
columnScope = new AliasedScope(cteScope, tableName, fromClause.alias.toLowerCase());
|
|
316
|
+
} else {
|
|
317
|
+
columnScope = new AliasedScope(cteScope, tableName, tableName);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// CRITICAL: Cache the reference node so later expression compilation uses the same attribute IDs
|
|
321
|
+
(columnScope as any).referenceNode = cteRefNode;
|
|
322
|
+
|
|
323
|
+
fromTable = cteRefNode;
|
|
324
|
+
}
|
|
193
325
|
} else {
|
|
194
326
|
// Check if this is a view
|
|
195
327
|
const schemaName = fromClause.table.schema || parentContext.db.schemaManager.getCurrentSchemaName();
|
|
@@ -215,7 +347,7 @@ export function buildFrom(fromClause: AST.FromClause, parentContext: PlanningCon
|
|
|
215
347
|
}
|
|
216
348
|
} else {
|
|
217
349
|
// Regular table
|
|
218
|
-
fromTable =
|
|
350
|
+
fromTable = buildTableReference(fromClause, parentContext);
|
|
219
351
|
|
|
220
352
|
// Create scope for table columns
|
|
221
353
|
const tableScope = new RegisteredScope(parentContext.scope);
|
|
@@ -2,10 +2,7 @@ import { QuereusError } from '../../common/errors.js';
|
|
|
2
2
|
import { StatusCode } from '../../common/types.js';
|
|
3
3
|
import type * as AST from '../../parser/ast.js';
|
|
4
4
|
import { TableReferenceNode } from '../nodes/reference.js';
|
|
5
|
-
import { TableScanNode } from '../nodes/scan.js';
|
|
6
5
|
import type { PlanningContext } from '../planning-context.js';
|
|
7
|
-
import type { IndexInfo, IndexConstraintUsage } from '../../vtab/index-info.js';
|
|
8
|
-
import type { FilterInfo } from '../../vtab/filter-info.js';
|
|
9
6
|
import { resolveTableSchema, resolveVtabModule } from './schema-resolution.js';
|
|
10
7
|
|
|
11
8
|
/**
|
|
@@ -18,7 +15,7 @@ import { resolveTableSchema, resolveVtabModule } from './schema-resolution.js';
|
|
|
18
15
|
*/
|
|
19
16
|
export function buildTableReference(fromClause: AST.FromClause, context: PlanningContext): TableReferenceNode {
|
|
20
17
|
if (fromClause.type !== 'table') {
|
|
21
|
-
throw new QuereusError('
|
|
18
|
+
throw new QuereusError('buildTableReference currently only supports simple table references.', StatusCode.INTERNAL);
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
// Resolve table schema at build time
|
|
@@ -35,39 +32,3 @@ export function buildTableReference(fromClause: AST.FromClause, context: Plannin
|
|
|
35
32
|
);
|
|
36
33
|
}
|
|
37
34
|
|
|
38
|
-
/**
|
|
39
|
-
* Plans a table scan operation based on a FROM clause item.
|
|
40
|
-
*
|
|
41
|
-
* @param fromClause The AST node representing a table in the FROM clause.
|
|
42
|
-
* @param context The planning context to resolve table definitions.
|
|
43
|
-
* @returns A TableScanNode for the specified table.
|
|
44
|
-
* @throws {QuereusError} If the table is not found, the reference is ambiguous, or fromClause is not a simple table.
|
|
45
|
-
*/
|
|
46
|
-
export function buildTableScan(fromClause: AST.FromClause, context: PlanningContext): TableScanNode {
|
|
47
|
-
const tableReference = buildTableReference(fromClause, context);
|
|
48
|
-
|
|
49
|
-
const defaultIndexInfo: IndexInfo = {
|
|
50
|
-
nConstraint: 0,
|
|
51
|
-
aConstraint: [],
|
|
52
|
-
nOrderBy: 0,
|
|
53
|
-
aOrderBy: [],
|
|
54
|
-
aConstraintUsage: [] as IndexConstraintUsage[],
|
|
55
|
-
idxNum: 0,
|
|
56
|
-
idxStr: 'fullscan',
|
|
57
|
-
orderByConsumed: false,
|
|
58
|
-
estimatedCost: tableReference.estimatedRows ?? 1000,
|
|
59
|
-
estimatedRows: BigInt(tableReference.estimatedRows ?? 100),
|
|
60
|
-
idxFlags: 0,
|
|
61
|
-
colUsed: 0n,
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const filterInfo: FilterInfo = {
|
|
65
|
-
idxNum: 0,
|
|
66
|
-
idxStr: 'fullscan',
|
|
67
|
-
constraints: [],
|
|
68
|
-
args: [],
|
|
69
|
-
indexInfoOutput: defaultIndexInfo,
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
return new TableScanNode(context.scope, tableReference, filterInfo);
|
|
73
|
-
}
|
|
@@ -2,7 +2,7 @@ import type * as AST from '../../parser/ast.js';
|
|
|
2
2
|
import type { PlanningContext } from '../planning-context.js';
|
|
3
3
|
import { UpdateNode, type UpdateAssignment } from '../nodes/update-node.js';
|
|
4
4
|
import { DmlExecutorNode } from '../nodes/dml-executor-node.js';
|
|
5
|
-
import { buildTableReference
|
|
5
|
+
import { buildTableReference } from './table.js';
|
|
6
6
|
import { buildExpression } from './expression.js';
|
|
7
7
|
import { PlanNode, type RelationalPlanNode, type ScalarPlanNode } from '../nodes/plan-node.js';
|
|
8
8
|
import { FilterNode } from '../nodes/filter.js';
|
|
@@ -15,6 +15,7 @@ import { ConstraintCheckNode } from '../nodes/constraint-check-node.js';
|
|
|
15
15
|
import { RowOp } from '../../schema/table.js';
|
|
16
16
|
import { ReturningNode } from '../nodes/returning-node.js';
|
|
17
17
|
import { buildOldNewRowDescriptors } from '../../util/row-descriptor.js';
|
|
18
|
+
import { buildConstraintChecks } from './constraint-builder.js';
|
|
18
19
|
|
|
19
20
|
export function buildUpdateStmt(
|
|
20
21
|
ctx: PlanningContext,
|
|
@@ -23,7 +24,7 @@ export function buildUpdateStmt(
|
|
|
23
24
|
const tableReference = buildTableReference({ type: 'table', table: stmt.table }, ctx);
|
|
24
25
|
|
|
25
26
|
// Plan the source of rows to update. This is typically the table itself, potentially filtered.
|
|
26
|
-
let sourceNode: RelationalPlanNode =
|
|
27
|
+
let sourceNode: RelationalPlanNode = buildTableReference({ type: 'table', table: stmt.table }, ctx);
|
|
27
28
|
|
|
28
29
|
// Create a new scope with the table columns registered for column resolution
|
|
29
30
|
const tableScope = new RegisteredScope(ctx.scope);
|
|
@@ -78,6 +79,16 @@ export function buildUpdateStmt(
|
|
|
78
79
|
|
|
79
80
|
const { oldRowDescriptor, newRowDescriptor, flatRowDescriptor } = buildOldNewRowDescriptors(oldAttributes, newAttributes);
|
|
80
81
|
|
|
82
|
+
// Build constraint checks at plan time
|
|
83
|
+
const constraintChecks = buildConstraintChecks(
|
|
84
|
+
updateCtx,
|
|
85
|
+
tableReference.tableSchema,
|
|
86
|
+
RowOp.UPDATE,
|
|
87
|
+
oldAttributes,
|
|
88
|
+
newAttributes,
|
|
89
|
+
flatRowDescriptor
|
|
90
|
+
);
|
|
91
|
+
|
|
81
92
|
if (stmt.returning && stmt.returning.length > 0) {
|
|
82
93
|
// For RETURNING, create coordinated attribute IDs like we do for INSERT
|
|
83
94
|
const returningScope = new RegisteredScope(updateCtx.scope);
|
|
@@ -207,7 +218,9 @@ export function buildUpdateStmt(
|
|
|
207
218
|
tableReference,
|
|
208
219
|
RowOp.UPDATE,
|
|
209
220
|
oldRowDescriptor,
|
|
210
|
-
newRowDescriptor
|
|
221
|
+
newRowDescriptor,
|
|
222
|
+
flatRowDescriptor,
|
|
223
|
+
constraintChecks
|
|
211
224
|
);
|
|
212
225
|
|
|
213
226
|
const updateExecutorNode = new DmlExecutorNode(
|
|
@@ -241,7 +254,9 @@ export function buildUpdateStmt(
|
|
|
241
254
|
tableReference,
|
|
242
255
|
RowOp.UPDATE,
|
|
243
256
|
oldRowDescriptor,
|
|
244
|
-
newRowDescriptor
|
|
257
|
+
newRowDescriptor,
|
|
258
|
+
flatRowDescriptor,
|
|
259
|
+
constraintChecks
|
|
245
260
|
);
|
|
246
261
|
|
|
247
262
|
const updateExecutorNode = new DmlExecutorNode(
|
|
@@ -2,6 +2,7 @@ import type * as AST from '../../parser/ast.js';
|
|
|
2
2
|
import type { PlanningContext } from '../planning-context.js';
|
|
3
3
|
import { CTENode, type CTEPlanNode } from '../nodes/cte-node.js';
|
|
4
4
|
import { RecursiveCTENode } from '../nodes/recursive-cte-node.js';
|
|
5
|
+
import { InternalRecursiveCTERefNode } from '../nodes/internal-recursive-cte-ref-node.js';
|
|
5
6
|
import { buildSelectStmt } from './select.js';
|
|
6
7
|
import type { RelationalPlanNode } from '../nodes/plan-node.js';
|
|
7
8
|
import { QuereusError } from '../../common/errors.js';
|
|
@@ -151,27 +152,25 @@ function buildRecursiveCTE(
|
|
|
151
152
|
options?.maxRecursion
|
|
152
153
|
);
|
|
153
154
|
|
|
154
|
-
|
|
155
|
+
// For the recursive case, we need to create a special context where the CTE name
|
|
155
156
|
// references the working table (this will be handled at runtime)
|
|
156
157
|
const recursiveContext = { ...ctx };
|
|
157
158
|
|
|
158
|
-
// Create
|
|
159
|
-
const
|
|
159
|
+
// Create an internal recursive reference node that will look up the working table at runtime
|
|
160
|
+
const internalRefNode = new InternalRecursiveCTERefNode(
|
|
160
161
|
ctx.scope,
|
|
161
162
|
cte.name,
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
true
|
|
163
|
+
recursiveCTENode.getAttributes(),
|
|
164
|
+
recursiveCTENode.getType(),
|
|
165
|
+
recursiveCTENode.tableDescriptor
|
|
166
166
|
);
|
|
167
|
-
// Share the same tableDescriptor for runtime coordination
|
|
168
|
-
(tempCteNode as any).tableDescriptor = recursiveCTENode.tableDescriptor;
|
|
169
167
|
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
recursiveCteMap
|
|
168
|
+
// Build the recursive case query with a simple replacement strategy
|
|
169
|
+
// We'll replace CTE references with the internal recursive reference during the FROM clause processing
|
|
170
|
+
const recursiveCteMap = new Map<string, any>();
|
|
171
|
+
recursiveCteMap.set(cte.name.toLowerCase(), internalRefNode);
|
|
173
172
|
|
|
174
|
-
// Build the recursive case query
|
|
173
|
+
// Build the recursive case query
|
|
175
174
|
const recursiveCaseQuery = buildSelectStmt(recursiveContext, recursiveCaseStmt, recursiveCteMap) as RelationalPlanNode;
|
|
176
175
|
|
|
177
176
|
// Now update the recursive CTE node with the actual recursive case query
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility to detect correlated subqueries
|
|
3
|
+
* A subquery is correlated if it references columns from outer query scopes
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { isRelationalNode, type PlanNode, type RelationalPlanNode } from '../nodes/plan-node.js';
|
|
7
|
+
import { PlanNodeType } from '../nodes/plan-node-type.js';
|
|
8
|
+
import type { ColumnReferenceNode } from '../nodes/reference.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Detects if a subquery is correlated by checking if it references any attributes
|
|
12
|
+
* that are not defined within its own scope.
|
|
13
|
+
*/
|
|
14
|
+
export function isCorrelatedSubquery(subqueryNode: RelationalPlanNode): boolean {
|
|
15
|
+
// Collect all attributes defined within the subquery
|
|
16
|
+
const definedAttributes = new Set<number>();
|
|
17
|
+
collectDefinedAttributes(subqueryNode, definedAttributes);
|
|
18
|
+
|
|
19
|
+
// Check if any column references use attributes not defined within the subquery
|
|
20
|
+
return hasExternalReferences(subqueryNode, definedAttributes);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Recursively collect all attributes defined by relational nodes within a subtree
|
|
25
|
+
*/
|
|
26
|
+
function collectDefinedAttributes(node: PlanNode, definedAttributes: Set<number>): void {
|
|
27
|
+
// If this is a relational node, add its attributes
|
|
28
|
+
const isRelational = isRelationalNode(node);
|
|
29
|
+
if (isRelational) {
|
|
30
|
+
const attributes = node.getAttributes();
|
|
31
|
+
for (const attr of attributes) {
|
|
32
|
+
definedAttributes.add(attr.id);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Recursively process all children
|
|
37
|
+
const children = node.getChildren();
|
|
38
|
+
for (const child of children) {
|
|
39
|
+
collectDefinedAttributes(child, definedAttributes);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Also process relational children if any
|
|
43
|
+
if (isRelational) {
|
|
44
|
+
const relations = node.getRelations();
|
|
45
|
+
for (const relation of relations) {
|
|
46
|
+
collectDefinedAttributes(relation, definedAttributes);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Check if the subtree contains any column references to attributes not in the defined set
|
|
53
|
+
*/
|
|
54
|
+
function hasExternalReferences(node: PlanNode, definedAttributes: Set<number>): boolean {
|
|
55
|
+
// Check if this is a column reference
|
|
56
|
+
if (node.nodeType === PlanNodeType.ColumnReference) {
|
|
57
|
+
const colRef = node as ColumnReferenceNode;
|
|
58
|
+
// If the referenced attribute is not defined within the subquery, it's an external reference
|
|
59
|
+
if (!definedAttributes.has(colRef.attributeId)) {
|
|
60
|
+
return true; // Found a correlated reference
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Check all children
|
|
65
|
+
const children = node.getChildren();
|
|
66
|
+
for (const child of children) {
|
|
67
|
+
if (hasExternalReferences(child, definedAttributes)) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Also check relational children if any
|
|
73
|
+
if (isRelationalNode(node)) {
|
|
74
|
+
const relations = node.getRelations();
|
|
75
|
+
for (const relation of relations) {
|
|
76
|
+
if (hasExternalReferences(relation, definedAttributes)) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return false;
|
|
83
|
+
}
|