@quereus/quereus 0.7.3 → 0.7.5

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 (568) hide show
  1. package/dist/src/schema/manager.d.ts.map +1 -1
  2. package/dist/src/schema/manager.js +19 -18
  3. package/package.json +3 -3
  4. package/dist/src/common/constants.js.map +0 -1
  5. package/dist/src/common/datatype.js.map +0 -1
  6. package/dist/src/common/errors.js.map +0 -1
  7. package/dist/src/common/json-types.js.map +0 -1
  8. package/dist/src/common/logger.js.map +0 -1
  9. package/dist/src/common/type-inference.js.map +0 -1
  10. package/dist/src/common/types.js.map +0 -1
  11. package/dist/src/core/database-options.js.map +0 -1
  12. package/dist/src/core/database.js.map +0 -1
  13. package/dist/src/core/param.js.map +0 -1
  14. package/dist/src/core/statement.js.map +0 -1
  15. package/dist/src/func/builtins/aggregate.js.map +0 -1
  16. package/dist/src/func/builtins/builtin-window-functions.js.map +0 -1
  17. package/dist/src/func/builtins/conversion.js.map +0 -1
  18. package/dist/src/func/builtins/datetime.js.map +0 -1
  19. package/dist/src/func/builtins/explain.js.map +0 -1
  20. package/dist/src/func/builtins/generation.js.map +0 -1
  21. package/dist/src/func/builtins/index.js.map +0 -1
  22. package/dist/src/func/builtins/json-helpers.js.map +0 -1
  23. package/dist/src/func/builtins/json-tvf.js.map +0 -1
  24. package/dist/src/func/builtins/json.js.map +0 -1
  25. package/dist/src/func/builtins/scalar.js.map +0 -1
  26. package/dist/src/func/builtins/schema.js.map +0 -1
  27. package/dist/src/func/builtins/string.js.map +0 -1
  28. package/dist/src/func/builtins/timespan.js.map +0 -1
  29. package/dist/src/func/context.js.map +0 -1
  30. package/dist/src/func/registration.js.map +0 -1
  31. package/dist/src/index.js.map +0 -1
  32. package/dist/src/parser/ast.js.map +0 -1
  33. package/dist/src/parser/index.js.map +0 -1
  34. package/dist/src/parser/lexer.js.map +0 -1
  35. package/dist/src/parser/parser.js.map +0 -1
  36. package/dist/src/parser/utils.js.map +0 -1
  37. package/dist/src/parser/visitor.js.map +0 -1
  38. package/dist/src/planner/analysis/binding-collector.js.map +0 -1
  39. package/dist/src/planner/analysis/const-evaluator.js.map +0 -1
  40. package/dist/src/planner/analysis/const-pass.js.map +0 -1
  41. package/dist/src/planner/analysis/constraint-extractor.js.map +0 -1
  42. package/dist/src/planner/analysis/predicate-normalizer.js.map +0 -1
  43. package/dist/src/planner/building/alter-table.js.map +0 -1
  44. package/dist/src/planner/building/block.js.map +0 -1
  45. package/dist/src/planner/building/constraint-builder.js.map +0 -1
  46. package/dist/src/planner/building/create-assertion.js.map +0 -1
  47. package/dist/src/planner/building/create-view.js.map +0 -1
  48. package/dist/src/planner/building/ddl.js.map +0 -1
  49. package/dist/src/planner/building/declare-schema.js.map +0 -1
  50. package/dist/src/planner/building/delete.js.map +0 -1
  51. package/dist/src/planner/building/drop-assertion.js.map +0 -1
  52. package/dist/src/planner/building/drop-table.js.map +0 -1
  53. package/dist/src/planner/building/drop-view.js.map +0 -1
  54. package/dist/src/planner/building/expression.js.map +0 -1
  55. package/dist/src/planner/building/function-call.js.map +0 -1
  56. package/dist/src/planner/building/insert.js.map +0 -1
  57. package/dist/src/planner/building/pragma.js.map +0 -1
  58. package/dist/src/planner/building/schema-resolution.js.map +0 -1
  59. package/dist/src/planner/building/select-aggregates.js.map +0 -1
  60. package/dist/src/planner/building/select-compound.js.map +0 -1
  61. package/dist/src/planner/building/select-context.js.map +0 -1
  62. package/dist/src/planner/building/select-modifiers.js.map +0 -1
  63. package/dist/src/planner/building/select-projections.js.map +0 -1
  64. package/dist/src/planner/building/select-window.js.map +0 -1
  65. package/dist/src/planner/building/select.js.map +0 -1
  66. package/dist/src/planner/building/table-function.js.map +0 -1
  67. package/dist/src/planner/building/table.js.map +0 -1
  68. package/dist/src/planner/building/transaction.js.map +0 -1
  69. package/dist/src/planner/building/update.js.map +0 -1
  70. package/dist/src/planner/building/with.js.map +0 -1
  71. package/dist/src/planner/cache/correlation-detector.js.map +0 -1
  72. package/dist/src/planner/cache/materialization-advisory.js.map +0 -1
  73. package/dist/src/planner/cache/reference-graph.js.map +0 -1
  74. package/dist/src/planner/cost/index.js.map +0 -1
  75. package/dist/src/planner/debug/logger-utils.js.map +0 -1
  76. package/dist/src/planner/debug.js.map +0 -1
  77. package/dist/src/planner/framework/characteristics.js.map +0 -1
  78. package/dist/src/planner/framework/context.js.map +0 -1
  79. package/dist/src/planner/framework/pass.js.map +0 -1
  80. package/dist/src/planner/framework/physical-utils.js.map +0 -1
  81. package/dist/src/planner/framework/registry.js.map +0 -1
  82. package/dist/src/planner/framework/trace.js.map +0 -1
  83. package/dist/src/planner/nodes/add-constraint-node.js.map +0 -1
  84. package/dist/src/planner/nodes/aggregate-function.js.map +0 -1
  85. package/dist/src/planner/nodes/aggregate-node.js.map +0 -1
  86. package/dist/src/planner/nodes/array-index-node.js.map +0 -1
  87. package/dist/src/planner/nodes/block.js.map +0 -1
  88. package/dist/src/planner/nodes/cache-node.js.map +0 -1
  89. package/dist/src/planner/nodes/constraint-check-node.js.map +0 -1
  90. package/dist/src/planner/nodes/create-assertion-node.js.map +0 -1
  91. package/dist/src/planner/nodes/create-index-node.js.map +0 -1
  92. package/dist/src/planner/nodes/create-table-node.js.map +0 -1
  93. package/dist/src/planner/nodes/create-view-node.js.map +0 -1
  94. package/dist/src/planner/nodes/cte-node.js.map +0 -1
  95. package/dist/src/planner/nodes/cte-reference-node.js.map +0 -1
  96. package/dist/src/planner/nodes/declarative-schema.js.map +0 -1
  97. package/dist/src/planner/nodes/delete-node.js.map +0 -1
  98. package/dist/src/planner/nodes/distinct-node.js.map +0 -1
  99. package/dist/src/planner/nodes/dml-executor-node.js.map +0 -1
  100. package/dist/src/planner/nodes/drop-assertion-node.js.map +0 -1
  101. package/dist/src/planner/nodes/drop-table-node.js.map +0 -1
  102. package/dist/src/planner/nodes/drop-view-node.js.map +0 -1
  103. package/dist/src/planner/nodes/filter.js.map +0 -1
  104. package/dist/src/planner/nodes/function.js.map +0 -1
  105. package/dist/src/planner/nodes/insert-node.js.map +0 -1
  106. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js.map +0 -1
  107. package/dist/src/planner/nodes/join-node.js.map +0 -1
  108. package/dist/src/planner/nodes/limit-offset.js.map +0 -1
  109. package/dist/src/planner/nodes/plan-node-type.js.map +0 -1
  110. package/dist/src/planner/nodes/plan-node.js.map +0 -1
  111. package/dist/src/planner/nodes/pragma.js.map +0 -1
  112. package/dist/src/planner/nodes/project-node.js.map +0 -1
  113. package/dist/src/planner/nodes/recursive-cte-node.js.map +0 -1
  114. package/dist/src/planner/nodes/reference.js.map +0 -1
  115. package/dist/src/planner/nodes/remote-query-node.js.map +0 -1
  116. package/dist/src/planner/nodes/retrieve-node.js.map +0 -1
  117. package/dist/src/planner/nodes/returning-node.js.map +0 -1
  118. package/dist/src/planner/nodes/scalar.js.map +0 -1
  119. package/dist/src/planner/nodes/sequencing-node.js.map +0 -1
  120. package/dist/src/planner/nodes/set-operation-node.js.map +0 -1
  121. package/dist/src/planner/nodes/single-row.js.map +0 -1
  122. package/dist/src/planner/nodes/sink-node.js.map +0 -1
  123. package/dist/src/planner/nodes/sort.js.map +0 -1
  124. package/dist/src/planner/nodes/stream-aggregate.js.map +0 -1
  125. package/dist/src/planner/nodes/subquery.js.map +0 -1
  126. package/dist/src/planner/nodes/table-access-nodes.js.map +0 -1
  127. package/dist/src/planner/nodes/table-function-call.js.map +0 -1
  128. package/dist/src/planner/nodes/transaction-node.js.map +0 -1
  129. package/dist/src/planner/nodes/update-node.js.map +0 -1
  130. package/dist/src/planner/nodes/values-node.js.map +0 -1
  131. package/dist/src/planner/nodes/view-reference-node.js.map +0 -1
  132. package/dist/src/planner/nodes/window-function.js.map +0 -1
  133. package/dist/src/planner/nodes/window-node.js.map +0 -1
  134. package/dist/src/planner/optimizer-tuning.js.map +0 -1
  135. package/dist/src/planner/optimizer.js.map +0 -1
  136. package/dist/src/planner/planning-context.js.map +0 -1
  137. package/dist/src/planner/resolve.js.map +0 -1
  138. package/dist/src/planner/rules/access/rule-select-access-path.js.map +0 -1
  139. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +0 -1
  140. package/dist/src/planner/rules/cache/rule-cte-optimization.js.map +0 -1
  141. package/dist/src/planner/rules/cache/rule-materialization-advisory.js.map +0 -1
  142. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js.map +0 -1
  143. package/dist/src/planner/rules/join/rule-join-greedy-commute.js.map +0 -1
  144. package/dist/src/planner/rules/join/rule-join-key-inference.js.map +0 -1
  145. package/dist/src/planner/rules/join/rule-quickpick-enumeration.js.map +0 -1
  146. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +0 -1
  147. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +0 -1
  148. package/dist/src/planner/scopes/aliased.js.map +0 -1
  149. package/dist/src/planner/scopes/base.js.map +0 -1
  150. package/dist/src/planner/scopes/empty.js.map +0 -1
  151. package/dist/src/planner/scopes/global.js.map +0 -1
  152. package/dist/src/planner/scopes/multi.js.map +0 -1
  153. package/dist/src/planner/scopes/param.js.map +0 -1
  154. package/dist/src/planner/scopes/registered.js.map +0 -1
  155. package/dist/src/planner/scopes/scope.js.map +0 -1
  156. package/dist/src/planner/stats/basic-estimates.js.map +0 -1
  157. package/dist/src/planner/stats/index.js.map +0 -1
  158. package/dist/src/planner/type-utils.js.map +0 -1
  159. package/dist/src/planner/util/key-utils.js.map +0 -1
  160. package/dist/src/planner/validation/determinism-validator.js.map +0 -1
  161. package/dist/src/planner/validation/plan-validator.js.map +0 -1
  162. package/dist/src/runtime/async-util.js.map +0 -1
  163. package/dist/src/runtime/cache/shared-cache.js.map +0 -1
  164. package/dist/src/runtime/context-helpers.js.map +0 -1
  165. package/dist/src/runtime/deferred-constraint-queue.js.map +0 -1
  166. package/dist/src/runtime/emission-context.js.map +0 -1
  167. package/dist/src/runtime/emit/add-constraint.js.map +0 -1
  168. package/dist/src/runtime/emit/aggregate.js.map +0 -1
  169. package/dist/src/runtime/emit/array-index.js.map +0 -1
  170. package/dist/src/runtime/emit/between.js.map +0 -1
  171. package/dist/src/runtime/emit/binary.js.map +0 -1
  172. package/dist/src/runtime/emit/block.js.map +0 -1
  173. package/dist/src/runtime/emit/cache.js.map +0 -1
  174. package/dist/src/runtime/emit/case.js.map +0 -1
  175. package/dist/src/runtime/emit/cast.js.map +0 -1
  176. package/dist/src/runtime/emit/collate.js.map +0 -1
  177. package/dist/src/runtime/emit/column-reference.js.map +0 -1
  178. package/dist/src/runtime/emit/constraint-check.js.map +0 -1
  179. package/dist/src/runtime/emit/create-assertion.js.map +0 -1
  180. package/dist/src/runtime/emit/create-index.js.map +0 -1
  181. package/dist/src/runtime/emit/create-table.js.map +0 -1
  182. package/dist/src/runtime/emit/create-view.js.map +0 -1
  183. package/dist/src/runtime/emit/cte-reference.js.map +0 -1
  184. package/dist/src/runtime/emit/cte.js.map +0 -1
  185. package/dist/src/runtime/emit/delete.js.map +0 -1
  186. package/dist/src/runtime/emit/distinct.js.map +0 -1
  187. package/dist/src/runtime/emit/dml-executor.js.map +0 -1
  188. package/dist/src/runtime/emit/drop-assertion.js.map +0 -1
  189. package/dist/src/runtime/emit/drop-table.js.map +0 -1
  190. package/dist/src/runtime/emit/drop-view.js.map +0 -1
  191. package/dist/src/runtime/emit/filter.js.map +0 -1
  192. package/dist/src/runtime/emit/insert.js.map +0 -1
  193. package/dist/src/runtime/emit/internal-recursive-cte-ref.js.map +0 -1
  194. package/dist/src/runtime/emit/join.js.map +0 -1
  195. package/dist/src/runtime/emit/limit-offset.js.map +0 -1
  196. package/dist/src/runtime/emit/literal.js.map +0 -1
  197. package/dist/src/runtime/emit/parameter.js.map +0 -1
  198. package/dist/src/runtime/emit/pragma.js.map +0 -1
  199. package/dist/src/runtime/emit/project.js.map +0 -1
  200. package/dist/src/runtime/emit/recursive-cte.js.map +0 -1
  201. package/dist/src/runtime/emit/remote-query.js.map +0 -1
  202. package/dist/src/runtime/emit/retrieve.js.map +0 -1
  203. package/dist/src/runtime/emit/returning.js.map +0 -1
  204. package/dist/src/runtime/emit/scalar-function.js.map +0 -1
  205. package/dist/src/runtime/emit/scan.js.map +0 -1
  206. package/dist/src/runtime/emit/schema-declarative.js.map +0 -1
  207. package/dist/src/runtime/emit/sequencing.js.map +0 -1
  208. package/dist/src/runtime/emit/set-operation.js.map +0 -1
  209. package/dist/src/runtime/emit/sink.js.map +0 -1
  210. package/dist/src/runtime/emit/sort.js.map +0 -1
  211. package/dist/src/runtime/emit/subquery.js.map +0 -1
  212. package/dist/src/runtime/emit/table-valued-function.js.map +0 -1
  213. package/dist/src/runtime/emit/temporal-arithmetic.js.map +0 -1
  214. package/dist/src/runtime/emit/transaction.js.map +0 -1
  215. package/dist/src/runtime/emit/unary.js.map +0 -1
  216. package/dist/src/runtime/emit/update.js.map +0 -1
  217. package/dist/src/runtime/emit/values.js.map +0 -1
  218. package/dist/src/runtime/emit/window-function.js.map +0 -1
  219. package/dist/src/runtime/emit/window.js.map +0 -1
  220. package/dist/src/runtime/emitters.js.map +0 -1
  221. package/dist/src/runtime/register.js.map +0 -1
  222. package/dist/src/runtime/scheduler.js.map +0 -1
  223. package/dist/src/runtime/types.js.map +0 -1
  224. package/dist/src/runtime/utils.js.map +0 -1
  225. package/dist/src/schema/assertion.js.map +0 -1
  226. package/dist/src/schema/catalog.js.map +0 -1
  227. package/dist/src/schema/change-events.js.map +0 -1
  228. package/dist/src/schema/column.js.map +0 -1
  229. package/dist/src/schema/declared-schema-manager.js.map +0 -1
  230. package/dist/src/schema/function.js.map +0 -1
  231. package/dist/src/schema/manager.js.map +0 -1
  232. package/dist/src/schema/schema-differ.js.map +0 -1
  233. package/dist/src/schema/schema-hasher.js.map +0 -1
  234. package/dist/src/schema/schema.js.map +0 -1
  235. package/dist/src/schema/table.js.map +0 -1
  236. package/dist/src/schema/view.js.map +0 -1
  237. package/dist/src/schema/window-function.js.map +0 -1
  238. package/dist/src/types/builtin-types.js.map +0 -1
  239. package/dist/src/types/index.js.map +0 -1
  240. package/dist/src/types/json-type.js.map +0 -1
  241. package/dist/src/types/logical-type.js.map +0 -1
  242. package/dist/src/types/plugin-interface.js.map +0 -1
  243. package/dist/src/types/registry.js.map +0 -1
  244. package/dist/src/types/temporal-types.js.map +0 -1
  245. package/dist/src/types/validation.js.map +0 -1
  246. package/dist/src/util/affinity.js.map +0 -1
  247. package/dist/src/util/ast-stringify.js.map +0 -1
  248. package/dist/src/util/cached.js.map +0 -1
  249. package/dist/src/util/coercion.js.map +0 -1
  250. package/dist/src/util/comparison.js.map +0 -1
  251. package/dist/src/util/environment.js.map +0 -1
  252. package/dist/src/util/hash.js.map +0 -1
  253. package/dist/src/util/latches.js.map +0 -1
  254. package/dist/src/util/mutation-statement.js.map +0 -1
  255. package/dist/src/util/patterns.js.map +0 -1
  256. package/dist/src/util/plan-formatter.js.map +0 -1
  257. package/dist/src/util/plugin-helper.js.map +0 -1
  258. package/dist/src/util/row-descriptor.js.map +0 -1
  259. package/dist/src/util/serialization.js.map +0 -1
  260. package/dist/src/util/sql-literal.js.map +0 -1
  261. package/dist/src/util/working-table-iterable.js.map +0 -1
  262. package/dist/src/vtab/best-access-plan.js.map +0 -1
  263. package/dist/src/vtab/connection.js.map +0 -1
  264. package/dist/src/vtab/filter-info.js.map +0 -1
  265. package/dist/src/vtab/index-info.js.map +0 -1
  266. package/dist/src/vtab/manifest.js.map +0 -1
  267. package/dist/src/vtab/memory/connection.js.map +0 -1
  268. package/dist/src/vtab/memory/index.js.map +0 -1
  269. package/dist/src/vtab/memory/layer/base-cursor.js.map +0 -1
  270. package/dist/src/vtab/memory/layer/base.js.map +0 -1
  271. package/dist/src/vtab/memory/layer/connection.js.map +0 -1
  272. package/dist/src/vtab/memory/layer/interface.js.map +0 -1
  273. package/dist/src/vtab/memory/layer/manager.js.map +0 -1
  274. package/dist/src/vtab/memory/layer/safe-iterate.js.map +0 -1
  275. package/dist/src/vtab/memory/layer/scan-plan.js.map +0 -1
  276. package/dist/src/vtab/memory/layer/transaction-cursor.js.map +0 -1
  277. package/dist/src/vtab/memory/layer/transaction.js.map +0 -1
  278. package/dist/src/vtab/memory/module.js.map +0 -1
  279. package/dist/src/vtab/memory/table.js.map +0 -1
  280. package/dist/src/vtab/memory/types.js.map +0 -1
  281. package/dist/src/vtab/memory/utils/logging.js.map +0 -1
  282. package/dist/src/vtab/memory/utils/primary-key.js.map +0 -1
  283. package/dist/src/vtab/module.js.map +0 -1
  284. package/dist/src/vtab/table.js.map +0 -1
  285. package/src/common/constants.ts +0 -60
  286. package/src/common/datatype.ts +0 -85
  287. package/src/common/errors.ts +0 -189
  288. package/src/common/json-types.ts +0 -16
  289. package/src/common/logger.ts +0 -97
  290. package/src/common/type-inference.ts +0 -39
  291. package/src/common/types.ts +0 -151
  292. package/src/core/database-options.ts +0 -258
  293. package/src/core/database.ts +0 -1461
  294. package/src/core/param.ts +0 -56
  295. package/src/core/statement.ts +0 -528
  296. package/src/func/builtins/aggregate.ts +0 -269
  297. package/src/func/builtins/builtin-window-functions.ts +0 -166
  298. package/src/func/builtins/conversion.ts +0 -226
  299. package/src/func/builtins/datetime.ts +0 -500
  300. package/src/func/builtins/explain.ts +0 -779
  301. package/src/func/builtins/generation.ts +0 -43
  302. package/src/func/builtins/index.ts +0 -167
  303. package/src/func/builtins/json-helpers.ts +0 -237
  304. package/src/func/builtins/json-tvf.ts +0 -224
  305. package/src/func/builtins/json.ts +0 -588
  306. package/src/func/builtins/scalar.ts +0 -423
  307. package/src/func/builtins/schema.ts +0 -213
  308. package/src/func/builtins/string.ts +0 -306
  309. package/src/func/builtins/timespan.ts +0 -179
  310. package/src/func/context.ts +0 -258
  311. package/src/func/registration.ts +0 -201
  312. package/src/index.ts +0 -172
  313. package/src/parser/ast.ts +0 -581
  314. package/src/parser/index.ts +0 -65
  315. package/src/parser/lexer.ts +0 -806
  316. package/src/parser/parser.ts +0 -3352
  317. package/src/parser/utils.ts +0 -10
  318. package/src/parser/visitor.ts +0 -188
  319. package/src/planner/analysis/README.md +0 -93
  320. package/src/planner/analysis/binding-collector.ts +0 -83
  321. package/src/planner/analysis/const-evaluator.ts +0 -63
  322. package/src/planner/analysis/const-pass.ts +0 -282
  323. package/src/planner/analysis/constraint-extractor.ts +0 -764
  324. package/src/planner/analysis/predicate-normalizer.ts +0 -237
  325. package/src/planner/building/alter-table.ts +0 -49
  326. package/src/planner/building/block.ts +0 -93
  327. package/src/planner/building/constraint-builder.ts +0 -178
  328. package/src/planner/building/create-assertion.ts +0 -7
  329. package/src/planner/building/create-view.ts +0 -29
  330. package/src/planner/building/ddl.ts +0 -24
  331. package/src/planner/building/declare-schema.ts +0 -22
  332. package/src/planner/building/delete.ts +0 -218
  333. package/src/planner/building/drop-assertion.ts +0 -11
  334. package/src/planner/building/drop-table.ts +0 -13
  335. package/src/planner/building/drop-view.ts +0 -19
  336. package/src/planner/building/expression.ts +0 -205
  337. package/src/planner/building/function-call.ts +0 -129
  338. package/src/planner/building/insert.ts +0 -435
  339. package/src/planner/building/pragma.ts +0 -34
  340. package/src/planner/building/schema-resolution.ts +0 -176
  341. package/src/planner/building/select-aggregates.ts +0 -318
  342. package/src/planner/building/select-compound.ts +0 -119
  343. package/src/planner/building/select-context.ts +0 -85
  344. package/src/planner/building/select-modifiers.ts +0 -236
  345. package/src/planner/building/select-projections.ts +0 -177
  346. package/src/planner/building/select-window.ts +0 -259
  347. package/src/planner/building/select.ts +0 -567
  348. package/src/planner/building/table-function.ts +0 -49
  349. package/src/planner/building/table.ts +0 -40
  350. package/src/planner/building/transaction.ts +0 -23
  351. package/src/planner/building/update.ts +0 -331
  352. package/src/planner/building/with.ts +0 -180
  353. package/src/planner/cache/correlation-detector.ts +0 -83
  354. package/src/planner/cache/materialization-advisory.ts +0 -265
  355. package/src/planner/cache/reference-graph.ts +0 -196
  356. package/src/planner/cost/index.ts +0 -169
  357. package/src/planner/debug/logger-utils.ts +0 -68
  358. package/src/planner/debug.ts +0 -480
  359. package/src/planner/framework/README.md +0 -132
  360. package/src/planner/framework/characteristics.ts +0 -503
  361. package/src/planner/framework/context.ts +0 -239
  362. package/src/planner/framework/pass.ts +0 -354
  363. package/src/planner/framework/physical-utils.ts +0 -210
  364. package/src/planner/framework/registry.ts +0 -261
  365. package/src/planner/framework/trace.ts +0 -259
  366. package/src/planner/nodes/add-constraint-node.ts +0 -62
  367. package/src/planner/nodes/aggregate-function.ts +0 -155
  368. package/src/planner/nodes/aggregate-node.ts +0 -267
  369. package/src/planner/nodes/array-index-node.ts +0 -50
  370. package/src/planner/nodes/block.ts +0 -80
  371. package/src/planner/nodes/cache-node.ts +0 -103
  372. package/src/planner/nodes/constraint-check-node.ts +0 -138
  373. package/src/planner/nodes/create-assertion-node.ts +0 -51
  374. package/src/planner/nodes/create-index-node.ts +0 -41
  375. package/src/planner/nodes/create-table-node.ts +0 -35
  376. package/src/planner/nodes/create-view-node.ts +0 -44
  377. package/src/planner/nodes/cte-node.ts +0 -168
  378. package/src/planner/nodes/cte-reference-node.ts +0 -125
  379. package/src/planner/nodes/declarative-schema.ts +0 -221
  380. package/src/planner/nodes/delete-node.ts +0 -102
  381. package/src/planner/nodes/distinct-node.ts +0 -107
  382. package/src/planner/nodes/dml-executor-node.ts +0 -104
  383. package/src/planner/nodes/drop-assertion-node.ts +0 -50
  384. package/src/planner/nodes/drop-table-node.ts +0 -36
  385. package/src/planner/nodes/drop-view-node.ts +0 -37
  386. package/src/planner/nodes/filter.ts +0 -144
  387. package/src/planner/nodes/function.ts +0 -98
  388. package/src/planner/nodes/insert-node.ts +0 -126
  389. package/src/planner/nodes/internal-recursive-cte-ref-node.ts +0 -61
  390. package/src/planner/nodes/join-node.ts +0 -336
  391. package/src/planner/nodes/limit-offset.ts +0 -144
  392. package/src/planner/nodes/plan-node-type.ts +0 -95
  393. package/src/planner/nodes/plan-node.ts +0 -503
  394. package/src/planner/nodes/pragma.ts +0 -98
  395. package/src/planner/nodes/project-node.ts +0 -337
  396. package/src/planner/nodes/recursive-cte-node.ts +0 -158
  397. package/src/planner/nodes/reference.ts +0 -334
  398. package/src/planner/nodes/remote-query-node.ts +0 -73
  399. package/src/planner/nodes/retrieve-node.ts +0 -86
  400. package/src/planner/nodes/returning-node.ts +0 -269
  401. package/src/planner/nodes/scalar.ts +0 -772
  402. package/src/planner/nodes/sequencing-node.ts +0 -113
  403. package/src/planner/nodes/set-operation-node.ts +0 -87
  404. package/src/planner/nodes/single-row.ts +0 -85
  405. package/src/planner/nodes/sink-node.ts +0 -61
  406. package/src/planner/nodes/sort.ts +0 -166
  407. package/src/planner/nodes/stream-aggregate.ts +0 -293
  408. package/src/planner/nodes/subquery.ts +0 -268
  409. package/src/planner/nodes/table-access-nodes.ts +0 -323
  410. package/src/planner/nodes/table-function-call.ts +0 -134
  411. package/src/planner/nodes/transaction-node.ts +0 -55
  412. package/src/planner/nodes/update-node.ts +0 -138
  413. package/src/planner/nodes/values-node.ts +0 -244
  414. package/src/planner/nodes/view-reference-node.ts +0 -97
  415. package/src/planner/nodes/window-function.ts +0 -73
  416. package/src/planner/nodes/window-node.ts +0 -199
  417. package/src/planner/optimizer-tuning.ts +0 -105
  418. package/src/planner/optimizer.ts +0 -332
  419. package/src/planner/planning-context.ts +0 -190
  420. package/src/planner/resolve.ts +0 -101
  421. package/src/planner/rules/README.md +0 -96
  422. package/src/planner/rules/access/rule-select-access-path.ts +0 -399
  423. package/src/planner/rules/aggregate/rule-aggregate-streaming.ts +0 -162
  424. package/src/planner/rules/cache/rule-cte-optimization.ts +0 -79
  425. package/src/planner/rules/cache/rule-materialization-advisory.ts +0 -77
  426. package/src/planner/rules/cache/rule-mutating-subquery-cache.ts +0 -104
  427. package/src/planner/rules/join/rule-join-greedy-commute.ts +0 -48
  428. package/src/planner/rules/join/rule-join-key-inference.ts +0 -35
  429. package/src/planner/rules/join/rule-quickpick-enumeration.ts +0 -267
  430. package/src/planner/rules/predicate/rule-predicate-pushdown.ts +0 -144
  431. package/src/planner/rules/retrieve/rule-grow-retrieve.ts +0 -337
  432. package/src/planner/scopes/aliased.ts +0 -50
  433. package/src/planner/scopes/base.ts +0 -10
  434. package/src/planner/scopes/empty.ts +0 -12
  435. package/src/planner/scopes/global.ts +0 -73
  436. package/src/planner/scopes/multi.ts +0 -40
  437. package/src/planner/scopes/param.ts +0 -95
  438. package/src/planner/scopes/registered.ts +0 -67
  439. package/src/planner/scopes/scope.ts +0 -16
  440. package/src/planner/stats/basic-estimates.ts +0 -107
  441. package/src/planner/stats/index.ts +0 -158
  442. package/src/planner/type-utils.ts +0 -87
  443. package/src/planner/util/key-utils.ts +0 -46
  444. package/src/planner/validation/determinism-validator.ts +0 -104
  445. package/src/planner/validation/plan-validator.ts +0 -335
  446. package/src/runtime/async-util.ts +0 -283
  447. package/src/runtime/cache/shared-cache.ts +0 -169
  448. package/src/runtime/context-helpers.ts +0 -191
  449. package/src/runtime/deferred-constraint-queue.ts +0 -196
  450. package/src/runtime/emission-context.ts +0 -319
  451. package/src/runtime/emit/add-constraint.ts +0 -78
  452. package/src/runtime/emit/aggregate.ts +0 -581
  453. package/src/runtime/emit/array-index.ts +0 -25
  454. package/src/runtime/emit/between.ts +0 -51
  455. package/src/runtime/emit/binary.ts +0 -357
  456. package/src/runtime/emit/block.ts +0 -23
  457. package/src/runtime/emit/cache.ts +0 -64
  458. package/src/runtime/emit/case.ts +0 -87
  459. package/src/runtime/emit/cast.ts +0 -151
  460. package/src/runtime/emit/collate.ts +0 -9
  461. package/src/runtime/emit/column-reference.ts +0 -17
  462. package/src/runtime/emit/constraint-check.ts +0 -290
  463. package/src/runtime/emit/create-assertion.ts +0 -82
  464. package/src/runtime/emit/create-index.ts +0 -15
  465. package/src/runtime/emit/create-table.ts +0 -15
  466. package/src/runtime/emit/create-view.ts +0 -52
  467. package/src/runtime/emit/cte-reference.ts +0 -38
  468. package/src/runtime/emit/cte.ts +0 -39
  469. package/src/runtime/emit/delete.ts +0 -24
  470. package/src/runtime/emit/distinct.ts +0 -40
  471. package/src/runtime/emit/dml-executor.ts +0 -198
  472. package/src/runtime/emit/drop-assertion.ts +0 -45
  473. package/src/runtime/emit/drop-table.ts +0 -27
  474. package/src/runtime/emit/drop-view.ts +0 -49
  475. package/src/runtime/emit/filter.ts +0 -30
  476. package/src/runtime/emit/insert.ts +0 -42
  477. package/src/runtime/emit/internal-recursive-cte-ref.ts +0 -37
  478. package/src/runtime/emit/join.ts +0 -148
  479. package/src/runtime/emit/limit-offset.ts +0 -73
  480. package/src/runtime/emit/literal.ts +0 -17
  481. package/src/runtime/emit/parameter.ts +0 -59
  482. package/src/runtime/emit/pragma.ts +0 -56
  483. package/src/runtime/emit/project.ts +0 -46
  484. package/src/runtime/emit/recursive-cte.ts +0 -111
  485. package/src/runtime/emit/remote-query.ts +0 -47
  486. package/src/runtime/emit/retrieve.ts +0 -15
  487. package/src/runtime/emit/returning.ts +0 -41
  488. package/src/runtime/emit/scalar-function.ts +0 -69
  489. package/src/runtime/emit/scan.ts +0 -106
  490. package/src/runtime/emit/schema-declarative.ts +0 -215
  491. package/src/runtime/emit/sequencing.ts +0 -24
  492. package/src/runtime/emit/set-operation.ts +0 -141
  493. package/src/runtime/emit/sink.ts +0 -27
  494. package/src/runtime/emit/sort.ts +0 -75
  495. package/src/runtime/emit/subquery.ts +0 -203
  496. package/src/runtime/emit/table-valued-function.ts +0 -106
  497. package/src/runtime/emit/temporal-arithmetic.ts +0 -302
  498. package/src/runtime/emit/transaction.ts +0 -205
  499. package/src/runtime/emit/unary.ts +0 -101
  500. package/src/runtime/emit/update.ts +0 -66
  501. package/src/runtime/emit/values.ts +0 -66
  502. package/src/runtime/emit/window-function.ts +0 -42
  503. package/src/runtime/emit/window.ts +0 -458
  504. package/src/runtime/emitters.ts +0 -183
  505. package/src/runtime/register.ts +0 -150
  506. package/src/runtime/scheduler.ts +0 -488
  507. package/src/runtime/types.ts +0 -242
  508. package/src/runtime/utils.ts +0 -177
  509. package/src/schema/assertion.ts +0 -21
  510. package/src/schema/catalog.ts +0 -269
  511. package/src/schema/change-events.ts +0 -80
  512. package/src/schema/column.ts +0 -51
  513. package/src/schema/declared-schema-manager.ts +0 -82
  514. package/src/schema/function.ts +0 -188
  515. package/src/schema/manager.ts +0 -1034
  516. package/src/schema/schema-differ.ts +0 -214
  517. package/src/schema/schema-hasher.ts +0 -26
  518. package/src/schema/schema.ts +0 -222
  519. package/src/schema/table.ts +0 -409
  520. package/src/schema/view.ts +0 -19
  521. package/src/schema/window-function.ts +0 -56
  522. package/src/types/builtin-types.ts +0 -350
  523. package/src/types/index.ts +0 -17
  524. package/src/types/json-type.ts +0 -152
  525. package/src/types/logical-type.ts +0 -91
  526. package/src/types/plugin-interface.ts +0 -10
  527. package/src/types/registry.ts +0 -204
  528. package/src/types/temporal-types.ts +0 -290
  529. package/src/types/validation.ts +0 -120
  530. package/src/util/affinity.ts +0 -151
  531. package/src/util/ast-stringify.ts +0 -887
  532. package/src/util/cached.ts +0 -25
  533. package/src/util/coercion.ts +0 -113
  534. package/src/util/comparison.ts +0 -510
  535. package/src/util/environment.ts +0 -52
  536. package/src/util/hash.ts +0 -90
  537. package/src/util/latches.ts +0 -47
  538. package/src/util/mutation-statement.ts +0 -135
  539. package/src/util/patterns.ts +0 -56
  540. package/src/util/plan-formatter.ts +0 -48
  541. package/src/util/plugin-helper.ts +0 -110
  542. package/src/util/row-descriptor.ts +0 -105
  543. package/src/util/serialization.ts +0 -47
  544. package/src/util/sql-literal.ts +0 -22
  545. package/src/util/working-table-iterable.ts +0 -38
  546. package/src/vtab/best-access-plan.ts +0 -244
  547. package/src/vtab/connection.ts +0 -36
  548. package/src/vtab/filter-info.ts +0 -23
  549. package/src/vtab/index-info.ts +0 -84
  550. package/src/vtab/manifest.ts +0 -86
  551. package/src/vtab/memory/connection.ts +0 -73
  552. package/src/vtab/memory/index.ts +0 -191
  553. package/src/vtab/memory/layer/base-cursor.ts +0 -124
  554. package/src/vtab/memory/layer/base.ts +0 -275
  555. package/src/vtab/memory/layer/connection.ts +0 -203
  556. package/src/vtab/memory/layer/interface.ts +0 -47
  557. package/src/vtab/memory/layer/manager.ts +0 -909
  558. package/src/vtab/memory/layer/safe-iterate.ts +0 -49
  559. package/src/vtab/memory/layer/scan-plan.ts +0 -84
  560. package/src/vtab/memory/layer/transaction-cursor.ts +0 -162
  561. package/src/vtab/memory/layer/transaction.ts +0 -229
  562. package/src/vtab/memory/module.ts +0 -667
  563. package/src/vtab/memory/table.ts +0 -251
  564. package/src/vtab/memory/types.ts +0 -23
  565. package/src/vtab/memory/utils/logging.ts +0 -36
  566. package/src/vtab/memory/utils/primary-key.ts +0 -163
  567. package/src/vtab/module.ts +0 -162
  568. package/src/vtab/table.ts +0 -177
