@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.
Files changed (512) hide show
  1. package/README.md +372 -361
  2. package/dist/src/common/errors.d.ts +2 -18
  3. package/dist/src/common/errors.d.ts.map +1 -1
  4. package/dist/src/common/errors.js +6 -29
  5. package/dist/src/common/errors.js.map +1 -1
  6. package/dist/src/common/types.d.ts +8 -0
  7. package/dist/src/common/types.d.ts.map +1 -1
  8. package/dist/src/common/types.js +20 -0
  9. package/dist/src/common/types.js.map +1 -1
  10. package/dist/src/core/database-assertions.d.ts +19 -2
  11. package/dist/src/core/database-assertions.d.ts.map +1 -1
  12. package/dist/src/core/database-assertions.js +113 -32
  13. package/dist/src/core/database-assertions.js.map +1 -1
  14. package/dist/src/core/database-events.d.ts +17 -0
  15. package/dist/src/core/database-events.d.ts.map +1 -1
  16. package/dist/src/core/database-events.js +36 -0
  17. package/dist/src/core/database-events.js.map +1 -1
  18. package/dist/src/core/database.d.ts +11 -0
  19. package/dist/src/core/database.d.ts.map +1 -1
  20. package/dist/src/core/database.js +178 -85
  21. package/dist/src/core/database.js.map +1 -1
  22. package/dist/src/core/statement.d.ts +6 -0
  23. package/dist/src/core/statement.d.ts.map +1 -1
  24. package/dist/src/core/statement.js +42 -56
  25. package/dist/src/core/statement.js.map +1 -1
  26. package/dist/src/emit/ast-stringify.d.ts +1 -0
  27. package/dist/src/emit/ast-stringify.d.ts.map +1 -1
  28. package/dist/src/emit/ast-stringify.js +12 -2
  29. package/dist/src/emit/ast-stringify.js.map +1 -1
  30. package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
  31. package/dist/src/func/builtins/builtin-window-functions.js +75 -0
  32. package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
  33. package/dist/src/func/builtins/conversion.js +9 -12
  34. package/dist/src/func/builtins/conversion.js.map +1 -1
  35. package/dist/src/func/builtins/datetime.js +1 -1
  36. package/dist/src/func/builtins/datetime.js.map +1 -1
  37. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  38. package/dist/src/func/builtins/explain.js +15 -3
  39. package/dist/src/func/builtins/explain.js.map +1 -1
  40. package/dist/src/func/builtins/index.d.ts.map +1 -1
  41. package/dist/src/func/builtins/index.js +1 -11
  42. package/dist/src/func/builtins/index.js.map +1 -1
  43. package/dist/src/func/builtins/json-helpers.js +1 -1
  44. package/dist/src/func/builtins/json-helpers.js.map +1 -1
  45. package/dist/src/func/builtins/json.d.ts.map +1 -1
  46. package/dist/src/func/builtins/json.js +2 -5
  47. package/dist/src/func/builtins/json.js.map +1 -1
  48. package/dist/src/func/builtins/schema.d.ts.map +1 -1
  49. package/dist/src/func/builtins/schema.js +30 -32
  50. package/dist/src/func/builtins/schema.js.map +1 -1
  51. package/dist/src/func/builtins/string.d.ts.map +1 -1
  52. package/dist/src/func/builtins/string.js +40 -64
  53. package/dist/src/func/builtins/string.js.map +1 -1
  54. package/dist/src/func/builtins/timespan.d.ts.map +1 -1
  55. package/dist/src/func/builtins/timespan.js.map +1 -1
  56. package/dist/src/index.d.ts +2 -2
  57. package/dist/src/index.d.ts.map +1 -1
  58. package/dist/src/index.js +2 -2
  59. package/dist/src/index.js.map +1 -1
  60. package/dist/src/parser/ast.d.ts +9 -2
  61. package/dist/src/parser/ast.d.ts.map +1 -1
  62. package/dist/src/parser/lexer.d.ts +1 -0
  63. package/dist/src/parser/lexer.d.ts.map +1 -1
  64. package/dist/src/parser/lexer.js +3 -0
  65. package/dist/src/parser/lexer.js.map +1 -1
  66. package/dist/src/parser/parser.d.ts +11 -1
  67. package/dist/src/parser/parser.d.ts.map +1 -1
  68. package/dist/src/parser/parser.js +75 -135
  69. package/dist/src/parser/parser.js.map +1 -1
  70. package/dist/src/planner/analysis/const-evaluator.d.ts.map +1 -1
  71. package/dist/src/planner/analysis/const-evaluator.js +6 -3
  72. package/dist/src/planner/analysis/const-evaluator.js.map +1 -1
  73. package/dist/src/planner/analysis/constraint-extractor.d.ts +2 -1
  74. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
  75. package/dist/src/planner/analysis/constraint-extractor.js +154 -22
  76. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
  77. package/dist/src/planner/building/alter-table.d.ts.map +1 -1
  78. package/dist/src/planner/building/alter-table.js +18 -1
  79. package/dist/src/planner/building/alter-table.js.map +1 -1
  80. package/dist/src/planner/building/analyze.d.ts +5 -0
  81. package/dist/src/planner/building/analyze.d.ts.map +1 -0
  82. package/dist/src/planner/building/analyze.js +5 -0
  83. package/dist/src/planner/building/analyze.js.map +1 -0
  84. package/dist/src/planner/building/block.d.ts.map +1 -1
  85. package/dist/src/planner/building/block.js +3 -0
  86. package/dist/src/planner/building/block.js.map +1 -1
  87. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
  88. package/dist/src/planner/building/constraint-builder.js +25 -3
  89. package/dist/src/planner/building/constraint-builder.js.map +1 -1
  90. package/dist/src/planner/building/delete.d.ts.map +1 -1
  91. package/dist/src/planner/building/delete.js +11 -0
  92. package/dist/src/planner/building/delete.js.map +1 -1
  93. package/dist/src/planner/building/drop-assertion.d.ts.map +1 -1
  94. package/dist/src/planner/building/drop-assertion.js +2 -1
  95. package/dist/src/planner/building/drop-assertion.js.map +1 -1
  96. package/dist/src/planner/building/expression.d.ts.map +1 -1
  97. package/dist/src/planner/building/expression.js +55 -7
  98. package/dist/src/planner/building/expression.js.map +1 -1
  99. package/dist/src/planner/building/foreign-key-builder.d.ts +16 -0
  100. package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -0
  101. package/dist/src/planner/building/foreign-key-builder.js +269 -0
  102. package/dist/src/planner/building/foreign-key-builder.js.map +1 -0
  103. package/dist/src/planner/building/function-call.d.ts.map +1 -1
  104. package/dist/src/planner/building/function-call.js +3 -2
  105. package/dist/src/planner/building/function-call.js.map +1 -1
  106. package/dist/src/planner/building/insert.d.ts.map +1 -1
  107. package/dist/src/planner/building/insert.js +91 -10
  108. package/dist/src/planner/building/insert.js.map +1 -1
  109. package/dist/src/planner/building/schema-resolution.d.ts +4 -0
  110. package/dist/src/planner/building/schema-resolution.d.ts.map +1 -1
  111. package/dist/src/planner/building/schema-resolution.js +14 -3
  112. package/dist/src/planner/building/schema-resolution.js.map +1 -1
  113. package/dist/src/planner/building/select-aggregates.d.ts +1 -0
  114. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  115. package/dist/src/planner/building/select-aggregates.js +118 -3
  116. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  117. package/dist/src/planner/building/select-modifiers.js +3 -3
  118. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  119. package/dist/src/planner/building/select-window.js +9 -8
  120. package/dist/src/planner/building/select-window.js.map +1 -1
  121. package/dist/src/planner/building/select.d.ts.map +1 -1
  122. package/dist/src/planner/building/select.js +21 -10
  123. package/dist/src/planner/building/select.js.map +1 -1
  124. package/dist/src/planner/building/table.d.ts.map +1 -1
  125. package/dist/src/planner/building/table.js +5 -3
  126. package/dist/src/planner/building/table.js.map +1 -1
  127. package/dist/src/planner/building/update.d.ts.map +1 -1
  128. package/dist/src/planner/building/update.js +30 -1
  129. package/dist/src/planner/building/update.js.map +1 -1
  130. package/dist/src/planner/building/with.js +1 -1
  131. package/dist/src/planner/building/with.js.map +1 -1
  132. package/dist/src/planner/cache/reference-graph.d.ts +1 -1
  133. package/dist/src/planner/cache/reference-graph.js +1 -1
  134. package/dist/src/planner/cost/index.d.ts +10 -3
  135. package/dist/src/planner/cost/index.d.ts.map +1 -1
  136. package/dist/src/planner/cost/index.js +17 -3
  137. package/dist/src/planner/cost/index.js.map +1 -1
  138. package/dist/src/planner/debug.js +1 -1
  139. package/dist/src/planner/debug.js.map +1 -1
  140. package/dist/src/planner/framework/characteristics.d.ts +1 -1
  141. package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
  142. package/dist/src/planner/framework/pass.d.ts +3 -1
  143. package/dist/src/planner/framework/pass.d.ts.map +1 -1
  144. package/dist/src/planner/framework/pass.js +62 -18
  145. package/dist/src/planner/framework/pass.js.map +1 -1
  146. package/dist/src/planner/framework/physical-utils.d.ts +5 -0
  147. package/dist/src/planner/framework/physical-utils.d.ts.map +1 -1
  148. package/dist/src/planner/framework/physical-utils.js +19 -0
  149. package/dist/src/planner/framework/physical-utils.js.map +1 -1
  150. package/dist/src/planner/framework/trace.d.ts.map +1 -1
  151. package/dist/src/planner/framework/trace.js +3 -2
  152. package/dist/src/planner/framework/trace.js.map +1 -1
  153. package/dist/src/planner/nodes/alias-node.d.ts +2 -1
  154. package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
  155. package/dist/src/planner/nodes/alias-node.js +8 -0
  156. package/dist/src/planner/nodes/alias-node.js.map +1 -1
  157. package/dist/src/planner/nodes/alter-table-node.d.ts +42 -0
  158. package/dist/src/planner/nodes/alter-table-node.d.ts.map +1 -0
  159. package/dist/src/planner/nodes/alter-table-node.js +55 -0
  160. package/dist/src/planner/nodes/alter-table-node.js.map +1 -0
  161. package/dist/src/planner/nodes/analyze-node.d.ts +25 -0
  162. package/dist/src/planner/nodes/analyze-node.d.ts.map +1 -0
  163. package/dist/src/planner/nodes/analyze-node.js +83 -0
  164. package/dist/src/planner/nodes/analyze-node.js.map +1 -0
  165. package/dist/src/planner/nodes/bloom-join-node.d.ts +66 -0
  166. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -0
  167. package/dist/src/planner/nodes/bloom-join-node.js +200 -0
  168. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -0
  169. package/dist/src/planner/nodes/constraint-check-node.d.ts +1 -1
  170. package/dist/src/planner/nodes/constraint-check-node.d.ts.map +1 -1
  171. package/dist/src/planner/nodes/cte-reference-node.js +7 -7
  172. package/dist/src/planner/nodes/cte-reference-node.js.map +1 -1
  173. package/dist/src/planner/nodes/join-node.d.ts +9 -1
  174. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  175. package/dist/src/planner/nodes/join-node.js +69 -79
  176. package/dist/src/planner/nodes/join-node.js.map +1 -1
  177. package/dist/src/planner/nodes/merge-join-node.d.ts +60 -0
  178. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -0
  179. package/dist/src/planner/nodes/merge-join-node.js +207 -0
  180. package/dist/src/planner/nodes/merge-join-node.js.map +1 -0
  181. package/dist/src/planner/nodes/plan-node-type.d.ts +1 -0
  182. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  183. package/dist/src/planner/nodes/plan-node-type.js +1 -0
  184. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  185. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  186. package/dist/src/planner/nodes/project-node.js +3 -2
  187. package/dist/src/planner/nodes/project-node.js.map +1 -1
  188. package/dist/src/planner/nodes/reference.d.ts +2 -1
  189. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  190. package/dist/src/planner/nodes/reference.js +6 -2
  191. package/dist/src/planner/nodes/reference.js.map +1 -1
  192. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  193. package/dist/src/planner/nodes/returning-node.js +3 -2
  194. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  195. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  196. package/dist/src/planner/nodes/subquery.js.map +1 -1
  197. package/dist/src/planner/nodes/table-access-nodes.js +1 -1
  198. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  199. package/dist/src/planner/nodes/update-node.d.ts +2 -0
  200. package/dist/src/planner/nodes/update-node.d.ts.map +1 -1
  201. package/dist/src/planner/nodes/update-node.js +2 -1
  202. package/dist/src/planner/nodes/update-node.js.map +1 -1
  203. package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
  204. package/dist/src/planner/nodes/window-function.js +7 -7
  205. package/dist/src/planner/nodes/window-function.js.map +1 -1
  206. package/dist/src/planner/nodes/window-node.d.ts +2 -2
  207. package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
  208. package/dist/src/planner/nodes/window-node.js +9 -14
  209. package/dist/src/planner/nodes/window-node.js.map +1 -1
  210. package/dist/src/planner/optimizer.d.ts.map +1 -1
  211. package/dist/src/planner/optimizer.js +40 -2
  212. package/dist/src/planner/optimizer.js.map +1 -1
  213. package/dist/src/planner/planning-context.d.ts.map +1 -1
  214. package/dist/src/planner/planning-context.js +1 -6
  215. package/dist/src/planner/planning-context.js.map +1 -1
  216. package/dist/src/planner/resolve.d.ts.map +1 -1
  217. package/dist/src/planner/resolve.js.map +1 -1
  218. package/dist/src/planner/rules/access/rule-select-access-path.js +157 -28
  219. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  220. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -1
  221. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +27 -6
  222. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
  223. package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts +19 -0
  224. package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts.map +1 -0
  225. package/dist/src/planner/rules/cache/rule-in-subquery-cache.js +53 -0
  226. package/dist/src/planner/rules/cache/rule-in-subquery-cache.js.map +1 -0
  227. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.d.ts.map +1 -1
  228. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js +5 -0
  229. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js.map +1 -1
  230. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts +18 -0
  231. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts.map +1 -0
  232. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js +37 -0
  233. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js.map +1 -0
  234. package/dist/src/planner/rules/join/rule-join-key-inference.d.ts +8 -3
  235. package/dist/src/planner/rules/join/rule-join-key-inference.d.ts.map +1 -1
  236. package/dist/src/planner/rules/join/rule-join-key-inference.js +28 -17
  237. package/dist/src/planner/rules/join/rule-join-key-inference.js.map +1 -1
  238. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts +16 -0
  239. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -0
  240. package/dist/src/planner/rules/join/rule-join-physical-selection.js +216 -0
  241. package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -0
  242. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.d.ts.map +1 -1
  243. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +34 -4
  244. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
  245. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts +23 -0
  246. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -0
  247. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +293 -0
  248. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -0
  249. package/dist/src/planner/scopes/multi.d.ts +3 -2
  250. package/dist/src/planner/scopes/multi.d.ts.map +1 -1
  251. package/dist/src/planner/scopes/multi.js +32 -7
  252. package/dist/src/planner/scopes/multi.js.map +1 -1
  253. package/dist/src/planner/scopes/shadow.d.ts +20 -0
  254. package/dist/src/planner/scopes/shadow.d.ts.map +1 -0
  255. package/dist/src/planner/scopes/shadow.js +31 -0
  256. package/dist/src/planner/scopes/shadow.js.map +1 -0
  257. package/dist/src/planner/stats/analyze.d.ts +17 -0
  258. package/dist/src/planner/stats/analyze.d.ts.map +1 -0
  259. package/dist/src/planner/stats/analyze.js +114 -0
  260. package/dist/src/planner/stats/analyze.js.map +1 -0
  261. package/dist/src/planner/stats/catalog-stats.d.ts +80 -0
  262. package/dist/src/planner/stats/catalog-stats.d.ts.map +1 -0
  263. package/dist/src/planner/stats/catalog-stats.js +248 -0
  264. package/dist/src/planner/stats/catalog-stats.js.map +1 -0
  265. package/dist/src/planner/stats/histogram.d.ts +24 -0
  266. package/dist/src/planner/stats/histogram.d.ts.map +1 -0
  267. package/dist/src/planner/stats/histogram.js +142 -0
  268. package/dist/src/planner/stats/histogram.js.map +1 -0
  269. package/dist/src/planner/type-utils.d.ts.map +1 -1
  270. package/dist/src/planner/type-utils.js +8 -2
  271. package/dist/src/planner/type-utils.js.map +1 -1
  272. package/dist/src/planner/util/key-utils.d.ts +48 -2
  273. package/dist/src/planner/util/key-utils.d.ts.map +1 -1
  274. package/dist/src/planner/util/key-utils.js +123 -0
  275. package/dist/src/planner/util/key-utils.js.map +1 -1
  276. package/dist/src/planner/validation/determinism-validator.d.ts +9 -0
  277. package/dist/src/planner/validation/determinism-validator.d.ts.map +1 -1
  278. package/dist/src/planner/validation/determinism-validator.js +11 -0
  279. package/dist/src/planner/validation/determinism-validator.js.map +1 -1
  280. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  281. package/dist/src/planner/validation/plan-validator.js +1 -0
  282. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  283. package/dist/src/runtime/context-helpers.d.ts +34 -10
  284. package/dist/src/runtime/context-helpers.d.ts.map +1 -1
  285. package/dist/src/runtime/context-helpers.js +115 -39
  286. package/dist/src/runtime/context-helpers.js.map +1 -1
  287. package/dist/src/runtime/deferred-constraint-queue.d.ts +0 -1
  288. package/dist/src/runtime/deferred-constraint-queue.d.ts.map +1 -1
  289. package/dist/src/runtime/deferred-constraint-queue.js +10 -23
  290. package/dist/src/runtime/deferred-constraint-queue.js.map +1 -1
  291. package/dist/src/runtime/descriptor-helpers.d.ts +7 -0
  292. package/dist/src/runtime/descriptor-helpers.d.ts.map +1 -0
  293. package/dist/src/runtime/descriptor-helpers.js +24 -0
  294. package/dist/src/runtime/descriptor-helpers.js.map +1 -0
  295. package/dist/src/runtime/emission-context.d.ts +7 -1
  296. package/dist/src/runtime/emission-context.d.ts.map +1 -1
  297. package/dist/src/runtime/emission-context.js +16 -0
  298. package/dist/src/runtime/emission-context.js.map +1 -1
  299. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  300. package/dist/src/runtime/emit/aggregate.js +97 -93
  301. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  302. package/dist/src/runtime/emit/alter-table.d.ts +5 -0
  303. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -0
  304. package/dist/src/runtime/emit/alter-table.js +209 -0
  305. package/dist/src/runtime/emit/alter-table.js.map +1 -0
  306. package/dist/src/runtime/emit/analyze.d.ts +9 -0
  307. package/dist/src/runtime/emit/analyze.d.ts.map +1 -0
  308. package/dist/src/runtime/emit/analyze.js +72 -0
  309. package/dist/src/runtime/emit/analyze.js.map +1 -0
  310. package/dist/src/runtime/emit/array-index.d.ts.map +1 -1
  311. package/dist/src/runtime/emit/array-index.js +4 -2
  312. package/dist/src/runtime/emit/array-index.js.map +1 -1
  313. package/dist/src/runtime/emit/between.d.ts.map +1 -1
  314. package/dist/src/runtime/emit/between.js +8 -20
  315. package/dist/src/runtime/emit/between.js.map +1 -1
  316. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  317. package/dist/src/runtime/emit/binary.js +155 -126
  318. package/dist/src/runtime/emit/binary.js.map +1 -1
  319. package/dist/src/runtime/emit/bloom-join.d.ts +12 -0
  320. package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -0
  321. package/dist/src/runtime/emit/bloom-join.js +114 -0
  322. package/dist/src/runtime/emit/bloom-join.js.map +1 -0
  323. package/dist/src/runtime/emit/cache.js +2 -2
  324. package/dist/src/runtime/emit/cache.js.map +1 -1
  325. package/dist/src/runtime/emit/cast.d.ts.map +1 -1
  326. package/dist/src/runtime/emit/cast.js +31 -117
  327. package/dist/src/runtime/emit/cast.js.map +1 -1
  328. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  329. package/dist/src/runtime/emit/constraint-check.js +2 -24
  330. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  331. package/dist/src/runtime/emit/cte-reference.d.ts.map +1 -1
  332. package/dist/src/runtime/emit/cte-reference.js +11 -5
  333. package/dist/src/runtime/emit/cte-reference.js.map +1 -1
  334. package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
  335. package/dist/src/runtime/emit/distinct.js +21 -12
  336. package/dist/src/runtime/emit/distinct.js.map +1 -1
  337. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  338. package/dist/src/runtime/emit/dml-executor.js +5 -1
  339. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  340. package/dist/src/runtime/emit/drop-assertion.d.ts.map +1 -1
  341. package/dist/src/runtime/emit/drop-assertion.js +2 -0
  342. package/dist/src/runtime/emit/drop-assertion.js.map +1 -1
  343. package/dist/src/runtime/emit/filter.d.ts.map +1 -1
  344. package/dist/src/runtime/emit/filter.js +26 -7
  345. package/dist/src/runtime/emit/filter.js.map +1 -1
  346. package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts.map +1 -1
  347. package/dist/src/runtime/emit/internal-recursive-cte-ref.js +11 -5
  348. package/dist/src/runtime/emit/internal-recursive-cte-ref.js.map +1 -1
  349. package/dist/src/runtime/emit/join.d.ts +1 -1
  350. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  351. package/dist/src/runtime/emit/join.js +44 -33
  352. package/dist/src/runtime/emit/join.js.map +1 -1
  353. package/dist/src/runtime/emit/merge-join.d.ts +14 -0
  354. package/dist/src/runtime/emit/merge-join.d.ts.map +1 -0
  355. package/dist/src/runtime/emit/merge-join.js +152 -0
  356. package/dist/src/runtime/emit/merge-join.js.map +1 -0
  357. package/dist/src/runtime/emit/parameter.d.ts.map +1 -1
  358. package/dist/src/runtime/emit/parameter.js +10 -32
  359. package/dist/src/runtime/emit/parameter.js.map +1 -1
  360. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  361. package/dist/src/runtime/emit/project.js +22 -12
  362. package/dist/src/runtime/emit/project.js.map +1 -1
  363. package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -1
  364. package/dist/src/runtime/emit/recursive-cte.js +5 -9
  365. package/dist/src/runtime/emit/recursive-cte.js.map +1 -1
  366. package/dist/src/runtime/emit/returning.d.ts.map +1 -1
  367. package/dist/src/runtime/emit/returning.js +14 -8
  368. package/dist/src/runtime/emit/returning.js.map +1 -1
  369. package/dist/src/runtime/emit/scan.d.ts.map +1 -1
  370. package/dist/src/runtime/emit/scan.js +4 -1
  371. package/dist/src/runtime/emit/scan.js.map +1 -1
  372. package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
  373. package/dist/src/runtime/emit/set-operation.js +8 -5
  374. package/dist/src/runtime/emit/set-operation.js.map +1 -1
  375. package/dist/src/runtime/emit/sort.js +2 -2
  376. package/dist/src/runtime/emit/sort.js.map +1 -1
  377. package/dist/src/runtime/emit/subquery.js +2 -2
  378. package/dist/src/runtime/emit/subquery.js.map +1 -1
  379. package/dist/src/runtime/emit/table-valued-function.d.ts.map +1 -1
  380. package/dist/src/runtime/emit/table-valued-function.js +21 -7
  381. package/dist/src/runtime/emit/table-valued-function.js.map +1 -1
  382. package/dist/src/runtime/emit/unary.js +2 -2
  383. package/dist/src/runtime/emit/unary.js.map +1 -1
  384. package/dist/src/runtime/emit/update.d.ts.map +1 -1
  385. package/dist/src/runtime/emit/update.js +43 -21
  386. package/dist/src/runtime/emit/update.js.map +1 -1
  387. package/dist/src/runtime/emit/window.d.ts.map +1 -1
  388. package/dist/src/runtime/emit/window.js +368 -126
  389. package/dist/src/runtime/emit/window.js.map +1 -1
  390. package/dist/src/runtime/foreign-key-actions.d.ts +15 -0
  391. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -0
  392. package/dist/src/runtime/foreign-key-actions.js +109 -0
  393. package/dist/src/runtime/foreign-key-actions.js.map +1 -0
  394. package/dist/src/runtime/register.d.ts.map +1 -1
  395. package/dist/src/runtime/register.js +8 -0
  396. package/dist/src/runtime/register.js.map +1 -1
  397. package/dist/src/runtime/scheduler.d.ts.map +1 -1
  398. package/dist/src/runtime/scheduler.js +4 -1
  399. package/dist/src/runtime/scheduler.js.map +1 -1
  400. package/dist/src/runtime/types.d.ts +6 -5
  401. package/dist/src/runtime/types.d.ts.map +1 -1
  402. package/dist/src/runtime/types.js.map +1 -1
  403. package/dist/src/schema/change-events.d.ts +36 -8
  404. package/dist/src/schema/change-events.d.ts.map +1 -1
  405. package/dist/src/schema/change-events.js.map +1 -1
  406. package/dist/src/schema/column.d.ts +5 -1
  407. package/dist/src/schema/column.d.ts.map +1 -1
  408. package/dist/src/schema/column.js +1 -2
  409. package/dist/src/schema/column.js.map +1 -1
  410. package/dist/src/schema/manager.d.ts +54 -4
  411. package/dist/src/schema/manager.d.ts.map +1 -1
  412. package/dist/src/schema/manager.js +353 -313
  413. package/dist/src/schema/manager.js.map +1 -1
  414. package/dist/src/schema/schema-differ.js +3 -3
  415. package/dist/src/schema/schema-differ.js.map +1 -1
  416. package/dist/src/schema/schema.d.ts +1 -1
  417. package/dist/src/schema/schema.js +2 -2
  418. package/dist/src/schema/schema.js.map +1 -1
  419. package/dist/src/schema/table.d.ts +49 -0
  420. package/dist/src/schema/table.d.ts.map +1 -1
  421. package/dist/src/schema/table.js +30 -11
  422. package/dist/src/schema/table.js.map +1 -1
  423. package/dist/src/types/builtin-types.d.ts.map +1 -1
  424. package/dist/src/types/builtin-types.js +26 -95
  425. package/dist/src/types/builtin-types.js.map +1 -1
  426. package/dist/src/types/index.d.ts +1 -1
  427. package/dist/src/types/index.d.ts.map +1 -1
  428. package/dist/src/types/index.js +1 -1
  429. package/dist/src/types/index.js.map +1 -1
  430. package/dist/src/types/json-type.d.ts.map +1 -1
  431. package/dist/src/types/json-type.js +28 -40
  432. package/dist/src/types/json-type.js.map +1 -1
  433. package/dist/src/types/logical-type.d.ts +6 -0
  434. package/dist/src/types/logical-type.d.ts.map +1 -1
  435. package/dist/src/types/logical-type.js +12 -0
  436. package/dist/src/types/logical-type.js.map +1 -1
  437. package/dist/src/types/temporal-types.d.ts.map +1 -1
  438. package/dist/src/types/temporal-types.js +8 -37
  439. package/dist/src/types/temporal-types.js.map +1 -1
  440. package/dist/src/util/coercion.d.ts +4 -5
  441. package/dist/src/util/coercion.d.ts.map +1 -1
  442. package/dist/src/util/coercion.js +10 -14
  443. package/dist/src/util/coercion.js.map +1 -1
  444. package/dist/src/util/comparison.d.ts +34 -21
  445. package/dist/src/util/comparison.d.ts.map +1 -1
  446. package/dist/src/util/comparison.js +77 -43
  447. package/dist/src/util/comparison.js.map +1 -1
  448. package/dist/src/util/environment.d.ts +0 -8
  449. package/dist/src/util/environment.d.ts.map +1 -1
  450. package/dist/src/util/environment.js +0 -12
  451. package/dist/src/util/environment.js.map +1 -1
  452. package/dist/src/util/key-serializer.d.ts +33 -0
  453. package/dist/src/util/key-serializer.d.ts.map +1 -0
  454. package/dist/src/util/key-serializer.js +95 -0
  455. package/dist/src/util/key-serializer.js.map +1 -0
  456. package/dist/src/util/plugin-helper.d.ts.map +1 -1
  457. package/dist/src/util/plugin-helper.js +21 -45
  458. package/dist/src/util/plugin-helper.js.map +1 -1
  459. package/dist/src/util/serialization.d.ts +1 -0
  460. package/dist/src/util/serialization.d.ts.map +1 -1
  461. package/dist/src/util/serialization.js +8 -1
  462. package/dist/src/util/serialization.js.map +1 -1
  463. package/dist/src/util/working-table-iterable.d.ts +6 -5
  464. package/dist/src/util/working-table-iterable.d.ts.map +1 -1
  465. package/dist/src/util/working-table-iterable.js +8 -15
  466. package/dist/src/util/working-table-iterable.js.map +1 -1
  467. package/dist/src/vtab/best-access-plan.d.ts +12 -0
  468. package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
  469. package/dist/src/vtab/best-access-plan.js +22 -0
  470. package/dist/src/vtab/best-access-plan.js.map +1 -1
  471. package/dist/src/vtab/manifest.d.ts +3 -1
  472. package/dist/src/vtab/manifest.d.ts.map +1 -1
  473. package/dist/src/vtab/memory/index.d.ts +2 -2
  474. package/dist/src/vtab/memory/index.d.ts.map +1 -1
  475. package/dist/src/vtab/memory/index.js +4 -7
  476. package/dist/src/vtab/memory/index.js.map +1 -1
  477. package/dist/src/vtab/memory/layer/base-cursor.d.ts.map +1 -1
  478. package/dist/src/vtab/memory/layer/base-cursor.js +37 -9
  479. package/dist/src/vtab/memory/layer/base-cursor.js.map +1 -1
  480. package/dist/src/vtab/memory/layer/base.js +1 -1
  481. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  482. package/dist/src/vtab/memory/layer/manager.d.ts +15 -3
  483. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  484. package/dist/src/vtab/memory/layer/manager.js +85 -37
  485. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  486. package/dist/src/vtab/memory/layer/scan-plan.d.ts +2 -0
  487. package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
  488. package/dist/src/vtab/memory/layer/scan-plan.js +153 -78
  489. package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
  490. package/dist/src/vtab/memory/layer/transaction-cursor.d.ts.map +1 -1
  491. package/dist/src/vtab/memory/layer/transaction-cursor.js +39 -9
  492. package/dist/src/vtab/memory/layer/transaction-cursor.js.map +1 -1
  493. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  494. package/dist/src/vtab/memory/layer/transaction.js +1 -5
  495. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  496. package/dist/src/vtab/memory/module.d.ts +14 -24
  497. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  498. package/dist/src/vtab/memory/module.js +88 -283
  499. package/dist/src/vtab/memory/module.js.map +1 -1
  500. package/dist/src/vtab/memory/table.d.ts +9 -0
  501. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  502. package/dist/src/vtab/memory/table.js +121 -18
  503. package/dist/src/vtab/memory/table.js.map +1 -1
  504. package/dist/src/vtab/memory/types.d.ts +1 -0
  505. package/dist/src/vtab/memory/types.d.ts.map +1 -1
  506. package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
  507. package/dist/src/vtab/module.d.ts +13 -0
  508. package/dist/src/vtab/module.d.ts.map +1 -1
  509. package/dist/src/vtab/table.d.ts +9 -0
  510. package/dist/src/vtab/table.d.ts.map +1 -1
  511. package/dist/src/vtab/table.js.map +1 -1
  512. 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](../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`](packages/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`](packages/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`](packages/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](packages/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`](packages/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
- * [Type System](../docs/types.md): Logical/physical types, temporal types, JSON, custom types
213
- * [Functions](../docs/functions.md): Built-in scalar, aggregate, window, and JSON functions
214
- * [Memory Tables](/docs/memory-table.md): Built-in MemoryTable module
215
- * [Module Authoring](../docs/module-authoring.md): Virtual table module development and event system
216
- * [Date/Time Handling](../docs/datetime.md): Temporal parsing, functions, and ISO 8601 formats
217
- * [Runtime](../docs/runtime.md): Instruction-based execution and opcodes
218
- * [Error Handling](../docs/error.md): Error types and status codes
219
- * [Plugin System](../docs/plugins.md): Virtual tables, functions, and collations
220
- * [TODO List](../docs/todo.md): Planned features
221
-
222
- ### Plugin Development
223
-
224
- Quereus exports all critical utilities needed for plugin and module development:
225
-
226
- * **Comparison Functions**: `compareSqlValues`, `compareRows`, `compareTypedValues`, `createTypedComparator` — Match Quereus SQL semantics in custom implementations
227
- * **Coercion Utilities**: `tryCoerceToNumber`, `coerceForComparison`, `coerceForAggregate` — Handle type coercion correctly
228
- * **Collation Support**: `registerCollation`, `getCollation`, built-in collations (`BINARY_COLLATION`, `NOCASE_COLLATION`, `RTRIM_COLLATION`)
229
- * **Type System**: Full access to logical types, validation, and parsing utilities
230
- * **Event Hooks**: `VTableEventEmitter` interface for mutation and schema change events — Enable reactive patterns, caching, and replication
231
-
232
- See the [Plugin System documentation](../docs/plugins.md#comparison-and-coercion-utilities) for complete API reference and examples.
233
-
234
- ## Key Design Decisions
235
-
236
- * **Federated / VTab-Centric**: All tables are virtual tables.
237
- * **Async Core**: Core operations are asynchronous. Cursors are `AsyncIterable<Row>`.
238
- * **Key-Based Addressing**: Rows are identified by their defined Primary Key. No separate implicit `rowid`.
239
- * **Relational Orthogonality**: Any statement that results in a relation can be used anywhere that expects a relation value, including mutating statements with RETURNING clauses.
240
- * **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.
241
- * **JavaScript Types**: Uses standard JavaScript types (`number`, `string`, `bigint`, `boolean`, `Uint8Array`, `null`) internally.
242
- * **Object-Based API**: Uses classes (`Database`, `Statement`) to represent resources with lifecycles, rather than handles.
243
- * **Transient Schema**: Schema information is primarily in-memory; persistence is not a goal. Emission of schema SQL export is supported.
244
- * **Multi-Schema Support**: Organize tables across multiple schemas with flexible search paths for modular designs.
245
- * **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.
246
- * **Attribute-Based Context System**: Robust column reference resolution using stable attribute IDs eliminates architectural fragilities and provides deterministic context lookup across plan transformations.
247
-
248
- ## Key Design Differences
249
-
250
- While Quereus supports standard SQL syntax, it has several distinctive design choices:
251
-
252
- * **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. See [Type System Documentation](../docs/types.md).
253
- * **Virtual Table Centric**: Uses `CREATE TABLE ... USING module(...)` syntax. All tables are virtual tables.
254
- * **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.
255
- * **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.
256
- * **Async API**: Core execution is asynchronous with async/await patterns throughout.
257
- * **No Triggers or Built-in Persistence**: Persistent storage can be implemented as a VTab module.
258
-
259
- ### Row-Level Constraints
260
-
261
- - Row-level CHECKs that reference only the current row are enforced immediately.
262
- - 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.
263
- - **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).
264
-
265
- ### Sequential ID Generation
266
-
267
- 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:
268
-
269
- ```sql
270
- insert into orders (id, customer_id, total)
271
- with context base_ts = epoch_ms('now')
272
- select
273
- base_ts * 1000 + row_number() over (order by c.customer_id),
274
- c.customer_id,
275
- c.total
276
- from (select customer_id, sum(price) as total from cart_items group by customer_id) c;
277
- ```
278
-
279
- 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.
280
-
281
- ## Current Status
282
-
283
- 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.
284
-
285
- **Current capabilities include:**
286
- * **Modern Type System** - Temporal types (DATE, TIME, DATETIME), JSON with deep equality, plugin-extensible custom types
287
- * **Complete JOIN support** - INNER, LEFT, RIGHT, CROSS joins with proper NULL padding
288
- * **Advanced window functions** - Ranking, aggregates, and frame specifications
289
- * **Full constraint system** - NOT NULL, CHECK constraints with operation-specific triggers
290
- * **Comprehensive subqueries** - Scalar, correlated, EXISTS, and IN subqueries
291
- * **Relational orthogonality** - INSERT/UPDATE/DELETE with RETURNING can be used as table sources
292
- * **Complete set operations** - UNION, INTERSECT, EXCEPT with proper deduplication
293
- * **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)`
294
- * **Robust transaction support** - Multi-level savepoints and rollback
295
- * **Rich built-in function library** - Scalar, aggregate, window, JSON, and date/time functions
296
-
297
- **Optimizer Status:**
298
-
299
- 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, and streaming aggregation.
300
-
301
- See the [Optimizer Documentation](../docs/optimizer.md) for architecture details and [Optimizer Conventions](../docs/optimizer-conventions.md) for development guidelines.
302
- [TODO List](../docs/todo.md) has remaining priorities.
303
-
304
- Recent changes:
305
- - 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.
306
- - Retrieve logical properties now expose `bindingsCount` and `bindingsNodeTypes` (visible in `query_plan().properties`) to aid verification that parameters/correlations are captured.
307
-
308
- ## Testing
309
-
310
- The tests are located in `test/*.spec.ts` and are driven by Mocha with ts-node/esm.
311
-
312
- ```bash
313
- yarn test
314
- ```
315
-
316
- Quereus employs a multi-faceted testing strategy:
317
-
318
- 1. **SQL Logic Tests (`test/logic/`)**:
319
- * Inspired by SQLite's own testing methodology.
320
- * Uses simple text files (`*.sqllogic`) containing SQL statements and their expected JSON results (using `→` marker) or expected error messages (using `-- error:` directive).
321
- * Driven by a Mocha test runner (`test/logic.spec.ts`) that executes the SQL against a fresh `Database` instance for each file.
322
- * **Configurable Diagnostics**: On unexpected failures, the test runner provides clean error messages by default with optional detailed diagnostics controlled by command line arguments:
323
- * `yarn test --verbose` - Show execution progress during tests
324
- * `yarn test --show-plan` - Include concise query plan in diagnostics
325
- * `yarn test --plan-full-detail` - Include full detailed query plan (JSON format)
326
- * `yarn test --plan-summary` - Show one-line execution path summary
327
- * `yarn test --expand-nodes node1,node2...` - Expand specific nodes in concise plan
328
- * `yarn test --max-plan-depth N` - Limit plan display depth
329
- * `yarn test --show-program` - Include instruction program in diagnostics
330
- * `yarn test --show-stack` - Include full stack trace in diagnostics
331
- * `yarn test --show-trace` - Include execution trace in diagnostics
332
- * `yarn test --trace-plan-stack` - Enable plan stack tracing in runtime
333
- * This helps pinpoint failures at the Parser, Planner, or Runtime layer while keeping output manageable.
334
- * 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.
335
-
336
- 2. **Property-Based Tests (`test/property.spec.ts`)**:
337
- * Uses the `fast-check` library to generate a wide range of inputs for specific, tricky areas.
338
- * Focuses on verifying fundamental properties and invariants that should hold true across many different values.
339
- * Currently includes tests for:
340
- * **Collation Consistency**: Ensures `ORDER BY` results match the behavior of the `compareSqlValues` utility for `BINARY`, `NOCASE`, and `RTRIM` collations across various strings.
341
- * **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.
342
- * **JSON Roundtrip**: Confirms that arbitrary JSON values survive being processed by `json_quote()` and `json_extract('$')` without data loss or corruption.
343
-
344
- 3. **Performance Sentinels (Planned)**:
345
- * Micro-benchmarks for specific scenarios (e.g., bulk inserts, complex queries) to catch performance regressions.
346
-
347
- 4. **CI Integration (Planned)**:
348
- * Utilize GitHub Actions (or similar) to run test suites automatically, potentially with different configurations (quick checks, full runs, browser environment).
349
-
350
- This layered approach aims for broad coverage via the logic tests while using property tests to explore edge cases in specific subsystems more thoroughly.
351
-
352
- ## Supported Built-in Functions
353
-
354
- * **Scalar:** `lower`, `upper`, `length`, `substr`/`substring`, `abs`, `round`, `coalesce`, `nullif`, `like`, `glob`, `typeof`
355
- * **Aggregate:** `count`, `sum`, `avg`, `min`, `max`, `group_concat`, `json_group_array`, `json_group_object`
356
- * **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
357
- * **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)
358
- * **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`
359
- * **Query Analysis:** `query_plan`, `scheduler_program`, `execution_trace` (debugging and performance analysis)
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
+