@quereus/quereus 0.1.0 → 0.2.1

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 (477) hide show
  1. package/README.md +47 -23
  2. package/dist/src/common/types.d.ts +1 -0
  3. package/dist/src/common/types.d.ts.map +1 -1
  4. package/dist/src/core/database.d.ts +22 -4
  5. package/dist/src/core/database.d.ts.map +1 -1
  6. package/dist/src/core/database.js +44 -6
  7. package/dist/src/core/database.js.map +1 -1
  8. package/dist/src/core/statement.d.ts +0 -7
  9. package/dist/src/core/statement.d.ts.map +1 -1
  10. package/dist/src/core/statement.js +1 -51
  11. package/dist/src/core/statement.js.map +1 -1
  12. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  13. package/dist/src/func/builtins/explain.js +0 -11
  14. package/dist/src/func/builtins/explain.js.map +1 -1
  15. package/dist/src/index.d.ts +13 -5
  16. package/dist/src/index.d.ts.map +1 -1
  17. package/dist/src/index.js +5 -2
  18. package/dist/src/index.js.map +1 -1
  19. package/dist/src/parser/ast.d.ts +10 -4
  20. package/dist/src/parser/ast.d.ts.map +1 -1
  21. package/dist/src/parser/parser.d.ts.map +1 -1
  22. package/dist/src/parser/parser.js +40 -44
  23. package/dist/src/parser/parser.js.map +1 -1
  24. package/dist/src/planner/analysis/const-pass.d.ts.map +1 -1
  25. package/dist/src/planner/analysis/const-pass.js +12 -6
  26. package/dist/src/planner/analysis/const-pass.js.map +1 -1
  27. package/dist/src/planner/building/constraint-builder.d.ts +11 -0
  28. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -0
  29. package/dist/src/planner/building/constraint-builder.js +79 -0
  30. package/dist/src/planner/building/constraint-builder.js.map +1 -0
  31. package/dist/src/planner/building/delete.d.ts.map +1 -1
  32. package/dist/src/planner/building/delete.js +7 -4
  33. package/dist/src/planner/building/delete.js.map +1 -1
  34. package/dist/src/planner/building/expression.d.ts +3 -0
  35. package/dist/src/planner/building/expression.d.ts.map +1 -1
  36. package/dist/src/planner/building/expression.js +33 -7
  37. package/dist/src/planner/building/expression.js.map +1 -1
  38. package/dist/src/planner/building/insert.d.ts.map +1 -1
  39. package/dist/src/planner/building/insert.js +5 -2
  40. package/dist/src/planner/building/insert.js.map +1 -1
  41. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  42. package/dist/src/planner/building/select-aggregates.js +46 -9
  43. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  44. package/dist/src/planner/building/select-context.js +20 -11
  45. package/dist/src/planner/building/select-context.js.map +1 -1
  46. package/dist/src/planner/building/select-modifiers.d.ts +5 -3
  47. package/dist/src/planner/building/select-modifiers.d.ts.map +1 -1
  48. package/dist/src/planner/building/select-modifiers.js +29 -20
  49. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  50. package/dist/src/planner/building/select-projections.d.ts +3 -1
  51. package/dist/src/planner/building/select-projections.d.ts.map +1 -1
  52. package/dist/src/planner/building/select-projections.js +15 -20
  53. package/dist/src/planner/building/select-projections.js.map +1 -1
  54. package/dist/src/planner/building/select-window.d.ts.map +1 -1
  55. package/dist/src/planner/building/select-window.js +6 -3
  56. package/dist/src/planner/building/select-window.js.map +1 -1
  57. package/dist/src/planner/building/select.d.ts +25 -2
  58. package/dist/src/planner/building/select.d.ts.map +1 -1
  59. package/dist/src/planner/building/select.js +147 -24
  60. package/dist/src/planner/building/select.js.map +1 -1
  61. package/dist/src/planner/building/table.d.ts +0 -10
  62. package/dist/src/planner/building/table.d.ts.map +1 -1
  63. package/dist/src/planner/building/table.js +1 -35
  64. package/dist/src/planner/building/table.js.map +1 -1
  65. package/dist/src/planner/building/update.d.ts.map +1 -1
  66. package/dist/src/planner/building/update.js +8 -5
  67. package/dist/src/planner/building/update.js.map +1 -1
  68. package/dist/src/planner/building/with.d.ts.map +1 -1
  69. package/dist/src/planner/building/with.js +7 -8
  70. package/dist/src/planner/building/with.js.map +1 -1
  71. package/dist/src/planner/cache/correlation-detector.d.ts +11 -0
  72. package/dist/src/planner/cache/correlation-detector.d.ts.map +1 -0
  73. package/dist/src/planner/cache/correlation-detector.js +73 -0
  74. package/dist/src/planner/cache/correlation-detector.js.map +1 -0
  75. package/dist/src/planner/cache/materialization-advisory.d.ts +12 -18
  76. package/dist/src/planner/cache/materialization-advisory.d.ts.map +1 -1
  77. package/dist/src/planner/cache/materialization-advisory.js +65 -46
  78. package/dist/src/planner/cache/materialization-advisory.js.map +1 -1
  79. package/dist/src/planner/cache/reference-graph.d.ts +14 -9
  80. package/dist/src/planner/cache/reference-graph.d.ts.map +1 -1
  81. package/dist/src/planner/cache/reference-graph.js +93 -84
  82. package/dist/src/planner/cache/reference-graph.js.map +1 -1
  83. package/dist/src/planner/debug.d.ts +25 -0
  84. package/dist/src/planner/debug.d.ts.map +1 -1
  85. package/dist/src/planner/debug.js +127 -0
  86. package/dist/src/planner/debug.js.map +1 -1
  87. package/dist/src/planner/framework/context.d.ts +11 -0
  88. package/dist/src/planner/framework/context.d.ts.map +1 -1
  89. package/dist/src/planner/framework/context.js +25 -2
  90. package/dist/src/planner/framework/context.js.map +1 -1
  91. package/dist/src/planner/framework/registry.d.ts +3 -7
  92. package/dist/src/planner/framework/registry.d.ts.map +1 -1
  93. package/dist/src/planner/framework/registry.js +20 -31
  94. package/dist/src/planner/framework/registry.js.map +1 -1
  95. package/dist/src/planner/nodes/add-constraint-node.d.ts +2 -1
  96. package/dist/src/planner/nodes/add-constraint-node.d.ts.map +1 -1
  97. package/dist/src/planner/nodes/add-constraint-node.js +3 -0
  98. package/dist/src/planner/nodes/add-constraint-node.js.map +1 -1
  99. package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
  100. package/dist/src/planner/nodes/aggregate-node.js +6 -4
  101. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  102. package/dist/src/planner/nodes/cache-node.d.ts.map +1 -1
  103. package/dist/src/planner/nodes/cache-node.js +2 -2
  104. package/dist/src/planner/nodes/cache-node.js.map +1 -1
  105. package/dist/src/planner/nodes/constraint-check-node.d.ts +13 -6
  106. package/dist/src/planner/nodes/constraint-check-node.d.ts.map +1 -1
  107. package/dist/src/planner/nodes/constraint-check-node.js +38 -12
  108. package/dist/src/planner/nodes/constraint-check-node.js.map +1 -1
  109. package/dist/src/planner/nodes/create-index-node.d.ts +2 -1
  110. package/dist/src/planner/nodes/create-index-node.d.ts.map +1 -1
  111. package/dist/src/planner/nodes/create-index-node.js +3 -0
  112. package/dist/src/planner/nodes/create-index-node.js.map +1 -1
  113. package/dist/src/planner/nodes/create-table-node.d.ts +2 -1
  114. package/dist/src/planner/nodes/create-table-node.d.ts.map +1 -1
  115. package/dist/src/planner/nodes/create-table-node.js +3 -0
  116. package/dist/src/planner/nodes/create-table-node.js.map +1 -1
  117. package/dist/src/planner/nodes/create-view-node.d.ts +2 -1
  118. package/dist/src/planner/nodes/create-view-node.d.ts.map +1 -1
  119. package/dist/src/planner/nodes/create-view-node.js +3 -0
  120. package/dist/src/planner/nodes/create-view-node.js.map +1 -1
  121. package/dist/src/planner/nodes/cte-node.d.ts +1 -1
  122. package/dist/src/planner/nodes/cte-node.d.ts.map +1 -1
  123. package/dist/src/planner/nodes/cte-node.js +33 -12
  124. package/dist/src/planner/nodes/cte-node.js.map +1 -1
  125. package/dist/src/planner/nodes/cte-reference-node.d.ts +18 -4
  126. package/dist/src/planner/nodes/cte-reference-node.d.ts.map +1 -1
  127. package/dist/src/planner/nodes/cte-reference-node.js +40 -10
  128. package/dist/src/planner/nodes/cte-reference-node.js.map +1 -1
  129. package/dist/src/planner/nodes/delete-node.d.ts +4 -3
  130. package/dist/src/planner/nodes/delete-node.d.ts.map +1 -1
  131. package/dist/src/planner/nodes/delete-node.js +20 -6
  132. package/dist/src/planner/nodes/delete-node.js.map +1 -1
  133. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
  134. package/dist/src/planner/nodes/distinct-node.js +2 -2
  135. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  136. package/dist/src/planner/nodes/dml-executor-node.d.ts +1 -1
  137. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  138. package/dist/src/planner/nodes/dml-executor-node.js +2 -2
  139. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  140. package/dist/src/planner/nodes/drop-table-node.d.ts +2 -1
  141. package/dist/src/planner/nodes/drop-table-node.d.ts.map +1 -1
  142. package/dist/src/planner/nodes/drop-table-node.js +3 -0
  143. package/dist/src/planner/nodes/drop-table-node.js.map +1 -1
  144. package/dist/src/planner/nodes/drop-view-node.d.ts +2 -1
  145. package/dist/src/planner/nodes/drop-view-node.d.ts.map +1 -1
  146. package/dist/src/planner/nodes/drop-view-node.js +3 -0
  147. package/dist/src/planner/nodes/drop-view-node.js.map +1 -1
  148. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  149. package/dist/src/planner/nodes/filter.js +3 -3
  150. package/dist/src/planner/nodes/filter.js.map +1 -1
  151. package/dist/src/planner/nodes/insert-node.d.ts +2 -1
  152. package/dist/src/planner/nodes/insert-node.d.ts.map +1 -1
  153. package/dist/src/planner/nodes/insert-node.js +18 -5
  154. package/dist/src/planner/nodes/insert-node.js.map +1 -1
  155. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts +28 -0
  156. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts.map +1 -0
  157. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js +69 -0
  158. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js.map +1 -0
  159. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  160. package/dist/src/planner/nodes/join-node.js +3 -3
  161. package/dist/src/planner/nodes/join-node.js.map +1 -1
  162. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  163. package/dist/src/planner/nodes/limit-offset.js +2 -2
  164. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  165. package/dist/src/planner/nodes/plan-node-type.d.ts +1 -1
  166. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  167. package/dist/src/planner/nodes/plan-node-type.js +1 -1
  168. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  169. package/dist/src/planner/nodes/plan-node.d.ts +23 -0
  170. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  171. package/dist/src/planner/nodes/plan-node.js +25 -2
  172. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  173. package/dist/src/planner/nodes/project-node.d.ts +5 -1
  174. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  175. package/dist/src/planner/nodes/project-node.js +39 -20
  176. package/dist/src/planner/nodes/project-node.js.map +1 -1
  177. package/dist/src/planner/nodes/recursive-cte-node.d.ts +2 -2
  178. package/dist/src/planner/nodes/recursive-cte-node.d.ts.map +1 -1
  179. package/dist/src/planner/nodes/recursive-cte-node.js +20 -8
  180. package/dist/src/planner/nodes/recursive-cte-node.js.map +1 -1
  181. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  182. package/dist/src/planner/nodes/reference.js +4 -2
  183. package/dist/src/planner/nodes/reference.js.map +1 -1
  184. package/dist/src/planner/nodes/returning-node.d.ts +1 -1
  185. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  186. package/dist/src/planner/nodes/returning-node.js +21 -13
  187. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  188. package/dist/src/planner/nodes/scalar.d.ts +26 -2
  189. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  190. package/dist/src/planner/nodes/scalar.js +82 -10
  191. package/dist/src/planner/nodes/scalar.js.map +1 -1
  192. package/dist/src/planner/nodes/sequencing-node.d.ts.map +1 -1
  193. package/dist/src/planner/nodes/sequencing-node.js +2 -2
  194. package/dist/src/planner/nodes/sequencing-node.js.map +1 -1
  195. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  196. package/dist/src/planner/nodes/set-operation-node.js +3 -3
  197. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  198. package/dist/src/planner/nodes/single-row.d.ts +4 -2
  199. package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
  200. package/dist/src/planner/nodes/single-row.js +3 -0
  201. package/dist/src/planner/nodes/single-row.js.map +1 -1
  202. package/dist/src/planner/nodes/sink-node.d.ts +1 -1
  203. package/dist/src/planner/nodes/sink-node.d.ts.map +1 -1
  204. package/dist/src/planner/nodes/sink-node.js +4 -4
  205. package/dist/src/planner/nodes/sink-node.js.map +1 -1
  206. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  207. package/dist/src/planner/nodes/sort.js +2 -2
  208. package/dist/src/planner/nodes/sort.js.map +1 -1
  209. package/dist/src/planner/nodes/stream-aggregate.d.ts +1 -0
  210. package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
  211. package/dist/src/planner/nodes/stream-aggregate.js +64 -11
  212. package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
  213. package/dist/src/planner/nodes/subquery.d.ts +4 -4
  214. package/dist/src/planner/nodes/subquery.d.ts.map +1 -1
  215. package/dist/src/planner/nodes/subquery.js +68 -23
  216. package/dist/src/planner/nodes/subquery.js.map +1 -1
  217. package/dist/src/planner/nodes/table-access-nodes.d.ts +83 -0
  218. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -0
  219. package/dist/src/planner/nodes/table-access-nodes.js +226 -0
  220. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -0
  221. package/dist/src/planner/nodes/update-node.d.ts +4 -2
  222. package/dist/src/planner/nodes/update-node.d.ts.map +1 -1
  223. package/dist/src/planner/nodes/update-node.js +26 -13
  224. package/dist/src/planner/nodes/update-node.js.map +1 -1
  225. package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
  226. package/dist/src/planner/nodes/window-node.js +25 -23
  227. package/dist/src/planner/nodes/window-node.js.map +1 -1
  228. package/dist/src/planner/optimizer.d.ts.map +1 -1
  229. package/dist/src/planner/optimizer.js +46 -50
  230. package/dist/src/planner/optimizer.js.map +1 -1
  231. package/dist/src/planner/planning-context.d.ts +13 -0
  232. package/dist/src/planner/planning-context.d.ts.map +1 -1
  233. package/dist/src/planner/planning-context.js.map +1 -1
  234. package/dist/src/planner/rules/access/rule-select-access-path.d.ts +1 -1
  235. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  236. package/dist/src/planner/rules/access/rule-select-access-path.js +59 -53
  237. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  238. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -1
  239. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +62 -2
  240. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
  241. package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts.map +1 -1
  242. package/dist/src/planner/rules/cache/rule-materialization-advisory.js +31 -24
  243. package/dist/src/planner/rules/cache/rule-materialization-advisory.js.map +1 -1
  244. package/dist/src/planner/scopes/base.d.ts +0 -10
  245. package/dist/src/planner/scopes/base.d.ts.map +1 -1
  246. package/dist/src/planner/scopes/base.js +0 -14
  247. package/dist/src/planner/scopes/base.js.map +1 -1
  248. package/dist/src/planner/scopes/empty.d.ts +0 -2
  249. package/dist/src/planner/scopes/empty.d.ts.map +1 -1
  250. package/dist/src/planner/scopes/empty.js +0 -8
  251. package/dist/src/planner/scopes/empty.js.map +1 -1
  252. package/dist/src/planner/scopes/multi.d.ts.map +1 -1
  253. package/dist/src/planner/scopes/multi.js +0 -1
  254. package/dist/src/planner/scopes/multi.js.map +1 -1
  255. package/dist/src/planner/scopes/param.d.ts.map +1 -1
  256. package/dist/src/planner/scopes/param.js +0 -1
  257. package/dist/src/planner/scopes/param.js.map +1 -1
  258. package/dist/src/planner/scopes/registered.d.ts +0 -10
  259. package/dist/src/planner/scopes/registered.d.ts.map +1 -1
  260. package/dist/src/planner/scopes/registered.js +1 -17
  261. package/dist/src/planner/scopes/registered.js.map +1 -1
  262. package/dist/src/planner/scopes/scope.d.ts +0 -8
  263. package/dist/src/planner/scopes/scope.d.ts.map +1 -1
  264. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  265. package/dist/src/planner/validation/plan-validator.js +1 -7
  266. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  267. package/dist/src/runtime/context-helpers.d.ts +45 -0
  268. package/dist/src/runtime/context-helpers.d.ts.map +1 -0
  269. package/dist/src/runtime/context-helpers.js +139 -0
  270. package/dist/src/runtime/context-helpers.js.map +1 -0
  271. package/dist/src/runtime/emission-context.d.ts +1 -0
  272. package/dist/src/runtime/emission-context.d.ts.map +1 -1
  273. package/dist/src/runtime/emission-context.js +2 -1
  274. package/dist/src/runtime/emission-context.js.map +1 -1
  275. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  276. package/dist/src/runtime/emit/aggregate.js +119 -86
  277. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  278. package/dist/src/runtime/emit/between.d.ts +5 -0
  279. package/dist/src/runtime/emit/between.d.ts.map +1 -0
  280. package/dist/src/runtime/emit/between.js +38 -0
  281. package/dist/src/runtime/emit/between.js.map +1 -0
  282. package/dist/src/runtime/emit/binary.d.ts +0 -1
  283. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  284. package/dist/src/runtime/emit/binary.js +0 -36
  285. package/dist/src/runtime/emit/binary.js.map +1 -1
  286. package/dist/src/runtime/emit/column-reference.d.ts.map +1 -1
  287. package/dist/src/runtime/emit/column-reference.js +2 -26
  288. package/dist/src/runtime/emit/column-reference.js.map +1 -1
  289. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  290. package/dist/src/runtime/emit/constraint-check.js +16 -123
  291. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  292. package/dist/src/runtime/emit/cte-reference.d.ts.map +1 -1
  293. package/dist/src/runtime/emit/cte-reference.js +16 -48
  294. package/dist/src/runtime/emit/cte-reference.js.map +1 -1
  295. package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
  296. package/dist/src/runtime/emit/distinct.js +2 -8
  297. package/dist/src/runtime/emit/distinct.js.map +1 -1
  298. package/dist/src/runtime/emit/filter.d.ts.map +1 -1
  299. package/dist/src/runtime/emit/filter.js +6 -13
  300. package/dist/src/runtime/emit/filter.js.map +1 -1
  301. package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts +5 -0
  302. package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts.map +1 -0
  303. package/dist/src/runtime/emit/internal-recursive-cte-ref.js +23 -0
  304. package/dist/src/runtime/emit/internal-recursive-cte-ref.js.map +1 -0
  305. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  306. package/dist/src/runtime/emit/join.js +40 -40
  307. package/dist/src/runtime/emit/join.js.map +1 -1
  308. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  309. package/dist/src/runtime/emit/project.js +13 -13
  310. package/dist/src/runtime/emit/project.js.map +1 -1
  311. package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -1
  312. package/dist/src/runtime/emit/recursive-cte.js +3 -14
  313. package/dist/src/runtime/emit/recursive-cte.js.map +1 -1
  314. package/dist/src/runtime/emit/returning.d.ts.map +1 -1
  315. package/dist/src/runtime/emit/returning.js +7 -14
  316. package/dist/src/runtime/emit/returning.js.map +1 -1
  317. package/dist/src/runtime/emit/scan.d.ts +5 -2
  318. package/dist/src/runtime/emit/scan.d.ts.map +1 -1
  319. package/dist/src/runtime/emit/scan.js +21 -17
  320. package/dist/src/runtime/emit/scan.js.map +1 -1
  321. package/dist/src/runtime/emit/sort.d.ts.map +1 -1
  322. package/dist/src/runtime/emit/sort.js +8 -11
  323. package/dist/src/runtime/emit/sort.js.map +1 -1
  324. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  325. package/dist/src/runtime/emit/subquery.js +95 -40
  326. package/dist/src/runtime/emit/subquery.js.map +1 -1
  327. package/dist/src/runtime/emit/table-valued-function.d.ts.map +1 -1
  328. package/dist/src/runtime/emit/table-valued-function.js +7 -22
  329. package/dist/src/runtime/emit/table-valued-function.js.map +1 -1
  330. package/dist/src/runtime/emit/update.d.ts.map +1 -1
  331. package/dist/src/runtime/emit/update.js +20 -27
  332. package/dist/src/runtime/emit/update.js.map +1 -1
  333. package/dist/src/runtime/emit/window.d.ts.map +1 -1
  334. package/dist/src/runtime/emit/window.js +55 -83
  335. package/dist/src/runtime/emit/window.js.map +1 -1
  336. package/dist/src/runtime/emitters.d.ts.map +1 -1
  337. package/dist/src/runtime/emitters.js +49 -1
  338. package/dist/src/runtime/emitters.js.map +1 -1
  339. package/dist/src/runtime/register.d.ts.map +1 -1
  340. package/dist/src/runtime/register.js +5 -4
  341. package/dist/src/runtime/register.js.map +1 -1
  342. package/dist/src/runtime/scheduler.d.ts.map +1 -1
  343. package/dist/src/runtime/scheduler.js +47 -42
  344. package/dist/src/runtime/scheduler.js.map +1 -1
  345. package/dist/src/runtime/types.d.ts +34 -0
  346. package/dist/src/runtime/types.d.ts.map +1 -1
  347. package/dist/src/runtime/types.js +21 -0
  348. package/dist/src/runtime/types.js.map +1 -1
  349. package/dist/src/schema/manager.d.ts.map +1 -1
  350. package/dist/src/schema/manager.js +29 -16
  351. package/dist/src/schema/manager.js.map +1 -1
  352. package/dist/src/schema/table.d.ts +4 -4
  353. package/dist/src/schema/table.d.ts.map +1 -1
  354. package/dist/src/schema/table.js +10 -10
  355. package/dist/src/schema/table.js.map +1 -1
  356. package/dist/src/util/plugin-loader.d.ts +10 -1
  357. package/dist/src/util/plugin-loader.d.ts.map +1 -1
  358. package/dist/src/util/plugin-loader.js +56 -1
  359. package/dist/src/util/plugin-loader.js.map +1 -1
  360. package/dist/src/util/working-table-iterable.d.ts.map +1 -1
  361. package/dist/src/util/working-table-iterable.js +8 -8
  362. package/dist/src/util/working-table-iterable.js.map +1 -1
  363. package/dist/src/vtab/manifest.d.ts +36 -0
  364. package/dist/src/vtab/manifest.d.ts.map +1 -1
  365. package/dist/src/vtab/table.d.ts +1 -1
  366. package/dist/src/vtab/table.d.ts.map +1 -1
  367. package/package.json +8 -3
  368. package/src/common/types.ts +1 -0
  369. package/src/core/database.ts +48 -6
  370. package/src/core/statement.ts +1 -49
  371. package/src/func/builtins/explain.ts +0 -11
  372. package/src/index.ts +39 -5
  373. package/src/parser/ast.ts +12 -6
  374. package/src/parser/parser.ts +45 -52
  375. package/src/planner/analysis/const-pass.ts +281 -270
  376. package/src/planner/building/constraint-builder.ts +114 -0
  377. package/src/planner/building/delete.ts +18 -5
  378. package/src/planner/building/expression.ts +35 -7
  379. package/src/planner/building/insert.ts +16 -3
  380. package/src/planner/building/select-aggregates.ts +57 -11
  381. package/src/planner/building/select-context.ts +22 -12
  382. package/src/planner/building/select-modifiers.ts +35 -21
  383. package/src/planner/building/select-projections.ts +25 -26
  384. package/src/planner/building/select-window.ts +14 -9
  385. package/src/planner/building/select.ts +163 -31
  386. package/src/planner/building/table.ts +1 -40
  387. package/src/planner/building/update.ts +22 -7
  388. package/src/planner/building/with.ts +12 -13
  389. package/src/planner/cache/correlation-detector.ts +83 -0
  390. package/src/planner/cache/materialization-advisory.ts +71 -50
  391. package/src/planner/cache/reference-graph.ts +115 -91
  392. package/src/planner/debug.ts +163 -0
  393. package/src/planner/framework/context.ts +36 -2
  394. package/src/planner/framework/registry.ts +261 -274
  395. package/src/planner/nodes/add-constraint-node.ts +5 -1
  396. package/src/planner/nodes/aggregate-node.ts +6 -4
  397. package/src/planner/nodes/cache-node.ts +2 -2
  398. package/src/planner/nodes/constraint-check-node.ts +49 -15
  399. package/src/planner/nodes/create-index-node.ts +5 -1
  400. package/src/planner/nodes/create-table-node.ts +5 -1
  401. package/src/planner/nodes/create-view-node.ts +5 -1
  402. package/src/planner/nodes/cte-node.ts +45 -14
  403. package/src/planner/nodes/cte-reference-node.ts +49 -13
  404. package/src/planner/nodes/delete-node.ts +31 -7
  405. package/src/planner/nodes/distinct-node.ts +2 -2
  406. package/src/planner/nodes/dml-executor-node.ts +3 -3
  407. package/src/planner/nodes/drop-table-node.ts +5 -1
  408. package/src/planner/nodes/drop-view-node.ts +5 -1
  409. package/src/planner/nodes/filter.ts +3 -3
  410. package/src/planner/nodes/function.ts +93 -93
  411. package/src/planner/nodes/insert-node.ts +28 -5
  412. package/src/planner/nodes/internal-recursive-cte-ref-node.ts +76 -0
  413. package/src/planner/nodes/join-node.ts +3 -3
  414. package/src/planner/nodes/limit-offset.ts +2 -2
  415. package/src/planner/nodes/plan-node-type.ts +1 -1
  416. package/src/planner/nodes/plan-node.ts +39 -2
  417. package/src/planner/nodes/project-node.ts +39 -19
  418. package/src/planner/nodes/recursive-cte-node.ts +37 -9
  419. package/src/planner/nodes/reference.ts +4 -2
  420. package/src/planner/nodes/returning-node.ts +25 -13
  421. package/src/planner/nodes/scalar.ts +95 -11
  422. package/src/planner/nodes/sequencing-node.ts +2 -2
  423. package/src/planner/nodes/set-operation-node.ts +3 -3
  424. package/src/planner/nodes/single-row.ts +7 -2
  425. package/src/planner/nodes/sink-node.ts +5 -5
  426. package/src/planner/nodes/sort.ts +2 -2
  427. package/src/planner/nodes/stream-aggregate.ts +76 -12
  428. package/src/planner/nodes/subquery.ts +90 -27
  429. package/src/planner/nodes/{physical-access-nodes.ts → table-access-nodes.ts} +6 -6
  430. package/src/planner/nodes/update-node.ts +31 -13
  431. package/src/planner/nodes/window-node.ts +28 -22
  432. package/src/planner/optimizer.ts +257 -263
  433. package/src/planner/planning-context.ts +15 -0
  434. package/src/planner/rules/access/rule-select-access-path.ts +68 -64
  435. package/src/planner/rules/aggregate/rule-aggregate-streaming.ts +74 -2
  436. package/src/planner/rules/cache/rule-materialization-advisory.ts +31 -27
  437. package/src/planner/scopes/base.ts +0 -17
  438. package/src/planner/scopes/empty.ts +0 -10
  439. package/src/planner/scopes/multi.ts +0 -1
  440. package/src/planner/scopes/param.ts +0 -1
  441. package/src/planner/scopes/registered.ts +1 -20
  442. package/src/planner/scopes/scope.ts +0 -12
  443. package/src/planner/validation/plan-validator.ts +1 -8
  444. package/src/runtime/context-helpers.ts +191 -0
  445. package/src/runtime/emission-context.ts +5 -2
  446. package/src/runtime/emit/aggregate.ts +131 -85
  447. package/src/runtime/emit/between.ts +51 -0
  448. package/src/runtime/emit/binary.ts +0 -46
  449. package/src/runtime/emit/column-reference.ts +3 -36
  450. package/src/runtime/emit/constraint-check.ts +19 -144
  451. package/src/runtime/emit/cte-reference.ts +23 -60
  452. package/src/runtime/emit/distinct.ts +2 -7
  453. package/src/runtime/emit/filter.ts +6 -13
  454. package/src/runtime/emit/internal-recursive-cte-ref.ts +37 -0
  455. package/src/runtime/emit/join.ts +45 -43
  456. package/src/runtime/emit/project.ts +18 -12
  457. package/src/runtime/emit/recursive-cte.ts +3 -12
  458. package/src/runtime/emit/returning.ts +7 -14
  459. package/src/runtime/emit/scan.ts +25 -23
  460. package/src/runtime/emit/sort.ts +8 -11
  461. package/src/runtime/emit/subquery.ts +108 -48
  462. package/src/runtime/emit/table-valued-function.ts +7 -20
  463. package/src/runtime/emit/update.ts +22 -29
  464. package/src/runtime/emit/window.ts +74 -88
  465. package/src/runtime/emitters.ts +52 -1
  466. package/src/runtime/register.ts +5 -4
  467. package/src/runtime/scheduler.ts +54 -54
  468. package/src/runtime/types.ts +45 -0
  469. package/src/schema/manager.ts +34 -19
  470. package/src/schema/table.ts +8 -8
  471. package/src/util/plugin-loader.ts +78 -4
  472. package/src/util/working-table-iterable.ts +15 -7
  473. package/src/vtab/manifest.ts +42 -0
  474. package/src/vtab/table.ts +1 -1
  475. package/src/planner/nodes/scan.ts +0 -103
  476. package/src/planner/rules/physical/rule-mark-physical.ts +0 -37
  477. package/src/runtime/emit/table-reference.ts +0 -92
