@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
@@ -5,6 +5,7 @@ import { type Row } from '../../common/types.js';
5
5
  import { type OutputValue } from '../../common/types.js';
6
6
  import type { EmissionContext } from '../emission-context.js';
7
7
  import { buildRowDescriptor } from '../../util/row-descriptor.js';
8
+ import { withAsyncRowContext, withRowContextGenerator } from '../context-helpers.js';
8
9
 
9
10
  export function emitProject(plan: ProjectNode, ctx: EmissionContext): Instruction {
10
11
  const sourceInstruction = emitPlanNode(plan.source, ctx);
@@ -12,23 +13,28 @@ export function emitProject(plan: ProjectNode, ctx: EmissionContext): Instructio
12
13
  return emitCallFromPlan(projection.node, ctx);
13
14
  });
14
15
 
15
- // Create row descriptor for source attributes
16
+ // Row descriptors
16
17
  const sourceRowDescriptor = buildRowDescriptor(plan.source.getAttributes());
18
+ const outputRowDescriptor = buildRowDescriptor(plan.getAttributes());
17
19
 
18
20
  async function* run(rctx: RuntimeContext, source: AsyncIterable<Row>, ...projectionFunctions: Array<(ctx: RuntimeContext) => OutputValue>): AsyncIterable<Row> {
19
21
  for await (const sourceRow of source) {
20
- // Set up context for this row using row descriptor
21
- rctx.context.set(sourceRowDescriptor, () => sourceRow);
22
+ // Evaluate projections using the source row context
23
+ const outputs = await withAsyncRowContext(rctx, sourceRowDescriptor, () => sourceRow, async () => {
24
+ return Promise.all(projectionFunctions.map(fn => fn(rctx)));
25
+ });
22
26
 
23
- try {
24
- const outputs = projectionFunctions.map(func => func(rctx));
25
- const resolved = await Promise.all(outputs);
26
- // Assume we have ensured that these are all scalar values
27
- yield resolved as Row;
28
- } finally {
29
- // Clean up context for this row
30
- rctx.context.delete(sourceRowDescriptor);
31
- }
27
+ // Push the output row descriptor for downstream consumers
28
+ yield* withRowContextGenerator(
29
+ rctx,
30
+ outputRowDescriptor,
31
+ (async function* () {
32
+ yield outputs as Row;
33
+ })(),
34
+ async function* (row) {
35
+ yield row;
36
+ }
37
+ );
32
38
  }
33
39
  }
34
40
 
@@ -11,6 +11,7 @@ import { DEFAULT_TUNING } from '../../planner/optimizer-tuning.js';
11
11
  import { quereusError } from '../../common/errors.js';
12
12
  import { StatusCode } from '../../common/types.js';
13
13
  import { buildRowDescriptor } from '../../util/row-descriptor.js';
14
+ import { withRowContext } from '../context-helpers.js';
14
15
 
15
16
  const log = createLogger('runtime:emit:recursive-cte');
16
17
 
@@ -42,12 +43,7 @@ export function emitRecursiveCTE(plan: RecursiveCTENode, ctx: EmissionContext):
42
43
 
