@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
package/README.md
CHANGED
|
@@ -1,361 +1,372 @@
|
|
|
1
|
-
# Quereus - A TypeScript SQL Query Processor
|
|
2
|
-
|
|
3
|
-
<img src="docs/images/Quereus_colored_wide.svg" alt="Quereus Logo" height="150">
|
|
4
|
-
|
|
5
|
-
Quereus is a feature-complete SQL query processor specifically designed for efficient in-memory data processing with a strong emphasis on the **virtual table** interface. It provides rich SQL query and constraint capabilities (joins, aggregates, subqueries, CTEs, window functions, constraints) over data sources exposed via the virtual table mechanism. Quereus features a modern type system with temporal types, JSON support, and plugin-extensible custom types. It has no persistent file storage, though one could be built as a virtual table module.
|
|
6
|
-
|
|
7
|
-
## Project Goals
|
|
8
|
-
|
|
9
|
-
* **Virtual Table Centric**: Provide a robust and flexible virtual table API as the primary means of interacting with data sources. All tables are virtual tables.
|
|
10
|
-
* **In-Memory Default**: Includes a comprehensive in-memory virtual table implementation (`MemoryTable`) with support for transactions and savepoints.
|
|
11
|
-
* **Modern Type System**: Extensible logical/physical type separation with built-in temporal types (DATE, TIME, DATETIME), native JSON type with deep equality comparison, and plugin support for custom types. See [Type System Documentation](
|
|
12
|
-
* **TypeScript & Modern JS**: Leverage TypeScript's type system and modern JavaScript features and idioms.
|
|
13
|
-
* **Async VTab Operations**: Virtual table data operations (reads/writes) are asynchronous. Cursors are implemented as async iterables.
|
|
14
|
-
* **Cross-Platform**: Target diverse Javascript runtime environments, including Node.js, browser, and React Native. Plugin loading (via `@quereus/plugin-loader`) uses dynamic `import()` and is not compatible with React Native; use static imports for RN.
|
|
15
|
-
* **Minimal Dependencies**: Avoid heavy external dependencies where possible.
|
|
16
|
-
* **SQL Compatibility**: Comprehensive support for modern SQL features including joins, window functions, subqueries, CTEs, constraints, views, and advanced DML/DDL operations.
|
|
17
|
-
* **Key-Based Addressing**: All tables are addressed by their defined Primary Key. The concept of a separate, implicit `rowid` for addressing rows is not used.
|
|
18
|
-
* **Third Manifesto Friendly**: Embraces some of the principles of the [Third Manifesto](https://www.dcs.warwick.ac.uk/~hugh/TTM/DTATRM.pdf), such as allowing for empty keys. Utilizes algebraic planning.
|
|
19
|
-
|
|
20
|
-
## Architecture Overview
|
|
21
|
-
|
|
22
|
-
Quereus is built on a modern architecture based on partially immutable PlanNodes and an Instruction-based runtime with robust attribute-based context system.
|
|
23
|
-
|
|
24
|
-
1. **SQL Input**: The process starts with a SQL query string.
|
|
25
|
-
2. **Parser (`src/parser`)**:
|
|
26
|
-
* **Lexer (`lexer.ts`)**: Tokenizes the raw SQL string.
|
|
27
|
-
* **Parser (`parser.ts`)**: Builds an Abstract Syntax Tree (AST).
|
|
28
|
-
3. **Planner (`src/planner`)**:
|
|
29
|
-
* Traverses the AST to construct a tree of immutable `PlanNode` objects representing the logical query structure.
|
|
30
|
-
* Handles Common Table Expressions (CTEs) and Subqueries by converting them into relational `PlanNode`s.
|
|
31
|
-
* Resolves table and function references using the Schema Manager.
|
|
32
|
-
* Performs query planning, incorporating virtual table `getBestAccessPlan` method and table schema statistics.
|
|
33
|
-
* **Optimizer (`src/planner/optimizer`)**: Transforms logical plans into efficient physical execution plans through a rule-based optimization system. See [Optimizer Documentation](
|
|
34
|
-
4. **Runtime (`src/runtime`)**:
|
|
35
|
-
* **Emitters (`src/runtime/emitters.ts`, `src/runtime/emit/`)**: Translate `PlanNode`s into a graph of `Instruction` objects.
|
|
36
|
-
* **Scheduler (`src/runtime/scheduler.ts`)**: Manages the execution flow of the `Instruction` graph.
|
|
37
|
-
* **Instructions**: JavaScript functions that operate on `RuntimeValue`s (which can be `SqlValue` or `AsyncIterable<Row>`). Async parameters are awaited.
|
|
38
|
-
* Invokes virtual table methods (e.g., `query` which returns `AsyncIterable<Row>`, `update`) to interact with data.
|
|
39
|
-
* Calls User-Defined Functions (UDFs) and aggregate functions.
|
|
40
|
-
* Handles transaction and savepoint control.
|
|
41
|
-
5. **Virtual Tables (`src/vtab`)**:
|
|
42
|
-
* The core data interface. Modules implement `VirtualTableModule`.
|
|
43
|
-
* `MemoryTable` (`vtab/memory/table.ts`) is a key implementation using `digitree`.
|
|
44
|
-
6. **Schema Management (`src/schema`)**: Manages schemas, tables, columns, functions.
|
|
45
|
-
7. **User-Defined Functions (`src/func`)**: Support for custom JS functions in SQL.
|
|
46
|
-
8. **Core API (`src/core`)**: `Database`, `Statement` classes.
|
|
47
|
-
|
|
48
|
-
## Source File Layout
|
|
49
|
-
|
|
50
|
-
The project is organized into the following main directories:
|
|
51
|
-
|
|
52
|
-
* `src/common`: Foundational types, constants, and error classes.
|
|
53
|
-
* `src/core`: High-level API classes (`Database`, `Statement`).
|
|
54
|
-
* `src/parser`: SQL lexing, parsing, and AST definitions.
|
|
55
|
-
* `src/planner`: Building and optimizing `PlanNode` trees from AST.
|
|
56
|
-
* `src/runtime`: Emission, scheduling, and execution of runtime `Instruction`s.
|
|
57
|
-
* `src/schema`: Management of database schemas.
|
|
58
|
-
* `src/vtab`: Virtual table interface and build-ins (including `memory`).
|
|
59
|
-
* `src/func`: User-defined functions.
|
|
60
|
-
* `src/util`: General utility functions.
|
|
61
|
-
* `docs`: Project documentation.
|
|
62
|
-
|
|
63
|
-
## Quick Start
|
|
64
|
-
|
|
65
|
-
```typescript
|
|
66
|
-
import { Database } from '@quereus/quereus';
|
|
67
|
-
|
|
68
|
-
const db = new Database();
|
|
69
|
-
|
|
70
|
-
// Create a table and insert data
|
|
71
|
-
await db.exec("create table users (id integer primary key, name text, email text)");
|
|
72
|
-
await db.exec("insert into users values (1, 'Alice', 'alice@example.com')");
|
|
73
|
-
|
|
74
|
-
// Query returns objects: { id: 1, name: 'Alice', email: 'alice@example.com' }
|
|
75
|
-
const user = await db.get("select * from users where id = ?", [1]);
|
|
76
|
-
console.log(user.name); // "Alice"
|
|
77
|
-
|
|
78
|
-
// Iterate over multiple rows
|
|
79
|
-
for await (const row of db.eval("select * from users")) {
|
|
80
|
-
console.log(row.name);
|
|
81
|
-
}
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Reactive Patterns with Event Hooks
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
import { Database } from '@quereus/quereus';
|
|
88
|
-
|
|
89
|
-
const db = new Database();
|
|
90
|
-
|
|
91
|
-
// Subscribe to data changes at the database level
|
|
92
|
-
db.onDataChange((event) => {
|
|
93
|
-
console.log(`${event.type} on ${event.tableName} (module: ${event.moduleName})`);
|
|
94
|
-
if (event.remote) {
|
|
95
|
-
console.log('Change came from remote sync');
|
|
96
|
-
}
|
|
97
|
-
if (event.type === 'update') {
|
|
98
|
-
console.log('Changed columns:', event.changedColumns);
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// Subscribe to schema changes
|
|
103
|
-
db.onSchemaChange((event) => {
|
|
104
|
-
console.log(`${event.type} ${event.objectType}: ${event.objectName}`);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// Events fire after commit
|
|
108
|
-
await db.exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
|
|
109
|
-
// Output: create table: users
|
|
110
|
-
|
|
111
|
-
await db.exec("INSERT INTO users VALUES (1, 'Alice')");
|
|
112
|
-
// Output: insert on users (module: memory)
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
The database-level event system aggregates events from all modules automatically. Events are batched within transactions and delivered only after successful commit.
|
|
116
|
-
|
|
117
|
-
SQL values use native JavaScript types (`string`, `number`, `bigint`, `Uint8Array`, `null`). Temporal types are ISO 8601 strings. Results stream as async iterators.
|
|
118
|
-
|
|
119
|
-
See the [Usage Guide](
|
|
120
|
-
|
|
121
|
-
## Platform Support & Storage
|
|
122
|
-
|
|
123
|
-
Quereus runs on any JavaScript runtime. For persistent storage, platform-specific plugins provide the `store` virtual table module:
|
|
124
|
-
|
|
125
|
-
### Node.js
|
|
126
|
-
|
|
127
|
-
Use [`@quereus/plugin-leveldb`](
|
|
128
|
-
|
|
129
|
-
```typescript
|
|
130
|
-
import { Database, registerPlugin } from '@quereus/quereus';
|
|
131
|
-
import leveldbPlugin from '@quereus/plugin-leveldb/plugin';
|
|
132
|
-
|
|
133
|
-
const db = new Database();
|
|
134
|
-
await registerPlugin(db, leveldbPlugin, { basePath: './data' }); // ./data/users/, ./data/orders/, etc.
|
|
135
|
-
|
|
136
|
-
await db.exec(`create table users (id integer primary key, name text) using store`);
|
|
137
|
-
|
|
138
|
-
// Full transaction isolation enabled by default
|
|
139
|
-
await db.exec('BEGIN');
|
|
140
|
-
await db.exec(`INSERT INTO users VALUES (1, 'Alice')`);
|
|
141
|
-
const user = await db.get('SELECT * FROM users WHERE id = 1'); // Sees uncommitted insert
|
|
142
|
-
await db.exec('COMMIT');
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
### Browser
|
|
146
|
-
|
|
147
|
-
Use [`@quereus/plugin-indexeddb`](
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
import { Database, registerPlugin } from '@quereus/quereus';
|
|
151
|
-
import indexeddbPlugin from '@quereus/plugin-indexeddb/plugin';
|
|
152
|
-
|
|
153
|
-
const db = new Database();
|
|
154
|
-
await registerPlugin(db, indexeddbPlugin, { databaseName: 'myapp' }); // IndexedDB database name
|
|
155
|
-
|
|
156
|
-
await db.exec(`create table users (id integer primary key, name text) using store`);
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### React Native
|
|
160
|
-
|
|
161
|
-
Use [`@quereus/plugin-react-native-leveldb`](
|
|
162
|
-
|
|
163
|
-
```typescript
|
|
164
|
-
import { LevelDB, LevelDBWriteBatch } from 'react-native-leveldb';
|
|
165
|
-
import { Database, registerPlugin } from '@quereus/quereus';
|
|
166
|
-
import leveldbPlugin from '@quereus/plugin-react-native-leveldb/plugin';
|
|
167
|
-
|
|
168
|
-
const db = new Database();
|
|
169
|
-
await registerPlugin(db, leveldbPlugin, {
|
|
170
|
-
openFn: LevelDB.open,
|
|
171
|
-
WriteBatch: LevelDBWriteBatch,
|
|
172
|
-
databaseName: 'myapp' // creates myapp_users, myapp_orders, etc.
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
await db.exec(`create table users (id integer primary key, name text) using store`);
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
**Note:** React Native requires runtime polyfills and static plugin loading. See the [plugin README](
|
|
179
|
-
|
|
180
|
-
**Required polyfills:**
|
|
181
|
-
- `structuredClone` (Quereus uses it internally)
|
|
182
|
-
- `TextEncoder` / `TextDecoder` (used by store plugins)
|
|
183
|
-
- `Symbol.asyncIterator` (required for async-iterable support; Quereus has a Hermes workaround for AsyncGenerator iterables, but the symbol must exist)
|
|
184
|
-
|
|
185
|
-
### NativeScript
|
|
186
|
-
|
|
187
|
-
Use [`@quereus/plugin-nativescript-sqlite`](
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
import { openOrCreate } from '@nativescript-community/sqlite';
|
|
191
|
-
import { Database, registerPlugin } from '@quereus/quereus';
|
|
192
|
-
import sqlitePlugin from '@quereus/plugin-nativescript-sqlite/plugin';
|
|
193
|
-
|
|
194
|
-
const sqliteDb = openOrCreate('myapp.db'); // SQLite database file
|
|
195
|
-
const db = new Database();
|
|
196
|
-
await registerPlugin(db, sqlitePlugin, { db: sqliteDb });
|
|
197
|
-
|
|
198
|
-
await db.exec(`create table users (id integer primary key, name text) using store`);
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
See [Store Documentation](
|
|
202
|
-
|
|
203
|
-
## Documentation
|
|
204
|
-
|
|
205
|
-
* [Usage Guide](
|
|
206
|
-
- Type mappings (SQL ↔ JavaScript)
|
|
207
|
-
- Parameter binding and prepared statements
|
|
208
|
-
- Logging via `debug` library with namespace control
|
|
209
|
-
- Instruction tracing for performance analysis
|
|
210
|
-
- Transaction and savepoint management
|
|
211
|
-
* [SQL Reference Guide](
|
|
212
|
-
* [
|
|
213
|
-
* [
|
|
214
|
-
* [
|
|
215
|
-
* [
|
|
216
|
-
* [
|
|
217
|
-
* [
|
|
218
|
-
* [
|
|
219
|
-
* [
|
|
220
|
-
* [
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
* **
|
|
228
|
-
* **
|
|
229
|
-
* **
|
|
230
|
-
* **
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
* **
|
|
238
|
-
* **
|
|
239
|
-
* **
|
|
240
|
-
* **
|
|
241
|
-
* **
|
|
242
|
-
* **
|
|
243
|
-
* **
|
|
244
|
-
* **
|
|
245
|
-
* **
|
|
246
|
-
* **
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
* **
|
|
254
|
-
* **
|
|
255
|
-
* **
|
|
256
|
-
* **
|
|
257
|
-
* **
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
- Row-level CHECKs that reference
|
|
263
|
-
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
* **
|
|
291
|
-
* **
|
|
292
|
-
* **
|
|
293
|
-
* **
|
|
294
|
-
* **
|
|
295
|
-
* **
|
|
296
|
-
|
|
297
|
-
**
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
* `yarn test --
|
|
328
|
-
* `yarn test --
|
|
329
|
-
* `yarn test --
|
|
330
|
-
* `yarn test --
|
|
331
|
-
* `yarn test --
|
|
332
|
-
* `yarn test --
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
*
|
|
360
|
-
|
|
361
|
-
|
|
1
|
+
# Quereus - A TypeScript SQL Query Processor
|
|
2
|
+
|
|
3
|
+
<img src="../../docs/images/Quereus_colored_wide.svg" alt="Quereus Logo" height="150">
|
|
4
|
+
|
|
5
|
+
Quereus is a feature-complete SQL query processor specifically designed for efficient in-memory data processing with a strong emphasis on the **virtual table** interface. It provides rich SQL query and constraint capabilities (joins, aggregates, subqueries, CTEs, window functions, constraints) over data sources exposed via the virtual table mechanism. Quereus features a modern type system with temporal types, JSON support, and plugin-extensible custom types. It has no persistent file storage, though one could be built as a virtual table module.
|
|
6
|
+
|
|
7
|
+
## Project Goals
|
|
8
|
+
|
|
9
|
+
* **Virtual Table Centric**: Provide a robust and flexible virtual table API as the primary means of interacting with data sources. All tables are virtual tables.
|
|
10
|
+
* **In-Memory Default**: Includes a comprehensive in-memory virtual table implementation (`MemoryTable`) with support for transactions and savepoints.
|
|
11
|
+
* **Modern Type System**: Extensible logical/physical type separation with built-in temporal types (DATE, TIME, DATETIME), native JSON type with deep equality comparison, and plugin support for custom types. See [Type System Documentation](../../docs/types.md).
|
|
12
|
+
* **TypeScript & Modern JS**: Leverage TypeScript's type system and modern JavaScript features and idioms.
|
|
13
|
+
* **Async VTab Operations**: Virtual table data operations (reads/writes) are asynchronous. Cursors are implemented as async iterables.
|
|
14
|
+
* **Cross-Platform**: Target diverse Javascript runtime environments, including Node.js, browser, and React Native. Plugin loading (via `@quereus/plugin-loader`) uses dynamic `import()` and is not compatible with React Native; use static imports for RN.
|
|
15
|
+
* **Minimal Dependencies**: Avoid heavy external dependencies where possible.
|
|
16
|
+
* **SQL Compatibility**: Comprehensive support for modern SQL features including joins, window functions, subqueries, CTEs, constraints, views, and advanced DML/DDL operations.
|
|
17
|
+
* **Key-Based Addressing**: All tables are addressed by their defined Primary Key. The concept of a separate, implicit `rowid` for addressing rows is not used.
|
|
18
|
+
* **Third Manifesto Friendly**: Embraces some of the principles of the [Third Manifesto](https://www.dcs.warwick.ac.uk/~hugh/TTM/DTATRM.pdf), such as allowing for empty keys. Utilizes algebraic planning.
|
|
19
|
+
|
|
20
|
+
## Architecture Overview
|
|
21
|
+
|
|
22
|
+
Quereus is built on a modern architecture based on partially immutable PlanNodes and an Instruction-based runtime with robust attribute-based context system.
|
|
23
|
+
|
|
24
|
+
1. **SQL Input**: The process starts with a SQL query string.
|
|
25
|
+
2. **Parser (`src/parser`)**:
|
|
26
|
+
* **Lexer (`lexer.ts`)**: Tokenizes the raw SQL string.
|
|
27
|
+
* **Parser (`parser.ts`)**: Builds an Abstract Syntax Tree (AST).
|
|
28
|
+
3. **Planner (`src/planner`)**:
|
|
29
|
+
* Traverses the AST to construct a tree of immutable `PlanNode` objects representing the logical query structure.
|
|
30
|
+
* Handles Common Table Expressions (CTEs) and Subqueries by converting them into relational `PlanNode`s.
|
|
31
|
+
* Resolves table and function references using the Schema Manager.
|
|
32
|
+
* Performs query planning, incorporating virtual table `getBestAccessPlan` method and table schema statistics.
|
|
33
|
+
* **Optimizer (`src/planner/optimizer`)**: Transforms logical plans into efficient physical execution plans through a rule-based optimization system. See [Optimizer Documentation](../../docs/optimizer.md) for details.
|
|
34
|
+
4. **Runtime (`src/runtime`)**:
|
|
35
|
+
* **Emitters (`src/runtime/emitters.ts`, `src/runtime/emit/`)**: Translate `PlanNode`s into a graph of `Instruction` objects.
|
|
36
|
+
* **Scheduler (`src/runtime/scheduler.ts`)**: Manages the execution flow of the `Instruction` graph.
|
|
37
|
+
* **Instructions**: JavaScript functions that operate on `RuntimeValue`s (which can be `SqlValue` or `AsyncIterable<Row>`). Async parameters are awaited.
|
|
38
|
+
* Invokes virtual table methods (e.g., `query` which returns `AsyncIterable<Row>`, `update`) to interact with data.
|
|
39
|
+
* Calls User-Defined Functions (UDFs) and aggregate functions.
|
|
40
|
+
* Handles transaction and savepoint control.
|
|
41
|
+
5. **Virtual Tables (`src/vtab`)**:
|
|
42
|
+
* The core data interface. Modules implement `VirtualTableModule`.
|
|
43
|
+
* `MemoryTable` (`vtab/memory/table.ts`) is a key implementation using `digitree`.
|
|
44
|
+
6. **Schema Management (`src/schema`)**: Manages schemas, tables, columns, functions.
|
|
45
|
+
7. **User-Defined Functions (`src/func`)**: Support for custom JS functions in SQL.
|
|
46
|
+
8. **Core API (`src/core`)**: `Database`, `Statement` classes.
|
|
47
|
+
|
|
48
|
+
## Source File Layout
|
|
49
|
+
|
|
50
|
+
The project is organized into the following main directories:
|
|
51
|
+
|
|
52
|
+
* `src/common`: Foundational types, constants, and error classes.
|
|
53
|
+
* `src/core`: High-level API classes (`Database`, `Statement`).
|
|
54
|
+
* `src/parser`: SQL lexing, parsing, and AST definitions.
|
|
55
|
+
* `src/planner`: Building and optimizing `PlanNode` trees from AST.
|
|
56
|
+
* `src/runtime`: Emission, scheduling, and execution of runtime `Instruction`s.
|
|
57
|
+
* `src/schema`: Management of database schemas.
|
|
58
|
+
* `src/vtab`: Virtual table interface and build-ins (including `memory`).
|
|
59
|
+
* `src/func`: User-defined functions.
|
|
60
|
+
* `src/util`: General utility functions.
|
|
61
|
+
* `docs`: Project documentation.
|
|
62
|
+
|
|
63
|
+
## Quick Start
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { Database } from '@quereus/quereus';
|
|
67
|
+
|
|
68
|
+
const db = new Database();
|
|
69
|
+
|
|
70
|
+
// Create a table and insert data
|
|
71
|
+
await db.exec("create table users (id integer primary key, name text, email text)");
|
|
72
|
+
await db.exec("insert into users values (1, 'Alice', 'alice@example.com')");
|
|
73
|
+
|
|
74
|
+
// Query returns objects: { id: 1, name: 'Alice', email: 'alice@example.com' }
|
|
75
|
+
const user = await db.get("select * from users where id = ?", [1]);
|
|
76
|
+
console.log(user.name); // "Alice"
|
|
77
|
+
|
|
78
|
+
// Iterate over multiple rows
|
|
79
|
+
for await (const row of db.eval("select * from users")) {
|
|
80
|
+
console.log(row.name);
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Reactive Patterns with Event Hooks
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { Database } from '@quereus/quereus';
|
|
88
|
+
|
|
89
|
+
const db = new Database();
|
|
90
|
+
|
|
91
|
+
// Subscribe to data changes at the database level
|
|
92
|
+
db.onDataChange((event) => {
|
|
93
|
+
console.log(`${event.type} on ${event.tableName} (module: ${event.moduleName})`);
|
|
94
|
+
if (event.remote) {
|
|
95
|
+
console.log('Change came from remote sync');
|
|
96
|
+
}
|
|
97
|
+
if (event.type === 'update') {
|
|
98
|
+
console.log('Changed columns:', event.changedColumns);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Subscribe to schema changes
|
|
103
|
+
db.onSchemaChange((event) => {
|
|
104
|
+
console.log(`${event.type} ${event.objectType}: ${event.objectName}`);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Events fire after commit
|
|
108
|
+
await db.exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
|
|
109
|
+
// Output: create table: users
|
|
110
|
+
|
|
111
|
+
await db.exec("INSERT INTO users VALUES (1, 'Alice')");
|
|
112
|
+
// Output: insert on users (module: memory)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
The database-level event system aggregates events from all modules automatically. Events are batched within transactions and delivered only after successful commit.
|
|
116
|
+
|
|
117
|
+
SQL values use native JavaScript types (`string`, `number`, `bigint`, `Uint8Array`, `null`). Temporal types are ISO 8601 strings. Results stream as async iterators.
|
|
118
|
+
|
|
119
|
+
See the [Usage Guide](../../docs/usage.md) for complete API reference and [Module Authoring Guide](../../docs/module-authoring.md) for event system details.
|
|
120
|
+
|
|
121
|
+
## Platform Support & Storage
|
|
122
|
+
|
|
123
|
+
Quereus runs on any JavaScript runtime. For persistent storage, platform-specific plugins provide the `store` virtual table module:
|
|
124
|
+
|
|
125
|
+
### Node.js
|
|
126
|
+
|
|
127
|
+
Use [`@quereus/plugin-leveldb`](../quereus-plugin-leveldb/) for LevelDB-based persistent storage with full transaction isolation. Each table becomes a subdirectory under `basePath`:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { Database, registerPlugin } from '@quereus/quereus';
|
|
131
|
+
import leveldbPlugin from '@quereus/plugin-leveldb/plugin';
|
|
132
|
+
|
|
133
|
+
const db = new Database();
|
|
134
|
+
await registerPlugin(db, leveldbPlugin, { basePath: './data' }); // ./data/users/, ./data/orders/, etc.
|
|
135
|
+
|
|
136
|
+
await db.exec(`create table users (id integer primary key, name text) using store`);
|
|
137
|
+
|
|
138
|
+
// Full transaction isolation enabled by default
|
|
139
|
+
await db.exec('BEGIN');
|
|
140
|
+
await db.exec(`INSERT INTO users VALUES (1, 'Alice')`);
|
|
141
|
+
const user = await db.get('SELECT * FROM users WHERE id = 1'); // Sees uncommitted insert
|
|
142
|
+
await db.exec('COMMIT');
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Browser
|
|
146
|
+
|
|
147
|
+
Use [`@quereus/plugin-indexeddb`](../quereus-plugin-indexeddb/) for IndexedDB-based persistent storage with cross-tab sync and full transaction isolation. All tables share one IndexedDB database:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { Database, registerPlugin } from '@quereus/quereus';
|
|
151
|
+
import indexeddbPlugin from '@quereus/plugin-indexeddb/plugin';
|
|
152
|
+
|
|
153
|
+
const db = new Database();
|
|
154
|
+
await registerPlugin(db, indexeddbPlugin, { databaseName: 'myapp' }); // IndexedDB database name
|
|
155
|
+
|
|
156
|
+
await db.exec(`create table users (id integer primary key, name text) using store`);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### React Native
|
|
160
|
+
|
|
161
|
+
Use [`@quereus/plugin-react-native-leveldb`](../quereus-plugin-react-native-leveldb/) for fast LevelDB storage with full transaction isolation. Each table becomes a separate LevelDB database with a name prefix:
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
import { LevelDB, LevelDBWriteBatch } from 'react-native-leveldb';
|
|
165
|
+
import { Database, registerPlugin } from '@quereus/quereus';
|
|
166
|
+
import leveldbPlugin from '@quereus/plugin-react-native-leveldb/plugin';
|
|
167
|
+
|
|
168
|
+
const db = new Database();
|
|
169
|
+
await registerPlugin(db, leveldbPlugin, {
|
|
170
|
+
openFn: LevelDB.open,
|
|
171
|
+
WriteBatch: LevelDBWriteBatch,
|
|
172
|
+
databaseName: 'myapp' // creates myapp_users, myapp_orders, etc.
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
await db.exec(`create table users (id integer primary key, name text) using store`);
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Note:** React Native requires runtime polyfills and static plugin loading. See the [plugin README](../quereus-plugin-react-native-leveldb/) for setup details.
|
|
179
|
+
|
|
180
|
+
**Required polyfills:**
|
|
181
|
+
- `structuredClone` (Quereus uses it internally)
|
|
182
|
+
- `TextEncoder` / `TextDecoder` (used by store plugins)
|
|
183
|
+
- `Symbol.asyncIterator` (required for async-iterable support; Quereus has a Hermes workaround for AsyncGenerator iterables, but the symbol must exist)
|
|
184
|
+
|
|
185
|
+
### NativeScript
|
|
186
|
+
|
|
187
|
+
Use [`@quereus/plugin-nativescript-sqlite`](../quereus-plugin-nativescript-sqlite/) for SQLite-based storage with full transaction isolation. All tables share one SQLite database file:
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
import { openOrCreate } from '@nativescript-community/sqlite';
|
|
191
|
+
import { Database, registerPlugin } from '@quereus/quereus';
|
|
192
|
+
import sqlitePlugin from '@quereus/plugin-nativescript-sqlite/plugin';
|
|
193
|
+
|
|
194
|
+
const sqliteDb = openOrCreate('myapp.db'); // SQLite database file
|
|
195
|
+
const db = new Database();
|
|
196
|
+
await registerPlugin(db, sqlitePlugin, { db: sqliteDb });
|
|
197
|
+
|
|
198
|
+
await db.exec(`create table users (id integer primary key, name text) using store`);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
See [Store Documentation](../../docs/store.md) for the storage architecture and custom backend implementation.
|
|
202
|
+
|
|
203
|
+
## Documentation
|
|
204
|
+
|
|
205
|
+
* [Usage Guide](../../docs/usage.md): Complete API reference including:
|
|
206
|
+
- Type mappings (SQL ↔ JavaScript)
|
|
207
|
+
- Parameter binding and prepared statements
|
|
208
|
+
- Logging via `debug` library with namespace control
|
|
209
|
+
- Instruction tracing for performance analysis
|
|
210
|
+
- Transaction and savepoint management
|
|
211
|
+
* [SQL Reference Guide](../../docs/sql.md): SQL syntax (includes Declarative Schema)
|
|
212
|
+
* [Schema Management](../../docs/schema.md): SchemaManager API, change events, key types
|
|
213
|
+
* [Type System](../../docs/types.md): Logical/physical types, temporal types, JSON, custom types
|
|
214
|
+
* [Functions](../../docs/functions.md): Built-in scalar, aggregate, window, and JSON functions
|
|
215
|
+
* [Memory Tables](../../docs/memory-table.md): Built-in MemoryTable module
|
|
216
|
+
* [Module Authoring](../../docs/module-authoring.md): Virtual table module development and event system
|
|
217
|
+
* [Date/Time Handling](../../docs/datetime.md): Temporal parsing, functions, and ISO 8601 formats
|
|
218
|
+
* [Runtime](../../docs/runtime.md): Instruction-based execution and opcodes
|
|
219
|
+
* [Error Handling](../../docs/errors.md): Error types and status codes
|
|
220
|
+
* [Plugin System](../../docs/plugins.md): Virtual tables, functions, and collations
|
|
221
|
+
* [TODO List](../../docs/todo.md): Planned features
|
|
222
|
+
|
|
223
|
+
### Plugin Development
|
|
224
|
+
|
|
225
|
+
Quereus exports all critical utilities needed for plugin and module development:
|
|
226
|
+
|
|
227
|
+
* **Comparison Functions**: `compareSqlValues`, `compareRows`, `compareTypedValues`, `createTypedComparator` — Match Quereus SQL semantics in custom implementations
|
|
228
|
+
* **Coercion Utilities**: `tryCoerceToNumber`, `coerceForAggregate` — Handle type coercion for aggregates and arithmetic
|
|
229
|
+
* **Collation Support**: `registerCollation`, `getCollation`, built-in collations (`BINARY_COLLATION`, `NOCASE_COLLATION`, `RTRIM_COLLATION`)
|
|
230
|
+
* **Type System**: Full access to logical types, validation, and parsing utilities
|
|
231
|
+
* **Event Hooks**: `VTableEventEmitter` interface for mutation and schema change events — Enable reactive patterns, caching, and replication
|
|
232
|
+
|
|
233
|
+
See the [Plugin System documentation](../../docs/plugins.md#comparison-and-coercion-utilities) for complete API reference and examples.
|
|
234
|
+
|
|
235
|
+
## Key Design Decisions
|
|
236
|
+
|
|
237
|
+
* **Federated / VTab-Centric**: All tables are virtual tables.
|
|
238
|
+
* **Async Core**: Core operations are asynchronous. Cursors are `AsyncIterable<Row>`.
|
|
239
|
+
* **Key-Based Addressing**: Rows are identified by their defined Primary Key. No separate implicit `rowid`.
|
|
240
|
+
* **Relational Orthogonality**: Any statement that results in a relation can be used anywhere that expects a relation value, including mutating statements with RETURNING clauses.
|
|
241
|
+
* **Declarative Schema (Optional)**: Keep using DDL normally. Optionally use order‑independent `declare schema { ... }` to describe end‑state; the engine computes diffs against current state using module‑reported catalogs and emits canonical DDL. You may auto‑apply via `apply schema` or fetch the DDL and run it yourself (enabling custom backfills). Supports seeds, imports (URL + cache), versioning, and schema hashing. Destructive changes require explicit acknowledgement.
|
|
242
|
+
* **JavaScript Types**: Uses standard JavaScript types (`number`, `string`, `bigint`, `boolean`, `Uint8Array`, `null`) internally.
|
|
243
|
+
* **Object-Based API**: Uses classes (`Database`, `Statement`) to represent resources with lifecycles, rather than handles.
|
|
244
|
+
* **Transient Schema**: Schema information is primarily in-memory; persistence is not a goal. Emission of schema SQL export is supported.
|
|
245
|
+
* **Multi-Schema Support**: Organize tables across multiple schemas with flexible search paths for modular designs.
|
|
246
|
+
* **Bags vs Sets Distinction**: Explicit type-level distinction between relations that guarantee unique rows (sets) and those that allow duplicates (bags), enabling sophisticated optimizations and maintaining algebraic correctness in line with Third Manifesto principles.
|
|
247
|
+
* **Attribute-Based Context System**: Robust column reference resolution using stable attribute IDs eliminates architectural fragilities and provides deterministic context lookup across plan transformations.
|
|
248
|
+
|
|
249
|
+
## Key Design Differences
|
|
250
|
+
|
|
251
|
+
While Quereus supports standard SQL syntax, it has several distinctive design choices:
|
|
252
|
+
|
|
253
|
+
* **Modern Type System**: Uses logical/physical type separation instead of SQLite's type affinity model. Includes native temporal types (DATE, TIME, DATETIME) and JSON type with deep equality comparison. Conversion functions (`integer()`, `date()`, `json()`) are preferred over CAST syntax. All expressions have known types at plan time, including parameters; cross-category comparisons (e.g., numeric vs text) are handled via explicit conversions rather than implicit runtime coercion. See [Type System Documentation](../../docs/types.md).
|
|
254
|
+
* **Virtual Table Centric**: Uses `CREATE TABLE ... USING module(...)` syntax. All tables are virtual tables.
|
|
255
|
+
* **Default NOT NULL Columns**: Following Third Manifesto principles, columns default to NOT NULL unless explicitly specified otherwise. This behavior can be controlled via `pragma default_column_nullability = 'nullable'` to restore SQL standard behavior.
|
|
256
|
+
* **No Rowids**: All tables are addressed by their Primary Key. When no explicit PRIMARY KEY is defined, Quereus includes all columns in the primary key.
|
|
257
|
+
* **Async API**: Core execution is asynchronous with async/await patterns throughout.
|
|
258
|
+
* **No Triggers or Built-in Persistence**: Persistent storage can be implemented as a VTab module.
|
|
259
|
+
|
|
260
|
+
### Constraints
|
|
261
|
+
|
|
262
|
+
- Row-level CHECKs that reference only the current row are enforced immediately.
|
|
263
|
+
- Row-level CHECKs that reference other tables (e.g., via subqueries) are automatically deferred and enforced at COMMIT using the same optimized engine as global assertions. No `DEFERRABLE` or `SET CONSTRAINTS` management is required by the user.
|
|
264
|
+
- `CREATE ASSERTION name CHECK (...)` defines database-wide invariants evaluated at COMMIT.
|
|
265
|
+
- `FOREIGN KEY ... REFERENCES` with `ON DELETE CASCADE/SET NULL/RESTRICT` and `ON UPDATE CASCADE/SET NULL/RESTRICT`.
|
|
266
|
+
- **`committed.tablename` pseudo-schema**: Provides read-only access to the pre-transaction (committed) state of any table. Enables transition constraints that compare current and committed state (e.g., `CREATE ASSERTION no_decrease CHECK (NOT EXISTS (SELECT 1 FROM t JOIN committed.t ct ON t.id = ct.id WHERE t.val < ct.val))`). The committed view is pinned to the transaction-start snapshot and is unaffected by savepoints.
|
|
267
|
+
- **Determinism Enforcement**: CHECK constraints and DEFAULT values must use only deterministic expressions. Non-deterministic values (like `datetime('now')` or `random()`) must be passed via mutation context to ensure captured statements are replayable. See [Runtime Documentation](../../docs/runtime.md#determinism-validation).
|
|
268
|
+
|
|
269
|
+
### Sequential ID Generation
|
|
270
|
+
|
|
271
|
+
Quereus has no built-in auto-increment or sequence objects. Instead, batch ID generation composes naturally from existing features: mutation context captures a non-deterministic seed once, a window function provides a deterministic per-row ordinal, and a scalar or table-valued function produces the final ID. For example, inserting with timestamp-derived IDs:
|
|
272
|
+
|
|
273
|
+
```sql
|
|
274
|
+
insert into orders (id, customer_id, total)
|
|
275
|
+
with context base_ts = epoch_ms('now')
|
|
276
|
+
select
|
|
277
|
+
base_ts * 1000 + row_number() over (order by c.customer_id),
|
|
278
|
+
c.customer_id,
|
|
279
|
+
c.total
|
|
280
|
+
from (select customer_id, sum(price) as total from cart_items group by customer_id) c;
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
The `WITH CONTEXT` boundary captures `epoch_ms('now')` as a literal, and `row_number() over (order by ...)` assigns a deterministic ordinal over a declared ordering. The entire statement is replayable. For richer formats (ULIDs, UUIDv7), register a deterministic scalar UDF that encodes `(seed, counter)` into the desired format — or use a lateral join to a deterministic TVF when multiple columns are needed per generated row.
|
|
284
|
+
|
|
285
|
+
## Current Status
|
|
286
|
+
|
|
287
|
+
Quereus is a feature-complete SQL query processor with a modern planner and instruction-based runtime architecture. The engine successfully handles complex SQL workloads including joins, window functions, subqueries, CTEs, constraints, and comprehensive DML/DDL operations.
|
|
288
|
+
|
|
289
|
+
**Current capabilities include:**
|
|
290
|
+
* **Modern Type System** - Temporal types (DATE, TIME, DATETIME), JSON with deep equality, plugin-extensible custom types
|
|
291
|
+
* **Complete JOIN support** - INNER, LEFT, RIGHT, CROSS, SEMI, and ANTI joins with proper NULL padding
|
|
292
|
+
* **Advanced window functions** - Ranking, aggregates, and frame specifications
|
|
293
|
+
* **Full constraint system** - NOT NULL, CHECK, FOREIGN KEY, and CREATE ASSERTION. Row-level constraints that reference other tables are automatically deferred to COMMIT. The `committed.tablename` pseudo-schema provides read-only access to pre-transaction state for transition constraints (e.g., "balance may not decrease")
|
|
294
|
+
* **Comprehensive subqueries** - Scalar, correlated, EXISTS, and IN subqueries
|
|
295
|
+
* **Relational orthogonality** - INSERT/UPDATE/DELETE with RETURNING can be used as table sources
|
|
296
|
+
* **Complete set operations** - UNION, INTERSECT, EXCEPT with proper deduplication
|
|
297
|
+
* **DIFF (symmetric difference)** - `A diff B` equals `(A except B) union (B except A)`, handy for table equality checks via `not exists(A diff B)`
|
|
298
|
+
* **Robust transaction support** - Multi-level savepoints and rollback. See [Usage Guide](../../docs/usage.md#transactions) for details
|
|
299
|
+
* **Rich built-in function library** - Scalar, aggregate, window, JSON, and date/time functions
|
|
300
|
+
|
|
301
|
+
**Optimizer Status:**
|
|
302
|
+
|
|
303
|
+
Quereus features a sophisticated rule-based query optimizer that transforms logical plans into efficient physical execution plans. The optimizer uses a single plan node hierarchy with logical-to-physical transformation, generic tree rewriting infrastructure, and comprehensive optimization rules including constant folding, intelligent caching, streaming aggregation, bloom (hash) join selection for equi-joins, and correlated subquery decorrelation (EXISTS/IN → semi/anti joins).
|
|
304
|
+
|
|
305
|
+
See the [Optimizer Documentation](../../docs/optimizer.md) for architecture details and [Optimizer Conventions](../../docs/optimizer-conventions.md) for development guidelines.
|
|
306
|
+
[TODO List](../../docs/todo.md) has remaining priorities.
|
|
307
|
+
|
|
308
|
+
Recent changes:
|
|
309
|
+
- Retrieve growth and push-down stabilized: query-based modules slide full nodes via `supports()`; index-style fallback injects supported-only fragments inside `Retrieve`, preserving residuals above.
|
|
310
|
+
- Retrieve logical properties now expose `bindingsCount` and `bindingsNodeTypes` (visible in `query_plan().properties`) to aid verification that parameters/correlations are captured.
|
|
311
|
+
|
|
312
|
+
## Testing
|
|
313
|
+
|
|
314
|
+
The tests are located in `test/*.spec.ts` and are driven by Mocha with ts-node/esm.
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
yarn test
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Quereus employs a multi-faceted testing strategy:
|
|
321
|
+
|
|
322
|
+
1. **SQL Logic Tests (`test/logic/`)**:
|
|
323
|
+
* Inspired by SQLite's own testing methodology.
|
|
324
|
+
* Uses simple text files (`*.sqllogic`) containing SQL statements and their expected JSON results (using `→` marker) or expected error messages (using `-- error:` directive).
|
|
325
|
+
* Driven by a Mocha test runner (`test/logic.spec.ts`) that executes the SQL against a fresh `Database` instance for each file.
|
|
326
|
+
* **Configurable Diagnostics**: On unexpected failures, the test runner provides clean error messages by default with optional detailed diagnostics controlled by command line arguments:
|
|
327
|
+
* `yarn test --verbose` - Show execution progress during tests
|
|
328
|
+
* `yarn test --show-plan` - Include concise query plan in diagnostics
|
|
329
|
+
* `yarn test --plan-full-detail` - Include full detailed query plan (JSON format)
|
|
330
|
+
* `yarn test --plan-summary` - Show one-line execution path summary
|
|
331
|
+
* `yarn test --expand-nodes node1,node2...` - Expand specific nodes in concise plan
|
|
332
|
+
* `yarn test --max-plan-depth N` - Limit plan display depth
|
|
333
|
+
* `yarn test --show-program` - Include instruction program in diagnostics
|
|
334
|
+
* `yarn test --show-stack` - Include full stack trace in diagnostics
|
|
335
|
+
* `yarn test --show-trace` - Include execution trace in diagnostics
|
|
336
|
+
* `yarn test --trace-plan-stack` - Enable plan stack tracing in runtime
|
|
337
|
+
* This helps pinpoint failures at the Parser, Planner, or Runtime layer while keeping output manageable.
|
|
338
|
+
* Provides comprehensive coverage of SQL features: basic CRUD, complex expressions, all join types, window functions, aggregates, subqueries, CTEs, constraints, transactions, set operations, views, and error handling.
|
|
339
|
+
|
|
340
|
+
2. **Property-Based Tests (`test/property.spec.ts`)**:
|
|
341
|
+
* Uses the `fast-check` library to generate a wide range of inputs for specific, tricky areas.
|
|
342
|
+
* Focuses on verifying fundamental properties and invariants that should hold true across many different values.
|
|
343
|
+
* Currently includes tests for:
|
|
344
|
+
* **Collation Consistency**: Ensures `ORDER BY` results match the behavior of the `compareSqlValues` utility for `BINARY`, `NOCASE`, and `RTRIM` collations across various strings.
|
|
345
|
+
* **Numeric Affinity**: Verifies that comparisons (`=`, `<`) in SQL handle mixed types (numbers, strings, booleans, nulls) consistently with SQLite's affinity rules, using `compareSqlValues` as the reference.
|
|
346
|
+
* **JSON Roundtrip**: Confirms that arbitrary JSON values survive being processed by `json_quote()` and `json_extract('$')` without data loss or corruption.
|
|
347
|
+
|
|
348
|
+
3. **Performance Sentinels (`test/performance-sentinels.spec.ts`)**:
|
|
349
|
+
* Micro-benchmarks with generous thresholds to catch severe performance regressions.
|
|
350
|
+
* Currently includes sentinels for: parser throughput (simple, wide-SELECT, nested-expression), query execution (full table scan), and self-join (nested-loop baseline).
|
|
351
|
+
* Thresholds are intentionally generous to avoid flakiness while still catching order-of-magnitude regressions.
|
|
352
|
+
|
|
353
|
+
4. **Unit Tests (`test/*.spec.ts`)**:
|
|
354
|
+
* Dedicated unit tests for core subsystems: type system (`type-system.spec.ts`), schema manager (`schema-manager.spec.ts`), optimizer rules (`optimizer/*.spec.ts`), memory vtable (`memory-vtable.spec.ts`), utility functions (`utility-edge-cases.spec.ts`).
|
|
355
|
+
* Integration boundary tests (`integration-boundaries.spec.ts`) verify all boundary transitions: Parser→Planner, Planner→Optimizer, Optimizer→Runtime, Runtime→VTab.
|
|
356
|
+
* Golden plan tests (`plan/golden-plans.spec.ts`) use snapshot testing to detect unintended query plan changes.
|
|
357
|
+
|
|
358
|
+
5. **CI Integration (Planned)**:
|
|
359
|
+
* Utilize GitHub Actions (or similar) to run test suites automatically, potentially with different configurations (quick checks, full runs, browser environment).
|
|
360
|
+
|
|
361
|
+
This layered approach aims for broad coverage via the logic tests, unit tests for individual subsystems, property tests to explore edge cases, and performance sentinels to guard against regressions.
|
|
362
|
+
|
|
363
|
+
## Supported Built-in Functions
|
|
364
|
+
|
|
365
|
+
* **Scalar:** `lower`, `upper`, `length`, `substr`/`substring`, `abs`, `round`, `coalesce`, `nullif`, `like`, `glob`, `typeof`
|
|
366
|
+
* **Aggregate:** `count`, `sum`, `avg`, `min`, `max`, `group_concat`, `json_group_array`, `json_group_object`
|
|
367
|
+
* **Window Functions:** Complete implementation with `row_number`, `rank`, `dense_rank`, `ntile` (ranking); `count`, `sum`, `avg`, `min`, `max` with OVER clause (aggregates); Full frame specification support (`ROWS BETWEEN`, `UNBOUNDED PRECEDING/FOLLOWING`); `NULLS FIRST/LAST` ordering
|
|
368
|
+
* **Date/Time:** `date`, `time`, `datetime`, `julianday`, `strftime` (supports common formats and modifiers), `epoch_s`, `epoch_ms`, `epoch_s_frac` (Unix epoch conversions with strict parsing)
|
|
369
|
+
* **JSON:** `json_valid`, `json_schema`, `json_type`, `json_extract`, `json_quote`, `json_array`, `json_object`, `json_insert`, `json_replace`, `json_set`, `json_remove`, `json_array_length`, `json_patch`
|
|
370
|
+
* **Query Analysis:** `query_plan`, `scheduler_program`, `execution_trace` (debugging and performance analysis)
|
|
371
|
+
|
|
372
|
+
|