@@ -1,6 +1,6 @@
1
1
  import type { WindowNode } from '../../planner/nodes/window-node.js';
2
2
  import type { Instruction, RuntimeContext } from '../types.js';
3
- import type { Row, SqlValue } from '../../common/types.js';
3
+ import type { OutputValue, Row, SqlValue } from '../../common/types.js';
4
4
  import type { EmissionContext } from '../emission-context.js';
5
5
  import { emitPlanNode, emitCallFromPlan } from '../emitters.js';
6
6
  import { resolveWindowFunction } from '../../schema/window-function.js';
@@ -10,6 +10,7 @@ import { compareSqlValues, createOrderByComparatorFast, resolveCollation } from
10
10
  import { createLogger } from '../../common/logger.js';
11
11
  import { buildRowDescriptor } from '../../util/row-descriptor.js';
12
12
  import { RowDescriptor } from '../../planner/nodes/plan-node.js';
13
+ import { withRowContext, withAsyncRowContext } from '../context-helpers.js';
13
14
 
14
15
  const log = createLogger('runtime:emit:window');
15
16
 
@@ -45,7 +46,7 @@ export function emitWindow(plan: WindowNode, ctx: EmissionContext): Instruction
45
46
  async function* run(
46
47
  rctx: RuntimeContext,
47
48
  source: AsyncIterable<Row>,
48
- ...callbacks: Array<(ctx: RuntimeContext) => any>
49
+ ...callbacks: Array<(ctx: RuntimeContext) => OutputValue>
49
50
  ): AsyncIterable<Row> {
50
51
  log('Starting window function execution');
51
52
 
@@ -113,23 +114,22 @@ async function groupByPartitions(
113
114
  const partitions = new Map<string, Row[]>();
114
115
 
115
116
  for (const row of rows) {
116
- rctx.context.set(sourceRowDescriptor, () => row);
117
- try {
117
+ const partitionKey = await withAsyncRowContext(rctx, sourceRowDescriptor, () => row, async () => {
118
118
  // Evaluate partition expressions
119
- const partitionValues = partitionCallbacks.map(callback => callback(rctx));
119
+ const partitionValues = await Promise.all(partitionCallbacks.map(callback =>
120
+ callback(rctx)
121
+ ));
120
122
 
121
123
  // Create partition key
122
- const partitionKey = partitionValues.map(val =>
124
+ return partitionValues.map(val =>
123
125
  val === null ? 'NULL' : String(val)
124
126
  ).join('|');
127
+ });
125
128
 
126
- if (!partitions.has(partitionKey)) {
127
- partitions.set(partitionKey, []);
128
- }
129
- partitions.get(partitionKey)!.push(row);
130
- } finally {
131
- rctx.context.delete(sourceRowDescriptor);
129
+ if (!partitions.has(partitionKey)) {
130
+ partitions.set(partitionKey, []);
132
131
  }
132
+ partitions.get(partitionKey)!.push(row);
133
133
  }
134
134
 
135
135
  return partitions;
@@ -142,9 +142,9 @@ async function* processPartition(
142
142
  rctx: RuntimeContext,
143
143
  sourceRowDescriptor: RowDescriptor,
144
144
  outputRowDescriptor: RowDescriptor,
145
- partitionCallbacks: Array<(ctx: RuntimeContext) => any>,
146
- orderByCallbacks: Array<(ctx: RuntimeContext) => any>,
147
- funcArgCallbacks: Array<((ctx: RuntimeContext) => any) | null>
145
+ partitionCallbacks: Array<(ctx: RuntimeContext) => OutputValue>,
146
+ orderByCallbacks: Array<(ctx: RuntimeContext) => OutputValue>,
147
+ funcArgCallbacks: Array<(ctx: RuntimeContext) => OutputValue | null>
148
148
  ): AsyncIterable<Row> {
149
149
  // Sort rows according to ORDER BY specification
150
150
  const sortedRows = await sortRows(
@@ -158,8 +158,8 @@ async function* processPartition(
158
158
  const outputRow = [...currentRow];
159
159
 
160
160
  // Set up context for current row
161
- rctx.context.set(sourceRowDescriptor, () => currentRow);
162
- try {
161
+ const outputValues = await withRowContext(rctx, sourceRowDescriptor, () => currentRow, async () => {
162
+ const values: SqlValue[] = [];
163
163
  // Compute each window function
164
164
  for (let funcIndex = 0; funcIndex < plan.functions.length; funcIndex++) {
165
165
  const func = plan.functions[funcIndex];
@@ -169,7 +169,7 @@ async function* processPartition(
169
169
  let value: SqlValue;
170
170
 
171
171
  if (schema.kind === 'ranking') {
172
- value = computeRankingFunction(
172
+ value = await computeRankingFunction(
173
173
  func.functionName, sortedRows, currentIndex,
174
174
  orderByCallbacks, rctx, sourceRowDescriptor
175
175
  );
@@ -186,26 +186,23 @@ async function* processPartition(
186
186
  );
187
187
  }
188
188
 
189
- outputRow.push(value);
189
+ values.push(value);
190
190
  }
191
- } finally {
192
- rctx.context.delete(sourceRowDescriptor);
193
- }
191
+ return values;
192
+ });
193
+
194
+ // Add computed values to output row
195
+ outputRow.push(...outputValues);
194
196
 
195
197
  // Yield the output row
196
- rctx.context.set(outputRowDescriptor, () => outputRow as Row);
197
- try {
198
- yield outputRow as Row;
199
- } finally {
200
- rctx.context.delete(outputRowDescriptor);
201
- }
198
+ yield await withRowContext(rctx, outputRowDescriptor, () => outputRow as Row, () => outputRow as Row);
202
199
  }
203
200
  }
204
201
 
205
202
  async function sortRows(
206
203
  rows: Row[],
207
204
  orderBy: any[],
208
- orderByCallbacks: Array<(ctx: RuntimeContext) => any>,
205
+ orderByCallbacks: Array<(ctx: RuntimeContext) => OutputValue>,
209
206
  rctx: RuntimeContext,
210
207
  sourceRowDescriptor: RowDescriptor
211
208
  ): Promise<Row[]> {
@@ -220,34 +217,29 @@ async function sortRows(
220
217
  const collationFunc = resolveCollation('BINARY');
221
218
  return createOrderByComparatorFast(
222
219
  orderClause.direction,
223
- (orderClause as any).nullsOrdering,
220
+ orderClause.nulls,
224
221
  collationFunc
225
222
  );
226
223
  });
227
224
 
228
- return [...rows].sort((a, b) => {
225
+ // Pre-evaluate ORDER BY values for all rows to avoid async in sort
226
+ const rowsWithValues = await Promise.all(rows.map(async (row) => {
227
+ const values = await Promise.all(orderByCallbacks.map(async (callback) => {
228
+ return await withAsyncRowContext(rctx, sourceRowDescriptor, () => row, async () => {
229
+ const result = callback(rctx);
230
+ return await Promise.resolve(result);
231
+ });
232
+ }));
233
+ return { row, values };
234
+ }));
235
+
236
+ // Now sort using the pre-evaluated values
237
+ rowsWithValues.sort((a, b) => {
229
238
  // Compare each ORDER BY expression in sequence
230
239
  for (let i = 0; i < orderBy.length; i++) {
231
- const callback = orderByCallbacks[i];
232
240
  const comparator = orderByComparators[i];
233
-
234
- // Evaluate expression for row A
235
- rctx.context.set(sourceRowDescriptor, () => a);
236
- let valueA: SqlValue;
237
- try {
238
- valueA = callback(rctx);
239
- } finally {
240
- rctx.context.delete(sourceRowDescriptor);
241
- }
242
-
243
- // Evaluate expression for row B
244
- rctx.context.set(sourceRowDescriptor, () => b);
245
- let valueB: SqlValue;
246
- try {
247
- valueB = callback(rctx);
248
- } finally {
249
- rctx.context.delete(sourceRowDescriptor);
250
- }
241
+ const valueA = a.values[i] as SqlValue;
242
+ const valueB = b.values[i] as SqlValue;
251
243
 
252
244
  // Use pre-created optimized comparator
253
245
  const comparison = comparator(valueA, valueB);
@@ -262,16 +254,19 @@ async function sortRows(
262
254
 
263
255
  return 0; // All ORDER BY expressions are equal
264
256
  });
257
+
258
+ // Extract just the rows in sorted order
259
+ return rowsWithValues.map(item => item.row);
265
260
  }
266
261
 
267
- function computeRankingFunction(
262
+ async function computeRankingFunction(
268
263
  functionName: string,
269
264
  sortedRows: Row[],
270
265
  currentIndex: number,
271
266
  orderByCallbacks: Array<(ctx: RuntimeContext) => any>,
272
267
  rctx: RuntimeContext,
273
268
  sourceRowDescriptor: RowDescriptor
274
- ): number {
269
+ ): Promise<number> {
275
270
  switch (functionName.toLowerCase()) {
276
271
  case 'row_number':
277
272
  return currentIndex + 1;
@@ -283,9 +278,9 @@ function computeRankingFunction(
283
278
 
284
279
  for (let i = 0; i < currentIndex; i++) {
285
280
  const prevRow = sortedRows[i];
286
- if (!areRowsEqualInOrderBy(
281
+ if (!(await areRowsEqualInOrderBy(
287
282
  prevRow, currentRow, orderByCallbacks, rctx, sourceRowDescriptor
288
- )) {
283
+ ))) {
289
284
  rank = i + 2; // Rank is 1-based and accounts for ties
290
285
  }
291
286
  }
@@ -300,11 +295,11 @@ function computeRankingFunction(
300
295
 
301
296
  for (let i = 0; i < currentIndex; i++) {
302
297
  const prevRow = sortedRows[i];
303
- if (!areRowsEqualInOrderBy(
298
+ if (!(await areRowsEqualInOrderBy(
304
299
  prevRow, currentRow, orderByCallbacks, rctx, sourceRowDescriptor
305
- )) {
300
+ ))) {
306
301
  // Create a key for this distinct set of ORDER BY values
307
- const key = getOrderByKey(prevRow, orderByCallbacks, rctx, sourceRowDescriptor);
302
+ const key = await getOrderByKey(prevRow, orderByCallbacks, rctx, sourceRowDescriptor);
308
303
  if (!seenValues.has(key)) {
309
304
  seenValues.add(key);
310
305
  denseRank++;
@@ -335,20 +330,20 @@ async function computeAggregateFunction(
335
330
  // Determine frame bounds
336
331
  const frameBounds = getFrameBounds(frame, sortedRows.length, currentIndex, hasOrderBy);
337
332
 
338
- let accumulator = null;
333
+ let accumulator: any = null;
339
334
  let rowCount = 0;
340
335
 
341
336
  // Process rows within the frame
342
337
  for (let i = frameBounds.start; i <= frameBounds.end; i++) {
343
338
  const frameRow = sortedRows[i];
344
339
 
345
- rctx.context.set(sourceRowDescriptor, () => frameRow);
346
- try {
340
+ await withAsyncRowContext(rctx, sourceRowDescriptor, () => frameRow, async () => {
347
341
  let argValue: SqlValue = null;
348
342
 
349
343
  // Get argument value if callback exists
350
344
  if (argCallback) {
351
- argValue = argCallback(rctx);
345
+ const result = argCallback(rctx);
346
+ argValue = await Promise.resolve(result);
352
347
  }
353
348
 
354
349
  // Apply aggregate step function
@@ -356,9 +351,7 @@ async function computeAggregateFunction(
356
351
  accumulator = schema.step(accumulator, argValue);
357
352
  rowCount++;
358
353
  }
359
- } finally {
360
- rctx.context.delete(sourceRowDescriptor);
361
- }
354
+ });
362
355
  }
363
356
 
364
357
  // Apply final function
@@ -421,31 +414,25 @@ function getFrameBounds(
421
414
  return { start, end };
422
415
  }
423
416
 
424
- function areRowsEqualInOrderBy(
417
+ async function areRowsEqualInOrderBy(
425
418
  rowA: Row,
426
419
  rowB: Row,
427
420
  orderByCallbacks: Array<(ctx: RuntimeContext) => any>,
428
421
  rctx: RuntimeContext,
429
422
  sourceRowDescriptor: RowDescriptor
430
- ): boolean {
423
+ ): Promise<boolean> {
431
424
  for (const callback of orderByCallbacks) {
432
425
  // Get value for row A
433
- rctx.context.set(sourceRowDescriptor, () => rowA);
434
- let valueA: SqlValue;
435
- try {
436
- valueA = callback(rctx);
437
- } finally {
438
- rctx.context.delete(sourceRowDescriptor);
439
- }
426
+ const valueA = await withAsyncRowContext(rctx, sourceRowDescriptor, () => rowA, async () => {
427
+ const result = callback(rctx);
428
+ return await Promise.resolve(result);
429
+ });
440
430
 
441
431
  // Get value for row B
442
- rctx.context.set(sourceRowDescriptor, () => rowB);
443
- let valueB: SqlValue;
444
- try {
445
- valueB = callback(rctx);
446
- } finally {
447
- rctx.context.delete(sourceRowDescriptor);
448
- }
432
+ const valueB = await withAsyncRowContext(rctx, sourceRowDescriptor, () => rowB, async () => {
433
+ const result = callback(rctx);
434
+ return await Promise.resolve(result);
435
+ });
449
436
 
450
437
  // If any ORDER BY expression differs, rows are not equal
451
438
  if (compareSqlValues(valueA, valueB) !== 0) {
@@ -456,17 +443,16 @@ function areRowsEqualInOrderBy(
456
443
  return true; // All ORDER BY expressions are equal
457
444
  }
458
445
 
459
- function getOrderByKey(
446
+ async function getOrderByKey(
460
447
  row: Row,
461
448
  orderByCallbacks: Array<(ctx: RuntimeContext) => any>,
462
449
  rctx: RuntimeContext,
463
450
  sourceRowDescriptor: RowDescriptor
464
- ): string {
465
- rctx.context.set(sourceRowDescriptor, () => row);
466
- try {
467
- const values = orderByCallbacks.map(callback => callback(rctx));
451
+ ): Promise<string> {
452
+ return await withAsyncRowContext(rctx, sourceRowDescriptor, () => row, async () => {
453
+ const values = await Promise.all(orderByCallbacks.map(callback =>
454
+ Promise.resolve(callback(rctx))
455
+ ));
468
456
  return values.map(val => val === null ? 'NULL' : String(val)).join('|');
469
- } finally {
470
- rctx.context.delete(sourceRowDescriptor);
471
- }
457
+ });
472
458
  }
@@ -61,12 +61,63 @@ export function getEmitterMeta(nodeType: PlanNodeType): EmitterMeta | undefined
61
61
  return registration?.meta;
62
62
  }
63
63
 
64
+ /**
65
+ * Wraps an instruction's run function with plan node stack tracking for debugging.
66
+ * Only adds overhead when tracing is enabled.
67
+ */
68
+ function instrumentRunForTracing(plan: PlanNode, originalRun: InstructionRun): InstructionRun {
69
+ return function (ctx: RuntimeContext, ...args: any[]) {
70
+ const stack = (ctx.planStack = ctx.planStack || []);
71
+ stack.push(plan);
72
+
73
+ let result: any;
74
+ try {
75
+ result = originalRun(ctx, ...args);
76
+ } catch (err) {
77
+ // Synchronous error – pop immediately and re-throw
78
+ stack.pop();
79
+ throw err;
80
+ }
81
+
82
+ // If the result is an async iterable, defer the pop until iteration completes
83
+ if (result && typeof result === 'object' && Symbol.asyncIterator in result) {
84
+ const iterable = result as AsyncIterable<unknown>;
85
+ // Wrap iterable to pop stack in a finally block once iteration ends
86
+ return (async function* () {
87
+ try {
88
+ for await (const item of iterable) {
89
+ yield item;
90
+ }
91
+ } finally {
92
+ stack.pop();
93
+ }
94
+ })();
95
+ }
96
+
97
+ // If the result is a promise, pop once it settles
98
+ if (result && typeof (result as Promise<unknown>).then === 'function') {
99
+ return (result as Promise<unknown>).finally(() => {
100
+ stack.pop();
101
+ });
102
+ }
103
+
104
+ // Synchronous return value – pop immediately
105
+ stack.pop();
106
+ return result;
107
+ };
108
+ }
109
+
64
110
  export function emitPlanNode(plan: PlanNode, ctx: EmissionContext): Instruction {
65
111
  const registration = emitters.get(plan.nodeType);
66
112
  if (!registration) {
67
113
  throw new QuereusError(`No emitter registered for ${plan.nodeType}`, StatusCode.ERROR);
68
114
  }
69
- return registration.emitter(plan, ctx);
115
+ const instruction = registration.emitter(plan, ctx);
116
+ // Wrap with instrumentation for tracing
117
+ if (ctx.tracePlanStack) {
118
+ instruction.run = instrumentRunForTracing(plan, instruction.run);
119
+ }
120
+ return instruction;
70
121
  }
71
122
 
72
123
  /**
@@ -13,7 +13,8 @@ import { emitDropTable } from './emit/drop-table.js';
13
13
  import { emitCreateView } from './emit/create-view.js';
14
14
  import { emitDropView } from './emit/drop-view.js';
15
15
  import { emitCTE } from './emit/cte.js';
16
- import { emitTableReference } from './emit/table-reference.js';
16
+ import { emitCTEReference } from './emit/cte-reference.js';
17
+ import { emitInternalRecursiveCTERef } from './emit/internal-recursive-cte-ref.js';
17
18
  import { emitInsert } from './emit/insert.js';
18
19
  import { emitUpdate } from './emit/update.js';
19
20
  import { emitDmlExecutor } from './emit/dml-executor.js';
@@ -45,7 +46,7 @@ import { emitLoopJoin } from './emit/join.js';
45
46
  import { emitCache } from './emit/cache.js';
46
47
  import { emitReturning } from './emit/returning.js';
47
48
  import { emitSink } from './emit/sink.js';
48
- import { emitCTEReference } from './emit/cte-reference.js';
49
+ import { emitBetween } from './emit/between.js';
49
50
 
50
51
  let registered = false;
51
52
 
@@ -67,14 +68,14 @@ export function registerEmitters() {
67
68
  registerEmitter(PlanNodeType.CaseExpr, emitCaseExpr as EmitterFunc);
68
69
  registerEmitter(PlanNodeType.Cast, emitCast as EmitterFunc);
69
70
  registerEmitter(PlanNodeType.Collate, emitCollate as EmitterFunc);
71
+ registerEmitter(PlanNodeType.Between, emitBetween as EmitterFunc);
70
72
  registerEmitter(PlanNodeType.ScalarSubquery, emitScalarSubquery as EmitterFunc);
71
73
  registerEmitter(PlanNodeType.Exists, emitExists as EmitterFunc);
72
74
 
73
75
  // Relational emitters (mix of logical and physical for now)
74
76
  registerEmitter(PlanNodeType.Block, emitBlock as EmitterFunc);
75
- registerEmitter(PlanNodeType.TableReference, emitTableReference as EmitterFunc);
76
77
  registerEmitter(PlanNodeType.CTEReference, emitCTEReference as EmitterFunc);
77
- registerEmitter(PlanNodeType.TableScan, emitSeqScan as EmitterFunc);
78
+ registerEmitter(PlanNodeType.InternalRecursiveCTERef, emitInternalRecursiveCTERef as EmitterFunc);
78
79
 
79
80
  // Physical access node emitters (Phase 1)
80
81
  registerEmitter(PlanNodeType.SeqScan, emitSeqScan as EmitterFunc);
@@ -2,8 +2,10 @@ import type { Instruction, RuntimeContext, InstructionRuntimeStats } from "./typ
2
2
  import type { OutputValue, RuntimeValue, Row } from "../common/types.js";
3
3
  import { isAsyncIterable } from "./utils.js";
4
4
  import { createLogger } from "../common/logger.js";
5
+ import { DefaultContextTracker } from './types.js';
5
6
 
6
7
  const log = createLogger('runtime:metrics');
8
+ const contextLog = createLogger('runtime:context');
7
9
 
8
10
  type ResultDestination = number | null;
9
11
 
@@ -71,13 +73,28 @@ export class Scheduler {
71
73
  }
72
74
 
73
75
  run(ctx: RuntimeContext): OutputValue {
76
+ // Initialize context tracker if not already present
77
+ if (!ctx.contextTracker) {
78
+ ctx.contextTracker = new DefaultContextTracker();
79
+ }
80
+
81
+ let result: OutputValue;
82
+
74
83
  if (ctx.enableMetrics) {
75
- return this.runWithMetrics(ctx);
84
+ result = this.runWithMetrics(ctx);
76
85
  } else if (!ctx.tracer) {
77
- return this.runOptimized(ctx);
86
+ result = this.runOptimized(ctx);
78
87
  } else {
79
- return this.runWithTracing(ctx);
88
+ result = this.runWithTracing(ctx);
80
89
  }
90
+
91
+ // Check for remaining contexts and warn rather than error
92
+ if (ctx.contextTracker && ctx.contextTracker.hasRemainingContexts()) {
93
+ const remaining = ctx.contextTracker.getRemainingContexts();
94
+ contextLog('Context leak detected - remaining contexts:', remaining.map(c => c.source));
95
+ }
96
+
97
+ return result;
81
98
  }
82
99
 
83
100
  private runOptimized(ctx: RuntimeContext): OutputValue {
@@ -164,7 +181,6 @@ export class Scheduler {
164
181
  const args = instrArgs[i]!; // Guaranteed not to contain promises
165
182
  instrArgs[i] = undefined; // Clear args as we go to minimize memory usage.
166
183
 
167
-
168
184
  // Trace input
169
185
  ctx.tracer!.traceInput(i, instruction, args as RuntimeValue[]);
170
186
 
@@ -386,12 +402,12 @@ export class Scheduler {
386
402
  stats.elapsedNs += process.hrtime.bigint() - start;
387
403
  throw error;
388
404
  });
389
- } else {
390
- // Sync result
391
- stats.out += this.countOutputs(result);
392
- stats.elapsedNs += process.hrtime.bigint() - start;
393
- return result;
394
405
  }
406
+
407
+ stats.out += this.countOutputs(result);
408
+ stats.elapsedNs += process.hrtime.bigint() - start;
409
+
410
+ return result;
395
411
  } catch (error) {
396
412
  stats.elapsedNs += process.hrtime.bigint() - start;
397
413
  throw error;
@@ -406,13 +422,10 @@ export class Scheduler {
406
422
  stats.in += this.countInputs(args);
407
423
 
408
424
  try {
409
- const result = instruction.run(ctx, ...args);
410
- const resolved = result instanceof Promise ? await result : result;
411
-
412
- stats.out += this.countOutputs(resolved);
425
+ const result = await instruction.run(ctx, ...args);
426
+ stats.out += this.countOutputs(result);
413
427
  stats.elapsedNs += process.hrtime.bigint() - start;
414
-
415
- return resolved;
428
+ return result;
416
429
  } catch (error) {
417
430
  stats.elapsedNs += process.hrtime.bigint() - start;
418
431
  throw error;
@@ -420,65 +433,52 @@ export class Scheduler {
420
433
  }
421
434
 
422
435
  private countInputs(args: RuntimeValue[]): number {
423
- let count = 0;
424
- for (const arg of args) {
425
- if (Array.isArray(arg)) {
426
- count += arg.length; // Count array elements
427
- } else if (isAsyncIterable(arg)) {
428
- count += 1; // Count iterables as 1 (we can't know size without consuming)
436
+ return args.reduce((sum: number, arg) => {
437
+ if (isAsyncIterable(arg)) {
438
+ return sum + 1; // Count as 1 for async iterables (we don't know size)
439
+ } else if (Array.isArray(arg)) {
440
+ return sum + arg.length;
429
441
  } else {
430
- count += 1; // Count other values as 1
442
+ return sum + 1;
431
443
  }
432
- }
433
- return count;
444
+ }, 0);
434
445
  }
435
446
 
436
447
  private countOutputs(result: OutputValue): number {
437
- if (Array.isArray(result)) {
448
+ if (isAsyncIterable(result)) {
449
+ return 1; // Count as 1 for async iterables (we don't know size)
450
+ } else if (Array.isArray(result)) {
438
451
  return result.length;
439
- } else if (isAsyncIterable(result)) {
440
- return 1; // Count iterables as 1 (we can't know size without consuming)
441
452
  } else {
442
453
  return 1;
443
454
  }
444
455
  }
445
456
 
446
457
  private logAggregateMetrics(): void {
447
- if (!log.enabled && !log.extend('stats').enabled) {
448
- return;
449
- }
450
-
451
- const statsLog = log.extend('stats');
452
- statsLog('Execution metrics summary:');
453
-
454
- let totalTime = 0n;
455
- for (let i = 0; i < this.instructions.length; i++) {
456
- const instruction = this.instructions[i];
457
- const stats = instruction.runtimeStats;
458
- if (stats) {
459
- const elapsedMs = Number(stats.elapsedNs) / 1_000_000;
460
- totalTime += stats.elapsedNs;
461
-
462
- statsLog(' [%d] %s: %d exec, %d in, %d out, %.2fms',
463
- i,
464
- instruction.note || 'unknown',
465
- stats.executions,
466
- stats.in,
467
- stats.out,
468
- elapsedMs
469
- );
458
+ if (log.enabled) {
459
+ let totalExecutions = 0;
460
+ let totalElapsed = 0n;
461
+ let totalIn = 0;
462
+ let totalOut = 0;
463
+
464
+ for (const instruction of this.instructions) {
465
+ if (instruction.runtimeStats) {
466
+ totalExecutions += instruction.runtimeStats.executions;
467
+ totalElapsed += instruction.runtimeStats.elapsedNs;
468
+ totalIn += instruction.runtimeStats.in;
469
+ totalOut += instruction.runtimeStats.out;
470
+ }
470
471
  }
471
- }
472
472
 
473
- const totalMs = Number(totalTime) / 1_000_000;
474
- statsLog('Total execution time: %.2fms', totalMs);
473
+ log(`Aggregate metrics: ${totalExecutions} executions, ${totalElapsed / 1000n}μs elapsed, ${totalIn} inputs, ${totalOut} outputs`);
474
+ }
475
475
  }
476
476
 
477
477
  /**
478
478
  * Get runtime statistics for all instructions
479
479
  */
480
480
  getMetrics(): InstructionRuntimeStats[] {
481
- return this.instructions.map(instr => instr.runtimeStats || {
481
+ return this.instructions.map(instruction => instruction.runtimeStats || {
482
482
  in: 0,
483
483
  out: 0,
484
484
  elapsedNs: 0n,
@@ -5,6 +5,7 @@ import type { RowDescriptor, RowGetter, TableDescriptor, TableGetter } from "../
5
5
  import type { Scheduler } from "./scheduler.js";
6
6
  import type { EmissionContext } from "./emission-context.js";
7
7
  import type { VirtualTableConnection } from "../vtab/connection.js";
8
+ import type { PlanNode } from '../planner/nodes/plan-node.js';
8
9
 
9
10
  export type RuntimeContext = {
10
11
  db: Database;
@@ -20,6 +21,10 @@ export type RuntimeContext = {
20
21
  activeConnection?: VirtualTableConnection;
21
22
  /** Whether to collect runtime execution metrics */
22
23
  enableMetrics: boolean;
24
+ /** Context tracking for debugging context leaks */
25
+ contextTracker?: ContextTracker;
26
+ /** Stack of currently executing plan nodes (only when tracing enabled) */
27
+ planStack?: PlanNode[];
23
28
  };
24
29
 
25
30
  export type InstructionRun = (ctx: RuntimeContext, ...args: any[]) => OutputValue;
@@ -189,3 +194,43 @@ export class CollectingInstructionTracer implements InstructionTracer {
189
194
  return value;
190
195
  }
191
196
  }
197
+
198
+ /**
199
+ * Tracks context additions and removals for debugging context leaks
200
+ */
201
+ export interface ContextTracker {
202
+ /** Record that a context was added */
203
+ addContext(descriptor: RowDescriptor, source: string): void;
204
+ /** Record that a context was removed */
205
+ removeContext(descriptor: RowDescriptor): void;
206
+ /** Get all remaining contexts with their sources */
207
+ getRemainingContexts(): Array<{ descriptor: RowDescriptor; source: string }>;
208
+ /** Check if there are any remaining contexts */
209
+ hasRemainingContexts(): boolean;
210
+ }
211
+
212
+ /**
213
+ * Default implementation of ContextTracker
214
+ */
215
+ export class DefaultContextTracker implements ContextTracker {
216
+ private contexts = new Map<RowDescriptor, string>();
217
+
218
+ addContext(descriptor: RowDescriptor, source: string): void {
219
+ this.contexts.set(descriptor, source);
220
+ }
221
+
222
+ removeContext(descriptor: RowDescriptor): void {
223
+ this.contexts.delete(descriptor);
224
+ }
225
+
226
+ getRemainingContexts(): Array<{ descriptor: RowDescriptor; source: string }> {
227
+ return Array.from(this.contexts.entries()).map(([descriptor, source]) => ({
228
+ descriptor,
229
+ source
230
+ }));
231
+ }
232
+
233
+ hasRemainingContexts(): boolean {
234
+ return this.contexts.size > 0;
235
+ }
236
+ }