@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
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
import type { ScalarType } from '../../common/datatype.js';
|
|
2
|
-
import type * as AST from '../../parser/ast.js';
|
|
3
|
-
import type { Scope } from '../scopes/scope.js';
|
|
4
|
-
import { PlanNode, type NaryScalarNode, type ScalarPlanNode, type PhysicalProperties } from './plan-node.js';
|
|
5
|
-
import { PlanNodeType } from './plan-node-type.js';
|
|
6
|
-
import { formatExpressionList, formatScalarType } from '../../util/plan-formatter.js';
|
|
7
|
-
import type { FunctionSchema } from '../../schema/function.js';
|
|
8
|
-
import { FunctionFlags } from '../../common/constants.js';
|
|
9
|
-
|
|
10
|
-
export class ScalarFunctionCallNode extends PlanNode implements NaryScalarNode {
|
|
11
|
-
override readonly nodeType = PlanNodeType.ScalarFunctionCall;
|
|
12
|
-
|
|
13
|
-
constructor(
|
|
14
|
-
scope: Scope,
|
|
15
|
-
public readonly expression: AST.FunctionExpr,
|
|
16
|
-
public readonly functionSchema: FunctionSchema,
|
|
17
|
-
public readonly operands: ScalarPlanNode[]
|
|
18
|
-
) {
|
|
19
|
-
super(scope);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
getType(): ScalarType {
|
|
23
|
-
return this.functionSchema.returnType as ScalarType;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
getChildren(): readonly ScalarPlanNode[] {
|
|
27
|
-
return this.operands;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
getRelations(): readonly [] {
|
|
31
|
-
return [];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
withChildren(newChildren: readonly PlanNode[]): PlanNode {
|
|
35
|
-
if (newChildren.length !== this.operands.length) {
|
|
36
|
-
throw new Error(`ScalarFunctionCallNode expects ${this.operands.length} children, got ${newChildren.length}`);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Type check
|
|
40
|
-
for (const child of newChildren) {
|
|
41
|
-
if (!('expression' in child)) {
|
|
42
|
-
throw new Error('ScalarFunctionCallNode: all children must be ScalarPlanNodes');
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Check if anything changed
|
|
47
|
-
const childrenChanged = newChildren.some((child, i) => child !== this.operands[i]);
|
|
48
|
-
if (!childrenChanged) {
|
|
49
|
-
return this;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Create new instance
|
|
53
|
-
return new ScalarFunctionCallNode(
|
|
54
|
-
this.scope,
|
|
55
|
-
this.expression,
|
|
56
|
-
this.functionSchema,
|
|
57
|
-
newChildren as ScalarPlanNode[]
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
override toString(): string {
|
|
62
|
-
return `${this.expression.name}(${formatExpressionList(this.operands)})`;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
override computePhysical(_childrenPhysical: PhysicalProperties[]): Partial<PhysicalProperties> {
|
|
66
|
-
// Function calls derive properties from their arguments and the function itself
|
|
67
|
-
const result: Partial<PhysicalProperties> = {};
|
|
68
|
-
|
|
69
|
-
// Use function schema to determine deterministic and readonly properties
|
|
70
|
-
const functionIsDeterministic = (this.functionSchema.flags & FunctionFlags.DETERMINISTIC) !== 0;
|
|
71
|
-
const functionIsReadonly = (this.functionSchema.returnType as ScalarType).isReadOnly ?? true;
|
|
72
|
-
|
|
73
|
-
// Function is deterministic only if both function and all arguments are deterministic
|
|
74
|
-
if (!functionIsDeterministic) {
|
|
75
|
-
result.deterministic = false;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Function is readonly only if both function and all arguments are readonly
|
|
79
|
-
if (!functionIsReadonly) {
|
|
80
|
-
result.readonly = false;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return result;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
override getLogicalAttributes(): Record<string, unknown> {
|
|
87
|
-
return {
|
|
88
|
-
function: this.expression.name,
|
|
89
|
-
arguments: this.operands.map(op => op.toString()),
|
|
90
|
-
resultType: formatScalarType(this.functionSchema.returnType as ScalarType)
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
}
|
|
1
|
+
import type { ScalarType } from '../../common/datatype.js';
|
|
2
|
+
import type * as AST from '../../parser/ast.js';
|
|
3
|
+
import type { Scope } from '../scopes/scope.js';
|
|
4
|
+
import { PlanNode, type NaryScalarNode, type ScalarPlanNode, type PhysicalProperties } from './plan-node.js';
|
|
5
|
+
import { PlanNodeType } from './plan-node-type.js';
|
|
6
|
+
import { formatExpressionList, formatScalarType } from '../../util/plan-formatter.js';
|
|
7
|
+
import type { FunctionSchema } from '../../schema/function.js';
|
|
8
|
+
import { FunctionFlags } from '../../common/constants.js';
|
|
9
|
+
|
|
10
|
+
export class ScalarFunctionCallNode extends PlanNode implements NaryScalarNode {
|
|
11
|
+
override readonly nodeType = PlanNodeType.ScalarFunctionCall;
|
|
12
|
+
|
|
13
|
+
constructor(
|
|
14
|
+
scope: Scope,
|
|
15
|
+
public readonly expression: AST.FunctionExpr,
|
|
16
|
+
public readonly functionSchema: FunctionSchema,
|
|
17
|
+
public readonly operands: ScalarPlanNode[]
|
|
18
|
+
) {
|
|
19
|
+
super(scope);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
getType(): ScalarType {
|
|
23
|
+
return this.functionSchema.returnType as ScalarType;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
getChildren(): readonly ScalarPlanNode[] {
|
|
27
|
+
return this.operands;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
getRelations(): readonly [] {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
withChildren(newChildren: readonly PlanNode[]): PlanNode {
|
|
35
|
+
if (newChildren.length !== this.operands.length) {
|
|
36
|
+
throw new Error(`ScalarFunctionCallNode expects ${this.operands.length} children, got ${newChildren.length}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Type check
|
|
40
|
+
for (const child of newChildren) {
|
|
41
|
+
if (!('expression' in child)) {
|
|
42
|
+
throw new Error('ScalarFunctionCallNode: all children must be ScalarPlanNodes');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Check if anything changed
|
|
47
|
+
const childrenChanged = newChildren.some((child, i) => child !== this.operands[i]);
|
|
48
|
+
if (!childrenChanged) {
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Create new instance
|
|
53
|
+
return new ScalarFunctionCallNode(
|
|
54
|
+
this.scope,
|
|
55
|
+
this.expression,
|
|
56
|
+
this.functionSchema,
|
|
57
|
+
newChildren as ScalarPlanNode[]
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
override toString(): string {
|
|
62
|
+
return `${this.expression.name}(${formatExpressionList(this.operands)})`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
override computePhysical(_childrenPhysical: PhysicalProperties[]): Partial<PhysicalProperties> {
|
|
66
|
+
// Function calls derive properties from their arguments and the function itself
|
|
67
|
+
const result: Partial<PhysicalProperties> = {};
|
|
68
|
+
|
|
69
|
+
// Use function schema to determine deterministic and readonly properties
|
|
70
|
+
const functionIsDeterministic = (this.functionSchema.flags & FunctionFlags.DETERMINISTIC) !== 0;
|
|
71
|
+
const functionIsReadonly = (this.functionSchema.returnType as ScalarType).isReadOnly ?? true;
|
|
72
|
+
|
|
73
|
+
// Function is deterministic only if both function and all arguments are deterministic
|
|
74
|
+
if (!functionIsDeterministic) {
|
|
75
|
+
result.deterministic = false;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Function is readonly only if both function and all arguments are readonly
|
|
79
|
+
if (!functionIsReadonly) {
|
|
80
|
+
result.readonly = false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
override getLogicalAttributes(): Record<string, unknown> {
|
|
87
|
+
return {
|
|
88
|
+
function: this.expression.name,
|
|
89
|
+
arguments: this.operands.map(op => op.toString()),
|
|
90
|
+
resultType: formatScalarType(this.functionSchema.returnType as ScalarType)
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Scope } from '../scopes/scope.js';
|
|
2
|
-
import { PlanNode, type RelationalPlanNode, type Attribute, type RowDescriptor } from './plan-node.js';
|
|
2
|
+
import { PlanNode, type RelationalPlanNode, type Attribute, type RowDescriptor, type PhysicalProperties, isRelationalNode } from './plan-node.js';
|
|
3
3
|
import { PlanNodeType } from './plan-node-type.js';
|
|
4
4
|
import type { TableReferenceNode } from './reference.js';
|
|
5
5
|
import type { ColumnDef, RelationType } from '../../common/datatype.js';
|
|
@@ -67,14 +67,37 @@ export class InsertNode extends PlanNode implements RelationalPlanNode {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
override getChildren(): readonly PlanNode[] {
|
|
70
|
-
|
|
70
|
+
// Return the source relation as a child so optimizer can traverse it
|
|
71
|
+
return [this.source];
|
|
71
72
|
}
|
|
72
73
|
|
|
73
74
|
withChildren(newChildren: readonly PlanNode[]): PlanNode {
|
|
74
|
-
if (newChildren.length !==
|
|
75
|
-
throw new Error(`InsertNode expects
|
|
75
|
+
if (newChildren.length !== 1) {
|
|
76
|
+
throw new Error(`InsertNode expects 1 child (source), got ${newChildren.length}`);
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
+
|
|
79
|
+
const newSource = newChildren[0] as RelationalPlanNode;
|
|
80
|
+
if (!isRelationalNode(newSource)) {
|
|
81
|
+
throw new Error('InsertNode: child must be a RelationalPlanNode');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (newSource === this.source) {
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return new InsertNode(
|
|
89
|
+
this.scope,
|
|
90
|
+
this.table,
|
|
91
|
+
this.targetColumns,
|
|
92
|
+
newSource,
|
|
93
|
+
this.flatRowDescriptor
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
computePhysical(): Partial<PhysicalProperties> {
|
|
98
|
+
return {
|
|
99
|
+
readonly: false, // INSERT has side effects
|
|
100
|
+
};
|
|
78
101
|
}
|
|
79
102
|
|
|
80
103
|
override toString(): string {
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { ZeroAryRelationalBase, type Attribute, type TableDescriptor } from './plan-node.js';
|
|
2
|
+
import type { RelationType } from '../../common/datatype.js';
|
|
3
|
+
import { PlanNodeType } from './plan-node-type.js';
|
|
4
|
+
import type { Scope } from '../scopes/scope.js';
|
|
5
|
+
import { Cached } from '../../util/cached.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Plan node for internal recursive CTE references.
|
|
9
|
+
* This represents a reference to the working table within a recursive CTE's recursive case.
|
|
10
|
+
* Unlike CTEReferenceNode, this doesn't materialize the CTE but looks up the working table
|
|
11
|
+
* from the runtime table context.
|
|
12
|
+
*/
|
|
13
|
+
export class InternalRecursiveCTERefNode extends ZeroAryRelationalBase {
|
|
14
|
+
readonly nodeType = PlanNodeType.InternalRecursiveCTERef;
|
|
15
|
+
|
|
16
|
+
private attributesCache: Cached<Attribute[]>;
|
|
17
|
+
private typeCache: Cached<RelationType>;
|
|
18
|
+
|
|
19
|
+
constructor(
|
|
20
|
+
scope: Scope,
|
|
21
|
+
public readonly cteName: string,
|
|
22
|
+
public readonly attributes: Attribute[],
|
|
23
|
+
public readonly relationType: RelationType,
|
|
24
|
+
public readonly workingTableDescriptor: TableDescriptor,
|
|
25
|
+
public readonly alias?: string
|
|
26
|
+
) {
|
|
27
|
+
super(scope, 0.01); // Very low cost since we're just reading from working table
|
|
28
|
+
this.attributesCache = new Cached(() => this.buildAttributes());
|
|
29
|
+
this.typeCache = new Cached(() => this.buildType());
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
private buildAttributes(): Attribute[] {
|
|
33
|
+
// Return the attributes as provided, with proper source relation
|
|
34
|
+
return this.attributes.map((attr: any) => ({
|
|
35
|
+
id: attr.id,
|
|
36
|
+
name: attr.name,
|
|
37
|
+
type: attr.type,
|
|
38
|
+
sourceRelation: `recursive_ref:${this.cteName}`
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private buildType(): RelationType {
|
|
43
|
+
return {
|
|
44
|
+
typeClass: 'relation',
|
|
45
|
+
isReadOnly: true, // Working table is read-only from recursive case perspective
|
|
46
|
+
isSet: this.relationType.isSet,
|
|
47
|
+
columns: this.getAttributes().map((attr: any) => ({
|
|
48
|
+
name: attr.name,
|
|
49
|
+
type: attr.type
|
|
50
|
+
})),
|
|
51
|
+
keys: [],
|
|
52
|
+
rowConstraints: []
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
getAttributes(): Attribute[] {
|
|
57
|
+
return this.attributesCache.value;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
getType(): RelationType {
|
|
61
|
+
return this.typeCache.value;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
toString(): string {
|
|
65
|
+
const aliasText = this.alias ? ` AS ${this.alias}` : '';
|
|
66
|
+
return `INTERNAL_RECURSIVE_REF ${this.cteName}${aliasText}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
getLogicalAttributes(): Record<string, unknown> {
|
|
70
|
+
return {
|
|
71
|
+
cteName: this.cteName,
|
|
72
|
+
alias: this.alias,
|
|
73
|
+
workingTableDescriptor: this.workingTableDescriptor
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PlanNode } from './plan-node.js';
|
|
1
|
+
import { isRelationalNode, PlanNode } from './plan-node.js';
|
|
2
2
|
import type { RelationalPlanNode, Attribute, BinaryRelationalNode, ScalarPlanNode } from './plan-node.js';
|
|
3
3
|
import type { RelationType } from '../../common/datatype.js';
|
|
4
4
|
import { PlanNodeType } from './plan-node-type.js';
|
|
@@ -131,10 +131,10 @@ export class JoinNode extends PlanNode implements BinaryRelationalNode {
|
|
|
131
131
|
const [newLeft, newRight, newCondition] = newChildren;
|
|
132
132
|
|
|
133
133
|
// Type check
|
|
134
|
-
if (!(
|
|
134
|
+
if (!isRelationalNode(newLeft)) {
|
|
135
135
|
quereusError('JoinNode: first child must be a RelationalPlanNode', StatusCode.INTERNAL);
|
|
136
136
|
}
|
|
137
|
-
if (!(
|
|
137
|
+
if (!isRelationalNode(newRight)) {
|
|
138
138
|
quereusError('JoinNode: second child must be a RelationalPlanNode', StatusCode.INTERNAL);
|
|
139
139
|
}
|
|
140
140
|
if (newCondition && !('expression' in newCondition)) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PlanNodeType } from './plan-node-type.js';
|
|
2
|
-
import { PlanNode, type RelationalPlanNode, type UnaryRelationalNode, type ScalarPlanNode, type Attribute } from './plan-node.js';
|
|
2
|
+
import { PlanNode, type RelationalPlanNode, type UnaryRelationalNode, type ScalarPlanNode, type Attribute, isRelationalNode } from './plan-node.js';
|
|
3
3
|
import type { RelationType } from '../../common/datatype.js';
|
|
4
4
|
import type { Scope } from '../scopes/scope.js';
|
|
5
5
|
import { formatExpression } from '../../util/plan-formatter.js';
|
|
@@ -88,7 +88,7 @@ export class LimitOffsetNode extends PlanNode implements UnaryRelationalNode {
|
|
|
88
88
|
const [newSource, ...restChildren] = newChildren;
|
|
89
89
|
|
|
90
90
|
// Type check
|
|
91
|
-
if (!(
|
|
91
|
+
if (!isRelationalNode(newSource)) {
|
|
92
92
|
quereusError('LimitOffsetNode: first child must be a RelationalPlanNode', StatusCode.INTERNAL);
|
|
93
93
|
}
|
|
94
94
|
|
|
@@ -3,7 +3,6 @@ export enum PlanNodeType {
|
|
|
3
3
|
Block = 'Block',
|
|
4
4
|
TableReference = 'TableReference',
|
|
5
5
|
CTEReference = 'CTEReference',
|
|
6
|
-
TableScan = 'TableScan',
|
|
7
6
|
TableSeek = 'TableSeek',
|
|
8
7
|
Filter = 'Filter',
|
|
9
8
|
Project = 'Project',
|
|
@@ -16,6 +15,7 @@ export enum PlanNodeType {
|
|
|
16
15
|
SetOperation = 'SetOperation',
|
|
17
16
|
CTE = 'CTE',
|
|
18
17
|
RecursiveCTE = 'RecursiveCTE',
|
|
18
|
+
InternalRecursiveCTERef = 'InternalRecursiveCTERef',
|
|
19
19
|
In = 'In',
|
|
20
20
|
Exists = 'Exists',
|
|
21
21
|
Sequencing = 'Sequencing',
|
|
@@ -74,6 +74,8 @@ export interface Attribute {
|
|
|
74
74
|
type: ScalarType;
|
|
75
75
|
/** Source relation that originally produced this column */
|
|
76
76
|
sourceRelation?: string;
|
|
77
|
+
/** Relation name for qualified access (e.g. table name or alias) */
|
|
78
|
+
relationName?: string;
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
/**
|
|
@@ -126,7 +128,7 @@ export abstract class PlanNode {
|
|
|
126
128
|
*/
|
|
127
129
|
getRelations(): readonly RelationalPlanNode[] {
|
|
128
130
|
return this.getChildren()
|
|
129
|
-
.filter(
|
|
131
|
+
.filter(isRelationalNode);
|
|
130
132
|
}
|
|
131
133
|
|
|
132
134
|
/**
|
|
@@ -195,7 +197,7 @@ export abstract class PlanNode {
|
|
|
195
197
|
deterministic: childrenPhysical.every(child => child.deterministic),
|
|
196
198
|
idempotent: childrenPhysical.every(child => child.idempotent),
|
|
197
199
|
readonly: childrenPhysical.every(child => child.readonly),
|
|
198
|
-
constant:
|
|
200
|
+
// constant: DON'T INHERIT - only ValueNodes can be directly constant
|
|
199
201
|
}
|
|
200
202
|
: DEFAULT_PHYSICAL;
|
|
201
203
|
|
|
@@ -269,6 +271,13 @@ export interface RelationalPlanNode extends PlanNode {
|
|
|
269
271
|
getAttributes(): Attribute[];
|
|
270
272
|
}
|
|
271
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Check if a node is relational (can be cached)
|
|
276
|
+
*/
|
|
277
|
+
export function isRelationalNode(node: PlanNode): node is RelationalPlanNode {
|
|
278
|
+
return node.getType().typeClass === 'relation';
|
|
279
|
+
}
|
|
280
|
+
|
|
272
281
|
/**
|
|
273
282
|
* Base interface for PlanNodes that produce a scalar value (Expression Nodes).
|
|
274
283
|
* Note: this is an interface that concrete ScalarNode classes will implement.
|
|
@@ -278,6 +287,13 @@ export interface ScalarPlanNode extends PlanNode {
|
|
|
278
287
|
getType(): ScalarType;
|
|
279
288
|
}
|
|
280
289
|
|
|
290
|
+
/**
|
|
291
|
+
* Check if a node is a scalar node
|
|
292
|
+
*/
|
|
293
|
+
export function isScalarNode(node: PlanNode): node is ScalarPlanNode {
|
|
294
|
+
return node.getType().typeClass === 'scalar';
|
|
295
|
+
}
|
|
296
|
+
|
|
281
297
|
// --- Arity-based Base Abstractions (Interfaces, to be implemented by concrete node classes) ---
|
|
282
298
|
|
|
283
299
|
/** A relational plan node that has no relational inputs (a leaf in the relational algebra tree).
|
|
@@ -322,6 +338,11 @@ export interface BinaryScalarNode extends ScalarPlanNode {
|
|
|
322
338
|
getChildren(): readonly [ScalarPlanNode, ScalarPlanNode];
|
|
323
339
|
}
|
|
324
340
|
|
|
341
|
+
/** A scalar plan node that operates on three scalar inputs. */
|
|
342
|
+
export interface TernaryScalarNode extends ScalarPlanNode {
|
|
343
|
+
getChildren(): readonly [ScalarPlanNode, ScalarPlanNode, ScalarPlanNode];
|
|
344
|
+
}
|
|
345
|
+
|
|
325
346
|
/** A scalar plan node that operates on N scalar inputs. */
|
|
326
347
|
export interface NaryScalarNode extends ScalarPlanNode {
|
|
327
348
|
readonly operands: ReadonlyArray<ScalarPlanNode>;
|
|
@@ -442,6 +463,22 @@ export abstract class BinaryScalarBase extends PlanNode implements BinaryScalarN
|
|
|
442
463
|
abstract withChildren(newChildren: readonly PlanNode[]): PlanNode;
|
|
443
464
|
}
|
|
444
465
|
|
|
466
|
+
/**
|
|
467
|
+
* Base class for scalar nodes with three scalar inputs
|
|
468
|
+
*/
|
|
469
|
+
export abstract class TernaryScalarBase extends PlanNode implements TernaryScalarNode {
|
|
470
|
+
abstract readonly expression: Expression;
|
|
471
|
+
abstract getType(): ScalarType;
|
|
472
|
+
abstract getChildren(): readonly [ScalarPlanNode, ScalarPlanNode, ScalarPlanNode];
|
|
473
|
+
|
|
474
|
+
withChildren(newChildren: readonly PlanNode[]): PlanNode {
|
|
475
|
+
if (newChildren.length !== 3) {
|
|
476
|
+
quereusError(`${this.nodeType} expects 3 children, got ${newChildren.length}`);
|
|
477
|
+
}
|
|
478
|
+
return this;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
445
482
|
/**
|
|
446
483
|
* Base class for scalar nodes with N scalar inputs
|
|
447
484
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PlanNodeType } from './plan-node-type.js';
|
|
2
|
-
import { PlanNode, type RelationalPlanNode, type UnaryRelationalNode, type ScalarPlanNode, type Attribute } from './plan-node.js';
|
|
2
|
+
import { PlanNode, type RelationalPlanNode, type UnaryRelationalNode, type ScalarPlanNode, type Attribute, isRelationalNode } from './plan-node.js';
|
|
3
3
|
import type { RelationType } from '../../common/datatype.js';
|
|
4
4
|
import type { Scope } from '../scopes/scope.js';
|
|
5
5
|
import { Cached } from '../../util/cached.js';
|
|
@@ -32,7 +32,9 @@ export class ProjectNode extends PlanNode implements UnaryRelationalNode {
|
|
|
32
32
|
public readonly projections: ReadonlyArray<Projection>,
|
|
33
33
|
estimatedCostOverride?: number,
|
|
34
34
|
/** Optional predefined attributes for preserving IDs during optimization */
|
|
35
|
-
predefinedAttributes?: Attribute[]
|
|
35
|
+
predefinedAttributes?: Attribute[],
|
|
36
|
+
/** Whether to preserve input columns in the output (default: true) */
|
|
37
|
+
public readonly preserveInputColumns: boolean = true
|
|
36
38
|
) {
|
|
37
39
|
super(scope, estimatedCostOverride);
|
|
38
40
|
|
|
@@ -97,35 +99,52 @@ export class ProjectNode extends PlanNode implements UnaryRelationalNode {
|
|
|
97
99
|
// Get the computed column names from the type
|
|
98
100
|
const outputType = this.getType();
|
|
99
101
|
|
|
100
|
-
//
|
|
102
|
+
// If preserveInputColumns is false, only create attributes for projections
|
|
103
|
+
if (!this.preserveInputColumns) {
|
|
104
|
+
return this.projections.map((proj, index) => ({
|
|
105
|
+
id: proj.attributeId ?? PlanNode.nextAttrId(),
|
|
106
|
+
name: outputType.columns[index].name,
|
|
107
|
+
type: proj.node.getType(),
|
|
108
|
+
sourceRelation: `${this.nodeType}:${this.id}`,
|
|
109
|
+
relationName: 'projection'
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// For each projection, preserve attribute ID for simple column references
|
|
101
114
|
return this.projections.map((proj, index) => {
|
|
102
|
-
//
|
|
115
|
+
// Use predefined attribute ID if supplied (optimizer path)
|
|
103
116
|
if (proj.attributeId !== undefined) {
|
|
104
117
|
return {
|
|
105
118
|
id: proj.attributeId,
|
|
106
119
|
name: outputType.columns[index].name,
|
|
107
120
|
type: proj.node.getType(),
|
|
108
|
-
sourceRelation: `${this.nodeType}:${this.id}
|
|
121
|
+
sourceRelation: `${this.nodeType}:${this.id}`,
|
|
122
|
+
relationName: 'projection'
|
|
109
123
|
};
|
|
110
124
|
}
|
|
111
125
|
|
|
112
|
-
// If this projection is a simple column reference, preserve its attribute ID
|
|
113
126
|
if (proj.node instanceof ColumnReferenceNode) {
|
|
127
|
+
// Always preserve the original attribute ID so that any reference
|
|
128
|
+
// to the underlying column (e.g., in ORDER BY) remains valid even
|
|
129
|
+
// after aliasing. The alias is purely a name change, not a new column.
|
|
130
|
+
const colRef = proj.node as ColumnReferenceNode;
|
|
114
131
|
return {
|
|
115
|
-
id:
|
|
116
|
-
name: outputType.columns[index].name,
|
|
117
|
-
type: proj.node.getType(),
|
|
118
|
-
sourceRelation: `${this.nodeType}:${this.id}`
|
|
119
|
-
};
|
|
120
|
-
} else {
|
|
121
|
-
// For computed expressions, generate new attribute ID
|
|
122
|
-
return {
|
|
123
|
-
id: PlanNode.nextAttrId(),
|
|
124
|
-
name: outputType.columns[index].name, // Use the deduplicated name
|
|
132
|
+
id: colRef.attributeId,
|
|
133
|
+
name: outputType.columns[index].name,
|
|
125
134
|
type: proj.node.getType(),
|
|
126
|
-
sourceRelation: `${this.nodeType}:${this.id}
|
|
135
|
+
sourceRelation: `${this.nodeType}:${this.id}`,
|
|
136
|
+
relationName: 'projection'
|
|
127
137
|
};
|
|
128
138
|
}
|
|
139
|
+
|
|
140
|
+
// Computed expression or aliased column – generate fresh attribute ID
|
|
141
|
+
return {
|
|
142
|
+
id: PlanNode.nextAttrId(),
|
|
143
|
+
name: outputType.columns[index].name,
|
|
144
|
+
type: proj.node.getType(),
|
|
145
|
+
sourceRelation: `${this.nodeType}:${this.id}`,
|
|
146
|
+
relationName: 'projection'
|
|
147
|
+
};
|
|
129
148
|
});
|
|
130
149
|
});
|
|
131
150
|
}
|
|
@@ -189,7 +208,7 @@ export class ProjectNode extends PlanNode implements UnaryRelationalNode {
|
|
|
189
208
|
const [newSource, ...newProjectionNodes] = newChildren;
|
|
190
209
|
|
|
191
210
|
// Type check
|
|
192
|
-
if (!(
|
|
211
|
+
if (!isRelationalNode(newSource)) {
|
|
193
212
|
quereusError('ProjectNode: first child must be a RelationalPlanNode', StatusCode.INTERNAL);
|
|
194
213
|
}
|
|
195
214
|
|
|
@@ -217,7 +236,8 @@ export class ProjectNode extends PlanNode implements UnaryRelationalNode {
|
|
|
217
236
|
newSource as RelationalPlanNode,
|
|
218
237
|
newProjections,
|
|
219
238
|
undefined, // estimatedCostOverride
|
|
220
|
-
originalAttributes // Pass original attributes to preserve IDs
|
|
239
|
+
originalAttributes, // Pass original attributes to preserve IDs
|
|
240
|
+
this.preserveInputColumns // Preserve the flag
|
|
221
241
|
);
|
|
222
242
|
}
|
|
223
243
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PlanNode, type RelationalPlanNode, type Attribute, type TableDescriptor } from './plan-node.js';
|
|
1
|
+
import { PlanNode, type RelationalPlanNode, type Attribute, type TableDescriptor, isRelationalNode } from './plan-node.js';
|
|
2
2
|
import type { RelationType } from '../../common/datatype.js';
|
|
3
3
|
import { PlanNodeType } from './plan-node-type.js';
|
|
4
4
|
import type { Scope } from '../scopes/scope.js';
|
|
@@ -12,7 +12,7 @@ import type { CTEPlanNode } from './cte-node.js';
|
|
|
12
12
|
export class RecursiveCTENode extends PlanNode implements CTEPlanNode {
|
|
13
13
|
readonly nodeType = PlanNodeType.RecursiveCTE;
|
|
14
14
|
readonly isRecursive = true; // Always true for recursive CTEs
|
|
15
|
-
readonly tableDescriptor: TableDescriptor
|
|
15
|
+
readonly tableDescriptor: TableDescriptor;
|
|
16
16
|
|
|
17
17
|
private attributesCache: Cached<Attribute[]>;
|
|
18
18
|
private typeCache: Cached<RelationType>;
|
|
@@ -26,10 +26,12 @@ export class RecursiveCTENode extends PlanNode implements CTEPlanNode {
|
|
|
26
26
|
recursiveCaseQuery: RelationalPlanNode,
|
|
27
27
|
public readonly isUnionAll: boolean,
|
|
28
28
|
public readonly materializationHint: 'materialized' | 'not_materialized' | undefined = 'materialized',
|
|
29
|
-
public readonly maxRecursion?: number
|
|
29
|
+
public readonly maxRecursion?: number,
|
|
30
|
+
tableDescriptor?: TableDescriptor
|
|
30
31
|
) {
|
|
31
32
|
super(scope, baseCaseQuery.getTotalCost() + recursiveCaseQuery.getTotalCost() + 50); // Higher cost for recursion
|
|
32
33
|
this._recursiveCaseQuery = recursiveCaseQuery;
|
|
34
|
+
this.tableDescriptor = tableDescriptor || {}; // Identity object for table context lookup
|
|
33
35
|
this.attributesCache = new Cached(() => this.buildAttributes());
|
|
34
36
|
this.typeCache = new Cached(() => this.buildType());
|
|
35
37
|
}
|
|
@@ -58,7 +60,7 @@ export class RecursiveCTENode extends PlanNode implements CTEPlanNode {
|
|
|
58
60
|
const columnNames = this.columns || baseCaseType.columns.map((c: any) => c.name);
|
|
59
61
|
|
|
60
62
|
return baseCaseAttributes.map((attr: any, index: number) => ({
|
|
61
|
-
id:
|
|
63
|
+
id: attr.id, // Preserve original attribute ID for proper context resolution
|
|
62
64
|
name: columnNames[index] || attr.name,
|
|
63
65
|
type: attr.type,
|
|
64
66
|
sourceRelation: `recursive_cte:${this.cteName}`
|
|
@@ -87,8 +89,8 @@ export class RecursiveCTENode extends PlanNode implements CTEPlanNode {
|
|
|
87
89
|
return this.typeCache.value;
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
getChildren(): readonly [] {
|
|
91
|
-
return [];
|
|
92
|
+
getChildren(): readonly [RelationalPlanNode, RelationalPlanNode] {
|
|
93
|
+
return [this.baseCaseQuery, this.recursiveCaseQuery];
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
// For recursive CTEs, we consider the base case as the primary source
|
|
@@ -101,10 +103,36 @@ export class RecursiveCTENode extends PlanNode implements CTEPlanNode {
|
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
withChildren(newChildren: readonly PlanNode[]): PlanNode {
|
|
104
|
-
if (newChildren.length !==
|
|
105
|
-
throw new Error(`RecursiveCTENode expects
|
|
106
|
+
if (newChildren.length !== 2) {
|
|
107
|
+
throw new Error(`RecursiveCTENode expects 2 children, got ${newChildren.length}`);
|
|
106
108
|
}
|
|
107
|
-
|
|
109
|
+
|
|
110
|
+
const [newBaseCaseQuery, newRecursiveCaseQuery] = newChildren;
|
|
111
|
+
|
|
112
|
+
// Type check
|
|
113
|
+
if (!isRelationalNode(newBaseCaseQuery) || !isRelationalNode(newRecursiveCaseQuery)) {
|
|
114
|
+
throw new Error('RecursiveCTENode: children must be RelationalPlanNodes');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Return same instance if nothing changed
|
|
118
|
+
if (newBaseCaseQuery === this.baseCaseQuery && newRecursiveCaseQuery === this.recursiveCaseQuery) {
|
|
119
|
+
return this;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Create new instance with updated children
|
|
123
|
+
const newNode = new RecursiveCTENode(
|
|
124
|
+
this.scope,
|
|
125
|
+
this.cteName,
|
|
126
|
+
this.columns,
|
|
127
|
+
newBaseCaseQuery as RelationalPlanNode,
|
|
128
|
+
newRecursiveCaseQuery as RelationalPlanNode,
|
|
129
|
+
this.isUnionAll,
|
|
130
|
+
this.materializationHint,
|
|
131
|
+
this.maxRecursion,
|
|
132
|
+
this.tableDescriptor
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
return newNode;
|
|
108
136
|
}
|
|
109
137
|
|
|
110
138
|
override toString(): string {
|
|
@@ -41,7 +41,8 @@ export class TableReferenceNode extends PlanNode implements ZeroAryRelationalNod
|
|
|
41
41
|
isReadOnly: false,
|
|
42
42
|
collationName: column.collation
|
|
43
43
|
},
|
|
44
|
-
sourceRelation: `${this.tableSchema.schemaName}.${this.tableSchema.name}
|
|
44
|
+
sourceRelation: `${this.tableSchema.schemaName}.${this.tableSchema.name}`,
|
|
45
|
+
relationName: this.tableSchema.name
|
|
45
46
|
}));
|
|
46
47
|
});
|
|
47
48
|
}
|
|
@@ -108,7 +109,8 @@ export class TableFunctionReferenceNode extends PlanNode implements ZeroAryRelat
|
|
|
108
109
|
id: PlanNode.nextAttrId(),
|
|
109
110
|
name: column.name,
|
|
110
111
|
type: column.type,
|
|
111
|
-
sourceRelation: `${this.functionSchema.name}()
|
|
112
|
+
sourceRelation: `${this.functionSchema.name}()`,
|
|
113
|
+
relationName: this.functionSchema.name
|
|
112
114
|
}));
|
|
113
115
|
}
|
|
114
116
|
return [];
|