43
44
  if (shouldYield) {
44
45
  // Yield immediately (streaming)
45
- rctx.context.set(rowDescriptor, () => row);
46
- try {
47
- yield row;
48
- } finally {
49
- rctx.context.delete(rowDescriptor);
50
- }
46
+ yield withRowContext(rctx, rowDescriptor, () => row, () => row);
51
47
 
52
48
  // Add to delta for recursive processing (deep copy to avoid reference issues)
53
49
  deltaRows.push([...row] as Row);
@@ -75,12 +71,7 @@ export function emitRecursiveCTE(plan: RecursiveCTENode, ctx: EmissionContext):
75
71
 
76
72
  if (shouldYield) {
77
73
  // Stream the row immediately
78
- rctx.context.set(rowDescriptor, () => row);
79
- try {
80
- yield row;
81
- } finally {
82
- rctx.context.delete(rowDescriptor);
83
- }
74
+ yield withRowContext(rctx, rowDescriptor, () => row, () => row);
84
75
 
85
76
  // Add to next iteration's delta (deep copy to avoid reference issues)
86
77
  newDeltaRows.push([...row] as Row);
@@ -4,6 +4,7 @@ import type { Row } from '../../common/types.js';
4
4
  import type { EmissionContext } from '../emission-context.js';
5
5
  import { emitPlanNode, emitCallFromPlan } from '../emitters.js';
6
6
  import { buildRowDescriptor } from '../../util/row-descriptor.js';
7
+ import { withRowContextGenerator } from '../context-helpers.js';
7
8
 
8
9
  export function emitReturning(plan: ReturningNode, ctx: EmissionContext): Instruction {
9
10
  // Use the executor's attributes to build the row descriptor
@@ -21,20 +22,12 @@ export function emitReturning(plan: ReturningNode, ctx: EmissionContext): Instru
21
22
  ...projectionCallbacks: Array<(ctx: RuntimeContext) => any>
22
23
  ): AsyncIterable<Row> {
23
24
  // Project the results from the executor rows
24
- for await (const sourceRow of executorRows) {
25
- // Set up the source context - the row is already in the correct flat OLD/NEW format
26
- rctx.context.set(sourceRowDescriptor, () => sourceRow);
27
-
28
- try {
29
- // Evaluate projection expressions in the context of this row
30
- const outputs = projectionCallbacks.map(func => func(rctx));
31
- const resolved = await Promise.all(outputs);
32
- yield resolved as Row;
33
- } finally {
34
- // Clean up source context
35
- rctx.context.delete(sourceRowDescriptor);
36
- }
37
- }
25
+ yield* withRowContextGenerator(rctx, sourceRowDescriptor, executorRows, async function* (_sourceRow) {
26
+ // Evaluate projection expressions in the context of this row
27
+ const outputs = projectionCallbacks.map(func => func(rctx));
28
+ const resolved = await Promise.all(outputs);
29
+ yield resolved as Row;
30
+ });
38
31
  }
39
32
 
40
33
  // Emit the executor (now always produces rows)
@@ -1,5 +1,5 @@
1
1
  import { StatusCode, type Row } from "../../common/types.js";
2
- import type { TableScanNode } from "../../planner/nodes/scan.js";
2
+ import { SeqScanNode, IndexScanNode, IndexSeekNode } from "../../planner/nodes/table-access-nodes.js";
3
3
  import { QuereusError } from "../../common/errors.js";
4
4
  import type { VirtualTable } from "../../vtab/table.js";
5
5
  import type { BaseModuleConfig } from "../../vtab/module.js";
@@ -8,32 +8,38 @@ import type { EmissionContext } from "../emission-context.js";
8
8
  import { createValidatedInstruction } from "../emitters.js";
9
9
  import { disconnectVTable } from "../utils.js";
10
10
  import { buildRowDescriptor } from "../../util/row-descriptor.js";
11
+ import { createRowSlot } from "../context-helpers.js";
11
12
 
12
- export function emitSeqScan(plan: TableScanNode, ctx: EmissionContext): Instruction {
13
- const tableSchema = plan.source.tableSchema;
13
+ /**
14
+ * Emits instructions for physical table access nodes (SeqScan, IndexScan, IndexSeek)
15
+ */
16
+ export function emitSeqScan(plan: SeqScanNode | IndexScanNode | IndexSeekNode, ctx: EmissionContext): Instruction {
17
+ // Handle physical access nodes
18
+ const source = plan.source;
19
+ const schema = source.tableSchema;
14
20
 
15
21
  // Create row descriptor mapping attribute IDs to column indices
16
22
  const rowDescriptor = buildRowDescriptor(plan.getAttributes());
17
23
 
18
24
  // Look up the virtual table module during emission and record the dependency
19
- const moduleInfo = ctx.getVtabModule(tableSchema.vtabModuleName);
25
+ const moduleInfo = ctx.getVtabModule(schema.vtabModuleName);
20
26
  if (!moduleInfo) {
21
- throw new QuereusError(`Virtual table module '${tableSchema.vtabModuleName}' not found`, StatusCode.ERROR);
27
+ throw new QuereusError(`Virtual table module '${schema.vtabModuleName}' not found`, StatusCode.ERROR);
22
28
  }
23
29
 
24
30
  // Capture the module info key for runtime retrieval
25
- const moduleKey = `vtab_module:${tableSchema.vtabModuleName}`;
31
+ const moduleKey = `vtab_module:${schema.vtabModuleName}`;
26
32
 
27
33
  async function* run(runtimeCtx: RuntimeContext): AsyncIterable<Row> {
28
34
  // Use the captured module info instead of doing a fresh lookup
29
35
  const capturedModuleInfo = ctx.getCapturedSchemaObject<{ module: any, auxData?: unknown }>(moduleKey);
30
36
  if (!capturedModuleInfo) {
31
- throw new QuereusError(`Virtual table module '${tableSchema.vtabModuleName}' was not captured during emission`, StatusCode.INTERNAL);
37
+ throw new QuereusError(`Virtual table module '${schema.vtabModuleName}' was not captured during emission`, StatusCode.INTERNAL);
32
38
  }
33
39
 
34
40
  const module = capturedModuleInfo.module;
35
41
  if (typeof module.xConnect !== 'function') {
36
- throw new QuereusError(`Virtual table module '${tableSchema.vtabModuleName}' does not implement xConnect`, StatusCode.MISUSE);
42
+ throw new QuereusError(`Virtual table module '${schema.vtabModuleName}' does not implement xConnect`, StatusCode.MISUSE);
37
43
  }
38
44
 
39
45
  let vtabInstance: VirtualTable;
@@ -42,38 +48,34 @@ export function emitSeqScan(plan: TableScanNode, ctx: EmissionContext): Instruct
42
48
  vtabInstance = module.xConnect(
43
49
  runtimeCtx.db,
44
50
  capturedModuleInfo.auxData,
45
- tableSchema.vtabModuleName,
46
- tableSchema.schemaName,
47
- tableSchema.name,
51
+ schema.vtabModuleName,
52
+ schema.schemaName,
53
+ schema.name,
48
54
  options
49
55
  );
50
56
  } catch (e: any) {
51
57
  const message = e instanceof Error ? e.message : String(e);
52
- throw new QuereusError(`Module '${tableSchema.vtabModuleName}' xConnect failed for table '${tableSchema.name}': ${message}`, e instanceof QuereusError ? e.code : StatusCode.ERROR, e instanceof Error ? e : undefined);
58
+ throw new QuereusError(`Module '${schema.vtabModuleName}' xConnect failed for table '${schema.name}': ${message}`, e instanceof QuereusError ? e.code : StatusCode.ERROR, e instanceof Error ? e : undefined);
53
59
  }
54
60
 
55
61
  if (typeof vtabInstance.xQuery !== 'function') {
56
62
  // Fallback or error if xQuery is not available. For now, throwing an error.
57
63
  // Later, we could implement the xOpen/xFilter/xNext loop here as a fallback.
58
- throw new QuereusError(`Virtual table '${tableSchema.name}' does not support xQuery.`, StatusCode.UNSUPPORTED);
64
+ throw new QuereusError(`Virtual table '${schema.name}' does not support xQuery.`, StatusCode.UNSUPPORTED);
59
65
  }
60
66
 
67
+ const rowSlot = createRowSlot(runtimeCtx, rowDescriptor);
61
68
  try {
62
- // Put cursor row into context using row descriptor
63
- let row: Row;
64
- runtimeCtx.context.set(rowDescriptor, () => row);
65
-
66
69
  const asyncRowIterable = vtabInstance.xQuery(plan.filterInfo);
67
- for await (row of asyncRowIterable) {
70
+ for await (const row of asyncRowIterable) {
71
+ rowSlot.set(row);
68
72
  yield row;
69
73
  }
70
-
71
- // Remove cursor row from context
72
- runtimeCtx.context.delete(rowDescriptor);
73
74
  } catch (e: any) {
74
75
  const message = e instanceof Error ? e.message : String(e);
75
- throw new QuereusError(`Error during xQuery on table '${tableSchema.name}': ${message}`, e instanceof QuereusError ? e.code : StatusCode.ERROR, e instanceof Error ? e : undefined);
76
+ throw new QuereusError(`Error during xQuery on table '${schema.name}': ${message}`, e instanceof QuereusError ? e.code : StatusCode.ERROR, e instanceof Error ? e : undefined);
76
77
  } finally {
78
+ rowSlot.close();
77
79
  // Properly disconnect the VirtualTable instance
78
80
  await disconnectVTable(runtimeCtx, vtabInstance);
79
81
  }
@@ -83,6 +85,6 @@ export function emitSeqScan(plan: TableScanNode, ctx: EmissionContext): Instruct
83
85
  [],
84
86
  run,
85
87
  ctx,
86
- `scan(${plan.source.tableSchema.name})`
88
+ `${plan.nodeType}(${schema.name})`
87
89
  );
88
90
  }
@@ -5,6 +5,7 @@ import { type SqlValue, type Row, type MaybePromise } from '../../common/types.j
5
5
  import type { EmissionContext } from '../emission-context.js';
6
6
  import { createOrderByComparatorFast, resolveCollation } from '../../util/comparison.js';
7
7
  import { buildRowDescriptor } from '../../util/row-descriptor.js';
8
+ import { withAsyncRowContext } from '../context-helpers.js';
8
9
 
9
10
  export function emitSort(plan: SortNode, ctx: EmissionContext): Instruction {
10
11
  const sourceInstruction = emitPlanNode(plan.source, ctx);
@@ -31,21 +32,17 @@ export function emitSort(plan: SortNode, ctx: EmissionContext): Instruction {
31
32
  const rowsWithKeys: Array<{ row: Row; keys: SqlValue[] }> = [];
32
33
 
33
34
  for await (const sourceRow of source) {
34
- // Set up context for this row using row descriptor
35
- ctx.context.set(sourceRowDescriptor, () => sourceRow);
36
-
37
- try {
35
+ const keys = await withAsyncRowContext(ctx, sourceRowDescriptor, () => sourceRow, async () => {
38
36
  // Evaluate sort key expressions
39
- const keys: SqlValue[] = [];
37
+ const keyValues: SqlValue[] = [];
40
38
  for (const keyFunc of sortKeyFunctions) {
41
- keys.push(await keyFunc(ctx));
39
+ const result = keyFunc(ctx);
40
+ keyValues.push(await Promise.resolve(result));
42
41
  }
42
+ return keyValues;
43
+ });
43
44
 
44
- rowsWithKeys.push({ row: sourceRow, keys });
45
- } finally {
46
- // Clean up context for this row
47
- ctx.context.delete(sourceRowDescriptor);
48
- }
45
+ rowsWithKeys.push({ row: sourceRow, keys });
49
46
  }
50
47
 
51
48
  // Sort the collected rows using pre-created optimized comparators
@@ -1,16 +1,17 @@
1
- import type { Instruction, RuntimeContext } from '../types.js';
1
+ import type { Instruction, InstructionRun, RuntimeContext } from '../types.js';
2
2
  import type { InNode, ScalarSubqueryNode, ExistsNode } from '../../planner/nodes/subquery.js';
3
3
  import { emitPlanNode } from '../emitters.js';
4
4
  import type { SqlValue, Row } from '../../common/types.js';
5
- import { compareSqlValuesFast, BINARY_COLLATION } from '../../util/comparison.js';
5
+ import { compareSqlValuesFast, resolveCollation } from '../../util/comparison.js';
6
6
  import type { EmissionContext } from '../emission-context.js';
7
7
  import { QuereusError } from '../../common/errors.js';
8
8
  import { StatusCode } from '../../common/types.js';
9
9
  import { BTree } from 'inheritree';
10
+ import { ConstantNode } from '../../planner/nodes/plan-node.js';
10
11
 
11
12
  export function emitScalarSubquery(plan: ScalarSubqueryNode, ctx: EmissionContext): Instruction {
12
13
 
13
- async function run(ctx: RuntimeContext, input: AsyncIterable<Row>): Promise<SqlValue> {
14
+ async function run(rctx: RuntimeContext, input: AsyncIterable<Row>): Promise<SqlValue> {
14
15
  let result: SqlValue = null;
15
16
  let seen = false;
16
17
 
@@ -18,8 +19,11 @@ export function emitScalarSubquery(plan: ScalarSubqueryNode, ctx: EmissionContex
18
19
  if (seen) {
19
20
  throw new QuereusError('Scalar subquery returned more than one row', StatusCode.ERROR, undefined, plan.expression.loc?.start.line, plan.expression.loc?.start.column);
20
21
  }
22
+ if (row.length > 1) {
23
+ throw new QuereusError('Subquery should return at most one column', StatusCode.ERROR);
24
+ }
25
+ result = row.length === 0 ? null : row[0];
21
26
  seen = true;
22
- result = row[0];
23
27
  }
24
28
 
25
29
  return result;
@@ -30,25 +34,25 @@ export function emitScalarSubquery(plan: ScalarSubqueryNode, ctx: EmissionContex
30
34
  return {
31
35
  params: [innerInstruction],
32
36
  run,
33
- note: 'scalar subquery'
37
+ note: 'SCALAR_SUBQUERY'
34
38
  };
35
39
  }
36
40
 
37
41
  export function emitIn(plan: InNode, ctx: EmissionContext): Instruction {
42
+ // Extract collation from the condition expression
43
+ const conditionType = plan.condition.getType();
44
+ const collationName = conditionType.collationName || 'BINARY';
45
+ const collation = resolveCollation(collationName);
46
+
38
47
  if (plan.source) {
39
48
  // IN subquery: expr IN (SELECT ...)
40
- async function runSubquery(ctx: RuntimeContext, input: AsyncIterable<Row>, condition: SqlValue): Promise<SqlValue> {
49
+ // Use streaming approach - check each row as we read it, return early on match
50
+ async function runSubqueryStreaming(_rctx: RuntimeContext, input: AsyncIterable<Row>, condition: SqlValue): Promise<SqlValue> {
41
51
  // If condition is NULL, result is NULL
42
52
  if (condition === null) {
43
53
  return null;
44
54
  }
45
55
 
46
- // Build BTree of all values from subquery
47
- const tree = new BTree<SqlValue, SqlValue>(
48
- (val: SqlValue) => val,
49
- (a: SqlValue, b: SqlValue) => compareSqlValuesFast(a, b, BINARY_COLLATION)
50
- );
51
-
52
56
  let hasNull = false;
53
57
  for await (const row of input) {
54
58
  if (row.length > 0) {
@@ -57,16 +61,13 @@ export function emitIn(plan: InNode, ctx: EmissionContext): Instruction {
57
61
  hasNull = true;
58
62
  continue;
59
63
  }
60
- tree.insert(rowValue);
64
+ // Check for match immediately - no need to materialize
65
+ if (compareSqlValuesFast(condition, rowValue, collation) === 0) {
66
+ return 1; // Found a match
67
+ }
61
68
  }
62
69
  }
63
70
 
64
- // Check if condition exists in tree
65
- const value = tree.get(condition);
66
- if (value !== undefined) {
67
- return 1; // Found a match
68
- }
69
-
70
71
  // No match found - if any value was NULL, result is NULL
71
72
  return hasNull ? null : 0;
72
73
  }
@@ -76,57 +77,116 @@ export function emitIn(plan: InNode, ctx: EmissionContext): Instruction {
76
77
 
77
78
  return {
78
79
  params: [sourceInstruction, conditionExpr],
79
- run: runSubquery as any,
80
+ run: runSubqueryStreaming as any,
80
81
  note: `IN (subquery)`
81
82
  };
82
83
  } else if (plan.values) {
83
84
  // IN value list: expr IN (value1, value2, ...)
84
- function runValues(ctx: RuntimeContext, condition: SqlValue, ...values: SqlValue[]): SqlValue {
85
- // If condition is NULL, result is NULL
86
- if (condition === null) {
87
- return null;
88
- }
89
85
 
90
- // Build BTree of all values
86
+ // Check if all values are truly constant (can be evaluated at emit time)
87
+ const allConstant = plan.values.every(val => val.physical.constant);
88
+
89
+ if (allConstant) {
90
+ // Pre-build BTree at emit time for constant values
91
91
  const tree = new BTree<SqlValue, SqlValue>(
92
92
  (val: SqlValue) => val,
93
- (a: SqlValue, b: SqlValue) => compareSqlValuesFast(a, b, BINARY_COLLATION)
93
+ (a: SqlValue, b: SqlValue) => compareSqlValuesFast(a, b, collation)
94
94
  );
95
-
96
95
  let hasNull = false;
97
- for (const value of values) {
98
- if (value === null) {
99
- hasNull = true;
100
- continue;
96
+
97
+ function innerConstantRun(_rctx: RuntimeContext, condition: SqlValue): SqlValue {
98
+ // If condition is NULL, result is NULL
99
+ if (condition === null) {
100
+ return null;
101
+ }
102
+
103
+ // Check if condition exists in pre-built tree
104
+ const path = tree.find(condition);
105
+ if (path.on) {
106
+ return 1; // Found a match
101
107
  }
102
- tree.insert(value);
108
+
109
+ // No match found - if any value was NULL, result is NULL
110
+ return hasNull ? null : 0;
103
111
  }
104
112
 
105
- // Check if condition exists in tree
106
- const path = tree.find(condition);
107
- if (path.on) {
108
- return 1; // Found a match
113
+ const values = plan.values.map(val => (val as unknown as ConstantNode).getValue());
114
+
115
+ let runFunc: InstructionRun;
116
+
117
+ if (values.some(val => val instanceof Promise)) {
118
+ // Must resolve promises at runtime
119
+ runFunc = async (rctx: RuntimeContext, condition: SqlValue): Promise<SqlValue> => {
120
+ const resolved = await Promise.all(values);
121
+
122
+ for (const value of resolved) {
123
+ if (value === null) {
124
+ hasNull = true;
125
+ continue;
126
+ }
127
+ tree.insert(value as SqlValue);
128
+ }
129
+
130
+ return innerConstantRun(rctx, condition);
131
+ }
132
+ } else {
133
+ for (const value of values) {
134
+ if (value === null) {
135
+ hasNull = true;
136
+ continue;
137
+ }
138
+ tree.insert(value as SqlValue);
139
+ }
140
+ runFunc = innerConstantRun;
109
141
  }
110
142
 
111
- // No match found - if any value was NULL, result is NULL
112
- return hasNull ? null : 0;
113
- }
143
+ const conditionExpr = emitPlanNode(plan.condition, ctx);
144
+
145
+ return {
146
+ params: [conditionExpr],
147
+ run: runFunc as InstructionRun,
148
+ note: `IN (${plan.values.length} constant values)`
149
+ };
150
+ } else {
151
+ // Some values are expressions - build tree at runtime
152
+ function runDynamicValues(_rctx: RuntimeContext, condition: SqlValue, ...values: SqlValue[]): SqlValue {
153
+ // If condition is NULL, result is NULL
154
+ if (condition === null) {
155
+ return null;
156
+ }
114
157
 
115
- const conditionExpr = emitPlanNode(plan.condition, ctx);
116
- const valueExprs = plan.values.map(val => emitPlanNode(val, ctx));
158
+ // Linear scan is optimal since we're only doing one lookup per execution
159
+ let hasNull = false;
160
+ for (const value of values) {
161
+ if (value === null) {
162
+ hasNull = true;
163
+ continue;
164
+ }
165
+ if (compareSqlValuesFast(condition, value, collation) === 0) {
166
+ return 1; // Found a match
167
+ }
168
+ }
117
169
 
118
- return {
119
- params: [conditionExpr, ...valueExprs],
120
- run: runValues as any,
121
- note: `IN (${plan.values.length} values)`
122
- };
170
+ // No match found - if any value was NULL, result is NULL
171
+ return hasNull ? null : 0;
172
+ }
173
+
174
+ const conditionExpr = emitPlanNode(plan.condition, ctx);
175
+ const valueExprs = plan.values.map(val => emitPlanNode(val, ctx));
176
+
177
+ return {
178
+ params: [conditionExpr, ...valueExprs],
179
+ run: runDynamicValues as any,
180
+ note: `IN (${plan.values.length} dynamic values)`
181
+ };
182
+ }
123
183
  } else {
124
184
  throw new QuereusError('IN node must have either source or values', StatusCode.INTERNAL);
125
185
  }
126
186
  }
127
187
 
128
188
  export function emitExists(plan: ExistsNode, ctx: EmissionContext): Instruction {
129
- async function run(ctx: RuntimeContext, input: AsyncIterable<Row>): Promise<SqlValue> {
189
+ async function run(_rctx: RuntimeContext, input: AsyncIterable<Row>): Promise<SqlValue> {
130
190
  for await (const _row of input) {
131
191
  return 1; // First row => TRUE
132
192
  }
@@ -7,6 +7,7 @@ import { isTableValuedFunctionSchema } from '../../schema/function.js';
7
7
  import type { EmissionContext } from '../emission-context.js';
8
8
  import type { TableFunctionCallNode } from '../../planner/nodes/table-function-call.js';
9
9
  import { buildRowDescriptor } from '../../util/row-descriptor.js';
10
+ import { withRowContextGenerator } from '../context-helpers.js';
10
11
 
11
12
  export function emitTableValuedFunctionCall(plan: TableFunctionCallNode, ctx: EmissionContext): Instruction {
12
13
  const functionName = plan.functionName.toLowerCase();
@@ -49,16 +50,9 @@ export function emitTableValuedFunctionCall(plan: TableFunctionCallNode, ctx: Em
49
50
  // Handle both direct AsyncIterable and Promise<AsyncIterable>
50
51
  const iterable = result instanceof Promise ? await result : result;
51
52
 
52
- for await (const row of iterable) {
53
- // Set up row context for column references
54
- innerCtx.context.set(rowDescriptor, () => row);
55
- try {
56
- yield row;
57
- } finally {
58
- // Clean up row context
59
- innerCtx.context.delete(rowDescriptor);
60
- }
61
- }
53
+ yield* withRowContextGenerator(innerCtx, rowDescriptor, iterable, async function* (row) {
54
+ yield row;
55
+ });
62
56
  } catch (error: any) {
63
57
  throw new QuereusError(`Table-valued function ${functionName} failed: ${error.message}`, StatusCode.ERROR, error);
64
58
  }
@@ -92,16 +86,9 @@ export function emitTableValuedFunctionCall(plan: TableFunctionCallNode, ctx: Em
92
86
  // Handle both direct AsyncIterable and Promise<AsyncIterable>
93
87
  const iterable = result instanceof Promise ? await result : result;
94
88
 
95
- for await (const row of iterable) {
96
- // Set up row context for column references
97
- innerCtx.context.set(rowDescriptor, () => row);
98
- try {
99
- yield row;
100
- } finally {
101
- // Clean up row context
102
- innerCtx.context.delete(rowDescriptor);
103
- }
104
- }
89
+ yield* withRowContextGenerator(innerCtx, rowDescriptor, iterable, async function* (row) {
90
+ yield row;
91
+ });
105
92
  } catch (error: any) {
106
93
  throw new QuereusError(`Table-valued function ${functionName} failed: ${error.message}`, StatusCode.ERROR, error);
107
94
  }
@@ -5,6 +5,7 @@ import { QuereusError } from '../../common/errors.js';
5
5
  import { StatusCode, type SqlValue, type Row } from '../../common/types.js';
6
6
  import type { EmissionContext } from '../emission-context.js';
7
7
  import { buildRowDescriptor, composeOldNewRow } from '../../util/row-descriptor.js';
8
+ import { withRowContextGenerator } from '../context-helpers.js';
8
9
 
9
10
  export function emitUpdate(plan: UpdateNode, ctx: EmissionContext): Instruction {
10
11
  const tableSchema = plan.table.tableSchema;
@@ -28,39 +29,31 @@ export function emitUpdate(plan: UpdateNode, ctx: EmissionContext): Instruction
28
29
  );
29
30
 
30
31
  async function* run(rctx: RuntimeContext, sourceRowsIterable: AsyncIterable<Row>, ...assignmentEvaluators: Array<(ctx: RuntimeContext) => SqlValue>): AsyncIterable<Row> {
31
- for await (const sourceRow of sourceRowsIterable) {
32
- // Set up row context for evaluating assignment expressions
33
- rctx.context.set(sourceRowDescriptor, () => sourceRow);
34
-
35
- try {
36
- // Evaluate assignment expressions in the context of this row
37
- const assignmentValues: SqlValue[] = [];
38
- for (const evaluator of assignmentEvaluators) {
39
- const value = evaluator(rctx) as SqlValue;
40
- assignmentValues.push(value);
41
- }
32
+ yield* withRowContextGenerator(rctx, sourceRowDescriptor, sourceRowsIterable, async function* (sourceRow) {
33
+ // Evaluate assignment expressions in the context of this row
34
+ const assignmentValues: SqlValue[] = [];
35
+ for (const evaluator of assignmentEvaluators) {
36
+ const value = evaluator(rctx) as SqlValue;
37
+ assignmentValues.push(value);
38
+ }
42
39
 
43
- // Create a new row with updated values
44
- const updatedRow = [...sourceRow]; // Copy the original row
40
+ // Create a new row with updated values
41
+ const updatedRow = [...sourceRow]; // Copy the original row
45
42
 
46
- // Apply assignment values to the row
47
- for (let i = 0; i < assignmentValues.length; i++) {
48
- const targetColIdx = assignmentTargetIndices[i];
49
- updatedRow[targetColIdx] = assignmentValues[i];
50
- }
43
+ // Apply assignment values to the row
44
+ for (let i = 0; i < assignmentValues.length; i++) {
45
+ const targetColIdx = assignmentTargetIndices[i];
46
+ updatedRow[targetColIdx] = assignmentValues[i];
47
+ }
51
48
 
52
- // Create flat row with OLD (source) and NEW (updated) values for constraint checking
53
- const flatRow = composeOldNewRow(sourceRow, updatedRow, tableSchema.columns.length);
49
+ // Create flat row with OLD (source) and NEW (updated) values for constraint checking
50
+ const flatRow = composeOldNewRow(sourceRow, updatedRow, tableSchema.columns.length);
54
51
 
55
- // Yield the flat row for constraint checking
56
- // NOTE: UpdateNode only transforms rows - it does NOT execute the actual update
57
- // The UpdateExecutorNode is responsible for calling vtab.xUpdate
58
- yield flatRow;
59
- } finally {
60
- // Clean up row context
61
- rctx.context.delete(sourceRowDescriptor);
62
- }
63
- }
52
+ // Yield the flat row for constraint checking
53
+ // NOTE: UpdateNode only transforms rows - it does NOT execute the actual update
54
+ // The UpdateExecutorNode is responsible for calling vtab.xUpdate
55
+ yield flatRow;
56
+ });
64
57
  }
65
58
 
66
59
  const sourceInstruction = emitPlanNode(plan.source, ctx);