@quereus/quereus 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. package/README.md +47 -23
  2. package/dist/src/core/database.d.ts +22 -4
  3. package/dist/src/core/database.d.ts.map +1 -1
  4. package/dist/src/core/database.js +44 -6
  5. package/dist/src/core/database.js.map +1 -1
  6. package/dist/src/core/statement.d.ts +0 -7
  7. package/dist/src/core/statement.d.ts.map +1 -1
  8. package/dist/src/core/statement.js +1 -51
  9. package/dist/src/core/statement.js.map +1 -1
  10. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  11. package/dist/src/func/builtins/explain.js +0 -11
  12. package/dist/src/func/builtins/explain.js.map +1 -1
  13. package/dist/src/index.d.ts +13 -5
  14. package/dist/src/index.d.ts.map +1 -1
  15. package/dist/src/index.js +5 -2
  16. package/dist/src/index.js.map +1 -1
  17. package/dist/src/parser/ast.d.ts +9 -2
  18. package/dist/src/parser/ast.d.ts.map +1 -1
  19. package/dist/src/parser/parser.d.ts.map +1 -1
  20. package/dist/src/parser/parser.js +40 -44
  21. package/dist/src/parser/parser.js.map +1 -1
  22. package/dist/src/planner/analysis/const-pass.d.ts.map +1 -1
  23. package/dist/src/planner/analysis/const-pass.js +12 -6
  24. package/dist/src/planner/analysis/const-pass.js.map +1 -1
  25. package/dist/src/planner/building/constraint-builder.d.ts +11 -0
  26. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -0
  27. package/dist/src/planner/building/constraint-builder.js +79 -0
  28. package/dist/src/planner/building/constraint-builder.js.map +1 -0
  29. package/dist/src/planner/building/delete.d.ts.map +1 -1
  30. package/dist/src/planner/building/delete.js +6 -3
  31. package/dist/src/planner/building/delete.js.map +1 -1
  32. package/dist/src/planner/building/expression.d.ts +3 -0
  33. package/dist/src/planner/building/expression.d.ts.map +1 -1
  34. package/dist/src/planner/building/expression.js +33 -7
  35. package/dist/src/planner/building/expression.js.map +1 -1
  36. package/dist/src/planner/building/insert.d.ts.map +1 -1
  37. package/dist/src/planner/building/insert.js +4 -1
  38. package/dist/src/planner/building/insert.js.map +1 -1
  39. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  40. package/dist/src/planner/building/select-aggregates.js +46 -9
  41. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  42. package/dist/src/planner/building/select-context.js +20 -11
  43. package/dist/src/planner/building/select-context.js.map +1 -1
  44. package/dist/src/planner/building/select-modifiers.d.ts +5 -3
  45. package/dist/src/planner/building/select-modifiers.d.ts.map +1 -1
  46. package/dist/src/planner/building/select-modifiers.js +29 -20
  47. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  48. package/dist/src/planner/building/select-projections.d.ts +3 -1
  49. package/dist/src/planner/building/select-projections.d.ts.map +1 -1
  50. package/dist/src/planner/building/select-projections.js +15 -20
  51. package/dist/src/planner/building/select-projections.js.map +1 -1
  52. package/dist/src/planner/building/select-window.d.ts.map +1 -1
  53. package/dist/src/planner/building/select-window.js +6 -3
  54. package/dist/src/planner/building/select-window.js.map +1 -1
  55. package/dist/src/planner/building/select.d.ts +25 -2
  56. package/dist/src/planner/building/select.d.ts.map +1 -1
  57. package/dist/src/planner/building/select.js +147 -24
  58. package/dist/src/planner/building/select.js.map +1 -1
  59. package/dist/src/planner/building/table.d.ts +0 -10
  60. package/dist/src/planner/building/table.d.ts.map +1 -1
  61. package/dist/src/planner/building/table.js +1 -35
  62. package/dist/src/planner/building/table.js.map +1 -1
  63. package/dist/src/planner/building/update.d.ts.map +1 -1
  64. package/dist/src/planner/building/update.js +7 -4
  65. package/dist/src/planner/building/update.js.map +1 -1
  66. package/dist/src/planner/building/with.d.ts.map +1 -1
  67. package/dist/src/planner/building/with.js +7 -8
  68. package/dist/src/planner/building/with.js.map +1 -1
  69. package/dist/src/planner/cache/correlation-detector.d.ts +11 -0
  70. package/dist/src/planner/cache/correlation-detector.d.ts.map +1 -0
  71. package/dist/src/planner/cache/correlation-detector.js +73 -0
  72. package/dist/src/planner/cache/correlation-detector.js.map +1 -0
  73. package/dist/src/planner/cache/materialization-advisory.d.ts +12 -18
  74. package/dist/src/planner/cache/materialization-advisory.d.ts.map +1 -1
  75. package/dist/src/planner/cache/materialization-advisory.js +65 -46
  76. package/dist/src/planner/cache/materialization-advisory.js.map +1 -1
  77. package/dist/src/planner/cache/reference-graph.d.ts +14 -9
  78. package/dist/src/planner/cache/reference-graph.d.ts.map +1 -1
  79. package/dist/src/planner/cache/reference-graph.js +93 -84
  80. package/dist/src/planner/cache/reference-graph.js.map +1 -1
  81. package/dist/src/planner/debug.d.ts +25 -0
  82. package/dist/src/planner/debug.d.ts.map +1 -1
  83. package/dist/src/planner/debug.js +127 -0
  84. package/dist/src/planner/debug.js.map +1 -1
  85. package/dist/src/planner/framework/context.d.ts +11 -0
  86. package/dist/src/planner/framework/context.d.ts.map +1 -1
  87. package/dist/src/planner/framework/context.js +25 -2
  88. package/dist/src/planner/framework/context.js.map +1 -1
  89. package/dist/src/planner/framework/registry.d.ts +3 -7
  90. package/dist/src/planner/framework/registry.d.ts.map +1 -1
  91. package/dist/src/planner/framework/registry.js +20 -31
  92. package/dist/src/planner/framework/registry.js.map +1 -1
  93. package/dist/src/planner/nodes/add-constraint-node.d.ts +2 -1
  94. package/dist/src/planner/nodes/add-constraint-node.d.ts.map +1 -1
  95. package/dist/src/planner/nodes/add-constraint-node.js +3 -0
  96. package/dist/src/planner/nodes/add-constraint-node.js.map +1 -1
  97. package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
  98. package/dist/src/planner/nodes/aggregate-node.js +6 -4
  99. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  100. package/dist/src/planner/nodes/cache-node.d.ts.map +1 -1
  101. package/dist/src/planner/nodes/cache-node.js +2 -2
  102. package/dist/src/planner/nodes/cache-node.js.map +1 -1
  103. package/dist/src/planner/nodes/constraint-check-node.d.ts +11 -4
  104. package/dist/src/planner/nodes/constraint-check-node.d.ts.map +1 -1
  105. package/dist/src/planner/nodes/constraint-check-node.js +38 -12
  106. package/dist/src/planner/nodes/constraint-check-node.js.map +1 -1
  107. package/dist/src/planner/nodes/create-index-node.d.ts +2 -1
  108. package/dist/src/planner/nodes/create-index-node.d.ts.map +1 -1
  109. package/dist/src/planner/nodes/create-index-node.js +3 -0
  110. package/dist/src/planner/nodes/create-index-node.js.map +1 -1
  111. package/dist/src/planner/nodes/create-table-node.d.ts +2 -1
  112. package/dist/src/planner/nodes/create-table-node.d.ts.map +1 -1
  113. package/dist/src/planner/nodes/create-table-node.js +3 -0
  114. package/dist/src/planner/nodes/create-table-node.js.map +1 -1
  115. package/dist/src/planner/nodes/create-view-node.d.ts +2 -1
  116. package/dist/src/planner/nodes/create-view-node.d.ts.map +1 -1
  117. package/dist/src/planner/nodes/create-view-node.js +3 -0
  118. package/dist/src/planner/nodes/create-view-node.js.map +1 -1
  119. package/dist/src/planner/nodes/cte-node.d.ts +1 -1
  120. package/dist/src/planner/nodes/cte-node.d.ts.map +1 -1
  121. package/dist/src/planner/nodes/cte-node.js +33 -12
  122. package/dist/src/planner/nodes/cte-node.js.map +1 -1
  123. package/dist/src/planner/nodes/cte-reference-node.d.ts +18 -4
  124. package/dist/src/planner/nodes/cte-reference-node.d.ts.map +1 -1
  125. package/dist/src/planner/nodes/cte-reference-node.js +40 -10
  126. package/dist/src/planner/nodes/cte-reference-node.js.map +1 -1
  127. package/dist/src/planner/nodes/delete-node.d.ts +4 -3
  128. package/dist/src/planner/nodes/delete-node.d.ts.map +1 -1
  129. package/dist/src/planner/nodes/delete-node.js +20 -6
  130. package/dist/src/planner/nodes/delete-node.js.map +1 -1
  131. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
  132. package/dist/src/planner/nodes/distinct-node.js +2 -2
  133. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  134. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  135. package/dist/src/planner/nodes/dml-executor-node.js +2 -2
  136. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  137. package/dist/src/planner/nodes/drop-table-node.d.ts +2 -1
  138. package/dist/src/planner/nodes/drop-table-node.d.ts.map +1 -1
  139. package/dist/src/planner/nodes/drop-table-node.js +3 -0
  140. package/dist/src/planner/nodes/drop-table-node.js.map +1 -1
  141. package/dist/src/planner/nodes/drop-view-node.d.ts +2 -1
  142. package/dist/src/planner/nodes/drop-view-node.d.ts.map +1 -1
  143. package/dist/src/planner/nodes/drop-view-node.js +3 -0
  144. package/dist/src/planner/nodes/drop-view-node.js.map +1 -1
  145. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  146. package/dist/src/planner/nodes/filter.js +3 -3
  147. package/dist/src/planner/nodes/filter.js.map +1 -1
  148. package/dist/src/planner/nodes/insert-node.d.ts +2 -1
  149. package/dist/src/planner/nodes/insert-node.d.ts.map +1 -1
  150. package/dist/src/planner/nodes/insert-node.js +18 -5
  151. package/dist/src/planner/nodes/insert-node.js.map +1 -1
  152. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts +28 -0
  153. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts.map +1 -0
  154. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js +69 -0
  155. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js.map +1 -0
  156. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  157. package/dist/src/planner/nodes/join-node.js +3 -3
  158. package/dist/src/planner/nodes/join-node.js.map +1 -1
  159. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  160. package/dist/src/planner/nodes/limit-offset.js +2 -2
  161. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  162. package/dist/src/planner/nodes/plan-node-type.d.ts +1 -1
  163. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  164. package/dist/src/planner/nodes/plan-node-type.js +1 -1
  165. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  166. package/dist/src/planner/nodes/plan-node.d.ts +23 -0
  167. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  168. package/dist/src/planner/nodes/plan-node.js +25 -2
  169. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  170. package/dist/src/planner/nodes/project-node.d.ts +5 -1
  171. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  172. package/dist/src/planner/nodes/project-node.js +39 -20
  173. package/dist/src/planner/nodes/project-node.js.map +1 -1
  174. package/dist/src/planner/nodes/recursive-cte-node.d.ts +2 -2
  175. package/dist/src/planner/nodes/recursive-cte-node.d.ts.map +1 -1
  176. package/dist/src/planner/nodes/recursive-cte-node.js +20 -8
  177. package/dist/src/planner/nodes/recursive-cte-node.js.map +1 -1
  178. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  179. package/dist/src/planner/nodes/reference.js +4 -2
  180. package/dist/src/planner/nodes/reference.js.map +1 -1
  181. package/dist/src/planner/nodes/returning-node.d.ts +1 -1
  182. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  183. package/dist/src/planner/nodes/returning-node.js +21 -13
  184. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  185. package/dist/src/planner/nodes/scalar.d.ts +26 -2
  186. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  187. package/dist/src/planner/nodes/scalar.js +82 -10
  188. package/dist/src/planner/nodes/scalar.js.map +1 -1
  189. package/dist/src/planner/nodes/sequencing-node.d.ts.map +1 -1
  190. package/dist/src/planner/nodes/sequencing-node.js +2 -2
  191. package/dist/src/planner/nodes/sequencing-node.js.map +1 -1
  192. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  193. package/dist/src/planner/nodes/set-operation-node.js +3 -3
  194. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  195. package/dist/src/planner/nodes/single-row.d.ts +4 -2
  196. package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
  197. package/dist/src/planner/nodes/single-row.js +3 -0
  198. package/dist/src/planner/nodes/single-row.js.map +1 -1
  199. package/dist/src/planner/nodes/sink-node.d.ts +1 -1
  200. package/dist/src/planner/nodes/sink-node.d.ts.map +1 -1
  201. package/dist/src/planner/nodes/sink-node.js +4 -4
  202. package/dist/src/planner/nodes/sink-node.js.map +1 -1
  203. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  204. package/dist/src/planner/nodes/sort.js +2 -2
  205. package/dist/src/planner/nodes/sort.js.map +1 -1
  206. package/dist/src/planner/nodes/stream-aggregate.d.ts +1 -0
  207. package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
  208. package/dist/src/planner/nodes/stream-aggregate.js +64 -11
  209. package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
  210. package/dist/src/planner/nodes/subquery.d.ts +4 -4
  211. package/dist/src/planner/nodes/subquery.d.ts.map +1 -1
  212. package/dist/src/planner/nodes/subquery.js +68 -23
  213. package/dist/src/planner/nodes/subquery.js.map +1 -1
  214. package/dist/src/planner/nodes/table-access-nodes.d.ts +83 -0
  215. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -0
  216. package/dist/src/planner/nodes/table-access-nodes.js +226 -0
  217. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -0
  218. package/dist/src/planner/nodes/update-node.d.ts +4 -2
  219. package/dist/src/planner/nodes/update-node.d.ts.map +1 -1
  220. package/dist/src/planner/nodes/update-node.js +26 -13
  221. package/dist/src/planner/nodes/update-node.js.map +1 -1
  222. package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
  223. package/dist/src/planner/nodes/window-node.js +25 -23
  224. package/dist/src/planner/nodes/window-node.js.map +1 -1
  225. package/dist/src/planner/optimizer.d.ts.map +1 -1
  226. package/dist/src/planner/optimizer.js +46 -50
  227. package/dist/src/planner/optimizer.js.map +1 -1
  228. package/dist/src/planner/planning-context.d.ts +13 -0
  229. package/dist/src/planner/planning-context.d.ts.map +1 -1
  230. package/dist/src/planner/planning-context.js.map +1 -1
  231. package/dist/src/planner/rules/access/rule-select-access-path.d.ts +1 -1
  232. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  233. package/dist/src/planner/rules/access/rule-select-access-path.js +59 -53
  234. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  235. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -1
  236. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +62 -2
  237. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
  238. package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts.map +1 -1
  239. package/dist/src/planner/rules/cache/rule-materialization-advisory.js +31 -24
  240. package/dist/src/planner/rules/cache/rule-materialization-advisory.js.map +1 -1
  241. package/dist/src/planner/scopes/base.d.ts +0 -10
  242. package/dist/src/planner/scopes/base.d.ts.map +1 -1
  243. package/dist/src/planner/scopes/base.js +0 -14
  244. package/dist/src/planner/scopes/base.js.map +1 -1
  245. package/dist/src/planner/scopes/empty.d.ts +0 -2
  246. package/dist/src/planner/scopes/empty.d.ts.map +1 -1
  247. package/dist/src/planner/scopes/empty.js +0 -8
  248. package/dist/src/planner/scopes/empty.js.map +1 -1
  249. package/dist/src/planner/scopes/multi.d.ts.map +1 -1
  250. package/dist/src/planner/scopes/multi.js +0 -1
  251. package/dist/src/planner/scopes/multi.js.map +1 -1
  252. package/dist/src/planner/scopes/param.d.ts.map +1 -1
  253. package/dist/src/planner/scopes/param.js +0 -1
  254. package/dist/src/planner/scopes/param.js.map +1 -1
  255. package/dist/src/planner/scopes/registered.d.ts +0 -10
  256. package/dist/src/planner/scopes/registered.d.ts.map +1 -1
  257. package/dist/src/planner/scopes/registered.js +1 -17
  258. package/dist/src/planner/scopes/registered.js.map +1 -1
  259. package/dist/src/planner/scopes/scope.d.ts +0 -8
  260. package/dist/src/planner/scopes/scope.d.ts.map +1 -1
  261. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  262. package/dist/src/planner/validation/plan-validator.js +1 -7
  263. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  264. package/dist/src/runtime/context-helpers.d.ts +45 -0
  265. package/dist/src/runtime/context-helpers.d.ts.map +1 -0
  266. package/dist/src/runtime/context-helpers.js +139 -0
  267. package/dist/src/runtime/context-helpers.js.map +1 -0
  268. package/dist/src/runtime/emission-context.d.ts +1 -0
  269. package/dist/src/runtime/emission-context.d.ts.map +1 -1
  270. package/dist/src/runtime/emission-context.js +2 -1
  271. package/dist/src/runtime/emission-context.js.map +1 -1
  272. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  273. package/dist/src/runtime/emit/aggregate.js +119 -86
  274. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  275. package/dist/src/runtime/emit/between.d.ts +5 -0
  276. package/dist/src/runtime/emit/between.d.ts.map +1 -0
  277. package/dist/src/runtime/emit/between.js +38 -0
  278. package/dist/src/runtime/emit/between.js.map +1 -0
  279. package/dist/src/runtime/emit/binary.d.ts +0 -1
  280. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  281. package/dist/src/runtime/emit/binary.js +0 -36
  282. package/dist/src/runtime/emit/binary.js.map +1 -1
  283. package/dist/src/runtime/emit/column-reference.d.ts.map +1 -1
  284. package/dist/src/runtime/emit/column-reference.js +2 -26
  285. package/dist/src/runtime/emit/column-reference.js.map +1 -1
  286. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  287. package/dist/src/runtime/emit/constraint-check.js +14 -121
  288. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  289. package/dist/src/runtime/emit/cte-reference.d.ts.map +1 -1
  290. package/dist/src/runtime/emit/cte-reference.js +16 -48
  291. package/dist/src/runtime/emit/cte-reference.js.map +1 -1
  292. package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
  293. package/dist/src/runtime/emit/distinct.js +2 -8
  294. package/dist/src/runtime/emit/distinct.js.map +1 -1
  295. package/dist/src/runtime/emit/filter.d.ts.map +1 -1
  296. package/dist/src/runtime/emit/filter.js +6 -13
  297. package/dist/src/runtime/emit/filter.js.map +1 -1
  298. package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts +5 -0
  299. package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts.map +1 -0
  300. package/dist/src/runtime/emit/internal-recursive-cte-ref.js +23 -0
  301. package/dist/src/runtime/emit/internal-recursive-cte-ref.js.map +1 -0
  302. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  303. package/dist/src/runtime/emit/join.js +40 -40
  304. package/dist/src/runtime/emit/join.js.map +1 -1
  305. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  306. package/dist/src/runtime/emit/project.js +13 -13
  307. package/dist/src/runtime/emit/project.js.map +1 -1
  308. package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -1
  309. package/dist/src/runtime/emit/recursive-cte.js +3 -14
  310. package/dist/src/runtime/emit/recursive-cte.js.map +1 -1
  311. package/dist/src/runtime/emit/returning.d.ts.map +1 -1
  312. package/dist/src/runtime/emit/returning.js +7 -14
  313. package/dist/src/runtime/emit/returning.js.map +1 -1
  314. package/dist/src/runtime/emit/scan.d.ts +5 -2
  315. package/dist/src/runtime/emit/scan.d.ts.map +1 -1
  316. package/dist/src/runtime/emit/scan.js +21 -17
  317. package/dist/src/runtime/emit/scan.js.map +1 -1
  318. package/dist/src/runtime/emit/sort.d.ts.map +1 -1
  319. package/dist/src/runtime/emit/sort.js +8 -11
  320. package/dist/src/runtime/emit/sort.js.map +1 -1
  321. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  322. package/dist/src/runtime/emit/subquery.js +95 -40
  323. package/dist/src/runtime/emit/subquery.js.map +1 -1
  324. package/dist/src/runtime/emit/table-valued-function.d.ts.map +1 -1
  325. package/dist/src/runtime/emit/table-valued-function.js +7 -22
  326. package/dist/src/runtime/emit/table-valued-function.js.map +1 -1
  327. package/dist/src/runtime/emit/update.d.ts.map +1 -1
  328. package/dist/src/runtime/emit/update.js +20 -27
  329. package/dist/src/runtime/emit/update.js.map +1 -1
  330. package/dist/src/runtime/emit/window.d.ts.map +1 -1
  331. package/dist/src/runtime/emit/window.js +55 -83
  332. package/dist/src/runtime/emit/window.js.map +1 -1
  333. package/dist/src/runtime/emitters.d.ts.map +1 -1
  334. package/dist/src/runtime/emitters.js +49 -1
  335. package/dist/src/runtime/emitters.js.map +1 -1
  336. package/dist/src/runtime/register.d.ts.map +1 -1
  337. package/dist/src/runtime/register.js +5 -4
  338. package/dist/src/runtime/register.js.map +1 -1
  339. package/dist/src/runtime/scheduler.d.ts.map +1 -1
  340. package/dist/src/runtime/scheduler.js +47 -42
  341. package/dist/src/runtime/scheduler.js.map +1 -1
  342. package/dist/src/runtime/types.d.ts +34 -0
  343. package/dist/src/runtime/types.d.ts.map +1 -1
  344. package/dist/src/runtime/types.js +21 -0
  345. package/dist/src/runtime/types.js.map +1 -1
  346. package/dist/src/schema/manager.d.ts.map +1 -1
  347. package/dist/src/schema/manager.js +29 -16
  348. package/dist/src/schema/manager.js.map +1 -1
  349. package/dist/src/util/plugin-loader.d.ts +10 -1
  350. package/dist/src/util/plugin-loader.d.ts.map +1 -1
  351. package/dist/src/util/plugin-loader.js +56 -1
  352. package/dist/src/util/plugin-loader.js.map +1 -1
  353. package/dist/src/util/working-table-iterable.d.ts.map +1 -1
  354. package/dist/src/util/working-table-iterable.js +8 -8
  355. package/dist/src/util/working-table-iterable.js.map +1 -1
  356. package/dist/src/vtab/manifest.d.ts +36 -0
  357. package/dist/src/vtab/manifest.d.ts.map +1 -1
  358. package/package.json +8 -3
  359. package/src/core/database.ts +48 -6
  360. package/src/core/statement.ts +1 -49
  361. package/src/func/builtins/explain.ts +0 -11
  362. package/src/index.ts +39 -5
  363. package/src/parser/ast.ts +11 -2
  364. package/src/parser/parser.ts +40 -47
  365. package/src/planner/analysis/const-pass.ts +281 -270
  366. package/src/planner/building/constraint-builder.ts +114 -0
  367. package/src/planner/building/delete.ts +16 -3
  368. package/src/planner/building/expression.ts +35 -7
  369. package/src/planner/building/insert.ts +14 -1
  370. package/src/planner/building/select-aggregates.ts +57 -11
  371. package/src/planner/building/select-context.ts +22 -12
  372. package/src/planner/building/select-modifiers.ts +35 -21
  373. package/src/planner/building/select-projections.ts +25 -26
  374. package/src/planner/building/select-window.ts +14 -9
  375. package/src/planner/building/select.ts +163 -31
  376. package/src/planner/building/table.ts +1 -40
  377. package/src/planner/building/update.ts +19 -4
  378. package/src/planner/building/with.ts +12 -13
  379. package/src/planner/cache/correlation-detector.ts +83 -0
  380. package/src/planner/cache/materialization-advisory.ts +71 -50
  381. package/src/planner/cache/reference-graph.ts +115 -91
  382. package/src/planner/debug.ts +163 -0
  383. package/src/planner/framework/context.ts +36 -2
  384. package/src/planner/framework/registry.ts +261 -274
  385. package/src/planner/nodes/add-constraint-node.ts +5 -1
  386. package/src/planner/nodes/aggregate-node.ts +6 -4
  387. package/src/planner/nodes/cache-node.ts +2 -2
  388. package/src/planner/nodes/constraint-check-node.ts +47 -13
  389. package/src/planner/nodes/create-index-node.ts +5 -1
  390. package/src/planner/nodes/create-table-node.ts +5 -1
  391. package/src/planner/nodes/create-view-node.ts +5 -1
  392. package/src/planner/nodes/cte-node.ts +45 -14
  393. package/src/planner/nodes/cte-reference-node.ts +49 -13
  394. package/src/planner/nodes/delete-node.ts +31 -7
  395. package/src/planner/nodes/distinct-node.ts +2 -2
  396. package/src/planner/nodes/dml-executor-node.ts +2 -2
  397. package/src/planner/nodes/drop-table-node.ts +5 -1
  398. package/src/planner/nodes/drop-view-node.ts +5 -1
  399. package/src/planner/nodes/filter.ts +3 -3
  400. package/src/planner/nodes/function.ts +93 -93
  401. package/src/planner/nodes/insert-node.ts +28 -5
  402. package/src/planner/nodes/internal-recursive-cte-ref-node.ts +76 -0
  403. package/src/planner/nodes/join-node.ts +3 -3
  404. package/src/planner/nodes/limit-offset.ts +2 -2
  405. package/src/planner/nodes/plan-node-type.ts +1 -1
  406. package/src/planner/nodes/plan-node.ts +39 -2
  407. package/src/planner/nodes/project-node.ts +39 -19
  408. package/src/planner/nodes/recursive-cte-node.ts +37 -9
  409. package/src/planner/nodes/reference.ts +4 -2
  410. package/src/planner/nodes/returning-node.ts +25 -13
  411. package/src/planner/nodes/scalar.ts +95 -11
  412. package/src/planner/nodes/sequencing-node.ts +2 -2
  413. package/src/planner/nodes/set-operation-node.ts +3 -3
  414. package/src/planner/nodes/single-row.ts +7 -2
  415. package/src/planner/nodes/sink-node.ts +5 -5
  416. package/src/planner/nodes/sort.ts +2 -2
  417. package/src/planner/nodes/stream-aggregate.ts +76 -12
  418. package/src/planner/nodes/subquery.ts +90 -27
  419. package/src/planner/nodes/{physical-access-nodes.ts → table-access-nodes.ts} +6 -6
  420. package/src/planner/nodes/update-node.ts +31 -13
  421. package/src/planner/nodes/window-node.ts +28 -22
  422. package/src/planner/optimizer.ts +257 -263
  423. package/src/planner/planning-context.ts +15 -0
  424. package/src/planner/rules/access/rule-select-access-path.ts +68 -64
  425. package/src/planner/rules/aggregate/rule-aggregate-streaming.ts +74 -2
  426. package/src/planner/rules/cache/rule-materialization-advisory.ts +31 -27
  427. package/src/planner/scopes/base.ts +0 -17
  428. package/src/planner/scopes/empty.ts +0 -10
  429. package/src/planner/scopes/multi.ts +0 -1
  430. package/src/planner/scopes/param.ts +0 -1
  431. package/src/planner/scopes/registered.ts +1 -20
  432. package/src/planner/scopes/scope.ts +0 -12
  433. package/src/planner/validation/plan-validator.ts +1 -8
  434. package/src/runtime/context-helpers.ts +191 -0
  435. package/src/runtime/emission-context.ts +5 -2
  436. package/src/runtime/emit/aggregate.ts +131 -85
  437. package/src/runtime/emit/between.ts +51 -0
  438. package/src/runtime/emit/binary.ts +0 -46
  439. package/src/runtime/emit/column-reference.ts +3 -36
  440. package/src/runtime/emit/constraint-check.ts +17 -142
  441. package/src/runtime/emit/cte-reference.ts +23 -60
  442. package/src/runtime/emit/distinct.ts +2 -7
  443. package/src/runtime/emit/filter.ts +6 -13
  444. package/src/runtime/emit/internal-recursive-cte-ref.ts +37 -0
  445. package/src/runtime/emit/join.ts +45 -43
  446. package/src/runtime/emit/project.ts +18 -12
  447. package/src/runtime/emit/recursive-cte.ts +3 -12
  448. package/src/runtime/emit/returning.ts +7 -14
  449. package/src/runtime/emit/scan.ts +25 -23
  450. package/src/runtime/emit/sort.ts +8 -11
  451. package/src/runtime/emit/subquery.ts +108 -48
  452. package/src/runtime/emit/table-valued-function.ts +7 -20
  453. package/src/runtime/emit/update.ts +22 -29
  454. package/src/runtime/emit/window.ts +74 -88
  455. package/src/runtime/emitters.ts +52 -1
  456. package/src/runtime/register.ts +5 -4
  457. package/src/runtime/scheduler.ts +54 -54
  458. package/src/runtime/types.ts +45 -0
  459. package/src/schema/manager.ts +34 -19
  460. package/src/util/plugin-loader.ts +78 -4
  461. package/src/util/working-table-iterable.ts +15 -7
  462. package/src/vtab/manifest.ts +42 -0
  463. package/src/planner/nodes/scan.ts +0 -103
  464. package/src/planner/rules/physical/rule-mark-physical.ts +0 -37
  465. package/src/runtime/emit/table-reference.ts +0 -92