@@ -1,1461 +0,0 @@
1
- import { createLogger } from '../common/logger.js';
2
- import { MisuseError, quereusError, QuereusError } from '../common/errors.js';
3
- import { StatusCode, type SqlParameters, type SqlValue, type Row, type OutputValue } from '../common/types.js';
4
- import type { ScalarType } from '../common/datatype.js';
5
- import type { AnyVirtualTableModule } from '../vtab/module.js';
6
- import { Statement } from './statement.js';
7
- import { SchemaManager } from '../schema/manager.js';
8
- import type { TableSchema } from '../schema/table.js';
9
- import type { FunctionSchema } from '../schema/function.js';
10
- import { BUILTIN_FUNCTIONS } from '../func/builtins/index.js';
11
- import { createScalarFunction, createAggregateFunction } from '../func/registration.js';
12
- import { FunctionFlags } from '../common/constants.js';
13
- import { MemoryTableModule } from '../vtab/memory/module.js';
14
- import type { VirtualTableConnection } from '../vtab/connection.js';
15
- import { BINARY_COLLATION, getCollation, NOCASE_COLLATION, registerCollation, RTRIM_COLLATION, type CollationFunction } from '../util/comparison.js';
16
- import { Parser, ParseError } from '../parser/parser.js';
17
- import * as AST from '../parser/ast.js';
18
- import { buildBlock } from '../planner/building/block.js';
19
- import { emitPlanNode } from '../runtime/emitters.js';
20
- import { Scheduler } from '../runtime/scheduler.js';
21
- import type { RuntimeContext } from '../runtime/types.js';
22
- import type { RowDescriptor } from '../planner/nodes/plan-node.js';
23
- import { BlockNode } from '../planner/nodes/block.js';
24
- import type { PlanningContext } from '../planner/planning-context.js';
25
- import { BuildTimeDependencyTracker } from '../planner/planning-context.js';
26
- import { ParameterScope } from '../planner/scopes/param.js';
27
- import { GlobalScope } from '../planner/scopes/global.js';
28
- import { PlanNode, type RelationalPlanNode, type ScalarPlanNode } from '../planner/nodes/plan-node.js';
29
- import { FilterNode } from '../planner/nodes/filter.js';
30
- import { BinaryOpNode } from '../planner/nodes/scalar.js';
31
- import { ParameterReferenceNode, ColumnReferenceNode, TableReferenceNode } from '../planner/nodes/reference.js';
32
- import { registerEmitters } from '../runtime/register.js';
33
- import { serializePlanTree, formatPlanTree } from '../planner/debug.js';
34
- import type { DebugOptions } from '../planner/planning-context.js';
35
- import { EmissionContext } from '../runtime/emission-context.js';
36
- import { Optimizer, DEFAULT_TUNING } from '../planner/optimizer.js';
37
- import type { OptimizerTuning } from '../planner/optimizer-tuning.js';
38
- import { registerBuiltinWindowFunctions } from '../func/builtins/builtin-window-functions.js';
39
- import { DatabaseOptionsManager } from './database-options.js';
40
- import type { InstructionTracer } from '../runtime/types.js';
41
- import { isAsyncIterable } from '../runtime/utils.js';
42
- import { DeclaredSchemaManager } from '../schema/declared-schema-manager.js';
43
- import { analyzeRowSpecific } from '../planner/analysis/constraint-extractor.js';
44
- import { DeferredConstraintQueue } from '../runtime/deferred-constraint-queue.js';
45
- import { type LogicalType } from '../types/logical-type.js';
46
- import { getParameterTypes } from './param.js';
47
-
48
- const log = createLogger('core:database');
49
- const warnLog = log.extend('warn');
50
- const errorLog = log.extend('error');
51
- const debugLog = log.extend('debug');
52
-
53
- /**
54
- * Represents a connection to an Quereus database (in-memory in this port).
55
- * Manages schema, prepared statements, virtual tables, and functions.
56
- */
57
- export class Database {
58
- public readonly schemaManager: SchemaManager;
59
- public readonly declaredSchemaManager: DeclaredSchemaManager;
60
- private isOpen = true;
61
- private statements = new Set<Statement>();
62
- private isAutocommit = true; // Manages transaction state
63
- private inTransaction = false;
64
- private activeConnections = new Map<string, VirtualTableConnection>();
65
- private inImplicitTransaction = false; // Track if we're in an implicit transaction
66
- public readonly optimizer: Optimizer;
67
- public readonly options: DatabaseOptionsManager;
68
- private instructionTracer: InstructionTracer | undefined;
69
- /** Per-transaction change tracking: base table name → serialized PK tuples */
70
- private changeLog: Map<string, Set<string>> = new Map();
71
- /** Savepoint layers for change tracking */
72
- private changeLogLayers: Array<Map<string, Set<string>>> = [];
73
- /** Deferred constraint evaluation queue */
74
- private readonly deferredConstraints = new DeferredConstraintQueue(this);
75
-
76
- constructor() {
77
- this.schemaManager = new SchemaManager(this);
78
- this.declaredSchemaManager = new DeclaredSchemaManager();
79
- this.options = new DatabaseOptionsManager();
80
- log("Database instance created.");
81
-
82
- // Register built-in functions
83
- this.registerBuiltinFunctions();
84
-
85
- // Register default virtual table modules via SchemaManager
86
- // The SchemaManager.defaultVTabModuleName is already initialized (e.g. to 'memory')
87
- // No need to set defaultVtabModuleName explicitly here unless it's different from SchemaManager's init value.
88
- // this.schemaManager.setDefaultVTabModuleName('memory'); // Already 'memory' by default in SchemaManager
89
- // this.schemaManager.setDefaultVTabArgs([]); // Already [] by default in SchemaManager
90
-
91
- this.schemaManager.registerModule('memory', new MemoryTableModule());
92
-
93
- // Register built-in collations
94
- this.registerDefaultCollations();
95
-
96
- // Register built-in window functions
97
- registerBuiltinWindowFunctions();
98
-
99
- registerEmitters();
100
-
101
- // Initialize optimizer with default tuning
102
- this.optimizer = new Optimizer(DEFAULT_TUNING);
103
-
104
- // Set up option change listeners
105
- this.setupOptionListeners();
106
- }
107
-
108
- /** @internal Set up listeners for option changes */
109
- private setupOptionListeners(): void {
110
- // Register core database options with their change handlers
111
- this.options.registerOption('runtime_stats', {
112
- type: 'boolean',
113
- defaultValue: false,
114
- aliases: ['runtime_metrics'],
115
- description: 'Enable runtime execution statistics collection'
116
- // No onChange needed - consumed directly when creating RuntimeContext
117
- });
118
-
119
- this.options.registerOption('validate_plan', {
120
- type: 'boolean',
121
- defaultValue: false,
122
- aliases: ['plan_validation'],
123
- description: 'Enable plan validation before execution',
124
- onChange: (event) => {
125
- const newTuning = {
126
- ...this.optimizer.tuning,
127
- debug: {
128
- ...this.optimizer.tuning.debug,
129
- validatePlan: event.newValue as boolean
130
- }
131
- };
132
- this.updateOptimizerTuning(newTuning as OptimizerTuning);
133
- log('Optimizer tuning updated with validate_plan = %s', event.newValue);
134
- }
135
- });
136
-
137
- this.options.registerOption('default_vtab_module', {
138
- type: 'string',
139
- defaultValue: 'memory',
140
- description: 'Default virtual table module name',
141
- onChange: (event) => {
142
- this.schemaManager.setDefaultVTabModuleName(event.newValue as string);
143
- }
144
- });
145
-
146
- this.options.registerOption('default_vtab_args', {
147
- type: 'object',
148
- defaultValue: {},
149
- description: 'Default virtual table module arguments',
150
- onChange: (event) => {
151
- this.schemaManager.setDefaultVTabArgs(event.newValue as Record<string, SqlValue>);
152
- }
153
- });
154
-
155
- this.options.registerOption('default_column_nullability', {
156
- type: 'string',
157
- defaultValue: 'not_null',
158
- aliases: ['column_nullability_default', 'nullable_default'],
159
- description: 'Default nullability for columns: "nullable" (SQL standard) or "not_null" (Third Manifesto)',
160
- onChange: (event) => {
161
- const value = event.newValue as string;
162
- if (value !== 'nullable' && value !== 'not_null') {
163
- throw new QuereusError(`Invalid default_column_nullability value: ${value}. Must be "nullable" or "not_null"`, StatusCode.ERROR);
164
- }
165
- log('Default column nullability changed to: %s', value);
166
- }
167
- });
168
-
169
- this.options.registerOption('trace_plan_stack', {
170
- type: 'boolean',
171
- defaultValue: false,
172
- description: 'Enable plan stack tracing',
173
- });
174
- }
175
-
176
- /** @internal Registers default built-in SQL functions */
177
- private registerBuiltinFunctions(): void {
178
- const mainSchema = this.schemaManager.getMainSchema();
179
- BUILTIN_FUNCTIONS.forEach(funcDef => {
180
- try {
181
- mainSchema.addFunction(funcDef);
182
- } catch (e) {
183
- errorLog(`Failed to register built-in function ${funcDef.name}/${funcDef.numArgs}: %O`, e);
184
- }
185
- });
186
- log(`Registered ${BUILTIN_FUNCTIONS.length} built-in functions.`);
187
- }
188
-
189
- /** @internal Registers default collation sequences */
190
- private registerDefaultCollations(): void {
191
- // Register the built-in collations
192
- registerCollation('BINARY', BINARY_COLLATION);
193
- registerCollation('NOCASE', NOCASE_COLLATION);
194
- registerCollation('RTRIM', RTRIM_COLLATION);
195
- log("Default collations registered (BINARY, NOCASE, RTRIM)");
196
- }
197
-
198
- /**
199
- * Prepares an SQL statement for execution.
200
- *
201
- * @param sql The SQL string to prepare.
202
- * @param paramsOrTypes Optional parameter values (to infer types) or explicit type map.
203
- * - If SqlParameters: Parameter types are inferred from the values
204
- * - If Map<string|number, ScalarType>: Explicit type hints for parameters
205
- * - If undefined: Parameters default to TEXT type
206
- * @returns A Statement object.
207
- * @throws QuereusError on failure (e.g., syntax error).
208
- *
209
- * @example
210
- * // Infer types from initial values
211
- * const stmt = db.prepare('INSERT INTO users (id, name) VALUES (?, ?)', [1, 'Alice']);
212
- *
213
- * @example
214
- * // Explicit param types
215
- * const types = new Map([
216
- * [1, { typeClass: 'scalar', logicalType: INTEGER_TYPE, nullable: false }],
217
- * [2, { typeClass: 'scalar', logicalType: TEXT_TYPE, nullable: false }]
218
- * ]);
219
- * const stmt = db.prepare('INSERT INTO users (id, name) VALUES (?, ?)', types);
220
- */
221
- prepare(sql: string, paramsOrTypes?: SqlParameters | SqlValue[] | Map<string | number, ScalarType>): Statement {
222
- this.checkOpen();
223
- log('Preparing SQL (new runtime): %s', sql);
224
-
225
- // Statement constructor defers planning/compilation until first step or explicit compile()
226
- const stmt = new Statement(this, sql, 0, paramsOrTypes);
227
-
228
- this.statements.add(stmt);
229
- return stmt;
230
- }
231
-
232
- /**
233
- * Executes a query and returns the first result row as an object.
234
- * @param sql The SQL query string to execute.
235
- * @param params Optional parameters to bind.
236
- * @returns A Promise resolving to the first result row as an object, or undefined if no rows.
237
- * @throws QuereusError on failure.
238
- */
239
- get(sql: string, params?: SqlParameters | SqlValue[]): Promise<Record<string, SqlValue> | undefined> {
240
- const stmt = this.prepare(sql, params);
241
- return stmt.get(params);
242
- }
243
-
244
- /**
245
- * Executes one or more SQL statements directly.
246
- * @param sql The SQL string(s) to execute.
247
- * @param params Optional parameters to bind.
248
- * @returns A Promise resolving when execution completes.
249
- * @throws QuereusError on failure.
250
- */
251
- /**
252
- * @internal
253
- * Executes a single AST statement without transaction management.
254
- * Used by both exec() and eval() to avoid code duplication.
255
- */
256
- private async _executeStatement(statementAst: AST.Statement, params?: SqlParameters | SqlValue[]): Promise<void> {
257
- const plan = this._buildPlan([statementAst], params);
258
-
259
- if (plan.statements.length === 0) return; // No-op for this AST
260
-
261
- const optimizedPlan = this.optimizer.optimize(plan, this) as BlockNode;
262
- const emissionContext = new EmissionContext(this);
263
- const rootInstruction = emitPlanNode(optimizedPlan, emissionContext);
264
- const scheduler = new Scheduler(rootInstruction);
265
-
266
- const runtimeCtx: RuntimeContext = {
267
- db: this,
268
- stmt: undefined,
269
- params: params ?? {},
270
- context: new Map(),
271
- tableContexts: new Map(),
272
- tracer: this.instructionTracer,
273
- enableMetrics: this.options.getBooleanOption('runtime_stats'),
274
- };
275
-
276
- await scheduler.run(runtimeCtx);
277
- }
278
-
279
- async exec(
280
- sql: string,
281
- params?: SqlParameters,
282
- ): Promise<void> {
283
- this.checkOpen();
284
-
285
- log('Executing SQL block (new runtime): %s', sql);
286
-
287
- const parser = new Parser();
288
- let batch: AST.Statement[];
289
- try {
290
- batch = parser.parseAll(sql);
291
- } catch (e) {
292
- if (e instanceof ParseError) throw new QuereusError(`Parse error: ${e.message}`, StatusCode.ERROR, e);
293
- throw e;
294
- }
295
-
296
- if (batch.length === 0) return;
297
-
298
- const needsImplicitTransaction = batch.length >= 1
299
- && this.isAutocommit
300
- // has explicit transaction
301
- && !batch.some(
302
- ast => ast.type === 'begin' || ast.type === 'commit' || ast.type === 'rollback' || ast.type === 'savepoint' || ast.type === 'release'
303
- );
304
-
305
- let executionError: Error | null = null;
306
- try {
307
- if (needsImplicitTransaction) {
308
- await this.beginImplicitTransaction();
309
- }
310
-
311
- for (let i = 0; i < batch.length; i++) {
312
- try {
313
- await this._executeStatement(batch[i], params);
314
- } catch (err) {
315
- const error = err instanceof Error ? err : new Error(String(err));
316
- executionError = error instanceof QuereusError ? error : new QuereusError(error.message, StatusCode.ERROR, error);
317
- break; // Stop processing further statements on error
318
- }
319
- }
320
-
321
- } finally {
322
- if (needsImplicitTransaction) {
323
- if (executionError) {
324
- await this.rollbackImplicitTransaction();
325
- } else {
326
- await this.commitImplicitTransaction();
327
- }
328
- }
329
- }
330
-
331
- if (executionError) {
332
- throw executionError;
333
- }
334
- }
335
-
336
- /**
337
- * Registers a virtual table module.
338
- * @param name The name of the module.
339
- * @param module The module implementation.
340
- * @param auxData Optional client data passed to create/connect.
341
- */
342
- registerVtabModule(name: string, module: AnyVirtualTableModule, auxData?: unknown): void {
343
- this.checkOpen();
344
- this.schemaManager.registerModule(name, module, auxData);
345
- }
346
-
347
- /**
348
- * Begins a transaction.
349
- */
350
- async beginTransaction(): Promise<void> {
351
- this.checkOpen();
352
-
353
- if (this.inTransaction) {
354
- throw new QuereusError("Transaction already active", StatusCode.ERROR);
355
- }
356
-
357
- await this.exec("BEGIN TRANSACTION");
358
- this.inTransaction = true;
359
- this.isAutocommit = false;
360
- }
361
-
362
- /**
363
- * Commits the current transaction.
364
- */
365
- async commit(): Promise<void> {
366
- this.checkOpen();
367
-
368
- if (!this.inTransaction) {
369
- throw new QuereusError("No transaction active", StatusCode.ERROR);
370
- }
371
-
372
- await this.exec("COMMIT");
373
- this.inTransaction = false;
374
- this.isAutocommit = true;
375
- }
376
-
377
- /**
378
- * Rolls back the current transaction.
379
- */
380
- async rollback(): Promise<void> {
381
- this.checkOpen();
382
-
383
- if (!this.inTransaction) {
384
- throw new QuereusError("No transaction active", StatusCode.ERROR);
385
- }
386
-
387
- await this.exec("ROLLBACK");
388
- this.inTransaction = false;
389
- this.isAutocommit = true;
390
- }
391
-
392
- /**
393
- * Closes the database connection and releases resources.
394
- * @returns A promise resolving on completion.
395
- */
396
- async close(): Promise<void> {
397
- if (!this.isOpen) {
398
- return;
399
- }
400
-
401
- log("Closing database...");
402
- this.isOpen = false;
403
-
404
- // Disconnect all active connections first
405
- await this.disconnectAllConnections();
406
-
407
- // Finalize all prepared statements
408
- const finalizePromises = Array.from(this.statements).map(stmt => stmt.finalize());
409
- await Promise.allSettled(finalizePromises); // Wait even if some fail
410
- this.statements.clear();
411
-
412
- // Clear schemas, ensuring VTabs are potentially disconnected
413
- // This will also call destroy on VTabs via SchemaManager.clearAll -> schema.clearTables -> schemaManager.dropTable
414
- this.schemaManager.clearAll();
415
-
416
- // this.registeredVTabs.clear(); // Removed, SchemaManager handles module lifecycle
417
- log("Database closed.");
418
- }
419
-
420
- /** @internal Called by Statement when it's finalized */
421
- _statementFinalized(stmt: Statement): void {
422
- this.statements.delete(stmt);
423
- }
424
-
425
- /**
426
- * Checks if the database connection is in autocommit mode.
427
- */
428
- getAutocommit(): boolean {
429
- this.checkOpen();
430
- return this.isAutocommit;
431
- }
432
-
433
- /**
434
- * Programmatically defines or replaces a table in the 'main' schema.
435
- * This is an alternative/supplement to using `CREATE TABLE`.
436
- * @param definition The schema definition for the table.
437
- */
438
- defineTable(definition: TableSchema): void {
439
- this.checkOpen();
440
- if (definition.schemaName !== 'main') {
441
- throw new MisuseError("Programmatic definition only supported for 'main' schema currently");
442
- }
443
-
444
- this.schemaManager.getMainSchema().addTable(definition);
445
- }
446
-
447
- /**
448
- * Registers a user-defined scalar function.
449
- *
450
- * @param name The name of the SQL function.
451
- * @param options Configuration: { numArgs: number, deterministic?: boolean, flags?: number }.
452
- * @param func The JavaScript function implementation.
453
- */
454
- createScalarFunction(
455
- name: string,
456
- options: {
457
- numArgs: number;
458
- deterministic?: boolean;
459
- flags?: number;
460
- },
461
- func: (...args: SqlValue[]) => SqlValue
462
- ): void {
463
- this.checkOpen();
464
-
465
- const baseFlags = (options.deterministic ? FunctionFlags.DETERMINISTIC : 0) | FunctionFlags.UTF8;
466
- const flags = options.flags ?? baseFlags;
467
-
468
- const schema = createScalarFunction(
469
- { name, numArgs: options.numArgs, flags },
470
- func
471
- );
472
-
473
- try {
474
- this.schemaManager.getMainSchema().addFunction(schema);
475
- } catch (e) {
476
- errorLog(`Failed to register scalar function ${name}/${options.numArgs}: %O`, e);
477
- if (e instanceof Error) throw e; else quereusError(String(e));
478
- }
479
- }
480
-
481
- /**
482
- * Registers a user-defined aggregate function.
483
- *
484
- * @param name The name of the SQL function.
485
- * @param options Configuration: { numArgs: number, flags?: number, initialState?: unknown }.
486
- * @param stepFunc The function called for each row (accumulator, ...args) => newAccumulator.
487
- * @param finalFunc The function called at the end (accumulator) => finalResult.
488
- */
489
- createAggregateFunction(
490
- name: string,
491
- options: {
492
- numArgs: number;
493
- flags?: number;
494
- initialState?: unknown;
495
- },
496
- stepFunc: (acc: unknown, ...args: SqlValue[]) => unknown,
497
- finalFunc: (acc: unknown) => SqlValue
498
- ): void {
499
- this.checkOpen();
500
-
501
- const flags = options.flags ?? FunctionFlags.UTF8;
502
-
503
- const schema = createAggregateFunction(
504
- { name, numArgs: options.numArgs, flags, initialValue: options.initialState },
505
- stepFunc,
506
- finalFunc
507
- );
508
-
509
- try {
510
- this.schemaManager.getMainSchema().addFunction(schema);
511
- } catch (e) {
512
- errorLog(`Failed to register aggregate function ${name}/${options.numArgs}: %O`, e);
513
- if (e instanceof Error) throw e; else quereusError(String(e));
514
- }
515
- }
516
-
517
- /**
518
- * Registers a function using a pre-defined FunctionSchema.
519
- * This is the lower-level registration method.
520
- *
521
- * @param schema The FunctionSchema object describing the function.
522
- */
523
- registerFunction(schema: FunctionSchema): void {
524
- this.checkOpen();
525
- try {
526
- this.schemaManager.getMainSchema().addFunction(schema);
527
- } catch (e) {
528
- errorLog(`Failed to register function ${schema.name}/${schema.numArgs}: %O`, e);
529
- if (e instanceof Error) throw e; else quereusError(String(e));
530
- }
531
- }
532
-
533
- /** Sets only the name of the default module. */
534
- setDefaultVtabName(name: string): void {
535
- this.checkOpen();
536
- this.schemaManager.setDefaultVTabModuleName(name);
537
- }
538
-
539
- /** Sets the default args directly. */
540
- setDefaultVtabArgs(args: Record<string, SqlValue>): void {
541
- this.checkOpen();
542
- this.schemaManager.setDefaultVTabArgs(args);
543
- }
544
-
545
- /** @internal Sets the default args by parsing a JSON string. Should be managed by SchemaManager now. */
546
- setDefaultVtabArgsFromJson(argsJsonString: string): void {
547
- this.checkOpen();
548
- this.schemaManager.setDefaultVTabArgsFromJson(argsJsonString);
549
- }
550
-
551
- /**
552
- * Gets the default virtual table module name and arguments.
553
- * @returns An object containing the module name and arguments.
554
- */
555
- getDefaultVtabModule(): { name: string; args: Record<string, SqlValue> } {
556
- this.checkOpen();
557
- return this.schemaManager.getDefaultVTabModule();
558
- }
559
-
560
- /**
561
- * Set database configuration options
562
- * @param option The option name
563
- * @param value The option value
564
- */
565
- setOption(option: string, value: unknown): void {
566
- this.checkOpen();
567
- this.options.setOption(option, value);
568
- }
569
-
570
- /**
571
- * Get database configuration option value
572
- * @param option The option name
573
- * @returns The option value
574
- */
575
- getOption(option: string): unknown {
576
- this.checkOpen();
577
- return this.options.getOption(option);
578
- }
579
-
580
- /** Update optimizer tuning in place */
581
- private updateOptimizerTuning(tuning: OptimizerTuning): void {
582
- this.optimizer.updateTuning(tuning);
583
- }
584
-
585
- /**
586
- * Registers a user-defined collation sequence.
587
- * @param name The name of the collation sequence (case-insensitive).
588
- * @param func The comparison function (a, b) => number (-1, 0, 1).
589
- * @example
590
- * // Example: Create a custom collation for phone numbers
591
- * db.registerCollation('PHONENUMBER', (a, b) => {
592
- * // Normalize phone numbers by removing non-digit characters
593
- * const normalize = (phone) => phone.replace(/\D/g, '');
594
- * const numA = normalize(a);
595
- * const numB = normalize(b);
596
- * return numA < numB ? -1 : numA > numB ? 1 : 0;
597
- * });
598
- *
599
- * // Then use it in SQL:
600
- * // SELECT * FROM contacts ORDER BY phone COLLATE PHONENUMBER;
601
- */
602
- registerCollation(name: string, func: CollationFunction): void {
603
- this.checkOpen();
604
- registerCollation(name, func);
605
- log('Registered collation: %s', name);
606
- }
607
-
608
- /**
609
- * Registers a custom logical type.
610
- * @param name The name of the type (case-insensitive).
611
- * @param definition The LogicalType implementation.
612
- * @example
613
- * // Example: Create a custom UUID type
614
- * db.registerType('UUID', {
615
- * name: 'UUID',
616
- * physicalType: PhysicalType.TEXT,
617
- * validate: (v) => typeof v === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v),
618
- * parse: (v) => typeof v === 'string' ? v.toLowerCase() : v,
619
- * });
620
- *
621
- * // Then use it in SQL:
622
- * // CREATE TABLE users (id UUID PRIMARY KEY, name TEXT);
623
- */
624
- registerType(name: string, definition: LogicalType): void {
625
- this.checkOpen();
626
- const { registerType } = require('../types/registry.js');
627
- registerType(name, definition);
628
- log('Registered type: %s', name);
629
- }
630
-
631
- /**
632
- * Sets the instruction tracer for this database.
633
- * The tracer will be used for all statement executions.
634
- * @param tracer The instruction tracer to use, or null to disable tracing.
635
- */
636
- setInstructionTracer(tracer: InstructionTracer | undefined): void {
637
- this.instructionTracer = tracer;
638
- log('Instruction tracer %s', tracer ? 'enabled' : 'disabled');
639
- }
640
-
641
- /**
642
- * Gets the current instruction tracer for this database.
643
- * @returns The instruction tracer, or undefined if none is set.
644
- */
645
- getInstructionTracer(): InstructionTracer | undefined {
646
- return this.instructionTracer;
647
- }
648
-
649
- /** @internal Gets a registered collation function */
650
- _getCollation(name: string): CollationFunction | undefined {
651
- return getCollation(name);
652
- }
653
-
654
- /** Serialize a composite primary key tuple for set storage */
655
- private serializeKeyTuple(values: SqlValue[]): string {
656
- // JSON serialization is sufficient because SqlValue is JSON-safe in this engine
657
- return JSON.stringify(values);
658
- }
659
-
660
- /** Add a key tuple to the current change log for a base table */
661
- private addChange(baseTable: string, keyTuple: SqlValue[]): void {
662
- const target = this.changeLogLayers.length > 0
663
- ? this.changeLogLayers[this.changeLogLayers.length - 1]
664
- : this.changeLog;
665
- const key = baseTable.toLowerCase();
666
- if (!target.has(key)) target.set(key, new Set());
667
- target.get(key)!.add(this.serializeKeyTuple(keyTuple));
668
- }
669
-
670
- public _queueDeferredConstraintRow(baseTable: string, constraintName: string, row: Row, descriptor: RowDescriptor, evaluator: (ctx: RuntimeContext) => OutputValue, connectionId?: string, contextRow?: Row, contextDescriptor?: RowDescriptor): void {
671
- this.deferredConstraints.enqueue(baseTable, constraintName, row, descriptor, evaluator, connectionId, contextRow, contextDescriptor);
672
- }
673
-
674
-
675
- /** @internal Flag to prevent new connections from starting transactions during constraint evaluation */
676
- private evaluatingDeferredConstraints = false;
677
- /** @internal Flag indicating we're in a coordinated multi-connection commit */
678
- private inCoordinatedCommit = false;
679
-
680
- public async runDeferredRowConstraints(): Promise<void> {
681
- this.evaluatingDeferredConstraints = true;
682
- try {
683
- await this.deferredConstraints.runDeferredRows();
684
- } finally {
685
- this.evaluatingDeferredConstraints = false;
686
- }
687
- }
688
-
689
- /** @internal Check if we should skip auto-beginning transactions on newly registered connections */
690
- public _isEvaluatingDeferredConstraints(): boolean {
691
- return this.evaluatingDeferredConstraints;
692
- }
693
-
694
- /** @internal Mark start of coordinated multi-connection commit */
695
- public _beginCoordinatedCommit(): void {
696
- this.inCoordinatedCommit = true;
697
- }
698
-
699
- /** @internal Mark end of coordinated multi-connection commit */
700
- public _endCoordinatedCommit(): void {
701
- this.inCoordinatedCommit = false;
702
- }
703
-
704
- /** @internal Check if we're in a coordinated commit (allows sibling layer validation) */
705
- public _inCoordinatedCommit(): boolean {
706
- return this.inCoordinatedCommit;
707
- }
708
-
709
- /** Public API used by DML emitters to record changes */
710
- public _recordInsert(baseTable: string, newKey: SqlValue[]): void {
711
- this.addChange(baseTable, newKey);
712
- }
713
-
714
- public _recordDelete(baseTable: string, oldKey: SqlValue[]): void {
715
- this.addChange(baseTable, oldKey);
716
- }
717
-
718
- public _recordUpdate(baseTable: string, oldKey: SqlValue[], newKey: SqlValue[]): void {
719
- this.addChange(baseTable, oldKey);
720
- // If the PK changed, also record the new key
721
- if (this.serializeKeyTuple(oldKey) !== this.serializeKeyTuple(newKey)) {
722
- this.addChange(baseTable, newKey);
723
- }
724
- }
725
-
726
- /** Savepoint change tracking */
727
- public _beginSavepointLayer(): void {
728
- this.changeLogLayers.push(new Map());
729
- this.deferredConstraints.beginLayer();
730
- }
731
-
732
- public _rollbackSavepointLayer(): void {
733
- // Discard the top layer
734
- this.changeLogLayers.pop();
735
- this.deferredConstraints.rollbackLayer();
736
- }
737
-
738
- public _releaseSavepointLayer(): void {
739
- // Merge the top layer into previous or main log
740
- const top = this.changeLogLayers.pop();
741
- if (!top) return;
742
- const target = this.changeLogLayers.length > 0 ? this.changeLogLayers[this.changeLogLayers.length - 1] : this.changeLog;
743
- for (const [table, set] of top) {
744
- if (!target.has(table)) target.set(table, new Set());
745
- const tgt = target.get(table)!;
746
- for (const k of set) tgt.add(k);
747
- }
748
- this.deferredConstraints.releaseLayer();
749
- }
750
-
751
- private getChangedBaseTables(): Set<string> {
752
- const result = new Set<string>();
753
- const collect = (m: Map<string, Set<string>>) => {
754
- for (const [t, s] of m) { if (s.size > 0) result.add(t); }
755
- };
756
- collect(this.changeLog);
757
- for (const layer of this.changeLogLayers) collect(layer);
758
- return result;
759
- }
760
-
761
- public _clearChangeLog(): void {
762
- this.changeLog.clear();
763
- this.changeLogLayers = [];
764
- this.deferredConstraints.clear();
765
- }
766
-
767
- /**
768
- * Marks that an explicit SQL BEGIN has started a transaction.
769
- * Ensures subsequently registered connections also begin a transaction.
770
- */
771
- public markExplicitTransactionStart(): void {
772
- this.inTransaction = true;
773
- this.isAutocommit = false;
774
- }
775
-
776
- /**
777
- * Marks that an explicit SQL COMMIT/ROLLBACK has ended the transaction.
778
- */
779
- public markExplicitTransactionEnd(): void {
780
- this.inTransaction = false;
781
- this.isAutocommit = true;
782
- }
783
-
784
- /**
785
- * Prepares, binds parameters, executes, and yields result rows for a query.
786
- * This is a high-level convenience method for iterating over query results.
787
- * The underlying statement is automatically finalized when iteration completes
788
- * or if an error occurs.
789
- *
790
- * @param sql The SQL query string to execute.
791
- * @param params Optional parameters to bind (array for positional, object for named).
792
- * @yields Each result row as an object (`Record<string, SqlValue>`).
793
- * @returns An `AsyncIterableIterator` yielding result rows.
794
- * @throws MisuseError if the database is closed.
795
- * @throws QuereusError on prepare/bind/execution errors.
796
- *
797
- * @example
798
- * ```typescript
799
- * try {
800
- * for await (const user of db.eval("SELECT * FROM users WHERE status = ?", ["active"])) {
801
- * console.log(`Active user: ${user.name}`);
802
- * }
803
- * } catch (e) {
804
- * console.error("Query failed:", e);
805
- * }
806
- * ```
807
- */
808
- async *eval(sql: string, params?: SqlParameters | SqlValue[]): AsyncIterable<Record<string, SqlValue>> {
809
- this.checkOpen();
810
-
811
- let stmt: Statement | null = null;
812
- try {
813
- stmt = this.prepare(sql);
814
-
815
- if (stmt.astBatch.length === 0) {
816
- // No statements, yield nothing.
817
- return;
818
- }
819
-
820
- if (stmt.astBatch.length > 1) {
821
- // Multi-statement batch: execute all but the last statement,
822
- // then yield results from the last statement
823
- const parser = new Parser();
824
- const batch = parser.parseAll(sql);
825
-
826
- // Execute all statements except the last one
827
- for (let i = 0; i < batch.length - 1; i++) {
828
- await this._executeStatement(batch[i], params);
829
- }
830
-
831
- // Now prepare and execute the last statement to yield its results
832
- const lastStmt = new Statement(this, [batch[batch.length - 1]]);
833
- this.statements.add(lastStmt);
834
- try {
835
- yield* lastStmt.all(params);
836
- } finally {
837
- await lastStmt.finalize();
838
- }
839
- } else {
840
- // Single statement: execute and yield results
841
- yield* stmt.all(params);
842
- }
843
- } finally {
844
- if (stmt) { await stmt.finalize(); }
845
- }
846
- }
847
-
848
- getPlan(sqlOrAst: string | AST.AstNode): PlanNode {
849
- this.checkOpen();
850
-
851
- let ast: AST.AstNode;
852
- let originalSqlString: string | undefined = undefined;
853
-
854
- if (typeof sqlOrAst === 'string') {
855
- originalSqlString = sqlOrAst;
856
- const parser = new Parser();
857
- try {
858
- ast = parser.parse(originalSqlString);
859
- } catch (err) {
860
- const error = err instanceof Error ? err : new Error(String(err));
861
- errorLog("Failed to parse SQL for query plan: %O", error);
862
- throw error;
863
- }
864
- } else {
865
- ast = sqlOrAst;
866
- }
867
-
868
- const plan = this._buildPlan([ast as AST.Statement]);
869
-
870
- if (plan.statements.length === 0) return plan; // No-op for this AST
871
-
872
- return this.optimizer.optimize(plan, this) as BlockNode;
873
- }
874
-
875
- /**
876
- * Gets a detailed representation of the query plan for debugging.
877
- * @param sql The SQL statement to plan.
878
- * @param options Optional formatting options. If not provided, uses concise tree format.
879
- * @returns String containing the formatted plan tree.
880
- */
881
- getDebugPlan(sql: string, options?: { verbose?: boolean; expandNodes?: string[]; maxDepth?: number }): string {
882
- this.checkOpen();
883
- const plan = this.getPlan(sql);
884
-
885
- if (options?.verbose) {
886
- // Use the original detailed JSON format
887
- return serializePlanTree(plan);
888
- } else {
889
- // Use the new concise tree format
890
- return formatPlanTree(plan, {
891
- concise: true,
892
- expandNodes: options?.expandNodes || [],
893
- maxDepth: options?.maxDepth,
894
- showPhysical: true
895
- });
896
- }
897
- }
898
-
899
- /**
900
- * Prepares a statement with debug options enabled.
901
- * @param sql The SQL statement to prepare.
902
- * @param debug Debug options to enable.
903
- * @returns A Statement with debug capabilities.
904
- */
905
- prepareDebug(sql: string, debug: DebugOptions): Statement {
906
- this.checkOpen();
907
- log('Preparing SQL with debug options: %s', sql);
908
-
909
- const stmt = new Statement(this, sql);
910
- // Set debug options on the statement
911
- (stmt as Statement & { _debugOptions?: DebugOptions })._debugOptions = debug;
912
-
913
- this.statements.add(stmt);
914
- return stmt;
915
- }
916
-
917
- /** @internal */
918
- _getVtabModule(name: string): { module: AnyVirtualTableModule, auxData?: unknown } | undefined {
919
- // Delegate to SchemaManager
920
- return this.schemaManager.getModule(name);
921
- // return this.registeredVTabs.get(name.toLowerCase()); // Old implementation
922
- }
923
-
924
- /** @internal */
925
- _findTable(tableName: string, dbName?: string): TableSchema | undefined {
926
- return this.schemaManager.findTable(tableName, dbName);
927
- }
928
-
929
- /** @internal */
930
- _findFunction(funcName: string, nArg: number): FunctionSchema | undefined {
931
- return this.schemaManager.findFunction(funcName, nArg);
932
- }
933
-
934
- /** @internal */
935
- _buildPlan(statements: AST.Statement[], paramsOrTypes?: SqlParameters | SqlValue[] | Map<string | number, ScalarType>) {
936
- const globalScope = new GlobalScope(this.schemaManager);
937
-
938
- // If we received parameter values, infer their types
939
- // If we received explicit parameter types, use them as-is
940
- const parameterTypes = paramsOrTypes instanceof Map
941
- ? paramsOrTypes
942
- : getParameterTypes(paramsOrTypes);
943
-
944
- // This ParameterScope is for the entire batch. It has globalScope as its parent.
945
- const parameterScope = new ParameterScope(globalScope, parameterTypes);
946
-
947
- const ctx: PlanningContext = {
948
- db: this,
949
- schemaManager: this.schemaManager,
950
- parameters: paramsOrTypes instanceof Map ? {} : (paramsOrTypes ?? {}),
951
- scope: parameterScope,
952
- cteNodes: new Map(),
953
- schemaDependencies: new BuildTimeDependencyTracker(),
954
- schemaCache: new Map(),
955
- cteReferenceCache: new Map(),
956
- outputScopes: new Map()
957
- };
958
-
959
- return buildBlock(ctx, statements);
960
- }
961
-
962
- /**
963
- * @internal Registers an active VirtualTable connection for transaction management.
964
- * @param connection The connection to register
965
- */
966
- async registerConnection(connection: VirtualTableConnection): Promise<void> {
967
- this.activeConnections.set(connection.connectionId, connection);
968
- debugLog(`Registered connection ${connection.connectionId} for table ${connection.tableName}`);
969
-
970
- // If we're already in a transaction (implicit or explicit),
971
- // start a transaction on this new connection UNLESS we're evaluating deferred constraints
972
- // (during which subqueries should read committed state without creating new transaction layers)
973
- if (this.inTransaction && !this.evaluatingDeferredConstraints) {
974
- try {
975
- await connection.begin();
976
- debugLog(`Started transaction on newly registered connection ${connection.connectionId}`);
977
- } catch (error) {
978
- errorLog(`Error starting transaction on newly registered connection ${connection.connectionId}: %O`, error);
979
- // Don't throw here - just log the error to avoid breaking connection registration
980
- }
981
- } else if (this.evaluatingDeferredConstraints) {
982
- debugLog(`Skipped transaction begin on connection ${connection.connectionId} (evaluating deferred constraints)`);
983
- }
984
- }
985
-
986
- /**
987
- * @internal Unregisters an active VirtualTable connection.
988
- * @param connectionId The ID of the connection to unregister
989
- */
990
- unregisterConnection(connectionId: string): void {
991
- const connection = this.activeConnections.get(connectionId);
992
- if (connection) {
993
- // Don't disconnect during implicit transactions - let the transaction coordinate
994
- if (this.inImplicitTransaction) {
995
- debugLog(`Deferring disconnect of connection ${connectionId} until implicit transaction completes`);
996
- return;
997
- }
998
-
999
- this.activeConnections.delete(connectionId);
1000
- debugLog(`Unregistered connection ${connectionId} for table ${connection.tableName}`);
1001
- }
1002
- }
1003
-
1004
- /**
1005
- * @internal Gets an active connection by ID.
1006
- * @param connectionId The connection ID to look up
1007
- * @returns The connection if found, undefined otherwise
1008
- */
1009
- getConnection(connectionId: string): VirtualTableConnection | undefined {
1010
- return this.activeConnections.get(connectionId);
1011
- }
1012
-
1013
- /**
1014
- * @internal Gets all active connections for a specific table.
1015
- * @param tableName The name of the table
1016
- * @returns Array of connections for the table
1017
- */
1018
- getConnectionsForTable(tableName: string): VirtualTableConnection[] {
1019
- const normalized = tableName.toLowerCase();
1020
- const simpleName = normalized.includes('.') ? normalized.substring(normalized.lastIndexOf('.') + 1) : normalized;
1021
- return Array.from(this.activeConnections.values())
1022
- .filter(conn => {
1023
- const connName = conn.tableName.toLowerCase();
1024
- return connName === normalized || connName === simpleName;
1025
- });
1026
- }
1027
-
1028
- /**
1029
- * @internal Gets all active connections.
1030
- * @returns Array of all active connections
1031
- */
1032
- getAllConnections(): VirtualTableConnection[] {
1033
- return Array.from(this.activeConnections.values());
1034
- }
1035
-
1036
- /**
1037
- * Disconnects and removes all active connections.
1038
- * Called during database close.
1039
- */
1040
- private async disconnectAllConnections(): Promise<void> {
1041
- const connections = Array.from(this.activeConnections.values());
1042
- debugLog(`Disconnecting ${connections.length} active connections`);
1043
-
1044
- const disconnectPromises = connections.map(async (conn) => {
1045
- try {
1046
- await conn.disconnect();
1047
- } catch (error) {
1048
- errorLog(`Error disconnecting connection ${conn.connectionId}: %O`, error);
1049
- }
1050
- });
1051
-
1052
- await Promise.allSettled(disconnectPromises);
1053
- this.activeConnections.clear();
1054
- }
1055
-
1056
- private checkOpen(): void {
1057
- if (!this.isOpen) throw new MisuseError("Database is closed");
1058
- }
1059
-
1060
- /**
1061
- * Begin an implicit transaction and coordinate with virtual table connections
1062
- */
1063
- private async beginImplicitTransaction(): Promise<void> {
1064
- debugLog("Database: Starting implicit transaction for multi-statement block.");
1065
-
1066
- this.inImplicitTransaction = true;
1067
-
1068
- // Begin transaction on all active connections first
1069
- const connections = this.getAllConnections();
1070
- for (const connection of connections) {
1071
- try {
1072
- await connection.begin();
1073
- } catch (error) {
1074
- errorLog(`Error beginning transaction on connection ${connection.connectionId}: %O`, error);
1075
- throw error;
1076
- }
1077
- }
1078
-
1079
- // Then set database state
1080
- this.inTransaction = true;
1081
- this.isAutocommit = false;
1082
- }
1083
-
1084
- /**
1085
- * Commit an implicit transaction and coordinate with virtual table connections
1086
- */
1087
- private async commitImplicitTransaction(): Promise<void> {
1088
- debugLog("Database: Committing implicit transaction.");
1089
-
1090
- try {
1091
- const connectionsToCommit = this.getAllConnections();
1092
-
1093
- // Evaluate global assertions and deferred row constraints BEFORE committing connections. If violated, rollback and abort.
1094
- await this.runGlobalAssertions();
1095
- await this.runDeferredRowConstraints();
1096
-
1097
- // Mark coordinated commit to relax layer validation for sibling layers
1098
- this._beginCoordinatedCommit();
1099
- try {
1100
- // Commit only the original connections (not any opened during constraint evaluation)
1101
- // Commit sequentially to avoid race conditions with layer promotion
1102
- for (const connection of connectionsToCommit) {
1103
- try {
1104
- await connection.commit();
1105
- } catch (error) {
1106
- errorLog(`Error committing transaction on connection ${connection.connectionId}: %O`, error);
1107
- throw error;
1108
- }
1109
- }
1110
- } finally {
1111
- this._endCoordinatedCommit();
1112
- }
1113
- } catch (e) {
1114
- // On pre-commit assertion failure (or commit error), rollback all connections
1115
- const conns = this.getAllConnections();
1116
- await Promise.allSettled(conns.map(c => c.rollback()));
1117
- throw e;
1118
- } finally {
1119
- this.inTransaction = false;
1120
- this.isAutocommit = true;
1121
- this.inImplicitTransaction = false;
1122
- this._clearChangeLog();
1123
- }
1124
- }
1125
-
1126
- public async runGlobalAssertions(): Promise<void> {
1127
- const assertions = this.schemaManager.getAllAssertions();
1128
- if (assertions.length === 0) return;
1129
-
1130
- // Only evaluate assertions impacted by changed base tables
1131
- const changedBases = this.getChangedBaseTables();
1132
- if (changedBases.size === 0) return;
1133
-
1134
- for (const assertion of assertions) {
1135
- const planSql = assertion.violationSql;
1136
- const parser = new Parser();
1137
- let ast: AST.Statement;
1138
- try {
1139
- ast = parser.parse(planSql) as AST.Statement;
1140
- } catch (err) {
1141
- const error = err instanceof Error ? err : new Error(String(err));
1142
- throw new QuereusError(
1143
- `Failed to parse deferred assertion '${assertion.name}': ${error.message}`,
1144
- StatusCode.INTERNAL,
1145
- error
1146
- );
1147
- }
1148
- const plan = this._buildPlan([ast]) as BlockNode;
1149
- const analyzed = this.optimizer.optimizeForAnalysis(plan, this) as BlockNode;
1150
-
1151
- // Collect base tables and relationKeys in this plan
1152
- const relationKeyToBase = new Map<string, string>();
1153
- const baseTablesInPlan = new Set<string>();
1154
- this.collectTables(analyzed, relationKeyToBase, baseTablesInPlan);
1155
-
1156
- // Determine impact: if assertion has no dependencies, treat as global and always impacted.
1157
- const hasDeps = baseTablesInPlan.size > 0;
1158
- let impacted = !hasDeps;
1159
- if (hasDeps) {
1160
- for (const b of baseTablesInPlan) { if (changedBases.has(b)) { impacted = true; break; } }
1161
- }
1162
- if (!impacted) continue;
1163
-
1164
- // Classify instances as row/global
1165
- const classifications: Map<string, 'row' | 'global'> = analyzeRowSpecific(analyzed as unknown as RelationalPlanNode);
1166
-
1167
- // If any changed base appears as a global instance, run full violation query once
1168
- let requiresGlobal = false;
1169
- for (const [relKey, klass] of classifications) {
1170
- if (klass === 'global') {
1171
- const base = relationKeyToBase.get(relKey);
1172
- if (base && changedBases.has(base)) { requiresGlobal = true; break; }
1173
- }
1174
- }
1175
-
1176
- if (requiresGlobal) {
1177
- await this.executeViolationOnce(assertion.name, assertion.violationSql);
1178
- continue;
1179
- }
1180
-
1181
- // Collect row-specific references that correspond to changed bases
1182
- const rowSpecificChanged: Array<{ relKey: string; base: string }> = [];
1183
- for (const [relKey, klass] of classifications) {
1184
- if (klass !== 'row') continue;
1185
- const base = relationKeyToBase.get(relKey);
1186
- if (base && changedBases.has(base)) rowSpecificChanged.push({ relKey, base });
1187
- }
1188
-
1189
- if (rowSpecificChanged.length === 0) {
1190
- // No row-specific changed refs (or no refs at all) → run once globally.
1191
- await this.executeViolationOnce(assertion.name, assertion.violationSql);
1192
- continue;
1193
- }
1194
-
1195
- // Execute parameterized variants per changed key for each row-specific reference; early-exit on violation
1196
- for (const { relKey, base } of rowSpecificChanged) {
1197
- await this.executeViolationPerChangedKeys(assertion.name, assertion.violationSql, analyzed, relKey, base);
1198
- }
1199
- }
1200
- }
1201
-
1202
- private async executeViolationOnce(assertionName: string, sql: string): Promise<void> {
1203
- const stmt = await this.prepare(sql);
1204
- try {
1205
- for await (const _ of stmt.all()) {
1206
- throw new QuereusError(`Integrity assertion failed: ${assertionName}`, StatusCode.CONSTRAINT);
1207
- }
1208
- } finally {
1209
- await stmt.finalize();
1210
- }
1211
- }
1212
-
1213
- private async executeViolationOnceFromPlan(assertionName: string, plan: BlockNode): Promise<void> {
1214
- const optimizedPlan = this.optimizer.optimize(plan, this) as BlockNode;
1215
- const emissionContext = new EmissionContext(this);
1216
- const rootInstruction = emitPlanNode(optimizedPlan, emissionContext);
1217
- const scheduler = new Scheduler(rootInstruction);
1218
-
1219
- const runtimeCtx: RuntimeContext = {
1220
- db: this,
1221
- stmt: undefined,
1222
- params: {},
1223
- context: new Map(),
1224
- tableContexts: new Map(),
1225
- tracer: this.instructionTracer,
1226
- enableMetrics: this.options.getBooleanOption('runtime_stats'),
1227
- };
1228
-
1229
- const result = await scheduler.run(runtimeCtx);
1230
- if (isAsyncIterable(result)) {
1231
- for await (const _ of result as AsyncIterable<unknown>) {
1232
- throw new QuereusError(`CHECK constraint failed: ${assertionName}`, StatusCode.CONSTRAINT);
1233
- }
1234
- }
1235
- }
1236
-
1237
- private async executeViolationPerChangedKeysFromPlan(
1238
- assertionName: string,
1239
- analyzed: BlockNode,
1240
- targetRelationKey: string,
1241
- base: string
1242
- ): Promise<void> {
1243
- const changedKeyTuples = this.getChangedKeyTuples(base);
1244
- if (changedKeyTuples.length === 0) return;
1245
-
1246
- // Find PK indices for the base table
1247
- const [schemaName, tableName] = base.split('.');
1248
- const table = this._findTable(tableName, schemaName);
1249
- if (!table) {
1250
- throw new QuereusError(`Constraint references unknown table ${base}`, StatusCode.INTERNAL);
1251
- }
1252
- const pkIndices = table.primaryKeyDefinition.map(def => def.index);
1253
-
1254
- // Prepare a rewritten plan with an injected Filter on the target relationKey
1255
- const rewritten = this.injectPkFilter(analyzed, targetRelationKey, base, pkIndices);
1256
- const optimizedPlan = this.optimizer.optimize(rewritten, this) as BlockNode;
1257
-
1258
- // Emit and execute for each changed PK tuple; stop on first violation row.
1259
- const emissionContext = new EmissionContext(this);
1260
- const rootInstruction = emitPlanNode(optimizedPlan, emissionContext);
1261
- const scheduler = new Scheduler(rootInstruction);
1262
-
1263
- for (const tuple of changedKeyTuples) {
1264
- const params: Record<string, SqlValue> = {};
1265
- for (let i = 0; i < pkIndices.length; i++) {
1266
- params[`pk${i}`] = tuple[i];
1267
- }
1268
-
1269
- const runtimeCtx: RuntimeContext = {
1270
- db: this,
1271
- stmt: undefined,
1272
- params,
1273
- context: new Map(),
1274
- tableContexts: new Map(),
1275
- tracer: this.instructionTracer,
1276
- enableMetrics: this.options.getBooleanOption('runtime_stats'),
1277
- };
1278
-
1279
- // Run and detect first output row (violation)
1280
- const result = await scheduler.run(runtimeCtx);
1281
- if (isAsyncIterable(result)) {
1282
- for await (const _ of result as AsyncIterable<unknown>) {
1283
- throw new QuereusError(`CHECK constraint failed: ${assertionName}`, StatusCode.CONSTRAINT);
1284
- }
1285
- }
1286
- }
1287
- }
1288
-
1289
- /** Execute a parameterized variant of the assertion once per changed key for a specific row-specific relationKey. */
1290
- private async executeViolationPerChangedKeys(
1291
- assertionName: string,
1292
- violationSql: string,
1293
- analyzed: BlockNode,
1294
- targetRelationKey: string,
1295
- base: string
1296
- ): Promise<void> {
1297
- const changedKeyTuples = this.getChangedKeyTuples(base);
1298
- if (changedKeyTuples.length === 0) return;
1299
-
1300
- // Find PK indices for the base table
1301
- const [schemaName, tableName] = base.split('.');
1302
- const table = this._findTable(tableName, schemaName);
1303
- if (!table) {
1304
- throw new QuereusError(`Assertion references unknown table ${base}`, StatusCode.INTERNAL);
1305
- }
1306
- const pkIndices = table.primaryKeyDefinition.map(def => def.index);
1307
-
1308
- // Prepare a rewritten plan with an injected Filter on the target relationKey
1309
- const rewritten = this.injectPkFilter(analyzed, targetRelationKey, base, pkIndices);
1310
- const optimizedPlan = this.optimizer.optimize(rewritten, this) as BlockNode;
1311
-
1312
- // Emit and execute for each changed PK tuple; stop on first violation row.
1313
- const emissionContext = new EmissionContext(this);
1314
- const rootInstruction = emitPlanNode(optimizedPlan, emissionContext);
1315
- const scheduler = new Scheduler(rootInstruction);
1316
-
1317
- for (const tuple of changedKeyTuples) {
1318
- const params: Record<string, SqlValue> = {};
1319
- for (let i = 0; i < pkIndices.length; i++) {
1320
- params[`pk${i}`] = tuple[i];
1321
- }
1322
-
1323
- const runtimeCtx: RuntimeContext = {
1324
- db: this,
1325
- stmt: undefined,
1326
- params,
1327
- context: new Map(),
1328
- tableContexts: new Map(),
1329
- tracer: this.instructionTracer,
1330
- enableMetrics: this.options.getBooleanOption('runtime_stats'),
1331
- };
1332
-
1333
- // Run and detect first output row (violation)
1334
- const result = await scheduler.run(runtimeCtx);
1335
- if (isAsyncIterable(result)) {
1336
- for await (const _ of result as AsyncIterable<unknown>) {
1337
- throw new QuereusError(`Integrity assertion failed: ${assertionName}`, StatusCode.CONSTRAINT);
1338
- }
1339
- }
1340
- }
1341
- }
1342
-
1343
- /** Gather all changed PK tuples for a base table across layers */
1344
- private getChangedKeyTuples(base: string): SqlValue[][] {
1345
- const lower = base.toLowerCase();
1346
- const tuples: SqlValue[][] = [];
1347
- const collect = (m: Map<string, Set<string>>): void => {
1348
- const set = m.get(lower);
1349
- if (!set) return;
1350
- for (const s of set) tuples.push(JSON.parse(s) as SqlValue[]);
1351
- };
1352
- collect(this.changeLog);
1353
- for (const layer of this.changeLogLayers) collect(layer);
1354
- return tuples;
1355
- }
1356
-
1357
- /** Inject an equality Filter with named parameters :pk0, :pk1, ... at the earliest reference of targetRelationKey. */
1358
- private injectPkFilter(block: BlockNode, targetRelationKey: string, base: string, pkIndices: number[]): BlockNode {
1359
- const newStatements = block.getChildren().map(stmt => this.rewriteForPkFilter(stmt, targetRelationKey, base, pkIndices));
1360
- if (newStatements.every((s, i) => s === block.getChildren()[i])) return block;
1361
- return this.createBlockWithNewStatements(block, newStatements);
1362
- }
1363
-
1364
- private rewriteForPkFilter(node: PlanNode, targetRelationKey: string, base: string, pkIndices: number[]): PlanNode {
1365
- // If this node is the target TableReference instance, wrap with a Filter
1366
- const maybe = this.tryWrapTableReference(node, targetRelationKey, base, pkIndices);
1367
- if (maybe) return maybe;
1368
-
1369
- const originalChildren = node.getChildren();
1370
- if (!originalChildren || originalChildren.length === 0) return node;
1371
- const rewrittenChildren = originalChildren.map(child => this.rewriteForPkFilter(child, targetRelationKey, base, pkIndices));
1372
- const changed = rewrittenChildren.some((c, i) => c !== originalChildren[i]);
1373
- return changed ? node.withChildren(rewrittenChildren) : node;
1374
- }
1375
-
1376
- private tryWrapTableReference(node: PlanNode, targetRelationKey: string, base: string, pkIndices: number[]): PlanNode | null {
1377
- if (!(node instanceof TableReferenceNode)) return null;
1378
- const tableSchema = node.tableSchema;
1379
- const schemaName = tableSchema.schemaName;
1380
- const tableName = tableSchema.name;
1381
- const relName = `${schemaName}.${tableName}`.toLowerCase();
1382
- const relKey = `${relName}#${node.id ?? 'unknown'}`;
1383
- if (relKey !== targetRelationKey) return null;
1384
-
1385
- // Build predicate: AND(col_pk_i = :pk{i}) for all PK columns
1386
- const relational = node as RelationalPlanNode;
1387
- const scope = relational.scope;
1388
- const attributes = relational.getAttributes();
1389
-
1390
- const makeColumnRef = (colIndex: number): ScalarPlanNode => {
1391
- const attr = attributes[colIndex];
1392
- const expr: AST.ColumnExpr = { type: 'column', name: attr.name, table: tableName, schema: schemaName };
1393
- return new ColumnReferenceNode(scope, expr, attr.type, attr.id, colIndex);
1394
- };
1395
-
1396
- const makeParamRef = (i: number, type: ScalarType): ScalarPlanNode => {
1397
- const pexpr: AST.ParameterExpr = { type: 'parameter', name: `pk${i}` };
1398
- return new ParameterReferenceNode(scope, pexpr, `pk${i}`, type);
1399
- };
1400
-
1401
- let predicate: ScalarPlanNode | null = null;
1402
- for (let i = 0; i < pkIndices.length; i++) {
1403
- const colIdx = pkIndices[i];
1404
- const left = makeColumnRef(colIdx);
1405
- const right = makeParamRef(i, attributes[colIdx].type);
1406
- const bexpr: AST.BinaryExpr = { type: 'binary', operator: '=', left: left.expression, right: right.expression };
1407
- const eqNode = new BinaryOpNode(scope, bexpr, left, right);
1408
- predicate = predicate
1409
- ? new BinaryOpNode(scope, { type: 'binary', operator: 'AND', left: predicate.expression, right: eqNode.expression }, predicate, eqNode)
1410
- : eqNode;
1411
- }
1412
-
1413
- if (!predicate) return null;
1414
-
1415
- // Wrap the table reference with a FilterNode
1416
- return new FilterNode(scope, relational, predicate);
1417
- }
1418
-
1419
- private collectTables(node: PlanNode, relToBase: Map<string, string>, bases: Set<string>): void {
1420
- for (const child of node.getChildren()) {
1421
- this.collectTables(child, relToBase, bases);
1422
- }
1423
- if (node instanceof TableReferenceNode) {
1424
- const schema = node.tableSchema;
1425
- const baseName = `${schema.schemaName}.${schema.name}`.toLowerCase();
1426
- bases.add(baseName);
1427
- const relKey = `${baseName}#${node.id ?? 'unknown'}`;
1428
- relToBase.set(relKey, baseName);
1429
- }
1430
- }
1431
-
1432
- /**
1433
- * Rollback an implicit transaction and coordinate with virtual table connections
1434
- */
1435
- private async rollbackImplicitTransaction(): Promise<void> {
1436
- debugLog("Database: Rolling back implicit transaction.");
1437
-
1438
- // Rollback all active connections
1439
- const connections = this.getAllConnections();
1440
- const rollbackPromises = connections.map(async (connection) => {
1441
- try {
1442
- await connection.rollback();
1443
- } catch (error) {
1444
- errorLog(`Error rolling back transaction on connection ${connection.connectionId}: %O`, error);
1445
- // Continue attempting rollback for other connections.
1446
- }
1447
- });
1448
-
1449
- await Promise.allSettled(rollbackPromises);
1450
-
1451
- // Reset database state
1452
- this.inTransaction = false;
1453
- this.isAutocommit = true;
1454
- this.inImplicitTransaction = false;
1455
- }
1456
-
1457
- private createBlockWithNewStatements(block: BlockNode, statements: PlanNode[]): BlockNode {
1458
- return new BlockNode(block.scope, statements, block.parameters);
1459
- }
1460
- }
1461
-