@quereus/quereus 0.17.0 → 0.18.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 +372 -361
- package/dist/src/common/errors.d.ts +2 -18
- package/dist/src/common/errors.d.ts.map +1 -1
- package/dist/src/common/errors.js +6 -29
- package/dist/src/common/errors.js.map +1 -1
- package/dist/src/common/types.d.ts +8 -0
- package/dist/src/common/types.d.ts.map +1 -1
- package/dist/src/common/types.js +20 -0
- package/dist/src/common/types.js.map +1 -1
- package/dist/src/core/database-assertions.d.ts +19 -2
- package/dist/src/core/database-assertions.d.ts.map +1 -1
- package/dist/src/core/database-assertions.js +113 -32
- package/dist/src/core/database-assertions.js.map +1 -1
- package/dist/src/core/database-events.d.ts +17 -0
- package/dist/src/core/database-events.d.ts.map +1 -1
- package/dist/src/core/database-events.js +36 -0
- package/dist/src/core/database-events.js.map +1 -1
- package/dist/src/core/database.d.ts +11 -0
- package/dist/src/core/database.d.ts.map +1 -1
- package/dist/src/core/database.js +178 -85
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/core/statement.d.ts +6 -0
- package/dist/src/core/statement.d.ts.map +1 -1
- package/dist/src/core/statement.js +42 -56
- package/dist/src/core/statement.js.map +1 -1
- package/dist/src/emit/ast-stringify.d.ts +1 -0
- package/dist/src/emit/ast-stringify.d.ts.map +1 -1
- package/dist/src/emit/ast-stringify.js +12 -2
- package/dist/src/emit/ast-stringify.js.map +1 -1
- package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
- package/dist/src/func/builtins/builtin-window-functions.js +75 -0
- package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
- package/dist/src/func/builtins/conversion.js +9 -12
- package/dist/src/func/builtins/conversion.js.map +1 -1
- package/dist/src/func/builtins/datetime.js +1 -1
- package/dist/src/func/builtins/datetime.js.map +1 -1
- package/dist/src/func/builtins/explain.d.ts.map +1 -1
- package/dist/src/func/builtins/explain.js +15 -3
- package/dist/src/func/builtins/explain.js.map +1 -1
- package/dist/src/func/builtins/index.d.ts.map +1 -1
- package/dist/src/func/builtins/index.js +1 -11
- package/dist/src/func/builtins/index.js.map +1 -1
- package/dist/src/func/builtins/json-helpers.js +1 -1
- package/dist/src/func/builtins/json-helpers.js.map +1 -1
- package/dist/src/func/builtins/json.d.ts.map +1 -1
- package/dist/src/func/builtins/json.js +2 -5
- package/dist/src/func/builtins/json.js.map +1 -1
- package/dist/src/func/builtins/schema.d.ts.map +1 -1
- package/dist/src/func/builtins/schema.js +30 -32
- package/dist/src/func/builtins/schema.js.map +1 -1
- package/dist/src/func/builtins/string.d.ts.map +1 -1
- package/dist/src/func/builtins/string.js +40 -64
- package/dist/src/func/builtins/string.js.map +1 -1
- package/dist/src/func/builtins/timespan.d.ts.map +1 -1
- package/dist/src/func/builtins/timespan.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -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/lexer.d.ts +1 -0
- package/dist/src/parser/lexer.d.ts.map +1 -1
- package/dist/src/parser/lexer.js +3 -0
- package/dist/src/parser/lexer.js.map +1 -1
- package/dist/src/parser/parser.d.ts +11 -1
- package/dist/src/parser/parser.d.ts.map +1 -1
- package/dist/src/parser/parser.js +75 -135
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/src/planner/analysis/const-evaluator.d.ts.map +1 -1
- package/dist/src/planner/analysis/const-evaluator.js +6 -3
- package/dist/src/planner/analysis/const-evaluator.js.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.d.ts +2 -1
- package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
- package/dist/src/planner/analysis/constraint-extractor.js +154 -22
- package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
- package/dist/src/planner/building/alter-table.d.ts.map +1 -1
- package/dist/src/planner/building/alter-table.js +18 -1
- package/dist/src/planner/building/alter-table.js.map +1 -1
- package/dist/src/planner/building/analyze.d.ts +5 -0
- package/dist/src/planner/building/analyze.d.ts.map +1 -0
- package/dist/src/planner/building/analyze.js +5 -0
- package/dist/src/planner/building/analyze.js.map +1 -0
- package/dist/src/planner/building/block.d.ts.map +1 -1
- package/dist/src/planner/building/block.js +3 -0
- package/dist/src/planner/building/block.js.map +1 -1
- package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
- package/dist/src/planner/building/constraint-builder.js +25 -3
- package/dist/src/planner/building/constraint-builder.js.map +1 -1
- package/dist/src/planner/building/delete.d.ts.map +1 -1
- package/dist/src/planner/building/delete.js +11 -0
- package/dist/src/planner/building/delete.js.map +1 -1
- package/dist/src/planner/building/drop-assertion.d.ts.map +1 -1
- package/dist/src/planner/building/drop-assertion.js +2 -1
- package/dist/src/planner/building/drop-assertion.js.map +1 -1
- package/dist/src/planner/building/expression.d.ts.map +1 -1
- package/dist/src/planner/building/expression.js +55 -7
- package/dist/src/planner/building/expression.js.map +1 -1
- package/dist/src/planner/building/foreign-key-builder.d.ts +16 -0
- package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -0
- package/dist/src/planner/building/foreign-key-builder.js +269 -0
- package/dist/src/planner/building/foreign-key-builder.js.map +1 -0
- package/dist/src/planner/building/function-call.d.ts.map +1 -1
- package/dist/src/planner/building/function-call.js +3 -2
- package/dist/src/planner/building/function-call.js.map +1 -1
- package/dist/src/planner/building/insert.d.ts.map +1 -1
- package/dist/src/planner/building/insert.js +91 -10
- package/dist/src/planner/building/insert.js.map +1 -1
- package/dist/src/planner/building/schema-resolution.d.ts +4 -0
- package/dist/src/planner/building/schema-resolution.d.ts.map +1 -1
- package/dist/src/planner/building/schema-resolution.js +14 -3
- package/dist/src/planner/building/schema-resolution.js.map +1 -1
- package/dist/src/planner/building/select-aggregates.d.ts +1 -0
- package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
- package/dist/src/planner/building/select-aggregates.js +118 -3
- package/dist/src/planner/building/select-aggregates.js.map +1 -1
- package/dist/src/planner/building/select-modifiers.js +3 -3
- package/dist/src/planner/building/select-modifiers.js.map +1 -1
- package/dist/src/planner/building/select-window.js +9 -8
- package/dist/src/planner/building/select-window.js.map +1 -1
- package/dist/src/planner/building/select.d.ts.map +1 -1
- package/dist/src/planner/building/select.js +21 -10
- package/dist/src/planner/building/select.js.map +1 -1
- package/dist/src/planner/building/table.d.ts.map +1 -1
- package/dist/src/planner/building/table.js +5 -3
- 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 +30 -1
- package/dist/src/planner/building/update.js.map +1 -1
- package/dist/src/planner/building/with.js +1 -1
- package/dist/src/planner/building/with.js.map +1 -1
- package/dist/src/planner/cache/reference-graph.d.ts +1 -1
- package/dist/src/planner/cache/reference-graph.js +1 -1
- package/dist/src/planner/cost/index.d.ts +10 -3
- package/dist/src/planner/cost/index.d.ts.map +1 -1
- package/dist/src/planner/cost/index.js +17 -3
- package/dist/src/planner/cost/index.js.map +1 -1
- package/dist/src/planner/debug.js +1 -1
- package/dist/src/planner/debug.js.map +1 -1
- package/dist/src/planner/framework/characteristics.d.ts +1 -1
- package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
- package/dist/src/planner/framework/pass.d.ts +3 -1
- package/dist/src/planner/framework/pass.d.ts.map +1 -1
- package/dist/src/planner/framework/pass.js +62 -18
- package/dist/src/planner/framework/pass.js.map +1 -1
- package/dist/src/planner/framework/physical-utils.d.ts +5 -0
- package/dist/src/planner/framework/physical-utils.d.ts.map +1 -1
- package/dist/src/planner/framework/physical-utils.js +19 -0
- package/dist/src/planner/framework/physical-utils.js.map +1 -1
- package/dist/src/planner/framework/trace.d.ts.map +1 -1
- package/dist/src/planner/framework/trace.js +3 -2
- package/dist/src/planner/framework/trace.js.map +1 -1
- package/dist/src/planner/nodes/alias-node.d.ts +2 -1
- package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/alias-node.js +8 -0
- package/dist/src/planner/nodes/alias-node.js.map +1 -1
- package/dist/src/planner/nodes/alter-table-node.d.ts +42 -0
- package/dist/src/planner/nodes/alter-table-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/alter-table-node.js +55 -0
- package/dist/src/planner/nodes/alter-table-node.js.map +1 -0
- package/dist/src/planner/nodes/analyze-node.d.ts +25 -0
- package/dist/src/planner/nodes/analyze-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/analyze-node.js +83 -0
- package/dist/src/planner/nodes/analyze-node.js.map +1 -0
- package/dist/src/planner/nodes/bloom-join-node.d.ts +66 -0
- package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/bloom-join-node.js +200 -0
- package/dist/src/planner/nodes/bloom-join-node.js.map +1 -0
- package/dist/src/planner/nodes/constraint-check-node.d.ts +1 -1
- package/dist/src/planner/nodes/constraint-check-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/cte-reference-node.js +7 -7
- package/dist/src/planner/nodes/cte-reference-node.js.map +1 -1
- package/dist/src/planner/nodes/join-node.d.ts +9 -1
- package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/join-node.js +69 -79
- package/dist/src/planner/nodes/join-node.js.map +1 -1
- package/dist/src/planner/nodes/merge-join-node.d.ts +60 -0
- package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -0
- package/dist/src/planner/nodes/merge-join-node.js +207 -0
- package/dist/src/planner/nodes/merge-join-node.js.map +1 -0
- package/dist/src/planner/nodes/plan-node-type.d.ts +1 -0
- package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
- package/dist/src/planner/nodes/plan-node-type.js +1 -0
- package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
- package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/project-node.js +3 -2
- package/dist/src/planner/nodes/project-node.js.map +1 -1
- package/dist/src/planner/nodes/reference.d.ts +2 -1
- package/dist/src/planner/nodes/reference.d.ts.map +1 -1
- package/dist/src/planner/nodes/reference.js +6 -2
- package/dist/src/planner/nodes/reference.js.map +1 -1
- package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/returning-node.js +3 -2
- package/dist/src/planner/nodes/returning-node.js.map +1 -1
- package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
- package/dist/src/planner/nodes/subquery.js.map +1 -1
- package/dist/src/planner/nodes/table-access-nodes.js +1 -1
- package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
- package/dist/src/planner/nodes/update-node.d.ts +2 -0
- package/dist/src/planner/nodes/update-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/update-node.js +2 -1
- package/dist/src/planner/nodes/update-node.js.map +1 -1
- package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
- package/dist/src/planner/nodes/window-function.js +7 -7
- package/dist/src/planner/nodes/window-function.js.map +1 -1
- package/dist/src/planner/nodes/window-node.d.ts +2 -2
- package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
- package/dist/src/planner/nodes/window-node.js +9 -14
- 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 +40 -2
- package/dist/src/planner/optimizer.js.map +1 -1
- package/dist/src/planner/planning-context.d.ts.map +1 -1
- package/dist/src/planner/planning-context.js +1 -6
- package/dist/src/planner/planning-context.js.map +1 -1
- package/dist/src/planner/resolve.d.ts.map +1 -1
- package/dist/src/planner/resolve.js.map +1 -1
- package/dist/src/planner/rules/access/rule-select-access-path.js +157 -28
- 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 +27 -6
- package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
- package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts +19 -0
- package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts.map +1 -0
- package/dist/src/planner/rules/cache/rule-in-subquery-cache.js +53 -0
- package/dist/src/planner/rules/cache/rule-in-subquery-cache.js.map +1 -0
- package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.d.ts.map +1 -1
- package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js +5 -0
- package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js.map +1 -1
- package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts +18 -0
- package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts.map +1 -0
- package/dist/src/planner/rules/distinct/rule-distinct-elimination.js +37 -0
- package/dist/src/planner/rules/distinct/rule-distinct-elimination.js.map +1 -0
- package/dist/src/planner/rules/join/rule-join-key-inference.d.ts +8 -3
- package/dist/src/planner/rules/join/rule-join-key-inference.d.ts.map +1 -1
- package/dist/src/planner/rules/join/rule-join-key-inference.js +28 -17
- package/dist/src/planner/rules/join/rule-join-key-inference.js.map +1 -1
- package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts +16 -0
- package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -0
- package/dist/src/planner/rules/join/rule-join-physical-selection.js +216 -0
- package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -0
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.d.ts.map +1 -1
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +34 -4
- package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts +23 -0
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -0
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +293 -0
- package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -0
- package/dist/src/planner/scopes/multi.d.ts +3 -2
- package/dist/src/planner/scopes/multi.d.ts.map +1 -1
- package/dist/src/planner/scopes/multi.js +32 -7
- package/dist/src/planner/scopes/multi.js.map +1 -1
- package/dist/src/planner/scopes/shadow.d.ts +20 -0
- package/dist/src/planner/scopes/shadow.d.ts.map +1 -0
- package/dist/src/planner/scopes/shadow.js +31 -0
- package/dist/src/planner/scopes/shadow.js.map +1 -0
- package/dist/src/planner/stats/analyze.d.ts +17 -0
- package/dist/src/planner/stats/analyze.d.ts.map +1 -0
- package/dist/src/planner/stats/analyze.js +114 -0
- package/dist/src/planner/stats/analyze.js.map +1 -0
- package/dist/src/planner/stats/catalog-stats.d.ts +80 -0
- package/dist/src/planner/stats/catalog-stats.d.ts.map +1 -0
- package/dist/src/planner/stats/catalog-stats.js +248 -0
- package/dist/src/planner/stats/catalog-stats.js.map +1 -0
- package/dist/src/planner/stats/histogram.d.ts +24 -0
- package/dist/src/planner/stats/histogram.d.ts.map +1 -0
- package/dist/src/planner/stats/histogram.js +142 -0
- package/dist/src/planner/stats/histogram.js.map +1 -0
- package/dist/src/planner/type-utils.d.ts.map +1 -1
- package/dist/src/planner/type-utils.js +8 -2
- package/dist/src/planner/type-utils.js.map +1 -1
- package/dist/src/planner/util/key-utils.d.ts +48 -2
- package/dist/src/planner/util/key-utils.d.ts.map +1 -1
- package/dist/src/planner/util/key-utils.js +123 -0
- package/dist/src/planner/util/key-utils.js.map +1 -1
- package/dist/src/planner/validation/determinism-validator.d.ts +9 -0
- package/dist/src/planner/validation/determinism-validator.d.ts.map +1 -1
- package/dist/src/planner/validation/determinism-validator.js +11 -0
- package/dist/src/planner/validation/determinism-validator.js.map +1 -1
- package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
- package/dist/src/planner/validation/plan-validator.js +1 -0
- package/dist/src/planner/validation/plan-validator.js.map +1 -1
- package/dist/src/runtime/context-helpers.d.ts +34 -10
- package/dist/src/runtime/context-helpers.d.ts.map +1 -1
- package/dist/src/runtime/context-helpers.js +115 -39
- package/dist/src/runtime/context-helpers.js.map +1 -1
- package/dist/src/runtime/deferred-constraint-queue.d.ts +0 -1
- package/dist/src/runtime/deferred-constraint-queue.d.ts.map +1 -1
- package/dist/src/runtime/deferred-constraint-queue.js +10 -23
- package/dist/src/runtime/deferred-constraint-queue.js.map +1 -1
- package/dist/src/runtime/descriptor-helpers.d.ts +7 -0
- package/dist/src/runtime/descriptor-helpers.d.ts.map +1 -0
- package/dist/src/runtime/descriptor-helpers.js +24 -0
- package/dist/src/runtime/descriptor-helpers.js.map +1 -0
- package/dist/src/runtime/emission-context.d.ts +7 -1
- package/dist/src/runtime/emission-context.d.ts.map +1 -1
- package/dist/src/runtime/emission-context.js +16 -0
- 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 +97 -93
- package/dist/src/runtime/emit/aggregate.js.map +1 -1
- package/dist/src/runtime/emit/alter-table.d.ts +5 -0
- package/dist/src/runtime/emit/alter-table.d.ts.map +1 -0
- package/dist/src/runtime/emit/alter-table.js +209 -0
- package/dist/src/runtime/emit/alter-table.js.map +1 -0
- package/dist/src/runtime/emit/analyze.d.ts +9 -0
- package/dist/src/runtime/emit/analyze.d.ts.map +1 -0
- package/dist/src/runtime/emit/analyze.js +72 -0
- package/dist/src/runtime/emit/analyze.js.map +1 -0
- package/dist/src/runtime/emit/array-index.d.ts.map +1 -1
- package/dist/src/runtime/emit/array-index.js +4 -2
- package/dist/src/runtime/emit/array-index.js.map +1 -1
- package/dist/src/runtime/emit/between.d.ts.map +1 -1
- package/dist/src/runtime/emit/between.js +8 -20
- package/dist/src/runtime/emit/between.js.map +1 -1
- package/dist/src/runtime/emit/binary.d.ts.map +1 -1
- package/dist/src/runtime/emit/binary.js +155 -126
- package/dist/src/runtime/emit/binary.js.map +1 -1
- package/dist/src/runtime/emit/bloom-join.d.ts +12 -0
- package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -0
- package/dist/src/runtime/emit/bloom-join.js +114 -0
- package/dist/src/runtime/emit/bloom-join.js.map +1 -0
- package/dist/src/runtime/emit/cache.js +2 -2
- package/dist/src/runtime/emit/cache.js.map +1 -1
- package/dist/src/runtime/emit/cast.d.ts.map +1 -1
- package/dist/src/runtime/emit/cast.js +31 -117
- package/dist/src/runtime/emit/cast.js.map +1 -1
- package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
- package/dist/src/runtime/emit/constraint-check.js +2 -24
- 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 +11 -5
- 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 +21 -12
- package/dist/src/runtime/emit/distinct.js.map +1 -1
- package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
- package/dist/src/runtime/emit/dml-executor.js +5 -1
- package/dist/src/runtime/emit/dml-executor.js.map +1 -1
- package/dist/src/runtime/emit/drop-assertion.d.ts.map +1 -1
- package/dist/src/runtime/emit/drop-assertion.js +2 -0
- package/dist/src/runtime/emit/drop-assertion.js.map +1 -1
- package/dist/src/runtime/emit/filter.d.ts.map +1 -1
- package/dist/src/runtime/emit/filter.js +26 -7
- package/dist/src/runtime/emit/filter.js.map +1 -1
- package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts.map +1 -1
- package/dist/src/runtime/emit/internal-recursive-cte-ref.js +11 -5
- package/dist/src/runtime/emit/internal-recursive-cte-ref.js.map +1 -1
- package/dist/src/runtime/emit/join.d.ts +1 -1
- package/dist/src/runtime/emit/join.d.ts.map +1 -1
- package/dist/src/runtime/emit/join.js +44 -33
- package/dist/src/runtime/emit/join.js.map +1 -1
- package/dist/src/runtime/emit/merge-join.d.ts +14 -0
- package/dist/src/runtime/emit/merge-join.d.ts.map +1 -0
- package/dist/src/runtime/emit/merge-join.js +152 -0
- package/dist/src/runtime/emit/merge-join.js.map +1 -0
- package/dist/src/runtime/emit/parameter.d.ts.map +1 -1
- package/dist/src/runtime/emit/parameter.js +10 -32
- package/dist/src/runtime/emit/parameter.js.map +1 -1
- package/dist/src/runtime/emit/project.d.ts.map +1 -1
- package/dist/src/runtime/emit/project.js +22 -12
- 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 +5 -9
- 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 +14 -8
- package/dist/src/runtime/emit/returning.js.map +1 -1
- package/dist/src/runtime/emit/scan.d.ts.map +1 -1
- package/dist/src/runtime/emit/scan.js +4 -1
- package/dist/src/runtime/emit/scan.js.map +1 -1
- package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
- package/dist/src/runtime/emit/set-operation.js +8 -5
- package/dist/src/runtime/emit/set-operation.js.map +1 -1
- package/dist/src/runtime/emit/sort.js +2 -2
- package/dist/src/runtime/emit/sort.js.map +1 -1
- package/dist/src/runtime/emit/subquery.js +2 -2
- 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 +21 -7
- package/dist/src/runtime/emit/table-valued-function.js.map +1 -1
- package/dist/src/runtime/emit/unary.js +2 -2
- package/dist/src/runtime/emit/unary.js.map +1 -1
- package/dist/src/runtime/emit/update.d.ts.map +1 -1
- package/dist/src/runtime/emit/update.js +43 -21
- 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 +368 -126
- package/dist/src/runtime/emit/window.js.map +1 -1
- package/dist/src/runtime/foreign-key-actions.d.ts +15 -0
- package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -0
- package/dist/src/runtime/foreign-key-actions.js +109 -0
- package/dist/src/runtime/foreign-key-actions.js.map +1 -0
- package/dist/src/runtime/register.d.ts.map +1 -1
- package/dist/src/runtime/register.js +8 -0
- 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 +4 -1
- package/dist/src/runtime/scheduler.js.map +1 -1
- package/dist/src/runtime/types.d.ts +6 -5
- package/dist/src/runtime/types.d.ts.map +1 -1
- package/dist/src/runtime/types.js.map +1 -1
- package/dist/src/schema/change-events.d.ts +36 -8
- package/dist/src/schema/change-events.d.ts.map +1 -1
- package/dist/src/schema/change-events.js.map +1 -1
- package/dist/src/schema/column.d.ts +5 -1
- package/dist/src/schema/column.d.ts.map +1 -1
- package/dist/src/schema/column.js +1 -2
- package/dist/src/schema/column.js.map +1 -1
- package/dist/src/schema/manager.d.ts +54 -4
- package/dist/src/schema/manager.d.ts.map +1 -1
- package/dist/src/schema/manager.js +353 -313
- package/dist/src/schema/manager.js.map +1 -1
- package/dist/src/schema/schema-differ.js +3 -3
- package/dist/src/schema/schema-differ.js.map +1 -1
- package/dist/src/schema/schema.d.ts +1 -1
- package/dist/src/schema/schema.js +2 -2
- package/dist/src/schema/schema.js.map +1 -1
- package/dist/src/schema/table.d.ts +49 -0
- package/dist/src/schema/table.d.ts.map +1 -1
- package/dist/src/schema/table.js +30 -11
- package/dist/src/schema/table.js.map +1 -1
- package/dist/src/types/builtin-types.d.ts.map +1 -1
- package/dist/src/types/builtin-types.js +26 -95
- package/dist/src/types/builtin-types.js.map +1 -1
- package/dist/src/types/index.d.ts +1 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js +1 -1
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/json-type.d.ts.map +1 -1
- package/dist/src/types/json-type.js +28 -40
- package/dist/src/types/json-type.js.map +1 -1
- package/dist/src/types/logical-type.d.ts +6 -0
- package/dist/src/types/logical-type.d.ts.map +1 -1
- package/dist/src/types/logical-type.js +12 -0
- package/dist/src/types/logical-type.js.map +1 -1
- package/dist/src/types/temporal-types.d.ts.map +1 -1
- package/dist/src/types/temporal-types.js +8 -37
- package/dist/src/types/temporal-types.js.map +1 -1
- package/dist/src/util/coercion.d.ts +4 -5
- package/dist/src/util/coercion.d.ts.map +1 -1
- package/dist/src/util/coercion.js +10 -14
- package/dist/src/util/coercion.js.map +1 -1
- package/dist/src/util/comparison.d.ts +34 -21
- package/dist/src/util/comparison.d.ts.map +1 -1
- package/dist/src/util/comparison.js +77 -43
- package/dist/src/util/comparison.js.map +1 -1
- package/dist/src/util/environment.d.ts +0 -8
- package/dist/src/util/environment.d.ts.map +1 -1
- package/dist/src/util/environment.js +0 -12
- package/dist/src/util/environment.js.map +1 -1
- package/dist/src/util/key-serializer.d.ts +33 -0
- package/dist/src/util/key-serializer.d.ts.map +1 -0
- package/dist/src/util/key-serializer.js +95 -0
- package/dist/src/util/key-serializer.js.map +1 -0
- package/dist/src/util/plugin-helper.d.ts.map +1 -1
- package/dist/src/util/plugin-helper.js +21 -45
- package/dist/src/util/plugin-helper.js.map +1 -1
- package/dist/src/util/serialization.d.ts +1 -0
- package/dist/src/util/serialization.d.ts.map +1 -1
- package/dist/src/util/serialization.js +8 -1
- package/dist/src/util/serialization.js.map +1 -1
- package/dist/src/util/working-table-iterable.d.ts +6 -5
- package/dist/src/util/working-table-iterable.d.ts.map +1 -1
- package/dist/src/util/working-table-iterable.js +8 -15
- package/dist/src/util/working-table-iterable.js.map +1 -1
- package/dist/src/vtab/best-access-plan.d.ts +12 -0
- package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
- package/dist/src/vtab/best-access-plan.js +22 -0
- package/dist/src/vtab/best-access-plan.js.map +1 -1
- package/dist/src/vtab/manifest.d.ts +3 -1
- package/dist/src/vtab/manifest.d.ts.map +1 -1
- package/dist/src/vtab/memory/index.d.ts +2 -2
- package/dist/src/vtab/memory/index.d.ts.map +1 -1
- package/dist/src/vtab/memory/index.js +4 -7
- package/dist/src/vtab/memory/index.js.map +1 -1
- package/dist/src/vtab/memory/layer/base-cursor.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/base-cursor.js +37 -9
- package/dist/src/vtab/memory/layer/base-cursor.js.map +1 -1
- package/dist/src/vtab/memory/layer/base.js +1 -1
- package/dist/src/vtab/memory/layer/base.js.map +1 -1
- package/dist/src/vtab/memory/layer/manager.d.ts +15 -3
- package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/manager.js +85 -37
- package/dist/src/vtab/memory/layer/manager.js.map +1 -1
- package/dist/src/vtab/memory/layer/scan-plan.d.ts +2 -0
- package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/scan-plan.js +153 -78
- package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
- package/dist/src/vtab/memory/layer/transaction-cursor.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/transaction-cursor.js +39 -9
- package/dist/src/vtab/memory/layer/transaction-cursor.js.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
- package/dist/src/vtab/memory/layer/transaction.js +1 -5
- package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
- package/dist/src/vtab/memory/module.d.ts +14 -24
- package/dist/src/vtab/memory/module.d.ts.map +1 -1
- package/dist/src/vtab/memory/module.js +88 -283
- package/dist/src/vtab/memory/module.js.map +1 -1
- package/dist/src/vtab/memory/table.d.ts +9 -0
- package/dist/src/vtab/memory/table.d.ts.map +1 -1
- package/dist/src/vtab/memory/table.js +121 -18
- package/dist/src/vtab/memory/table.js.map +1 -1
- package/dist/src/vtab/memory/types.d.ts +1 -0
- package/dist/src/vtab/memory/types.d.ts.map +1 -1
- package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
- package/dist/src/vtab/module.d.ts +13 -0
- package/dist/src/vtab/module.d.ts.map +1 -1
- package/dist/src/vtab/table.d.ts +9 -0
- package/dist/src/vtab/table.d.ts.map +1 -1
- package/dist/src/vtab/table.js.map +1 -1
- package/package.json +2 -2
|
@@ -204,9 +204,9 @@ export class SchemaManager {
|
|
|
204
204
|
if (this.schemas.has(lowerName)) {
|
|
205
205
|
throw new QuereusError(`Schema '${name}' already exists`, StatusCode.ERROR);
|
|
206
206
|
}
|
|
207
|
-
const schema = new Schema(
|
|
207
|
+
const schema = new Schema(lowerName);
|
|
208
208
|
this.schemas.set(lowerName, schema);
|
|
209
|
-
log(`Added schema '%s'`,
|
|
209
|
+
log(`Added schema '%s'`, lowerName);
|
|
210
210
|
return schema;
|
|
211
211
|
}
|
|
212
212
|
/**
|
|
@@ -314,7 +314,7 @@ export class SchemaManager {
|
|
|
314
314
|
* @returns The ViewSchema or undefined if not found
|
|
315
315
|
*/
|
|
316
316
|
getView(schemaName, viewName) {
|
|
317
|
-
const targetSchemaName = schemaName ?? this.currentSchemaName;
|
|
317
|
+
const targetSchemaName = (schemaName ?? this.currentSchemaName).toLowerCase();
|
|
318
318
|
const schema = this.schemas.get(targetSchemaName);
|
|
319
319
|
return schema?.getView(viewName);
|
|
320
320
|
}
|
|
@@ -326,7 +326,7 @@ export class SchemaManager {
|
|
|
326
326
|
* @returns The TableSchema or ViewSchema, or undefined if not found
|
|
327
327
|
*/
|
|
328
328
|
getSchemaItem(schemaName, itemName) {
|
|
329
|
-
const targetSchemaName = schemaName ?? this.currentSchemaName;
|
|
329
|
+
const targetSchemaName = (schemaName ?? this.currentSchemaName).toLowerCase();
|
|
330
330
|
const schema = this.schemas.get(targetSchemaName);
|
|
331
331
|
if (!schema)
|
|
332
332
|
return undefined;
|
|
@@ -414,7 +414,7 @@ export class SchemaManager {
|
|
|
414
414
|
* @returns True if the view was found and dropped, false otherwise
|
|
415
415
|
*/
|
|
416
416
|
dropView(schemaName, viewName) {
|
|
417
|
-
const schema = this.schemas.get(schemaName);
|
|
417
|
+
const schema = this.schemas.get(schemaName.toLowerCase());
|
|
418
418
|
if (!schema)
|
|
419
419
|
return false;
|
|
420
420
|
return schema.removeView(viewName);
|
|
@@ -452,137 +452,15 @@ export class SchemaManager {
|
|
|
452
452
|
* @returns The TableSchema or undefined if not found
|
|
453
453
|
*/
|
|
454
454
|
getTable(schemaName, tableName) {
|
|
455
|
-
const targetSchemaName = schemaName ?? this.currentSchemaName;
|
|
455
|
+
const targetSchemaName = (schemaName ?? this.currentSchemaName).toLowerCase();
|
|
456
456
|
const schema = this.schemas.get(targetSchemaName);
|
|
457
457
|
return schema?.getTable(tableName);
|
|
458
458
|
}
|
|
459
459
|
/**
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
*
|
|
463
|
-
* @param stmt The AST node for the CREATE INDEX statement.
|
|
464
|
-
* @returns A Promise that resolves when the index is created.
|
|
465
|
-
* @throws QuereusError on errors (e.g., table not found, column not found, createIndex fails).
|
|
466
|
-
*/
|
|
467
|
-
async createIndex(stmt) {
|
|
468
|
-
const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
|
|
469
|
-
const tableName = stmt.table.name;
|
|
470
|
-
const indexName = stmt.index.name;
|
|
471
|
-
// Find the table schema
|
|
472
|
-
const tableSchema = this.getTable(targetSchemaName, tableName);
|
|
473
|
-
if (!tableSchema) {
|
|
474
|
-
throw new QuereusError(`no such table: ${tableName}`, StatusCode.ERROR, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
|
|
475
|
-
}
|
|
476
|
-
// Check if the virtual table module supports createIndex
|
|
477
|
-
if (!tableSchema.vtabModule.createIndex) {
|
|
478
|
-
throw new QuereusError(`Virtual table module '${tableSchema.vtabModuleName}' for table '${tableName}' does not support CREATE INDEX.`, StatusCode.ERROR, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
|
|
479
|
-
}
|
|
480
|
-
// Check if index already exists (if not IF NOT EXISTS)
|
|
481
|
-
const existingIndex = tableSchema.indexes?.find(idx => idx.name.toLowerCase() === indexName.toLowerCase());
|
|
482
|
-
if (existingIndex) {
|
|
483
|
-
if (stmt.ifNotExists) {
|
|
484
|
-
log(`Skipping CREATE INDEX: Index %s.%s already exists (IF NOT EXISTS).`, targetSchemaName, indexName);
|
|
485
|
-
return;
|
|
486
|
-
}
|
|
487
|
-
else {
|
|
488
|
-
throw new QuereusError(`Index ${indexName} already exists on table ${tableName}`, StatusCode.CONSTRAINT, undefined, stmt.index.loc?.start.line, stmt.index.loc?.start.column);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
// Convert AST columns to IndexSchema columns
|
|
492
|
-
const indexColumns = stmt.columns.map((indexedCol) => {
|
|
493
|
-
if (indexedCol.expr) {
|
|
494
|
-
throw new QuereusError(`Indices on expressions are not supported yet.`, StatusCode.ERROR, undefined, indexedCol.expr.loc?.start.line, indexedCol.expr.loc?.start.column);
|
|
495
|
-
}
|
|
496
|
-
const colName = indexedCol.name;
|
|
497
|
-
if (!colName) {
|
|
498
|
-
// Should not happen if expr is checked first
|
|
499
|
-
throw new QuereusError(`Indexed column must be a simple column name.`, StatusCode.ERROR);
|
|
500
|
-
}
|
|
501
|
-
const tableColIndex = tableSchema.columnIndexMap.get(colName.toLowerCase());
|
|
502
|
-
if (tableColIndex === undefined) {
|
|
503
|
-
throw new QuereusError(`Column '${colName}' not found in table '${tableName}'`, StatusCode.ERROR, undefined, stmt.loc?.start.line, stmt.loc?.start.column);
|
|
504
|
-
}
|
|
505
|
-
const tableColSchema = tableSchema.columns[tableColIndex];
|
|
506
|
-
return {
|
|
507
|
-
index: tableColIndex,
|
|
508
|
-
desc: indexedCol.direction === 'desc',
|
|
509
|
-
collation: indexedCol.collation || tableColSchema.collation // Use specified collation or inherit from table column
|
|
510
|
-
};
|
|
511
|
-
});
|
|
512
|
-
// Construct the IndexSchema object
|
|
513
|
-
const indexSchema = {
|
|
514
|
-
name: indexName,
|
|
515
|
-
columns: Object.freeze(indexColumns),
|
|
516
|
-
};
|
|
517
|
-
try {
|
|
518
|
-
// Call createIndex on the virtual table module
|
|
519
|
-
await tableSchema.vtabModule.createIndex(this.db, targetSchemaName, tableName, indexSchema);
|
|
520
|
-
// Update the table schema with the new index by creating a new schema object
|
|
521
|
-
const updatedIndexes = [...(tableSchema.indexes || []), indexSchema];
|
|
522
|
-
const updatedTableSchema = {
|
|
523
|
-
...tableSchema,
|
|
524
|
-
indexes: Object.freeze(updatedIndexes),
|
|
525
|
-
};
|
|
526
|
-
// Replace the table schema in the schema
|
|
527
|
-
const schema = this.getSchemaOrFail(targetSchemaName);
|
|
528
|
-
schema.addTable(updatedTableSchema);
|
|
529
|
-
// Notify schema change listeners that the table was modified
|
|
530
|
-
this.changeNotifier.notifyChange({
|
|
531
|
-
type: 'table_modified',
|
|
532
|
-
schemaName: targetSchemaName,
|
|
533
|
-
objectName: tableName,
|
|
534
|
-
oldObject: tableSchema,
|
|
535
|
-
newObject: updatedTableSchema
|
|
536
|
-
});
|
|
537
|
-
// Emit auto schema event for modules without native event support
|
|
538
|
-
const moduleReg = tableSchema.vtabModuleName ? this.getModule(tableSchema.vtabModuleName) : undefined;
|
|
539
|
-
if (this.db.hasSchemaListeners() && !hasNativeEventSupport(moduleReg?.module)) {
|
|
540
|
-
this.db._getEventEmitter().emitAutoSchemaEvent(tableSchema.vtabModuleName ?? 'memory', {
|
|
541
|
-
type: 'create',
|
|
542
|
-
objectType: 'index',
|
|
543
|
-
schemaName: targetSchemaName,
|
|
544
|
-
objectName: indexName,
|
|
545
|
-
});
|
|
546
|
-
}
|
|
547
|
-
log(`Successfully created index %s on table %s.%s`, indexName, targetSchemaName, tableName);
|
|
548
|
-
}
|
|
549
|
-
catch (e) {
|
|
550
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
551
|
-
const code = e instanceof QuereusError ? e.code : StatusCode.ERROR;
|
|
552
|
-
throw new QuereusError(`createIndex failed for index '${indexName}' on table '${tableName}': ${message}`, code, e instanceof Error ? e : undefined, stmt.loc?.start.line, stmt.loc?.start.column);
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
/**
|
|
556
|
-
* Defines a new table in the schema based on an AST.CreateTableStmt.
|
|
557
|
-
* This method encapsulates the logic for interacting with VTab modules (create)
|
|
558
|
-
* and registering the new table schema.
|
|
559
|
-
*
|
|
560
|
-
* @param stmt The AST node for the CREATE TABLE statement.
|
|
561
|
-
* @returns A Promise that resolves to the created TableSchema.
|
|
562
|
-
* @throws QuereusError on errors (e.g., module not found, create fails, table exists).
|
|
460
|
+
* Resolves the VTab module name and args from a CREATE TABLE statement,
|
|
461
|
+
* falling back to configured defaults when USING is omitted.
|
|
563
462
|
*/
|
|
564
|
-
|
|
565
|
-
const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
|
|
566
|
-
const tableName = stmt.table.name;
|
|
567
|
-
// Check IF NOT EXISTS
|
|
568
|
-
const schema = this.getSchema(targetSchemaName);
|
|
569
|
-
if (!schema) {
|
|
570
|
-
throw new QuereusError(`Internal error: Schema '${targetSchemaName}' not found.`, StatusCode.INTERNAL);
|
|
571
|
-
}
|
|
572
|
-
const existingTable = schema.getTable(tableName);
|
|
573
|
-
const existingView = schema.getView(tableName);
|
|
574
|
-
if (existingTable || existingView) {
|
|
575
|
-
if (stmt.ifNotExists) {
|
|
576
|
-
log(`Skipping CREATE TABLE: Item %s.%s already exists (IF NOT EXISTS).`, targetSchemaName, tableName);
|
|
577
|
-
if (existingTable)
|
|
578
|
-
return existingTable;
|
|
579
|
-
throw new QuereusError(`Cannot CREATE TABLE ${targetSchemaName}.${tableName}: a VIEW with the same name already exists.`, StatusCode.CONSTRAINT, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
|
|
580
|
-
}
|
|
581
|
-
else {
|
|
582
|
-
const itemType = existingTable ? 'Table' : 'View';
|
|
583
|
-
throw new QuereusError(`${itemType} ${targetSchemaName}.${tableName} already exists`, StatusCode.CONSTRAINT, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
463
|
+
resolveModuleInfo(stmt) {
|
|
586
464
|
let moduleName;
|
|
587
465
|
let effectiveModuleArgs;
|
|
588
466
|
if (stmt.moduleName) {
|
|
@@ -598,31 +476,38 @@ export class SchemaManager {
|
|
|
598
476
|
if (!moduleInfo || !moduleInfo.module) {
|
|
599
477
|
throw new QuereusError(`No virtual table module named '${moduleName}'`, StatusCode.ERROR, undefined, stmt.loc?.start.line, stmt.loc?.start.column);
|
|
600
478
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
const
|
|
479
|
+
return { moduleName, effectiveModuleArgs, moduleInfo };
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Builds column schemas from AST column/constraint definitions,
|
|
483
|
+
* resolving PK membership and nullability.
|
|
484
|
+
*/
|
|
485
|
+
buildColumnSchemas(astColumns, astConstraints, defaultNotNull) {
|
|
486
|
+
const preliminaryColumnSchemas = astColumns.map(colDef => columnDefToSchema(colDef, defaultNotNull));
|
|
487
|
+
const pkDefinition = findPKDefinition(preliminaryColumnSchemas, astConstraints);
|
|
488
|
+
const columns = preliminaryColumnSchemas.map((col, idx) => {
|
|
609
489
|
const isPkColumn = pkDefinition.some(pkCol => pkCol.index === idx);
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
}
|
|
490
|
+
const pkOrder = isPkColumn
|
|
491
|
+
? pkDefinition.findIndex(pkC => pkC.index === idx) + 1
|
|
492
|
+
: 0;
|
|
614
493
|
return {
|
|
615
494
|
...col,
|
|
616
495
|
primaryKey: isPkColumn,
|
|
617
|
-
pkOrder
|
|
496
|
+
pkOrder,
|
|
618
497
|
notNull: isPkColumn ? true : col.notNull,
|
|
619
498
|
};
|
|
620
499
|
});
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
500
|
+
return { columns, pkDefinition };
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Extracts CHECK constraints from AST column and table constraint definitions.
|
|
504
|
+
*/
|
|
505
|
+
extractCheckConstraints(astColumns, astConstraints) {
|
|
506
|
+
const result = [];
|
|
507
|
+
for (const colDef of astColumns) {
|
|
508
|
+
for (const con of colDef.constraints ?? []) {
|
|
624
509
|
if (con.type === 'check' && con.expr) {
|
|
625
|
-
|
|
510
|
+
result.push({
|
|
626
511
|
name: con.name ?? `_check_${colDef.name}`,
|
|
627
512
|
expr: con.expr,
|
|
628
513
|
operations: opsToMask(con.operations),
|
|
@@ -630,11 +515,11 @@ export class SchemaManager {
|
|
|
630
515
|
initiallyDeferred: con.initiallyDeferred
|
|
631
516
|
});
|
|
632
517
|
}
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
(
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
for (const con of astConstraints ?? []) {
|
|
636
521
|
if (con.type === 'check' && con.expr) {
|
|
637
|
-
|
|
522
|
+
result.push({
|
|
638
523
|
name: con.name,
|
|
639
524
|
expr: con.expr,
|
|
640
525
|
operations: opsToMask(con.operations),
|
|
@@ -642,16 +527,147 @@ export class SchemaManager {
|
|
|
642
527
|
initiallyDeferred: con.initiallyDeferred
|
|
643
528
|
});
|
|
644
529
|
}
|
|
645
|
-
}
|
|
646
|
-
|
|
530
|
+
}
|
|
531
|
+
return result;
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Extracts FOREIGN KEY constraints from AST column and table constraint definitions.
|
|
535
|
+
* Resolves column indices in the child table. Parent table resolution is deferred
|
|
536
|
+
* to enforcement time (the parent table may not exist yet during declarative schema setup).
|
|
537
|
+
*/
|
|
538
|
+
extractForeignKeys(astColumns, astConstraints, columnIndexMap, tableName, schemaName) {
|
|
539
|
+
const result = [];
|
|
540
|
+
// Column-level foreign keys
|
|
541
|
+
for (const colDef of astColumns) {
|
|
542
|
+
for (const con of colDef.constraints ?? []) {
|
|
543
|
+
if (con.type === 'foreignKey' && con.foreignKey) {
|
|
544
|
+
const fk = con.foreignKey;
|
|
545
|
+
const childColIndex = columnIndexMap.get(colDef.name.toLowerCase());
|
|
546
|
+
if (childColIndex === undefined) {
|
|
547
|
+
throw new QuereusError(`FK column '${colDef.name}' not found in table '${tableName}'`, StatusCode.ERROR);
|
|
548
|
+
}
|
|
549
|
+
// Parent column resolution is deferred — store names for now
|
|
550
|
+
// We need the parent table schema to resolve indices, but it may not exist yet
|
|
551
|
+
result.push({
|
|
552
|
+
name: con.name ?? `_fk_${tableName}_${colDef.name}`,
|
|
553
|
+
columns: Object.freeze([childColIndex]),
|
|
554
|
+
referencedTable: fk.table,
|
|
555
|
+
referencedSchema: schemaName,
|
|
556
|
+
referencedColumns: Object.freeze([]), // resolved at enforcement time
|
|
557
|
+
referencedColumnNames: fk.columns, // deferred resolution via resolveReferencedColumns
|
|
558
|
+
onDelete: fk.onDelete ?? 'noAction',
|
|
559
|
+
onUpdate: fk.onUpdate ?? 'noAction',
|
|
560
|
+
deferred: fk.initiallyDeferred ?? false,
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
// Table-level foreign keys
|
|
566
|
+
for (const con of astConstraints ?? []) {
|
|
567
|
+
if (con.type === 'foreignKey' && con.foreignKey && con.columns) {
|
|
568
|
+
const fk = con.foreignKey;
|
|
569
|
+
const childColIndices = con.columns.map(col => {
|
|
570
|
+
const idx = columnIndexMap.get(col.name.toLowerCase());
|
|
571
|
+
if (idx === undefined) {
|
|
572
|
+
throw new QuereusError(`FK column '${col.name}' not found in table '${tableName}'`, StatusCode.ERROR);
|
|
573
|
+
}
|
|
574
|
+
return idx;
|
|
575
|
+
});
|
|
576
|
+
result.push({
|
|
577
|
+
name: con.name ?? `_fk_${tableName}_${con.columns.map(c => c.name).join('_')}`,
|
|
578
|
+
columns: Object.freeze(childColIndices),
|
|
579
|
+
referencedTable: fk.table,
|
|
580
|
+
referencedSchema: schemaName,
|
|
581
|
+
referencedColumns: Object.freeze([]), // resolved at enforcement time
|
|
582
|
+
referencedColumnNames: fk.columns, // deferred resolution via resolveReferencedColumns
|
|
583
|
+
onDelete: fk.onDelete ?? 'noAction',
|
|
584
|
+
onUpdate: fk.onUpdate ?? 'noAction',
|
|
585
|
+
deferred: fk.initiallyDeferred ?? false,
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
return result;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Extracts UNIQUE constraints from AST column and table constraint definitions.
|
|
593
|
+
* Resolves column names to indices.
|
|
594
|
+
*/
|
|
595
|
+
extractUniqueConstraints(astColumns, astConstraints, columnIndexMap) {
|
|
596
|
+
const result = [];
|
|
597
|
+
// Column-level unique constraints
|
|
598
|
+
for (const colDef of astColumns) {
|
|
599
|
+
for (const con of colDef.constraints ?? []) {
|
|
600
|
+
if (con.type === 'unique') {
|
|
601
|
+
const colIndex = columnIndexMap.get(colDef.name.toLowerCase());
|
|
602
|
+
if (colIndex !== undefined) {
|
|
603
|
+
result.push({
|
|
604
|
+
name: con.name,
|
|
605
|
+
columns: Object.freeze([colIndex]),
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
// Table-level unique constraints
|
|
612
|
+
for (const con of astConstraints ?? []) {
|
|
613
|
+
if (con.type === 'unique' && con.columns && con.columns.length > 0) {
|
|
614
|
+
const colIndices = con.columns.map(col => {
|
|
615
|
+
const idx = columnIndexMap.get(col.name.toLowerCase());
|
|
616
|
+
if (idx === undefined) {
|
|
617
|
+
throw new QuereusError(`UNIQUE constraint column '${col.name}' not found`, StatusCode.ERROR);
|
|
618
|
+
}
|
|
619
|
+
return idx;
|
|
620
|
+
});
|
|
621
|
+
result.push({
|
|
622
|
+
name: con.name,
|
|
623
|
+
columns: Object.freeze(colIndices),
|
|
624
|
+
});
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
return result;
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Builds a base TableSchema from an AST CREATE TABLE statement.
|
|
631
|
+
* Shared by both createTable (new storage) and importTable (existing storage).
|
|
632
|
+
*/
|
|
633
|
+
buildTableSchemaFromAST(stmt, moduleName, effectiveModuleArgs, moduleInfo) {
|
|
634
|
+
const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
|
|
635
|
+
const tableName = stmt.table.name;
|
|
636
|
+
const defaultNullability = this.db.options.getStringOption('default_column_nullability');
|
|
637
|
+
const defaultNotNull = defaultNullability === 'not_null';
|
|
638
|
+
const astColumns = stmt.columns || [];
|
|
639
|
+
const { columns, pkDefinition } = this.buildColumnSchemas(astColumns, stmt.constraints, defaultNotNull);
|
|
640
|
+
const checkConstraints = this.extractCheckConstraints(astColumns, stmt.constraints);
|
|
641
|
+
const columnIndexMap = buildColumnIndexMap(columns);
|
|
642
|
+
const foreignKeys = this.extractForeignKeys(astColumns, stmt.constraints, columnIndexMap, tableName, targetSchemaName);
|
|
643
|
+
const uniqueConstraints = this.extractUniqueConstraints(astColumns, stmt.constraints, columnIndexMap);
|
|
647
644
|
const mutationContextSchemas = stmt.contextDefinitions
|
|
648
645
|
? stmt.contextDefinitions.map(varDef => mutationContextVarToSchema(varDef, defaultNotNull))
|
|
649
646
|
: undefined;
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
647
|
+
return {
|
|
648
|
+
name: tableName,
|
|
649
|
+
schemaName: targetSchemaName,
|
|
650
|
+
columns: Object.freeze(columns),
|
|
651
|
+
columnIndexMap,
|
|
652
|
+
primaryKeyDefinition: pkDefinition,
|
|
653
|
+
checkConstraints: Object.freeze(checkConstraints),
|
|
654
|
+
foreignKeys: foreignKeys.length > 0 ? Object.freeze(foreignKeys) : undefined,
|
|
655
|
+
uniqueConstraints: uniqueConstraints.length > 0 ? Object.freeze(uniqueConstraints) : undefined,
|
|
656
|
+
isTemporary: !!stmt.isTemporary,
|
|
657
|
+
isView: false,
|
|
658
|
+
vtabModuleName: moduleName,
|
|
659
|
+
vtabArgs: effectiveModuleArgs,
|
|
660
|
+
vtabModule: moduleInfo.module,
|
|
661
|
+
vtabAuxData: moduleInfo.auxData,
|
|
662
|
+
estimatedRows: 0,
|
|
663
|
+
mutationContext: mutationContextSchemas ? Object.freeze(mutationContextSchemas) : undefined,
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Validates that all DEFAULT expressions in the column schemas are deterministic.
|
|
668
|
+
* Skips expressions that reference columns (validated at INSERT time instead).
|
|
669
|
+
*/
|
|
670
|
+
validateDefaultDeterminism(columns, tableName) {
|
|
655
671
|
const globalScope = new GlobalScope(this.db.schemaManager);
|
|
656
672
|
const parameterScope = new ParameterScope(globalScope);
|
|
657
673
|
const planningCtx = {
|
|
@@ -665,63 +681,36 @@ export class SchemaManager {
|
|
|
665
681
|
cteReferenceCache: new Map(),
|
|
666
682
|
outputScopes: new Map()
|
|
667
683
|
};
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
if (defaultExpr) {
|
|
686
|
-
const result = checkDeterministic(defaultExpr);
|
|
687
|
-
if (!result.valid) {
|
|
688
|
-
throw new QuereusError(`Non-deterministic expression not allowed in DEFAULT for column '${col.name}' in table '${tableName}'. ` +
|
|
689
|
-
`Expression: ${result.expression}. ` +
|
|
690
|
-
`Use mutation context to pass non-deterministic values (e.g., WITH CONTEXT (timestamp = datetime('now'))).`, StatusCode.ERROR);
|
|
691
|
-
}
|
|
684
|
+
for (const col of columns) {
|
|
685
|
+
if (!col.defaultValue || typeof col.defaultValue !== 'object' || col.defaultValue === null || !('type' in col.defaultValue)) {
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
688
|
+
let defaultExpr;
|
|
689
|
+
try {
|
|
690
|
+
defaultExpr = buildExpression(planningCtx, col.defaultValue);
|
|
691
|
+
}
|
|
692
|
+
catch (_e) {
|
|
693
|
+
log('Skipping determinism validation for default on column %s.%s at CREATE TABLE time (will validate at INSERT time): %s', tableName, col.name, _e.message);
|
|
694
|
+
}
|
|
695
|
+
if (defaultExpr) {
|
|
696
|
+
const result = checkDeterministic(defaultExpr);
|
|
697
|
+
if (!result.valid) {
|
|
698
|
+
throw new QuereusError(`Non-deterministic expression not allowed in DEFAULT for column '${col.name}' in table '${tableName}'. ` +
|
|
699
|
+
`Expression: ${result.expression}. ` +
|
|
700
|
+
`Use mutation context to pass non-deterministic values (e.g., WITH CONTEXT (timestamp = datetime('now'))).`, StatusCode.ERROR);
|
|
692
701
|
}
|
|
693
702
|
}
|
|
694
703
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
checkConstraints: Object.freeze(checkConstraintsSchema),
|
|
702
|
-
isTemporary: !!stmt.isTemporary,
|
|
703
|
-
isView: false,
|
|
704
|
-
vtabModuleName: moduleName,
|
|
705
|
-
vtabArgs: effectiveModuleArgs,
|
|
706
|
-
vtabModule: moduleInfo.module,
|
|
707
|
-
vtabAuxData: moduleInfo.auxData,
|
|
708
|
-
estimatedRows: 0,
|
|
709
|
-
mutationContext: mutationContextSchemas ? Object.freeze(mutationContextSchemas) : undefined,
|
|
710
|
-
};
|
|
711
|
-
let tableInstance;
|
|
712
|
-
try {
|
|
713
|
-
tableInstance = await moduleInfo.module.create(this.db, baseTableSchema);
|
|
714
|
-
}
|
|
715
|
-
catch (e) {
|
|
716
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
717
|
-
const code = e instanceof QuereusError ? e.code : StatusCode.ERROR;
|
|
718
|
-
throw new QuereusError(`Module '${moduleName}' create failed for table '${tableName}': ${message}`, code, e instanceof Error ? e : undefined, stmt.loc?.start.line, stmt.loc?.start.column);
|
|
719
|
-
}
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Registers a table schema after module.create() returns, correcting
|
|
707
|
+
* name/schema if the module returned different values.
|
|
708
|
+
*/
|
|
709
|
+
finalizeCreatedTableSchema(tableInstance, tableName, targetSchemaName, moduleName, effectiveModuleArgs, moduleInfo) {
|
|
720
710
|
const finalRegisteredSchema = tableInstance.tableSchema;
|
|
721
711
|
if (!finalRegisteredSchema) {
|
|
722
712
|
throw new QuereusError(`Module '${moduleName}' create did not provide a tableSchema for '${tableName}'.`, StatusCode.INTERNAL);
|
|
723
713
|
}
|
|
724
|
-
// Create a properly typed schema object instead of mutating properties
|
|
725
714
|
let correctedSchema = finalRegisteredSchema;
|
|
726
715
|
if (finalRegisteredSchema.name.toLowerCase() !== tableName.toLowerCase() ||
|
|
727
716
|
finalRegisteredSchema.schemaName.toLowerCase() !== targetSchemaName.toLowerCase()) {
|
|
@@ -732,8 +721,7 @@ export class SchemaManager {
|
|
|
732
721
|
schemaName: targetSchemaName,
|
|
733
722
|
};
|
|
734
723
|
}
|
|
735
|
-
|
|
736
|
-
const completeTableSchema = {
|
|
724
|
+
return {
|
|
737
725
|
...correctedSchema,
|
|
738
726
|
vtabModuleName: moduleName,
|
|
739
727
|
vtabArgs: effectiveModuleArgs,
|
|
@@ -741,25 +729,161 @@ export class SchemaManager {
|
|
|
741
729
|
vtabAuxData: moduleInfo.auxData,
|
|
742
730
|
estimatedRows: correctedSchema.estimatedRows ?? 0,
|
|
743
731
|
};
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Creates a new index on an existing table based on an AST.CreateIndexStmt.
|
|
735
|
+
*
|
|
736
|
+
* @param stmt The AST node for the CREATE INDEX statement.
|
|
737
|
+
* @throws QuereusError on errors (e.g., table not found, column not found, createIndex fails).
|
|
738
|
+
*/
|
|
739
|
+
async createIndex(stmt) {
|
|
740
|
+
const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
|
|
741
|
+
const tableName = stmt.table.name;
|
|
742
|
+
const indexName = stmt.index.name;
|
|
743
|
+
const tableSchema = this.getTable(targetSchemaName, tableName);
|
|
744
|
+
if (!tableSchema) {
|
|
745
|
+
throw new QuereusError(`no such table: ${tableName}`, StatusCode.ERROR, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
|
|
746
|
+
}
|
|
747
|
+
if (!tableSchema.vtabModule.createIndex) {
|
|
748
|
+
throw new QuereusError(`Virtual table module '${tableSchema.vtabModuleName}' for table '${tableName}' does not support CREATE INDEX.`, StatusCode.ERROR, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
|
|
749
|
+
}
|
|
750
|
+
const existingIndex = tableSchema.indexes?.find(idx => idx.name.toLowerCase() === indexName.toLowerCase());
|
|
751
|
+
if (existingIndex) {
|
|
752
|
+
if (stmt.ifNotExists) {
|
|
753
|
+
log(`Skipping CREATE INDEX: Index %s.%s already exists (IF NOT EXISTS).`, targetSchemaName, indexName);
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
throw new QuereusError(`Index ${indexName} already exists on table ${tableName}`, StatusCode.CONSTRAINT, undefined, stmt.index.loc?.start.line, stmt.index.loc?.start.column);
|
|
757
|
+
}
|
|
758
|
+
const indexSchema = this.buildIndexSchema(stmt, tableSchema, tableName, indexName);
|
|
759
|
+
try {
|
|
760
|
+
await tableSchema.vtabModule.createIndex(this.db, targetSchemaName, tableName, indexSchema);
|
|
761
|
+
}
|
|
762
|
+
catch (e) {
|
|
763
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
764
|
+
const code = e instanceof QuereusError ? e.code : StatusCode.ERROR;
|
|
765
|
+
throw new QuereusError(`createIndex failed for index '${indexName}' on table '${tableName}': ${message}`, code, e instanceof Error ? e : undefined, stmt.loc?.start.line, stmt.loc?.start.column);
|
|
766
|
+
}
|
|
767
|
+
const updatedTableSchema = this.addIndexToTableSchema(tableSchema, indexSchema);
|
|
768
|
+
const schema = this.getSchemaOrFail(targetSchemaName);
|
|
769
|
+
schema.addTable(updatedTableSchema);
|
|
770
|
+
this.changeNotifier.notifyChange({
|
|
771
|
+
type: 'table_modified',
|
|
772
|
+
schemaName: targetSchemaName,
|
|
773
|
+
objectName: tableName,
|
|
774
|
+
oldObject: tableSchema,
|
|
775
|
+
newObject: updatedTableSchema
|
|
776
|
+
});
|
|
777
|
+
this.emitAutoSchemaEventIfNeeded(tableSchema.vtabModuleName, {
|
|
778
|
+
type: 'create',
|
|
779
|
+
objectType: 'index',
|
|
780
|
+
schemaName: targetSchemaName,
|
|
781
|
+
objectName: indexName,
|
|
782
|
+
});
|
|
783
|
+
log(`Successfully created index %s on table %s.%s`, indexName, targetSchemaName, tableName);
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* Builds an IndexSchema from AST column definitions, validating against the table schema.
|
|
787
|
+
*/
|
|
788
|
+
buildIndexSchema(stmt, tableSchema, tableName, indexName) {
|
|
789
|
+
const indexColumns = stmt.columns.map((indexedCol) => {
|
|
790
|
+
if (indexedCol.expr) {
|
|
791
|
+
throw new QuereusError(`Indices on expressions are not supported yet.`, StatusCode.ERROR, undefined, indexedCol.expr.loc?.start.line, indexedCol.expr.loc?.start.column);
|
|
792
|
+
}
|
|
793
|
+
const colName = indexedCol.name;
|
|
794
|
+
if (!colName) {
|
|
795
|
+
throw new QuereusError(`Indexed column must be a simple column name.`, StatusCode.ERROR);
|
|
796
|
+
}
|
|
797
|
+
const tableColIndex = tableSchema.columnIndexMap.get(colName.toLowerCase());
|
|
798
|
+
if (tableColIndex === undefined) {
|
|
799
|
+
throw new QuereusError(`Column '${colName}' not found in table '${tableName}'`, StatusCode.ERROR, undefined, stmt.loc?.start.line, stmt.loc?.start.column);
|
|
800
|
+
}
|
|
801
|
+
const tableColSchema = tableSchema.columns[tableColIndex];
|
|
802
|
+
return {
|
|
803
|
+
index: tableColIndex,
|
|
804
|
+
desc: indexedCol.direction === 'desc',
|
|
805
|
+
collation: indexedCol.collation || tableColSchema.collation
|
|
806
|
+
};
|
|
807
|
+
});
|
|
808
|
+
return {
|
|
809
|
+
name: indexName,
|
|
810
|
+
columns: Object.freeze(indexColumns),
|
|
811
|
+
};
|
|
812
|
+
}
|
|
813
|
+
/**
|
|
814
|
+
* Returns a new TableSchema with the given index appended.
|
|
815
|
+
*/
|
|
816
|
+
addIndexToTableSchema(tableSchema, indexSchema) {
|
|
817
|
+
const updatedIndexes = [...(tableSchema.indexes || []), indexSchema];
|
|
818
|
+
return {
|
|
819
|
+
...tableSchema,
|
|
820
|
+
indexes: Object.freeze(updatedIndexes),
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* Emits an auto schema event for modules that don't have native event support,
|
|
825
|
+
* if any schema listeners are registered.
|
|
826
|
+
*/
|
|
827
|
+
emitAutoSchemaEventIfNeeded(moduleName, event) {
|
|
828
|
+
const moduleReg = moduleName ? this.getModule(moduleName) : undefined;
|
|
829
|
+
if (this.db.hasSchemaListeners() && !hasNativeEventSupport(moduleReg?.module)) {
|
|
830
|
+
this.db._getEventEmitter().emitAutoSchemaEvent(moduleName ?? 'memory', event);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Defines a new table in the schema based on an AST.CreateTableStmt.
|
|
835
|
+
* Interacts with VTab modules (create) and registers the new table schema.
|
|
836
|
+
*
|
|
837
|
+
* @param stmt The AST node for the CREATE TABLE statement.
|
|
838
|
+
* @returns A Promise that resolves to the created TableSchema.
|
|
839
|
+
* @throws QuereusError on errors (e.g., module not found, create fails, table exists).
|
|
840
|
+
*/
|
|
841
|
+
async createTable(stmt) {
|
|
842
|
+
const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
|
|
843
|
+
const tableName = stmt.table.name;
|
|
844
|
+
const schema = this.getSchema(targetSchemaName);
|
|
845
|
+
if (!schema) {
|
|
846
|
+
throw new QuereusError(`Internal error: Schema '${targetSchemaName}' not found.`, StatusCode.INTERNAL);
|
|
847
|
+
}
|
|
848
|
+
const existingTable = schema.getTable(tableName);
|
|
849
|
+
const existingView = schema.getView(tableName);
|
|
850
|
+
if (existingTable || existingView) {
|
|
851
|
+
if (stmt.ifNotExists) {
|
|
852
|
+
log(`Skipping CREATE TABLE: Item %s.%s already exists (IF NOT EXISTS).`, targetSchemaName, tableName);
|
|
853
|
+
if (existingTable)
|
|
854
|
+
return existingTable;
|
|
855
|
+
throw new QuereusError(`Cannot CREATE TABLE ${targetSchemaName}.${tableName}: a VIEW with the same name already exists.`, StatusCode.CONSTRAINT, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
|
|
856
|
+
}
|
|
857
|
+
const itemType = existingTable ? 'Table' : 'View';
|
|
858
|
+
throw new QuereusError(`${itemType} ${targetSchemaName}.${tableName} already exists`, StatusCode.CONSTRAINT, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
|
|
859
|
+
}
|
|
860
|
+
const { moduleName, effectiveModuleArgs, moduleInfo } = this.resolveModuleInfo(stmt);
|
|
861
|
+
const baseTableSchema = this.buildTableSchemaFromAST(stmt, moduleName, effectiveModuleArgs, moduleInfo);
|
|
862
|
+
this.validateDefaultDeterminism(baseTableSchema.columns, tableName);
|
|
863
|
+
let tableInstance;
|
|
864
|
+
try {
|
|
865
|
+
tableInstance = await moduleInfo.module.create(this.db, baseTableSchema);
|
|
866
|
+
}
|
|
867
|
+
catch (e) {
|
|
868
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
869
|
+
const code = e instanceof QuereusError ? e.code : StatusCode.ERROR;
|
|
870
|
+
throw new QuereusError(`Module '${moduleName}' create failed for table '${tableName}': ${message}`, code, e instanceof Error ? e : undefined, stmt.loc?.start.line, stmt.loc?.start.column);
|
|
871
|
+
}
|
|
872
|
+
const completeTableSchema = this.finalizeCreatedTableSchema(tableInstance, tableName, targetSchemaName, moduleName, effectiveModuleArgs, moduleInfo);
|
|
744
873
|
schema.addTable(completeTableSchema);
|
|
745
874
|
log(`Successfully created table %s.%s using module %s`, targetSchemaName, tableName, moduleName);
|
|
746
|
-
// Notify schema change listeners
|
|
747
875
|
this.changeNotifier.notifyChange({
|
|
748
876
|
type: 'table_added',
|
|
749
877
|
schemaName: targetSchemaName,
|
|
750
878
|
objectName: tableName,
|
|
751
879
|
newObject: completeTableSchema
|
|
752
880
|
});
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
schemaName: targetSchemaName,
|
|
760
|
-
objectName: tableName,
|
|
761
|
-
});
|
|
762
|
-
}
|
|
881
|
+
this.emitAutoSchemaEventIfNeeded(moduleName, {
|
|
882
|
+
type: 'create',
|
|
883
|
+
objectType: 'table',
|
|
884
|
+
schemaName: targetSchemaName,
|
|
885
|
+
objectName: tableName,
|
|
886
|
+
});
|
|
763
887
|
return completeTableSchema;
|
|
764
888
|
}
|
|
765
889
|
/**
|
|
@@ -800,7 +924,6 @@ export class SchemaManager {
|
|
|
800
924
|
* Import a single DDL statement without creating storage.
|
|
801
925
|
*/
|
|
802
926
|
async importSingleDDL(ddl) {
|
|
803
|
-
// Parse the DDL using the parser
|
|
804
927
|
const parser = new Parser();
|
|
805
928
|
const statements = parser.parseAll(ddl);
|
|
806
929
|
if (statements.length !== 1) {
|
|
@@ -813,9 +936,7 @@ export class SchemaManager {
|
|
|
813
936
|
else if (stmt.type === 'createIndex') {
|
|
814
937
|
return this.importIndex(stmt);
|
|
815
938
|
}
|
|
816
|
-
|
|
817
|
-
throw new QuereusError(`importCatalog does not support statement type: ${stmt.type}`, StatusCode.ERROR);
|
|
818
|
-
}
|
|
939
|
+
throw new QuereusError(`importCatalog does not support statement type: ${stmt.type}`, StatusCode.ERROR);
|
|
819
940
|
}
|
|
820
941
|
/**
|
|
821
942
|
* Import a table schema without calling module.create().
|
|
@@ -824,102 +945,21 @@ export class SchemaManager {
|
|
|
824
945
|
async importTable(stmt) {
|
|
825
946
|
const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
|
|
826
947
|
const tableName = stmt.table.name;
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
if (stmt.moduleName) {
|
|
830
|
-
moduleName = stmt.moduleName;
|
|
831
|
-
effectiveModuleArgs = Object.freeze(stmt.moduleArgs || {});
|
|
832
|
-
}
|
|
833
|
-
else {
|
|
834
|
-
const defaultVtab = this.getDefaultVTabModule();
|
|
835
|
-
moduleName = defaultVtab.name;
|
|
836
|
-
effectiveModuleArgs = Object.freeze(defaultVtab.args || {});
|
|
837
|
-
}
|
|
838
|
-
const moduleInfo = this.getModule(moduleName);
|
|
839
|
-
if (!moduleInfo || !moduleInfo.module) {
|
|
840
|
-
throw new QuereusError(`No virtual table module named '${moduleName}'`, StatusCode.ERROR);
|
|
841
|
-
}
|
|
842
|
-
// Get default nullability setting from database options
|
|
843
|
-
const defaultNullability = this.db.options.getStringOption('default_column_nullability');
|
|
844
|
-
const defaultNotNull = defaultNullability === 'not_null';
|
|
845
|
-
const astColumnsToProcess = stmt.columns || [];
|
|
846
|
-
const astConstraintsToProcess = stmt.constraints;
|
|
847
|
-
const preliminaryColumnSchemas = astColumnsToProcess.map(colDef => columnDefToSchema(colDef, defaultNotNull));
|
|
848
|
-
const pkDefinition = findPKDefinition(preliminaryColumnSchemas, astConstraintsToProcess);
|
|
849
|
-
const finalColumnSchemas = preliminaryColumnSchemas.map((col, idx) => {
|
|
850
|
-
const isPkColumn = pkDefinition.some(pkCol => pkCol.index === idx);
|
|
851
|
-
let pkOrder = 0;
|
|
852
|
-
if (isPkColumn) {
|
|
853
|
-
pkOrder = pkDefinition.findIndex(pkC => pkC.index === idx) + 1;
|
|
854
|
-
}
|
|
855
|
-
return {
|
|
856
|
-
...col,
|
|
857
|
-
primaryKey: isPkColumn,
|
|
858
|
-
pkOrder: pkOrder,
|
|
859
|
-
notNull: isPkColumn ? true : col.notNull,
|
|
860
|
-
};
|
|
861
|
-
});
|
|
862
|
-
const checkConstraintsSchema = [];
|
|
863
|
-
astColumnsToProcess.forEach(colDef => {
|
|
864
|
-
colDef.constraints?.forEach(con => {
|
|
865
|
-
if (con.type === 'check' && con.expr) {
|
|
866
|
-
checkConstraintsSchema.push({
|
|
867
|
-
name: con.name ?? `_check_${colDef.name}`,
|
|
868
|
-
expr: con.expr,
|
|
869
|
-
operations: opsToMask(con.operations),
|
|
870
|
-
deferrable: con.deferrable,
|
|
871
|
-
initiallyDeferred: con.initiallyDeferred
|
|
872
|
-
});
|
|
873
|
-
}
|
|
874
|
-
});
|
|
875
|
-
});
|
|
876
|
-
(astConstraintsToProcess || []).forEach(con => {
|
|
877
|
-
if (con.type === 'check' && con.expr) {
|
|
878
|
-
checkConstraintsSchema.push({
|
|
879
|
-
name: con.name,
|
|
880
|
-
expr: con.expr,
|
|
881
|
-
operations: opsToMask(con.operations),
|
|
882
|
-
deferrable: con.deferrable,
|
|
883
|
-
initiallyDeferred: con.initiallyDeferred
|
|
884
|
-
});
|
|
885
|
-
}
|
|
886
|
-
});
|
|
887
|
-
// Process mutation context definitions if present
|
|
888
|
-
const mutationContextSchemas = stmt.contextDefinitions
|
|
889
|
-
? stmt.contextDefinitions.map(varDef => mutationContextVarToSchema(varDef, defaultNotNull))
|
|
890
|
-
: undefined;
|
|
891
|
-
const tableSchema = {
|
|
892
|
-
name: tableName,
|
|
893
|
-
schemaName: targetSchemaName,
|
|
894
|
-
columns: Object.freeze(finalColumnSchemas),
|
|
895
|
-
columnIndexMap: buildColumnIndexMap(finalColumnSchemas),
|
|
896
|
-
primaryKeyDefinition: pkDefinition,
|
|
897
|
-
checkConstraints: Object.freeze(checkConstraintsSchema),
|
|
898
|
-
isTemporary: !!stmt.isTemporary,
|
|
899
|
-
isView: false,
|
|
900
|
-
vtabModuleName: moduleName,
|
|
901
|
-
vtabArgs: effectiveModuleArgs,
|
|
902
|
-
vtabModule: moduleInfo.module,
|
|
903
|
-
vtabAuxData: moduleInfo.auxData,
|
|
904
|
-
estimatedRows: 0,
|
|
905
|
-
mutationContext: mutationContextSchemas ? Object.freeze(mutationContextSchemas) : undefined,
|
|
906
|
-
};
|
|
907
|
-
// Use connect() instead of create() - the storage already exists
|
|
948
|
+
const { moduleName, effectiveModuleArgs, moduleInfo } = this.resolveModuleInfo(stmt);
|
|
949
|
+
const tableSchema = this.buildTableSchemaFromAST(stmt, moduleName, effectiveModuleArgs, moduleInfo);
|
|
908
950
|
try {
|
|
909
|
-
await moduleInfo.module.connect(this.db, moduleInfo.auxData, moduleName, targetSchemaName, tableName, effectiveModuleArgs, tableSchema
|
|
910
|
-
);
|
|
951
|
+
await moduleInfo.module.connect(this.db, moduleInfo.auxData, moduleName, targetSchemaName, tableName, effectiveModuleArgs, tableSchema);
|
|
911
952
|
}
|
|
912
953
|
catch (e) {
|
|
913
954
|
const message = e instanceof Error ? e.message : String(e);
|
|
914
955
|
throw new QuereusError(`Module '${moduleName}' connect failed during import for table '${tableName}': ${message}`, StatusCode.ERROR);
|
|
915
956
|
}
|
|
916
|
-
// Ensure schema exists
|
|
917
957
|
let schema = this.getSchema(targetSchemaName);
|
|
918
958
|
if (!schema) {
|
|
919
|
-
|
|
920
|
-
|
|
959
|
+
const lowerSchemaName = targetSchemaName.toLowerCase();
|
|
960
|
+
schema = new Schema(lowerSchemaName);
|
|
961
|
+
this.schemas.set(lowerSchemaName, schema);
|
|
921
962
|
}
|
|
922
|
-
// Register without notifying change listeners (this is an import, not a create)
|
|
923
963
|
schema.addTable(tableSchema);
|
|
924
964
|
log(`Imported table %s.%s using module %s`, targetSchemaName, tableName, moduleName);
|
|
925
965
|
return { type: 'table', name: `${targetSchemaName}.${tableName}` };
|