@@ -32,8 +32,6 @@ export function emitBinaryOp(plan: BinaryOpNode, ctx: EmissionContext): Instruct
32
32
  case 'OR':
33
33
  case 'XOR':
34
34
  return emitLogicalOp(plan, ctx);
35
- case 'BETWEEN':
36
- return emitBetweenOp(plan, ctx);
37
35
  case 'LIKE':
38
36
  return emitLikeOp(plan, ctx);
39
37
  // TODO: emitBitwise
@@ -289,47 +287,3 @@ export function emitLikeOp(plan: BinaryOpNode, ctx: EmissionContext): Instructio
289
287
  };
290
288
  }
291
289
 
292
- export function emitBetweenOp(plan: BinaryOpNode, ctx: EmissionContext): Instruction {
293
- // Pre-resolve collation function for optimal performance (using BINARY as default for BETWEEN)
294
- const collationFunc = resolveCollation('BINARY');
295
-
296
- function run(ctx: RuntimeContext, value: SqlValue, lowerBound: SqlValue, upperBound: SqlValue): SqlValue {
297
- // SQL BETWEEN logic: value BETWEEN lower AND upper
298
- // Equivalent to: value >= lower AND value <= upper
299
- // NULL handling: if any operand is NULL, result is NULL
300
- if (value === null || lowerBound === null || upperBound === null) {
301
- return null;
302
- }
303
-
304
- // Use pre-resolved collation function for optimal performance
305
- const lowerResult = compareSqlValuesFast(value, lowerBound, collationFunc);
306
- const upperResult = compareSqlValuesFast(value, upperBound, collationFunc);
307
-
308
- // value >= lowerBound AND value <= upperBound
309
- return (lowerResult >= 0 && upperResult <= 0) ? 1 : 0;
310
- }
311
-
312
- const valueExpr = emitPlanNode(plan.left, ctx);
313
-
314
- // The right side should be an AND expression with lower and upper bounds
315
- const rightNode = plan.right;
316
- if (rightNode.nodeType !== 'BinaryOp') {
317
- throw new QuereusError(`Expected binary AND expression for BETWEEN bounds`, StatusCode.INTERNAL);
318
- }
319
- const rightBinaryNode = rightNode as BinaryOpNode;
320
- if (rightBinaryNode.expression.operator !== 'AND') {
321
- throw new QuereusError(`Expected AND operator for BETWEEN bounds, got ${rightBinaryNode.expression.operator}`, StatusCode.INTERNAL);
322
- }
323
-
324
- const lowerExpr = emitPlanNode(rightBinaryNode.left, ctx);
325
- const upperExpr = emitPlanNode(rightBinaryNode.right, ctx);
326
-
327
- return {
328
- params: [valueExpr, lowerExpr, upperExpr],
329
- run: run as InstructionRun,
330
- note: 'BETWEEN(between)'
331
- };
332
- }
333
-
334
-
335
-
@@ -1,45 +1,12 @@
1
1
  import type { ColumnReferenceNode } from '../../planner/nodes/reference.js';
2
2
  import type { Instruction, RuntimeContext } from '../types.js';
3
- import { QuereusError } from '../../common/errors.js';
4
- import { StatusCode, type SqlValue } from '../../common/types.js';
3
+ import type { SqlValue } from '../../common/types.js';
5
4
  import type { EmissionContext } from '../emission-context.js';
6
- import { createLogger } from '../../common/logger.js';
7
-
8
- const log = createLogger('runtime:context:lookup');
5
+ import { resolveAttribute } from '../context-helpers.js';
9
6
 
10
7
  export function emitColumnReference(plan: ColumnReferenceNode, _ctx: EmissionContext): Instruction {
11
8
  function run(rctx: RuntimeContext): SqlValue {
12
- log('Looking up column %s (attr#%d)', plan.expression.name, plan.attributeId);
13
-
14
- // Log available contexts for debugging
15
- const availableContexts: string[] = [];
16
- for (const [descriptor] of rctx.context.entries()) {
17
- const attrs = Object.keys(descriptor).filter(k => descriptor[parseInt(k)] !== undefined);
18
- availableContexts.push(`[attrs: ${attrs.join(',')}]`);
19
- }
20
- log('Available contexts: %O', availableContexts);
21
-
22
- // Use deterministic lookup based on attribute ID
23
- for (const [descriptor, rowGetter] of rctx.context.entries()) {
24
- const columnIndex = descriptor[plan.attributeId];
25
- if (columnIndex !== undefined) {
26
- const row = rowGetter();
27
- if (Array.isArray(row) && columnIndex < row.length) {
28
- const value = row[columnIndex];
29
- log('Successfully resolved %s (attr#%d) to value: %O from row: %O at index %d', plan.expression.name, plan.attributeId, value, row, columnIndex);
30
- return value;
31
- }
32
- }
33
- }
34
-
35
- log('Failed to resolve %s (attr#%d) - no matching context found', plan.expression.name, plan.attributeId);
36
- throw new QuereusError(
37
- `No row context found for column ${plan.expression.name} (attr#${plan.attributeId}). The column reference must be evaluated within the context of its source relation.`,
38
- StatusCode.ERROR,
39
- undefined,
40
- plan.expression.loc?.start.line,
41
- plan.expression.loc?.start.column
42
- );
9
+ return resolveAttribute(rctx, plan.attributeId, plan.expression.name);
43
10
  }
44
11
 
45
12
  return {
@@ -6,137 +6,23 @@ import { emitPlanNode, emitCallFromPlan } from '../emitters.js';
6
6
  import { QuereusError } from '../../common/errors.js';
7
7
  import { StatusCode, type SqlValue, type OutputValue } from '../../common/types.js';
8
8
  import type { RowConstraintSchema, TableSchema } from '../../schema/table.js';
9
- import type { ColumnSchema } from '../../schema/column.js';
10
- import type { RowDescriptor } from '../../planner/nodes/plan-node.js';
11
9
  import { RowOp } from '../../schema/table.js';
12
- import { buildExpression } from '../../planner/building/expression.js';
13
- import { GlobalScope } from '../../planner/scopes/global.js';
14
- import { RegisteredScope } from '../../planner/scopes/registered.js';
15
- import { ColumnReferenceNode } from '../../planner/nodes/reference.js';
16
- import * as AST from '../../parser/ast.js';
17
- import { BuildTimeDependencyTracker } from '../../planner/planning-context.js';
10
+ import { withAsyncRowContext } from '../context-helpers.js';
18
11
 
19
12
  export function emitConstraintCheck(plan: ConstraintCheckNode, ctx: EmissionContext): Instruction {
20
13
  // Get the table schema to access constraints
21
14
  const tableSchema = plan.table.tableSchema;
22
15
 
23
- // Create flat row descriptor that includes both OLD and NEW attributes
24
- const flatRowDescriptor: RowDescriptor = [];
16
+ // Use the pre-built flat row descriptor from the plan
17
+ const flatRowDescriptor = plan.flatRowDescriptor;
25
18
 
26
- // OLD attributes are at indices 0..n-1, NEW attributes at n..2n-1
27
- if (plan.oldRowDescriptor) {
28
- for (const attrIdStr in plan.oldRowDescriptor) {
29
- const attrId = parseInt(attrIdStr);
30
- const columnIndex = plan.oldRowDescriptor[attrId];
31
- if (columnIndex !== undefined) {
32
- flatRowDescriptor[attrId] = columnIndex; // OLD section: 0..n-1
33
- }
34
- }
35
- }
36
-
37
- if (plan.newRowDescriptor) {
38
- for (const attrIdStr in plan.newRowDescriptor) {
39
- const attrId = parseInt(attrIdStr);
40
- const columnIndex = plan.newRowDescriptor[attrId];
41
- if (columnIndex !== undefined) {
42
- flatRowDescriptor[attrId] = tableSchema.columns.length + columnIndex; // NEW section: n..2n-1
43
- }
44
- }
45
- }
46
-
47
- // Discover attribute mappings for constraint building
48
- const newAttrIdByCol: Record<string, number> = {};
49
- const oldAttrIdByCol: Record<string, number> = {};
50
-
51
- if (plan.newRowDescriptor) {
52
- for (const attrIdStr in plan.newRowDescriptor) {
53
- const attrId = parseInt(attrIdStr);
54
- const columnIndex = plan.newRowDescriptor[attrId];
55
- if (columnIndex !== undefined && columnIndex < tableSchema.columns.length) {
56
- const column = tableSchema.columns[columnIndex];
57
- newAttrIdByCol[column.name.toLowerCase()] = attrId;
58
- }
59
- }
60
- }
61
-
62
- if (plan.oldRowDescriptor) {
63
- for (const attrIdStr in plan.oldRowDescriptor) {
64
- const attrId = parseInt(attrIdStr);
65
- const columnIndex = plan.oldRowDescriptor[attrId];
66
- if (columnIndex !== undefined && columnIndex < tableSchema.columns.length) {
67
- const column = tableSchema.columns[columnIndex];
68
- oldAttrIdByCol[column.name.toLowerCase()] = attrId;
69
- }
70
- }
71
- }
72
-
73
- const checkConstraintData = tableSchema.checkConstraints
74
- .filter((constraint: RowConstraintSchema) => shouldCheckConstraint(constraint, plan.operation))
75
- .map((constraint: RowConstraintSchema) => {
76
- // Build a PlanNode from the AST expression
77
- // Create a scope that has access to the table columns for constraint evaluation
78
- const scope = new RegisteredScope(new GlobalScope(ctx.db.schemaManager));
79
-
80
- // Register table columns for constraint evaluation using flat row attributes
81
- tableSchema.columns.forEach((tableColumn: ColumnSchema, tableColIndex: number) => {
82
- const colNameLower = tableColumn.name.toLowerCase();
83
-
84
- // Register NEW.<col> (defaults to NEW for unqualified references)
85
- const newAttrId = newAttrIdByCol[colNameLower];
86
- if (newAttrId !== undefined) {
87
- // Unqualified column name (defaults to NEW)
88
- scope.registerSymbol(colNameLower, (exp, s) =>
89
- new ColumnReferenceNode(s, exp as AST.ColumnExpr, {
90
- typeClass: 'scalar',
91
- affinity: tableColumn.affinity,
92
- nullable: !tableColumn.notNull,
93
- isReadOnly: false
94
- }, newAttrId, tableColIndex));
95
-
96
- // NEW.<col>
97
- scope.registerSymbol(`new.${colNameLower}`, (exp, s) =>
98
- new ColumnReferenceNode(s, exp as AST.ColumnExpr, {
99
- typeClass: 'scalar',
100
- affinity: tableColumn.affinity,
101
- nullable: !tableColumn.notNull,
102
- isReadOnly: false
103
- }, newAttrId, tableColIndex));
104
- }
105
-
106
- // Register OLD.<col>
107
- const oldAttrId = oldAttrIdByCol[colNameLower];
108
- if (oldAttrId !== undefined) {
109
- scope.registerSymbol(`old.${colNameLower}`, (exp, s) =>
110
- new ColumnReferenceNode(s, exp as AST.ColumnExpr, {
111
- typeClass: 'scalar',
112
- affinity: tableColumn.affinity,
113
- nullable: true, // OLD values can be NULL
114
- isReadOnly: false
115
- }, oldAttrId, tableColIndex));
116
- }
117
- });
19
+ // Emit evaluator instructions for each pre-built constraint expression
20
+ const checkEvaluators = plan.constraintChecks.map(check =>
21
+ emitCallFromPlan(check.expression, ctx)
22
+ );
118
23
 
119
- const exprPlanNode = buildExpression(
120
- {
121
- scope,
122
- db: ctx.db,
123
- parameters: {},
124
- schemaManager: ctx.db.schemaManager,
125
- schemaDependencies: new BuildTimeDependencyTracker(), // Not used in constraint evaluation
126
- schemaCache: new Map() // Not used in constraint evaluation
127
- },
128
- constraint.expr
129
- );
130
-
131
- return {
132
- constraint,
133
- evaluator: emitCallFromPlan(exprPlanNode, ctx)
134
- };
135
- });
136
-
137
- // Extract just the constraint metadata and evaluator functions
138
- const constraintMetadata = checkConstraintData.map(item => item.constraint);
139
- const checkEvaluators = checkConstraintData.map(item => item.evaluator);
24
+ // Extract just the constraint metadata for the runtime checker
25
+ const constraintMetadata = plan.constraintChecks.map(c => c.constraint);
140
26
 
141
27
  async function* run(rctx: RuntimeContext, inputRows: AsyncIterable<Row>, ...evaluatorFunctions: Array<(ctx: RuntimeContext) => OutputValue>): AsyncIterable<Row> {
142
28
  if (!inputRows) {
@@ -146,20 +32,16 @@ export function emitConstraintCheck(plan: ConstraintCheckNode, ctx: EmissionCont
146
32
  for await (const inputRow of inputRows) {
147
33
  const flatRow = inputRow;
148
34
 
149
- // Set up single flat context
150
- rctx.context.set(flatRowDescriptor, () => flatRow);
151
-
152
- try {
35
+ const result = await withAsyncRowContext(rctx, flatRowDescriptor, () => flatRow, async () => {
153
36
  // Check all constraints that apply to this operation
154
37
  await checkConstraints(rctx, plan, tableSchema, flatRow, constraintMetadata, evaluatorFunctions);
155
38
 
156
39
  // If all constraints pass, yield the flat row for downstream processing
157
40
  // All downstream operations (INSERT executor, DELETE executor, RETURNING) expect flat rows
158
- yield flatRow;
159
- } finally {
160
- // Clean up flat context
161
- rctx.context.delete(flatRowDescriptor);
162
- }
41
+ return flatRow;
42
+ });
43
+
44
+ yield result;
163
45
  }
164
46
  }
165
47
 
@@ -169,7 +51,7 @@ export function emitConstraintCheck(plan: ConstraintCheckNode, ctx: EmissionCont
169
51
  return {
170
52
  params: [sourceInstruction, ...checkEvaluators],
171
53
  run: run as any,
172
- note: `constraintCheck(${plan.operation})`
54
+ note: `constraintCheck(${plan.operation}, ${plan.constraintChecks.length} checks)`
173
55
  };
174
56
  }
175
57
 
@@ -243,7 +125,7 @@ async function checkCheckConstraints(
243
125
  constraintMetadata: Array<RowConstraintSchema>,
244
126
  evaluatorFunctions: Array<(ctx: RuntimeContext) => OutputValue>
245
127
  ): Promise<void> {
246
- // Evaluate each CHECK constraint
128
+ // Evaluate each CHECK constraint using pre-built evaluators
247
129
  for (let i = 0; i < constraintMetadata.length; i++) {
248
130
  const constraint = constraintMetadata[i];
249
131
  const evaluator = evaluatorFunctions[i];
@@ -256,8 +138,6 @@ async function checkCheckConstraints(
256
138
  // It fails only if result is false or 0 (SQLite-style numeric boolean)
257
139
  if (result === false || result === 0) {
258
140
  // Generate a proper constraint name if none was provided
259
- // IMPORTANT: Use the original index from the full tableSchema.checkConstraints array
260
- // not the filtered index, to get the correct constraint name
261
141
  const constraintName = constraint.name || generateDefaultConstraintName(tableSchema, constraint);
262
142
  throw new QuereusError(
263
143
  `CHECK constraint failed: ${constraintName}`,
@@ -273,13 +153,8 @@ async function checkCheckConstraints(
273
153
  }
274
154
  }
275
155
 
276
- function shouldCheckConstraint(constraint: RowConstraintSchema, operation: RowOp): boolean {
277
- // Check if the current operation is in the constraint's operations bitmask
278
- return (constraint.operations & operation) !== 0;
279
- }
280
-
281
156
  function generateDefaultConstraintName(tableSchema: TableSchema, constraint: RowConstraintSchema): string {
282
157
  // Find the index of this constraint in the original array to get the correct constraint number
283
158
  const originalIndex = tableSchema.checkConstraints.findIndex((c: RowConstraintSchema) => c === constraint);
284
- return `check_${originalIndex >= 0 ? originalIndex : 'unknown'}`;
159
+ return `_check_${originalIndex >= 0 ? originalIndex : 'unknown'}`;
285
160
  }
@@ -3,73 +3,36 @@ import type { CTEReferenceNode } from '../../planner/nodes/cte-reference-node.js
3
3
  import type { EmissionContext } from '../emission-context.js';
4
4
  import { emitPlanNode, createValidatedInstruction } from '../emitters.js';
5
5
  import type { Instruction, RuntimeContext } from '../types.js';
6
- import { QuereusError } from '../../common/errors.js';
7
- import { StatusCode } from '../../common/types.js';
8
- import { PlanNodeType } from '../../planner/nodes/plan-node-type.js';
9
6
  import { buildRowDescriptor } from '../../util/row-descriptor.js';
7
+ import { withRowContextGenerator } from '../context-helpers.js';
8
+ import { createLogger } from '../../common/logger.js';
9
+
10
+ const logger = createLogger('runtime:cte');
10
11
 
11
12
  export function emitCTEReference(plan: CTEReferenceNode, ctx: EmissionContext): Instruction {
12
13
  // Create row descriptor for output attributes
13
14
  const rowDescriptor = buildRowDescriptor(plan.getAttributes());
15
+ const attrs = plan.getAttributes();
16
+ const cteAlias = plan.alias || plan.source.cteName;
14
17
 
15
- // Check if this is an internal recursive reference (inside the recursive case)
16
- // These use table context to access the working table
17
- const isInternalRecursiveRef = plan.source.nodeType === PlanNodeType.CTE && plan.source.isRecursive;
18
-
19
- if (isInternalRecursiveRef) {
20
- // Internal recursive CTE reference: Look up the working table from table contexts
21
- async function* run(rctx: RuntimeContext): AsyncIterable<Row> {
22
- const tableGetter = rctx.tableContexts.get(plan.source.tableDescriptor);
23
- if (!tableGetter) {
24
- throw new QuereusError(
25
- `Recursive CTE '${plan.source.cteName}' not found in table context`,
26
- StatusCode.INTERNAL
27
- );
28
- }
29
-
30
- // Execute the working table and yield each row
31
- for await (const row of tableGetter()) {
32
- // Set up context for this row using row descriptor
33
- rctx.context.set(rowDescriptor, () => row);
34
- try {
35
- yield row;
36
- } finally {
37
- // Clean up context
38
- rctx.context.delete(rowDescriptor);
39
- }
40
- }
41
- }
18
+ logger(`Emitting CTE reference ${cteAlias} with attrs=[${attrs.map(a => a.id).join(',')}]`);
42
19
 
43
- return createValidatedInstruction(
44
- [], // No instruction parameters - data comes from table context
45
- run as any,
46
- ctx,
47
- `cte_ref(internal_recursive ${plan.source.cteName}${plan.alias ? ` AS ${plan.alias}` : ''})`
48
- );
49
- } else {
50
- // External CTE reference (or non-recursive): Use normal instruction parameter approach
51
- async function* run(rctx: RuntimeContext, cteResult: AsyncIterable<Row>): AsyncIterable<Row> {
52
- // Execute the CTE and yield each row
53
- for await (const row of cteResult) {
54
- // Set up context for this row using row descriptor
55
- rctx.context.set(rowDescriptor, () => row);
56
- try {
57
- yield row;
58
- } finally {
59
- // Clean up context
60
- rctx.context.delete(rowDescriptor);
61
- }
62
- }
63
- }
20
+ // Standard CTE reference: Use normal instruction parameter approach
21
+ async function* run(rctx: RuntimeContext, cteResult: AsyncIterable<Row>): AsyncIterable<Row> {
22
+ logger(`Executing CTE reference ${cteAlias}`);
23
+ // Execute the CTE and yield each row
24
+ yield* withRowContextGenerator(rctx, rowDescriptor, cteResult, async function* (row) {
25
+ yield row;
26
+ });
27
+ }
64
28
 
65
- // Emit the underlying CTE
66
- const cteInstruction = emitPlanNode(plan.source, ctx);
29
+ // Emit the underlying CTE
30
+ const cteInstruction = emitPlanNode(plan.source, ctx);
67
31
 
68
- return createValidatedInstruction(
69
- [cteInstruction],
70
- run as any,
71
- ctx,
72
- `cte_ref(${plan.source.isRecursive ? 'external_recursive' : 'non_recursive'} ${plan.source.cteName}${plan.alias ? ` AS ${plan.alias}` : ''})`
73
- );
74
- }
32
+ return createValidatedInstruction(
33
+ [cteInstruction],
34
+ run as any,
35
+ ctx,
36
+ `cte_ref(${plan.source.cteName}${plan.alias ? ` AS ${plan.alias}` : ''})`
37
+ );
75
38
  }
@@ -6,6 +6,7 @@ import type { EmissionContext } from '../emission-context.js';
6
6
  import { compareRows } from '../../util/comparison.js';
7
7
  import { BTree } from 'inheritree';
8
8
  import { buildRowDescriptor } from '../../util/row-descriptor.js';
9
+ import { withRowContext } from '../context-helpers.js';
9
10
 
10
11
  export function emitDistinct(plan: DistinctNode, ctx: EmissionContext): Instruction {
11
12
  // Create row descriptor for output attributes (same as source since DISTINCT preserves attributes)
@@ -24,13 +25,7 @@ export function emitDistinct(plan: DistinctNode, ctx: EmissionContext): Instruct
24
25
 
25
26
  if (newPath.on) {
26
27
  // This is a new distinct row - set up context and yield it
27
- ctx.context.set(outputRowDescriptor, () => sourceRow);
28
- try {
29
- yield sourceRow;
30
- } finally {
31
- // Clean up context for this row
32
- ctx.context.delete(outputRowDescriptor);
33
- }
28
+ yield await withRowContext(ctx, outputRowDescriptor, () => sourceRow, () => sourceRow);
34
29
  }
35
30
  }
36
31
  }
@@ -4,6 +4,7 @@ import { emitPlanNode, emitCallFromPlan } from '../emitters.js';
4
4
  import { type Row } from '../../common/types.js';
5
5
  import type { EmissionContext } from '../emission-context.js';
6
6
  import { buildRowDescriptor } from '../../util/row-descriptor.js';
7
+ import { withRowContextGenerator } from '../context-helpers.js';
7
8
 
8
9
  export function emitFilter(plan: FilterNode, ctx: EmissionContext): Instruction {
9
10
  const sourceInstruction = emitPlanNode(plan.source, ctx);
@@ -13,20 +14,12 @@ export function emitFilter(plan: FilterNode, ctx: EmissionContext): Instruction
13
14
  const sourceRowDescriptor = buildRowDescriptor(plan.source.getAttributes());
14
15
 
15
16
  async function* run(ctx: RuntimeContext, source: AsyncIterable<Row>, predicate: (ctx: RuntimeContext) => any): AsyncIterable<Row> {
16
- for await (const sourceRow of source) {
17
- // Set up context for this row using row descriptor
18
- ctx.context.set(sourceRowDescriptor, () => sourceRow);
19
-
20
- try {
21
- const result = await predicate(ctx);
22
- if (result) {
23
- yield sourceRow;
24
- }
25
- } finally {
26
- // Clean up context for this row
27
- ctx.context.delete(sourceRowDescriptor);
17
+ yield* withRowContextGenerator(ctx, sourceRowDescriptor, source, async function* (sourceRow) {
18
+ const result = await predicate(ctx);
19
+ if (result) {
20
+ yield sourceRow;
28
21
  }
29
- }
22
+ });
30
23
  }
31
24
 
32
25
  return {
@@ -0,0 +1,37 @@
1
+ import type { Row } from '../../common/types.js';
2
+ import type { InternalRecursiveCTERefNode } from '../../planner/nodes/internal-recursive-cte-ref-node.js';
3
+ import type { EmissionContext } from '../emission-context.js';
4
+ import { createValidatedInstruction } from '../emitters.js';
5
+ import type { Instruction, RuntimeContext } from '../types.js';
6
+ import { QuereusError } from '../../common/errors.js';
7
+ import { StatusCode } from '../../common/types.js';
8
+ import { buildRowDescriptor } from '../../util/row-descriptor.js';
9
+ import { withRowContextGenerator } from '../context-helpers.js';
10
+
11
+ export function emitInternalRecursiveCTERef(plan: InternalRecursiveCTERefNode, ctx: EmissionContext): Instruction {
12
+ // Create row descriptor for output attributes
13
+ const rowDescriptor = buildRowDescriptor(plan.getAttributes());
14
+
15
+ async function* run(rctx: RuntimeContext): AsyncIterable<Row> {
16
+ // Look up the working table from runtime context using the tableDescriptor
17
+ const tableGetter = rctx.tableContexts.get(plan.workingTableDescriptor);
18
+ if (!tableGetter) {
19
+ throw new QuereusError(
20
+ `Internal recursive CTE '${plan.cteName}' working table not found in context`,
21
+ StatusCode.INTERNAL
22
+ );
23
+ }
24
+
25
+ // Execute the working table and yield each row
26
+ yield* withRowContextGenerator(rctx, rowDescriptor, tableGetter(), async function* (row) {
27
+ yield row;
28
+ });
29
+ }
30
+
31
+ return createValidatedInstruction(
32
+ [], // No instruction parameters - data comes from table context
33
+ run,
34
+ ctx,
35
+ `internal_recursive_ref(${plan.cteName}${plan.alias ? ` AS ${plan.alias}` : ''})`
36
+ );
37
+ }
@@ -6,6 +6,7 @@ import type { EmissionContext } from '../emission-context.js';
6
6
  import { createLogger } from '../../common/logger.js';
7
7
  import { compareSqlValues } from '../../util/comparison.js';
8
8
  import { buildRowDescriptor } from '../../util/row-descriptor.js';
9
+ import { createRowSlot } from '../context-helpers.js';
9
10
 
10
11
  const log = createLogger('runtime:emit:join');
11
12
 
@@ -28,41 +29,41 @@ export function emitLoopJoin(plan: JoinNode, ctx: EmissionContext): Instruction
28
29
  log('Starting %s join between %d left attrs and %d right attrs',
29
30
  joinType.toUpperCase(), leftAttributes.length, rightAttributes.length);
30
31
 
31
- // Process left side and join with right (pure streaming)
32
- for await (const leftRow of leftSource) {
33
- // Set up left context
34
- rctx.context.set(leftRowDescriptor, () => leftRow);
32
+ // Create row slots for efficient context management
33
+ const leftSlot = createRowSlot(rctx, leftRowDescriptor);
34
+ const rightSlot = createRowSlot(rctx, rightRowDescriptor);
35
+
36
+ try {
37
+ // Process left side and join with right (pure streaming)
38
+ for await (const leftRow of leftSource) {
39
+ // Set up left context
40
+ leftSlot.set(leftRow);
35
41
 
36
- try {
37
42
  let leftMatched = false;
38
43
 
39
44
  // Stream through right side for each left row
40
45
  for await (const rightRow of rightCallback(rctx)) {
41
46
  // Set up right context
42
- rctx.context.set(rightRowDescriptor, () => rightRow);
43
-
44
- try {
45
- // Evaluate join condition
46
- let conditionMet = true;
47
-
48
- if (conditionCallback) {
49
- // Evaluate the join condition using the callback provided by scheduler
50
- const conditionResult = await conditionCallback(rctx);
51
- conditionMet = !!conditionResult; // Convert to boolean
52
- } else if (plan.usingColumns) {
53
- // Handle USING condition: check equality of specified columns
54
- conditionMet = evaluateUsingCondition(leftRow, rightRow, plan.usingColumns, leftAttributes, rightAttributes);
55
- } else if (joinType === 'cross') {
56
- // Cross join - always true
57
- conditionMet = true;
58
- }
59
-
60
- if (conditionMet) {
61
- leftMatched = true;
62
- yield [...leftRow, ...rightRow] as Row;
63
- }
64
- } finally {
65
- rctx.context.delete(rightRowDescriptor);
47
+ rightSlot.set(rightRow);
48
+
49
+ // Evaluate join condition
50
+ let conditionMet = true;
51
+
52
+ if (conditionCallback) {
53
+ // Evaluate the join condition using the callback provided by scheduler
54
+ const conditionResult = await conditionCallback(rctx);
55
+ conditionMet = !!conditionResult; // Convert to boolean
56
+ } else if (plan.usingColumns) {
57
+ // Handle USING condition: check equality of specified columns
58
+ conditionMet = evaluateUsingCondition(leftRow, rightRow, plan.usingColumns, leftAttributes, rightAttributes);
59
+ } else if (joinType === 'cross') {
60
+ // Cross join - always true
61
+ conditionMet = true;
62
+ }
63
+
64
+ if (conditionMet) {
65
+ leftMatched = true;
66
+ yield [...leftRow, ...rightRow] as Row;
66
67
  }
67
68
  }
68
69
 
@@ -73,22 +74,23 @@ export function emitLoopJoin(plan: JoinNode, ctx: EmissionContext): Instruction
73
74
  const outputRow = [...leftRow, ...nullPadding] as Row;
74
75
  yield outputRow;
75
76
  }
76
- } finally {
77
- rctx.context.delete(leftRowDescriptor);
78
77
  }
79
- }
80
78
 
81
- // Handle right outer join semantics - we need to track which right rows were matched
82
- // For now, we'll handle this in a simpler way by iterating again for right/full outer joins
83
- if (joinType === 'right' || joinType === 'full') {
84
- // For right outer joins, we need to find unmatched right rows
85
- // This is more complex and less efficient - a real implementation would track matches
86
- // For now, we'll implement a simplified version
87
- log('Right/full outer join - checking for unmatched right rows');
88
-
89
- // We'd need to track which right rows were matched during the main loop
90
- // For now, we'll skip this implementation detail
91
- // TODO: Implement proper right outer join semantics
79
+ // Handle right outer join semantics - we need to track which right rows were matched
80
+ // For now, we'll handle this in a simpler way by iterating again for right/full outer joins
81
+ if (joinType === 'right' || joinType === 'full') {
82
+ // For right outer joins, we need to find unmatched right rows
83
+ // This is more complex and less efficient - a real implementation would track matches
84
+ // For now, we'll implement a simplified version
85
+ log('Right/full outer join - checking for unmatched right rows');
86
+
87
+ // We'd need to track which right rows were matched during the main loop
88
+ // For now, we'll skip this implementation detail
89
+ // TODO: Implement proper right outer join semantics
90
+ }
91
+ } finally {
92
+ leftSlot.close();
93
+ rightSlot.close();
92
94
  }
93
95
  }
94
96