@quereus/quereus 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (477) hide show
  1. package/README.md +47 -23
  2. package/dist/src/common/types.d.ts +1 -0
  3. package/dist/src/common/types.d.ts.map +1 -1
  4. package/dist/src/core/database.d.ts +22 -4
  5. package/dist/src/core/database.d.ts.map +1 -1
  6. package/dist/src/core/database.js +44 -6
  7. package/dist/src/core/database.js.map +1 -1
  8. package/dist/src/core/statement.d.ts +0 -7
  9. package/dist/src/core/statement.d.ts.map +1 -1
  10. package/dist/src/core/statement.js +1 -51
  11. package/dist/src/core/statement.js.map +1 -1
  12. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  13. package/dist/src/func/builtins/explain.js +0 -11
  14. package/dist/src/func/builtins/explain.js.map +1 -1
  15. package/dist/src/index.d.ts +13 -5
  16. package/dist/src/index.d.ts.map +1 -1
  17. package/dist/src/index.js +5 -2
  18. package/dist/src/index.js.map +1 -1
  19. package/dist/src/parser/ast.d.ts +10 -4
  20. package/dist/src/parser/ast.d.ts.map +1 -1
  21. package/dist/src/parser/parser.d.ts.map +1 -1
  22. package/dist/src/parser/parser.js +40 -44
  23. package/dist/src/parser/parser.js.map +1 -1
  24. package/dist/src/planner/analysis/const-pass.d.ts.map +1 -1
  25. package/dist/src/planner/analysis/const-pass.js +12 -6
  26. package/dist/src/planner/analysis/const-pass.js.map +1 -1
  27. package/dist/src/planner/building/constraint-builder.d.ts +11 -0
  28. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -0
  29. package/dist/src/planner/building/constraint-builder.js +79 -0
  30. package/dist/src/planner/building/constraint-builder.js.map +1 -0
  31. package/dist/src/planner/building/delete.d.ts.map +1 -1
  32. package/dist/src/planner/building/delete.js +7 -4
  33. package/dist/src/planner/building/delete.js.map +1 -1
  34. package/dist/src/planner/building/expression.d.ts +3 -0
  35. package/dist/src/planner/building/expression.d.ts.map +1 -1
  36. package/dist/src/planner/building/expression.js +33 -7
  37. package/dist/src/planner/building/expression.js.map +1 -1
  38. package/dist/src/planner/building/insert.d.ts.map +1 -1
  39. package/dist/src/planner/building/insert.js +5 -2
  40. package/dist/src/planner/building/insert.js.map +1 -1
  41. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  42. package/dist/src/planner/building/select-aggregates.js +46 -9
  43. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  44. package/dist/src/planner/building/select-context.js +20 -11
  45. package/dist/src/planner/building/select-context.js.map +1 -1
  46. package/dist/src/planner/building/select-modifiers.d.ts +5 -3
  47. package/dist/src/planner/building/select-modifiers.d.ts.map +1 -1
  48. package/dist/src/planner/building/select-modifiers.js +29 -20
  49. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  50. package/dist/src/planner/building/select-projections.d.ts +3 -1
  51. package/dist/src/planner/building/select-projections.d.ts.map +1 -1
  52. package/dist/src/planner/building/select-projections.js +15 -20
  53. package/dist/src/planner/building/select-projections.js.map +1 -1
  54. package/dist/src/planner/building/select-window.d.ts.map +1 -1
  55. package/dist/src/planner/building/select-window.js +6 -3
  56. package/dist/src/planner/building/select-window.js.map +1 -1
  57. package/dist/src/planner/building/select.d.ts +25 -2
  58. package/dist/src/planner/building/select.d.ts.map +1 -1
  59. package/dist/src/planner/building/select.js +147 -24
  60. package/dist/src/planner/building/select.js.map +1 -1
  61. package/dist/src/planner/building/table.d.ts +0 -10
  62. package/dist/src/planner/building/table.d.ts.map +1 -1
  63. package/dist/src/planner/building/table.js +1 -35
  64. package/dist/src/planner/building/table.js.map +1 -1
  65. package/dist/src/planner/building/update.d.ts.map +1 -1
  66. package/dist/src/planner/building/update.js +8 -5
  67. package/dist/src/planner/building/update.js.map +1 -1
  68. package/dist/src/planner/building/with.d.ts.map +1 -1
  69. package/dist/src/planner/building/with.js +7 -8
  70. package/dist/src/planner/building/with.js.map +1 -1
  71. package/dist/src/planner/cache/correlation-detector.d.ts +11 -0
  72. package/dist/src/planner/cache/correlation-detector.d.ts.map +1 -0
  73. package/dist/src/planner/cache/correlation-detector.js +73 -0
  74. package/dist/src/planner/cache/correlation-detector.js.map +1 -0
  75. package/dist/src/planner/cache/materialization-advisory.d.ts +12 -18
  76. package/dist/src/planner/cache/materialization-advisory.d.ts.map +1 -1
  77. package/dist/src/planner/cache/materialization-advisory.js +65 -46
  78. package/dist/src/planner/cache/materialization-advisory.js.map +1 -1
  79. package/dist/src/planner/cache/reference-graph.d.ts +14 -9
  80. package/dist/src/planner/cache/reference-graph.d.ts.map +1 -1
  81. package/dist/src/planner/cache/reference-graph.js +93 -84
  82. package/dist/src/planner/cache/reference-graph.js.map +1 -1
  83. package/dist/src/planner/debug.d.ts +25 -0
  84. package/dist/src/planner/debug.d.ts.map +1 -1
  85. package/dist/src/planner/debug.js +127 -0
  86. package/dist/src/planner/debug.js.map +1 -1
  87. package/dist/src/planner/framework/context.d.ts +11 -0
  88. package/dist/src/planner/framework/context.d.ts.map +1 -1
  89. package/dist/src/planner/framework/context.js +25 -2
  90. package/dist/src/planner/framework/context.js.map +1 -1
  91. package/dist/src/planner/framework/registry.d.ts +3 -7
  92. package/dist/src/planner/framework/registry.d.ts.map +1 -1
  93. package/dist/src/planner/framework/registry.js +20 -31
  94. package/dist/src/planner/framework/registry.js.map +1 -1
  95. package/dist/src/planner/nodes/add-constraint-node.d.ts +2 -1
  96. package/dist/src/planner/nodes/add-constraint-node.d.ts.map +1 -1
  97. package/dist/src/planner/nodes/add-constraint-node.js +3 -0
  98. package/dist/src/planner/nodes/add-constraint-node.js.map +1 -1
  99. package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
  100. package/dist/src/planner/nodes/aggregate-node.js +6 -4
  101. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  102. package/dist/src/planner/nodes/cache-node.d.ts.map +1 -1
  103. package/dist/src/planner/nodes/cache-node.js +2 -2
  104. package/dist/src/planner/nodes/cache-node.js.map +1 -1
  105. package/dist/src/planner/nodes/constraint-check-node.d.ts +13 -6
  106. package/dist/src/planner/nodes/constraint-check-node.d.ts.map +1 -1
  107. package/dist/src/planner/nodes/constraint-check-node.js +38 -12
  108. package/dist/src/planner/nodes/constraint-check-node.js.map +1 -1
  109. package/dist/src/planner/nodes/create-index-node.d.ts +2 -1
  110. package/dist/src/planner/nodes/create-index-node.d.ts.map +1 -1
  111. package/dist/src/planner/nodes/create-index-node.js +3 -0
  112. package/dist/src/planner/nodes/create-index-node.js.map +1 -1
  113. package/dist/src/planner/nodes/create-table-node.d.ts +2 -1
  114. package/dist/src/planner/nodes/create-table-node.d.ts.map +1 -1
  115. package/dist/src/planner/nodes/create-table-node.js +3 -0
  116. package/dist/src/planner/nodes/create-table-node.js.map +1 -1
  117. package/dist/src/planner/nodes/create-view-node.d.ts +2 -1
  118. package/dist/src/planner/nodes/create-view-node.d.ts.map +1 -1
  119. package/dist/src/planner/nodes/create-view-node.js +3 -0
  120. package/dist/src/planner/nodes/create-view-node.js.map +1 -1
  121. package/dist/src/planner/nodes/cte-node.d.ts +1 -1
  122. package/dist/src/planner/nodes/cte-node.d.ts.map +1 -1
  123. package/dist/src/planner/nodes/cte-node.js +33 -12
  124. package/dist/src/planner/nodes/cte-node.js.map +1 -1
  125. package/dist/src/planner/nodes/cte-reference-node.d.ts +18 -4
  126. package/dist/src/planner/nodes/cte-reference-node.d.ts.map +1 -1
  127. package/dist/src/planner/nodes/cte-reference-node.js +40 -10
  128. package/dist/src/planner/nodes/cte-reference-node.js.map +1 -1
  129. package/dist/src/planner/nodes/delete-node.d.ts +4 -3
  130. package/dist/src/planner/nodes/delete-node.d.ts.map +1 -1
  131. package/dist/src/planner/nodes/delete-node.js +20 -6
  132. package/dist/src/planner/nodes/delete-node.js.map +1 -1
  133. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
  134. package/dist/src/planner/nodes/distinct-node.js +2 -2
  135. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  136. package/dist/src/planner/nodes/dml-executor-node.d.ts +1 -1
  137. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  138. package/dist/src/planner/nodes/dml-executor-node.js +2 -2
  139. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  140. package/dist/src/planner/nodes/drop-table-node.d.ts +2 -1
  141. package/dist/src/planner/nodes/drop-table-node.d.ts.map +1 -1
  142. package/dist/src/planner/nodes/drop-table-node.js +3 -0
  143. package/dist/src/planner/nodes/drop-table-node.js.map +1 -1
  144. package/dist/src/planner/nodes/drop-view-node.d.ts +2 -1
  145. package/dist/src/planner/nodes/drop-view-node.d.ts.map +1 -1
  146. package/dist/src/planner/nodes/drop-view-node.js +3 -0
  147. package/dist/src/planner/nodes/drop-view-node.js.map +1 -1
  148. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  149. package/dist/src/planner/nodes/filter.js +3 -3
  150. package/dist/src/planner/nodes/filter.js.map +1 -1
  151. package/dist/src/planner/nodes/insert-node.d.ts +2 -1
  152. package/dist/src/planner/nodes/insert-node.d.ts.map +1 -1
  153. package/dist/src/planner/nodes/insert-node.js +18 -5
  154. package/dist/src/planner/nodes/insert-node.js.map +1 -1
  155. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts +28 -0
  156. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts.map +1 -0
  157. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js +69 -0
  158. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js.map +1 -0
  159. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  160. package/dist/src/planner/nodes/join-node.js +3 -3
  161. package/dist/src/planner/nodes/join-node.js.map +1 -1
  162. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  163. package/dist/src/planner/nodes/limit-offset.js +2 -2
  164. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  165. package/dist/src/planner/nodes/plan-node-type.d.ts +1 -1
  166. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  167. package/dist/src/planner/nodes/plan-node-type.js +1 -1
  168. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  169. package/dist/src/planner/nodes/plan-node.d.ts +23 -0
  170. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  171. package/dist/src/planner/nodes/plan-node.js +25 -2
  172. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  173. package/dist/src/planner/nodes/project-node.d.ts +5 -1
  174. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  175. package/dist/src/planner/nodes/project-node.js +39 -20
  176. package/dist/src/planner/nodes/project-node.js.map +1 -1
  177. package/dist/src/planner/nodes/recursive-cte-node.d.ts +2 -2
  178. package/dist/src/planner/nodes/recursive-cte-node.d.ts.map +1 -1
  179. package/dist/src/planner/nodes/recursive-cte-node.js +20 -8
  180. package/dist/src/planner/nodes/recursive-cte-node.js.map +1 -1
  181. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  182. package/dist/src/planner/nodes/reference.js +4 -2
  183. package/dist/src/planner/nodes/reference.js.map +1 -1
  184. package/dist/src/planner/nodes/returning-node.d.ts +1 -1
  185. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  186. package/dist/src/planner/nodes/returning-node.js +21 -13
  187. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  188. package/dist/src/planner/nodes/scalar.d.ts +26 -2
  189. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  190. package/dist/src/planner/nodes/scalar.js +82 -10
  191. package/dist/src/planner/nodes/scalar.js.map +1 -1
  192. package/dist/src/planner/nodes/sequencing-node.d.ts.map +1 -1
  193. package/dist/src/planner/nodes/sequencing-node.js +2 -2
  194. package/dist/src/planner/nodes/sequencing-node.js.map +1 -1
  195. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  196. package/dist/src/planner/nodes/set-operation-node.js +3 -3
  197. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  198. package/dist/src/planner/nodes/single-row.d.ts +4 -2
  199. package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
  200. package/dist/src/planner/nodes/single-row.js +3 -0
  201. package/dist/src/planner/nodes/single-row.js.map +1 -1
  202. package/dist/src/planner/nodes/sink-node.d.ts +1 -1
  203. package/dist/src/planner/nodes/sink-node.d.ts.map +1 -1
  204. package/dist/src/planner/nodes/sink-node.js +4 -4
  205. package/dist/src/planner/nodes/sink-node.js.map +1 -1
  206. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  207. package/dist/src/planner/nodes/sort.js +2 -2
  208. package/dist/src/planner/nodes/sort.js.map +1 -1
  209. package/dist/src/planner/nodes/stream-aggregate.d.ts +1 -0
  210. package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
  211. package/dist/src/planner/nodes/stream-aggregate.js +64 -11
  212. package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
  213. package/dist/src/planner/nodes/subquery.d.ts +4 -4
  214. package/dist/src/planner/nodes/subquery.d.ts.map +1 -1
  215. package/dist/src/planner/nodes/subquery.js +68 -23
  216. package/dist/src/planner/nodes/subquery.js.map +1 -1
  217. package/dist/src/planner/nodes/table-access-nodes.d.ts +83 -0
  218. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -0
  219. package/dist/src/planner/nodes/table-access-nodes.js +226 -0
  220. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -0
  221. package/dist/src/planner/nodes/update-node.d.ts +4 -2
  222. package/dist/src/planner/nodes/update-node.d.ts.map +1 -1
  223. package/dist/src/planner/nodes/update-node.js +26 -13
  224. package/dist/src/planner/nodes/update-node.js.map +1 -1
  225. package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
  226. package/dist/src/planner/nodes/window-node.js +25 -23
  227. package/dist/src/planner/nodes/window-node.js.map +1 -1
  228. package/dist/src/planner/optimizer.d.ts.map +1 -1
  229. package/dist/src/planner/optimizer.js +46 -50
  230. package/dist/src/planner/optimizer.js.map +1 -1
  231. package/dist/src/planner/planning-context.d.ts +13 -0
  232. package/dist/src/planner/planning-context.d.ts.map +1 -1
  233. package/dist/src/planner/planning-context.js.map +1 -1
  234. package/dist/src/planner/rules/access/rule-select-access-path.d.ts +1 -1
  235. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  236. package/dist/src/planner/rules/access/rule-select-access-path.js +59 -53
  237. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  238. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -1
  239. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +62 -2
  240. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
  241. package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts.map +1 -1
  242. package/dist/src/planner/rules/cache/rule-materialization-advisory.js +31 -24
  243. package/dist/src/planner/rules/cache/rule-materialization-advisory.js.map +1 -1
  244. package/dist/src/planner/scopes/base.d.ts +0 -10
  245. package/dist/src/planner/scopes/base.d.ts.map +1 -1
  246. package/dist/src/planner/scopes/base.js +0 -14
  247. package/dist/src/planner/scopes/base.js.map +1 -1
  248. package/dist/src/planner/scopes/empty.d.ts +0 -2
  249. package/dist/src/planner/scopes/empty.d.ts.map +1 -1
  250. package/dist/src/planner/scopes/empty.js +0 -8
  251. package/dist/src/planner/scopes/empty.js.map +1 -1
  252. package/dist/src/planner/scopes/multi.d.ts.map +1 -1
  253. package/dist/src/planner/scopes/multi.js +0 -1
  254. package/dist/src/planner/scopes/multi.js.map +1 -1
  255. package/dist/src/planner/scopes/param.d.ts.map +1 -1
  256. package/dist/src/planner/scopes/param.js +0 -1
  257. package/dist/src/planner/scopes/param.js.map +1 -1
  258. package/dist/src/planner/scopes/registered.d.ts +0 -10
  259. package/dist/src/planner/scopes/registered.d.ts.map +1 -1
  260. package/dist/src/planner/scopes/registered.js +1 -17
  261. package/dist/src/planner/scopes/registered.js.map +1 -1
  262. package/dist/src/planner/scopes/scope.d.ts +0 -8
  263. package/dist/src/planner/scopes/scope.d.ts.map +1 -1
  264. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  265. package/dist/src/planner/validation/plan-validator.js +1 -7
  266. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  267. package/dist/src/runtime/context-helpers.d.ts +45 -0
  268. package/dist/src/runtime/context-helpers.d.ts.map +1 -0
  269. package/dist/src/runtime/context-helpers.js +139 -0
  270. package/dist/src/runtime/context-helpers.js.map +1 -0
  271. package/dist/src/runtime/emission-context.d.ts +1 -0
  272. package/dist/src/runtime/emission-context.d.ts.map +1 -1
  273. package/dist/src/runtime/emission-context.js +2 -1
  274. package/dist/src/runtime/emission-context.js.map +1 -1
  275. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  276. package/dist/src/runtime/emit/aggregate.js +119 -86
  277. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  278. package/dist/src/runtime/emit/between.d.ts +5 -0
  279. package/dist/src/runtime/emit/between.d.ts.map +1 -0
  280. package/dist/src/runtime/emit/between.js +38 -0
  281. package/dist/src/runtime/emit/between.js.map +1 -0
  282. package/dist/src/runtime/emit/binary.d.ts +0 -1
  283. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  284. package/dist/src/runtime/emit/binary.js +0 -36
  285. package/dist/src/runtime/emit/binary.js.map +1 -1
  286. package/dist/src/runtime/emit/column-reference.d.ts.map +1 -1
  287. package/dist/src/runtime/emit/column-reference.js +2 -26
  288. package/dist/src/runtime/emit/column-reference.js.map +1 -1
  289. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  290. package/dist/src/runtime/emit/constraint-check.js +16 -123
  291. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  292. package/dist/src/runtime/emit/cte-reference.d.ts.map +1 -1
  293. package/dist/src/runtime/emit/cte-reference.js +16 -48
  294. package/dist/src/runtime/emit/cte-reference.js.map +1 -1
  295. package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
  296. package/dist/src/runtime/emit/distinct.js +2 -8
  297. package/dist/src/runtime/emit/distinct.js.map +1 -1
  298. package/dist/src/runtime/emit/filter.d.ts.map +1 -1
  299. package/dist/src/runtime/emit/filter.js +6 -13
  300. package/dist/src/runtime/emit/filter.js.map +1 -1
  301. package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts +5 -0
  302. package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts.map +1 -0
  303. package/dist/src/runtime/emit/internal-recursive-cte-ref.js +23 -0
  304. package/dist/src/runtime/emit/internal-recursive-cte-ref.js.map +1 -0
  305. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  306. package/dist/src/runtime/emit/join.js +40 -40
  307. package/dist/src/runtime/emit/join.js.map +1 -1
  308. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  309. package/dist/src/runtime/emit/project.js +13 -13
  310. package/dist/src/runtime/emit/project.js.map +1 -1
  311. package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -1
  312. package/dist/src/runtime/emit/recursive-cte.js +3 -14
  313. package/dist/src/runtime/emit/recursive-cte.js.map +1 -1
  314. package/dist/src/runtime/emit/returning.d.ts.map +1 -1
  315. package/dist/src/runtime/emit/returning.js +7 -14
  316. package/dist/src/runtime/emit/returning.js.map +1 -1
  317. package/dist/src/runtime/emit/scan.d.ts +5 -2
  318. package/dist/src/runtime/emit/scan.d.ts.map +1 -1
  319. package/dist/src/runtime/emit/scan.js +21 -17
  320. package/dist/src/runtime/emit/scan.js.map +1 -1
  321. package/dist/src/runtime/emit/sort.d.ts.map +1 -1
  322. package/dist/src/runtime/emit/sort.js +8 -11
  323. package/dist/src/runtime/emit/sort.js.map +1 -1
  324. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  325. package/dist/src/runtime/emit/subquery.js +95 -40
  326. package/dist/src/runtime/emit/subquery.js.map +1 -1
  327. package/dist/src/runtime/emit/table-valued-function.d.ts.map +1 -1
  328. package/dist/src/runtime/emit/table-valued-function.js +7 -22
  329. package/dist/src/runtime/emit/table-valued-function.js.map +1 -1
  330. package/dist/src/runtime/emit/update.d.ts.map +1 -1
  331. package/dist/src/runtime/emit/update.js +20 -27
  332. package/dist/src/runtime/emit/update.js.map +1 -1
  333. package/dist/src/runtime/emit/window.d.ts.map +1 -1
  334. package/dist/src/runtime/emit/window.js +55 -83
  335. package/dist/src/runtime/emit/window.js.map +1 -1
  336. package/dist/src/runtime/emitters.d.ts.map +1 -1
  337. package/dist/src/runtime/emitters.js +49 -1
  338. package/dist/src/runtime/emitters.js.map +1 -1
  339. package/dist/src/runtime/register.d.ts.map +1 -1
  340. package/dist/src/runtime/register.js +5 -4
  341. package/dist/src/runtime/register.js.map +1 -1
  342. package/dist/src/runtime/scheduler.d.ts.map +1 -1
  343. package/dist/src/runtime/scheduler.js +47 -42
  344. package/dist/src/runtime/scheduler.js.map +1 -1
  345. package/dist/src/runtime/types.d.ts +34 -0
  346. package/dist/src/runtime/types.d.ts.map +1 -1
  347. package/dist/src/runtime/types.js +21 -0
  348. package/dist/src/runtime/types.js.map +1 -1
  349. package/dist/src/schema/manager.d.ts.map +1 -1
  350. package/dist/src/schema/manager.js +29 -16
  351. package/dist/src/schema/manager.js.map +1 -1
  352. package/dist/src/schema/table.d.ts +4 -4
  353. package/dist/src/schema/table.d.ts.map +1 -1
  354. package/dist/src/schema/table.js +10 -10
  355. package/dist/src/schema/table.js.map +1 -1
  356. package/dist/src/util/plugin-loader.d.ts +10 -1
  357. package/dist/src/util/plugin-loader.d.ts.map +1 -1
  358. package/dist/src/util/plugin-loader.js +56 -1
  359. package/dist/src/util/plugin-loader.js.map +1 -1
  360. package/dist/src/util/working-table-iterable.d.ts.map +1 -1
  361. package/dist/src/util/working-table-iterable.js +8 -8
  362. package/dist/src/util/working-table-iterable.js.map +1 -1
  363. package/dist/src/vtab/manifest.d.ts +36 -0
  364. package/dist/src/vtab/manifest.d.ts.map +1 -1
  365. package/dist/src/vtab/table.d.ts +1 -1
  366. package/dist/src/vtab/table.d.ts.map +1 -1
  367. package/package.json +8 -3
  368. package/src/common/types.ts +1 -0
  369. package/src/core/database.ts +48 -6
  370. package/src/core/statement.ts +1 -49
  371. package/src/func/builtins/explain.ts +0 -11
  372. package/src/index.ts +39 -5
  373. package/src/parser/ast.ts +12 -6
  374. package/src/parser/parser.ts +45 -52
  375. package/src/planner/analysis/const-pass.ts +281 -270
  376. package/src/planner/building/constraint-builder.ts +114 -0
  377. package/src/planner/building/delete.ts +18 -5
  378. package/src/planner/building/expression.ts +35 -7
  379. package/src/planner/building/insert.ts +16 -3
  380. package/src/planner/building/select-aggregates.ts +57 -11
  381. package/src/planner/building/select-context.ts +22 -12
  382. package/src/planner/building/select-modifiers.ts +35 -21
  383. package/src/planner/building/select-projections.ts +25 -26
  384. package/src/planner/building/select-window.ts +14 -9
  385. package/src/planner/building/select.ts +163 -31
  386. package/src/planner/building/table.ts +1 -40
  387. package/src/planner/building/update.ts +22 -7
  388. package/src/planner/building/with.ts +12 -13
  389. package/src/planner/cache/correlation-detector.ts +83 -0
  390. package/src/planner/cache/materialization-advisory.ts +71 -50
  391. package/src/planner/cache/reference-graph.ts +115 -91
  392. package/src/planner/debug.ts +163 -0
  393. package/src/planner/framework/context.ts +36 -2
  394. package/src/planner/framework/registry.ts +261 -274
  395. package/src/planner/nodes/add-constraint-node.ts +5 -1
  396. package/src/planner/nodes/aggregate-node.ts +6 -4
  397. package/src/planner/nodes/cache-node.ts +2 -2
  398. package/src/planner/nodes/constraint-check-node.ts +49 -15
  399. package/src/planner/nodes/create-index-node.ts +5 -1
  400. package/src/planner/nodes/create-table-node.ts +5 -1
  401. package/src/planner/nodes/create-view-node.ts +5 -1
  402. package/src/planner/nodes/cte-node.ts +45 -14
  403. package/src/planner/nodes/cte-reference-node.ts +49 -13
  404. package/src/planner/nodes/delete-node.ts +31 -7
  405. package/src/planner/nodes/distinct-node.ts +2 -2
  406. package/src/planner/nodes/dml-executor-node.ts +3 -3
  407. package/src/planner/nodes/drop-table-node.ts +5 -1
  408. package/src/planner/nodes/drop-view-node.ts +5 -1
  409. package/src/planner/nodes/filter.ts +3 -3
  410. package/src/planner/nodes/function.ts +93 -93
  411. package/src/planner/nodes/insert-node.ts +28 -5
  412. package/src/planner/nodes/internal-recursive-cte-ref-node.ts +76 -0
  413. package/src/planner/nodes/join-node.ts +3 -3
  414. package/src/planner/nodes/limit-offset.ts +2 -2
  415. package/src/planner/nodes/plan-node-type.ts +1 -1
  416. package/src/planner/nodes/plan-node.ts +39 -2
  417. package/src/planner/nodes/project-node.ts +39 -19
  418. package/src/planner/nodes/recursive-cte-node.ts +37 -9
  419. package/src/planner/nodes/reference.ts +4 -2
  420. package/src/planner/nodes/returning-node.ts +25 -13
  421. package/src/planner/nodes/scalar.ts +95 -11
  422. package/src/planner/nodes/sequencing-node.ts +2 -2
  423. package/src/planner/nodes/set-operation-node.ts +3 -3
  424. package/src/planner/nodes/single-row.ts +7 -2
  425. package/src/planner/nodes/sink-node.ts +5 -5
  426. package/src/planner/nodes/sort.ts +2 -2
  427. package/src/planner/nodes/stream-aggregate.ts +76 -12
  428. package/src/planner/nodes/subquery.ts +90 -27
  429. package/src/planner/nodes/{physical-access-nodes.ts → table-access-nodes.ts} +6 -6
  430. package/src/planner/nodes/update-node.ts +31 -13
  431. package/src/planner/nodes/window-node.ts +28 -22
  432. package/src/planner/optimizer.ts +257 -263
  433. package/src/planner/planning-context.ts +15 -0
  434. package/src/planner/rules/access/rule-select-access-path.ts +68 -64
  435. package/src/planner/rules/aggregate/rule-aggregate-streaming.ts +74 -2
  436. package/src/planner/rules/cache/rule-materialization-advisory.ts +31 -27
  437. package/src/planner/scopes/base.ts +0 -17
  438. package/src/planner/scopes/empty.ts +0 -10
  439. package/src/planner/scopes/multi.ts +0 -1
  440. package/src/planner/scopes/param.ts +0 -1
  441. package/src/planner/scopes/registered.ts +1 -20
  442. package/src/planner/scopes/scope.ts +0 -12
  443. package/src/planner/validation/plan-validator.ts +1 -8
  444. package/src/runtime/context-helpers.ts +191 -0
  445. package/src/runtime/emission-context.ts +5 -2
  446. package/src/runtime/emit/aggregate.ts +131 -85
  447. package/src/runtime/emit/between.ts +51 -0
  448. package/src/runtime/emit/binary.ts +0 -46
  449. package/src/runtime/emit/column-reference.ts +3 -36
  450. package/src/runtime/emit/constraint-check.ts +19 -144
  451. package/src/runtime/emit/cte-reference.ts +23 -60
  452. package/src/runtime/emit/distinct.ts +2 -7
  453. package/src/runtime/emit/filter.ts +6 -13
  454. package/src/runtime/emit/internal-recursive-cte-ref.ts +37 -0
  455. package/src/runtime/emit/join.ts +45 -43
  456. package/src/runtime/emit/project.ts +18 -12
  457. package/src/runtime/emit/recursive-cte.ts +3 -12
  458. package/src/runtime/emit/returning.ts +7 -14
  459. package/src/runtime/emit/scan.ts +25 -23
  460. package/src/runtime/emit/sort.ts +8 -11
  461. package/src/runtime/emit/subquery.ts +108 -48
  462. package/src/runtime/emit/table-valued-function.ts +7 -20
  463. package/src/runtime/emit/update.ts +22 -29
  464. package/src/runtime/emit/window.ts +74 -88
  465. package/src/runtime/emitters.ts +52 -1
  466. package/src/runtime/register.ts +5 -4
  467. package/src/runtime/scheduler.ts +54 -54
  468. package/src/runtime/types.ts +45 -0
  469. package/src/schema/manager.ts +34 -19
  470. package/src/schema/table.ts +8 -8
  471. package/src/util/plugin-loader.ts +78 -4
  472. package/src/util/working-table-iterable.ts +15 -7
  473. package/src/vtab/manifest.ts +42 -0
  474. package/src/vtab/table.ts +1 -1
  475. package/src/planner/nodes/scan.ts +0 -103
  476. package/src/planner/rules/physical/rule-mark-physical.ts +0 -37
  477. package/src/runtime/emit/table-reference.ts +0 -92
@@ -0,0 +1,114 @@
1
+ import type { PlanningContext } from '../planning-context.js';
2
+ import type { TableSchema, RowConstraintSchema } from '../../schema/table.js';
3
+ import type { RowOpFlag } from '../../schema/table.js';
4
+ import type { Attribute, RowDescriptor } from '../nodes/plan-node.js';
5
+ import type { ConstraintCheck } from '../nodes/constraint-check-node.js';
6
+ import { RegisteredScope } from '../scopes/registered.js';
7
+ import { buildExpression } from './expression.js';
8
+ import { ColumnReferenceNode } from '../nodes/reference.js';
9
+ import type { ScalarPlanNode } from '../nodes/plan-node.js';
10
+ import * as AST from '../../parser/ast.js';
11
+
12
+ /**
13
+ * Determines if a constraint should be checked for the given operation
14
+ */
15
+ function shouldCheckConstraint(constraint: RowConstraintSchema, operation: RowOpFlag): boolean {
16
+ // Check if the current operation is in the constraint's operations bitmask
17
+ return (constraint.operations & operation) !== 0;
18
+ }
19
+
20
+ /**
21
+ * Builds constraint check expressions at plan time.
22
+ * This allows the optimizer to see and optimize constraint expressions.
23
+ */
24
+ export function buildConstraintChecks(
25
+ ctx: PlanningContext,
26
+ tableSchema: TableSchema,
27
+ operation: RowOpFlag,
28
+ oldAttributes: Attribute[],
29
+ newAttributes: Attribute[],
30
+ _flatRowDescriptor: RowDescriptor
31
+ ): ConstraintCheck[] {
32
+ // Build attribute ID mappings for column registration
33
+ const newAttrIdByCol: Record<string, number> = {};
34
+ const oldAttrIdByCol: Record<string, number> = {};
35
+
36
+ newAttributes.forEach((attr, columnIndex) => {
37
+ if (columnIndex < tableSchema.columns.length) {
38
+ const column = tableSchema.columns[columnIndex];
39
+ newAttrIdByCol[column.name.toLowerCase()] = attr.id;
40
+ }
41
+ });
42
+
43
+ oldAttributes.forEach((attr, columnIndex) => {
44
+ if (columnIndex < tableSchema.columns.length) {
45
+ const column = tableSchema.columns[columnIndex];
46
+ oldAttrIdByCol[column.name.toLowerCase()] = attr.id;
47
+ }
48
+ });
49
+
50
+ // Filter constraints by operation
51
+ const applicableConstraints = tableSchema.checkConstraints
52
+ .filter(constraint => shouldCheckConstraint(constraint, operation));
53
+
54
+ // Build expression nodes for each constraint
55
+ return applicableConstraints.map(constraint => {
56
+ // Create scope with OLD/NEW column access for constraint evaluation
57
+ const constraintScope = new RegisteredScope(ctx.scope);
58
+
59
+ // Register column symbols (similar to current emitConstraintCheck logic)
60
+ tableSchema.columns.forEach((tableColumn, tableColIndex) => {
61
+ const colNameLower = tableColumn.name.toLowerCase();
62
+
63
+ // Register NEW.col and unqualified col (defaults to NEW for INSERT/UPDATE, OLD for DELETE)
64
+ const newAttrId = newAttrIdByCol[colNameLower];
65
+ if (newAttrId !== undefined) {
66
+ const newColumnType = {
67
+ typeClass: 'scalar' as const,
68
+ affinity: tableColumn.affinity,
69
+ nullable: !tableColumn.notNull,
70
+ isReadOnly: false
71
+ };
72
+
73
+ // NEW.column
74
+ constraintScope.registerSymbol(`new.${colNameLower}`, (exp, s) =>
75
+ new ColumnReferenceNode(s, exp as AST.ColumnExpr, newColumnType, newAttrId, tableColIndex));
76
+
77
+ // For INSERT/UPDATE, unqualified column defaults to NEW
78
+ if (operation === 1 || operation === 2) { // INSERT or UPDATE
79
+ constraintScope.registerSymbol(colNameLower, (exp, s) =>
80
+ new ColumnReferenceNode(s, exp as AST.ColumnExpr, newColumnType, newAttrId, tableColIndex));
81
+ }
82
+ }
83
+
84
+ // Register OLD.col
85
+ const oldAttrId = oldAttrIdByCol[colNameLower];
86
+ if (oldAttrId !== undefined) {
87
+ const oldColumnType = {
88
+ typeClass: 'scalar' as const,
89
+ affinity: tableColumn.affinity,
90
+ nullable: true, // OLD values can be NULL (especially for INSERT)
91
+ isReadOnly: false
92
+ };
93
+
94
+ // OLD.column
95
+ constraintScope.registerSymbol(`old.${colNameLower}`, (exp, s) =>
96
+ new ColumnReferenceNode(s, exp as AST.ColumnExpr, oldColumnType, oldAttrId, tableColIndex));
97
+
98
+ // For DELETE, unqualified column defaults to OLD
99
+ if (operation === 4) { // DELETE
100
+ constraintScope.registerSymbol(colNameLower, (exp, s) =>
101
+ new ColumnReferenceNode(s, exp as AST.ColumnExpr, oldColumnType, oldAttrId, tableColIndex));
102
+ }
103
+ }
104
+ });
105
+
106
+ // Build the constraint expression using the specialized scope
107
+ const expression = buildExpression(
108
+ { ...ctx, scope: constraintScope },
109
+ constraint.expr
110
+ ) as ScalarPlanNode;
111
+
112
+ return { constraint, expression };
113
+ });
114
+ }
@@ -1,7 +1,7 @@
1
1
  import type * as AST from '../../parser/ast.js';
2
2
  import type { PlanningContext } from '../planning-context.js';
3
3
  import { DeleteNode } from '../nodes/delete-node.js';
4
- import { buildTableReference, buildTableScan } from './table.js';
4
+ import { buildTableReference } from './table.js';
5
5
  import { buildExpression } from './expression.js';
6
6
  import { PlanNode, type RelationalPlanNode, type ScalarPlanNode } from '../nodes/plan-node.js';
7
7
  import { FilterNode } from '../nodes/filter.js';
@@ -11,10 +11,11 @@ import { RegisteredScope } from '../scopes/registered.js';
11
11
  import { ColumnReferenceNode } from '../nodes/reference.js';
12
12
  import { SinkNode } from '../nodes/sink-node.js';
13
13
  import { ConstraintCheckNode } from '../nodes/constraint-check-node.js';
14
- import { RowOp } from '../../schema/table.js';
14
+ import { RowOpFlag } from '../../schema/table.js';
15
15
  import { ReturningNode } from '../nodes/returning-node.js';
16
16
  import { buildOldNewRowDescriptors } from '../../util/row-descriptor.js';
17
17
  import { DmlExecutorNode } from '../nodes/dml-executor-node.js';
18
+ import { buildConstraintChecks } from './constraint-builder.js';
18
19
 
19
20
  export function buildDeleteStmt(
20
21
  ctx: PlanningContext,
@@ -23,7 +24,7 @@ export function buildDeleteStmt(
23
24
  const tableReference = buildTableReference({ type: 'table', table: stmt.table }, ctx);
24
25
 
25
26
  // Plan the source of rows to delete. This is typically the table itself, potentially filtered.
26
- let sourceNode: RelationalPlanNode = buildTableScan({ type: 'table', table: stmt.table }, ctx);
27
+ let sourceNode: RelationalPlanNode = buildTableReference({ type: 'table', table: stmt.table }, ctx);
27
28
 
28
29
  // Create a new scope with the table columns registered for column resolution
29
30
  const tableScope = new RegisteredScope(ctx.scope);
@@ -69,14 +70,26 @@ export function buildDeleteStmt(
69
70
 
70
71
  const { oldRowDescriptor, newRowDescriptor, flatRowDescriptor } = buildOldNewRowDescriptors(oldAttributes, newAttributes);
71
72
 
73
+ // Build constraint checks at plan time
74
+ const constraintChecks = buildConstraintChecks(
75
+ deleteCtx,
76
+ tableReference.tableSchema,
77
+ RowOpFlag.DELETE,
78
+ oldAttributes,
79
+ newAttributes,
80
+ flatRowDescriptor
81
+ );
82
+
72
83
  // Always inject ConstraintCheckNode for DELETE operations
73
84
  const constraintCheckNode = new ConstraintCheckNode(
74
85
  deleteCtx.scope,
75
86
  sourceNode,
76
87
  tableReference,
77
- RowOp.DELETE,
88
+ RowOpFlag.DELETE,
78
89
  oldRowDescriptor,
79
- newRowDescriptor
90
+ newRowDescriptor,
91
+ flatRowDescriptor,
92
+ constraintChecks
80
93
  );
81
94
 
82
95
  const deleteNode = new DeleteNode(
@@ -1,6 +1,6 @@
1
1
  import type * as AST from '../../parser/ast.js';
2
2
  import type { PlanningContext } from '../planning-context.js';
3
- import { LiteralNode, BinaryOpNode, UnaryOpNode, CaseExprNode, CastNode, CollateNode } from '../nodes/scalar.js';
3
+ import { LiteralNode, BinaryOpNode, UnaryOpNode, CaseExprNode, CastNode, CollateNode, BetweenNode } from '../nodes/scalar.js';
4
4
  import { ScalarSubqueryNode, InNode, ExistsNode } from '../nodes/subquery.js';
5
5
  import { WindowFunctionCallNode } from '../nodes/window-function.js';
6
6
  import type { ScalarPlanNode, RelationalPlanNode } from '../nodes/plan-node.js';
@@ -12,7 +12,13 @@ import { Ambiguous } from '../scopes/scope.js';
12
12
  import { buildSelectStmt } from './select.js';
13
13
  import { resolveWindowFunction } from '../../schema/window-function.js';
14
14
  import { buildFunctionCall } from './function-call.js';
15
+ import { createLogger } from '../../common/logger.js';
15
16
 
17
+ const logger = createLogger('planner:expression');
18
+
19
+ /**
20
+ * Builds an expression plan node from an AST expression.
21
+ */
16
22
  export function buildExpression(ctx: PlanningContext, expr: AST.Expression, allowAggregates: boolean = false): ScalarPlanNode {
17
23
  switch (expr.type) {
18
24
  case 'literal':
@@ -92,8 +98,16 @@ export function buildExpression(ctx: PlanningContext, expr: AST.Expression, allo
92
98
  case 'subquery': {
93
99
  // For scalar subqueries, create a context that allows correlation
94
100
  // The buildSelectStmt will create the proper scope chain with subquery tables taking precedence
95
- const subqueryContext = { ...ctx };
96
- const subqueryPlan = buildSelectStmt(subqueryContext, expr.query);
101
+ // CRITICAL: Share the cteReferenceCache to ensure consistent attribute IDs across contexts
102
+ logger(`Building scalar subquery - ctx.cteReferenceCache size: ${ctx.cteReferenceCache?.size ?? 'undefined'}`);
103
+ const subqueryContext = {
104
+ ...ctx,
105
+ cteReferenceCache: ctx.cteReferenceCache || new Map()
106
+ };
107
+ // Preserve input columns in scalar subqueries to ensure correlated predicates
108
+ // have access to all underlying attributes.
109
+ const subqueryPlan = buildSelectStmt(subqueryContext, expr.query, ctx.cteNodes, true);
110
+ logger(`Building scalar subquery with preserveInputColumns=true`);
97
111
  if (subqueryPlan.getType().typeClass !== 'relation') {
98
112
  throw new QuereusError('Subquery must produce a relation', StatusCode.ERROR, undefined, expr.loc?.start.line, expr.loc?.start.column);
99
113
  }
@@ -138,8 +152,11 @@ export function buildExpression(ctx: PlanningContext, expr: AST.Expression, allo
138
152
 
139
153
  if (expr.subquery) {
140
154
  // IN subquery: expr IN (SELECT ...)
141
- const inSubqueryContext = { ...ctx };
142
- const inSubqueryPlan = buildSelectStmt(inSubqueryContext, expr.subquery);
155
+ const inSubqueryContext = {
156
+ ...ctx,
157
+ cteReferenceCache: ctx.cteReferenceCache || new Map()
158
+ };
159
+ const inSubqueryPlan = buildSelectStmt(inSubqueryContext, expr.subquery, ctx.cteNodes, true);
143
160
  if (inSubqueryPlan.getType().typeClass !== 'relation') {
144
161
  throw new QuereusError('IN subquery must produce a relation', StatusCode.ERROR, undefined, expr.loc?.start.line, expr.loc?.start.column);
145
162
  }
@@ -162,14 +179,25 @@ export function buildExpression(ctx: PlanningContext, expr: AST.Expression, allo
162
179
 
163
180
  case 'exists': {
164
181
  // Build the EXISTS subquery
165
- const existsSubqueryContext = { ...ctx };
166
- const existsSubqueryPlan = buildSelectStmt(existsSubqueryContext, expr.subquery);
182
+ const existsSubqueryContext = {
183
+ ...ctx,
184
+ cteReferenceCache: ctx.cteReferenceCache || new Map()
185
+ };
186
+ const existsSubqueryPlan = buildSelectStmt(existsSubqueryContext, expr.subquery, ctx.cteNodes, true);
167
187
  if (existsSubqueryPlan.getType().typeClass !== 'relation') {
168
188
  throw new QuereusError('EXISTS subquery must produce a relation', StatusCode.ERROR, undefined, expr.loc?.start.line, expr.loc?.start.column);
169
189
  }
170
190
  return new ExistsNode(ctx.scope, expr, existsSubqueryPlan as RelationalPlanNode);
171
191
  }
172
192
 
193
+ case 'between': {
194
+ // Build the BETWEEN expression: expr BETWEEN lower AND upper
195
+ const exprNode = buildExpression(ctx, expr.expr, allowAggregates);
196
+ const lowerNode = buildExpression(ctx, expr.lower, allowAggregates);
197
+ const upperNode = buildExpression(ctx, expr.upper, allowAggregates);
198
+ return new BetweenNode(ctx.scope, expr, exprNode, lowerNode, upperNode);
199
+ }
200
+
173
201
  default:
174
202
  throw new QuereusError(`Expression type '${(expr as any).type}' not yet supported in buildExpression.`, StatusCode.UNSUPPORTED, undefined, expr.loc?.start.line, expr.loc?.start.column);
175
203
  }
@@ -16,11 +16,12 @@ import { RegisteredScope } from '../scopes/registered.js';
16
16
  import { ColumnReferenceNode } from '../nodes/reference.js';
17
17
  import { SinkNode } from '../nodes/sink-node.js';
18
18
  import { ConstraintCheckNode } from '../nodes/constraint-check-node.js';
19
- import { RowOp } from '../../schema/table.js';
19
+ import { RowOpFlag } from '../../schema/table.js';
20
20
  import { ReturningNode } from '../nodes/returning-node.js';
21
21
  import { ProjectNode, type Projection } from '../nodes/project-node.js';
22
22
  import { buildOldNewRowDescriptors } from '../../util/row-descriptor.js';
23
23
  import { DmlExecutorNode } from '../nodes/dml-executor-node.js';
24
+ import { buildConstraintChecks } from './constraint-builder.js';
24
25
 
25
26
  /**
26
27
  * Creates a uniform row expansion projection that maps any relational source
@@ -243,6 +244,16 @@ export function buildInsertStmt(
243
244
 
244
245
  const { oldRowDescriptor, newRowDescriptor, flatRowDescriptor } = buildOldNewRowDescriptors(oldAttributes, newAttributes);
245
246
 
247
+ // Build constraint checks at plan time
248
+ const constraintChecks = buildConstraintChecks(
249
+ ctx,
250
+ tableReference.tableSchema,
251
+ RowOpFlag.INSERT,
252
+ oldAttributes,
253
+ newAttributes,
254
+ flatRowDescriptor
255
+ );
256
+
246
257
  const insertNode = new InsertNode(
247
258
  ctx.scope,
248
259
  tableReference,
@@ -255,9 +266,11 @@ export function buildInsertStmt(
255
266
  ctx.scope,
256
267
  insertNode,
257
268
  tableReference,
258
- RowOp.INSERT,
269
+ RowOpFlag.INSERT,
259
270
  oldRowDescriptor,
260
- newRowDescriptor
271
+ newRowDescriptor,
272
+ flatRowDescriptor,
273
+ constraintChecks
261
274
  );
262
275
 
263
276
  // Add DML executor node to perform the actual database insert operations
@@ -27,17 +27,17 @@ export function buildAggregatePhase(
27
27
  needsFinalProjection: boolean;
28
28
  preAggregateSort: boolean;
29
29
  } {
30
+ const hasGroupBy = stmt.groupBy && stmt.groupBy.length > 0;
31
+
30
32
  // If there is a HAVING clause but the SELECT contains **no aggregate functions**
31
- // we can safely treat the HAVING predicate as a regular filter that runs *before*
32
- // the aggregation (i.e. between the source and the AggregateNode). This avoids
33
- // the "missing column context" problem where the predicate refers to columns
33
+ // AND **no GROUP BY**, we can safely treat the HAVING predicate as a regular filter
34
+ // that runs *before* the aggregation (i.e. between the source and the AggregateNode).
35
+ // This avoids the "missing column context" problem where the predicate refers to columns
34
36
  // that are not available after the AggregateNode (only grouping columns and
35
37
  // aggregate results are exposed). This behaviour is compatible with SQLite –
36
38
  // GROUP BY with a primary-key guarantees one row per group so the semantics
37
39
  // are unchanged.
38
- const shouldPushHavingBelowAggregate = Boolean(stmt.having && !hasAggregates);
39
-
40
- const hasGroupBy = stmt.groupBy && stmt.groupBy.length > 0;
40
+ const shouldPushHavingBelowAggregate = Boolean(stmt.having && !hasAggregates && !hasGroupBy);
41
41
 
42
42
  if (!hasAggregates && !hasGroupBy) {
43
43
  return { output: input, needsFinalProjection: false, preAggregateSort: false };
@@ -67,7 +67,7 @@ export function buildAggregatePhase(
67
67
  const groupByExpressions = stmt.groupBy ?
68
68
  stmt.groupBy.map(expr => buildExpression(selectContext, expr, false)) : [];
69
69
 
70
- // Create AggregateNode
70
+ // Create AggregateNode
71
71
  currentInput = new AggregateNode(selectContext.scope, currentInput, groupByExpressions, aggregates);
72
72
 
73
73
  // Create aggregate output scope
@@ -166,6 +166,21 @@ function createAggregateOutputScope(
166
166
  new ColumnReferenceNode(s, exp as AST.ColumnExpr, agg.expression.getType(), attr.id, columnIndex));
167
167
  });
168
168
 
169
+ // Register source columns for HAVING clause access
170
+ // Start after GROUP BY and aggregate columns
171
+ const sourceColumnStartIndex = groupByExpressions.length + aggregates.length;
172
+ for (let i = sourceColumnStartIndex; i < aggregateAttributes.length; i++) {
173
+ const attr = aggregateAttributes[i];
174
+ // Only register if not already registered (avoid conflicts with GROUP BY columns)
175
+ const symbolName = attr.name.toLowerCase();
176
+ const existingSymbols = aggregateOutputScope.getSymbols();
177
+ const alreadyRegistered = existingSymbols.some(([key]) => key === symbolName);
178
+ if (!alreadyRegistered) {
179
+ aggregateOutputScope.registerSymbol(symbolName, (exp, s) =>
180
+ new ColumnReferenceNode(s, exp as AST.ColumnExpr, attr.type, attr.id, i));
181
+ }
182
+ }
183
+
169
184
  return aggregateOutputScope;
170
185
  }
171
186
 
@@ -182,10 +197,35 @@ function buildHavingFilter(
182
197
  ): RelationalPlanNode {
183
198
  const aggregateAttributes = input.getAttributes();
184
199
 
185
- // Build HAVING expression with the aggregate scope
200
+ // Create a hybrid scope that first tries the aggregate output scope,
201
+ // then falls back to the original source scope for column resolution
202
+ const hybridScope = new RegisteredScope();
203
+
204
+ // Copy all symbols from aggregate output scope
205
+ for (const [symbolKey, callback] of aggregateOutputScope.getSymbols()) {
206
+ hybridScope.registerSymbol(symbolKey, callback);
207
+ }
208
+
209
+ // For any source columns not already registered, register them with
210
+ // references to the source table
211
+ const sourceInput = input.getRelations()[0]; // The AggregateNode's source
212
+ const sourceAttributes = sourceInput.getAttributes();
213
+
214
+ sourceAttributes.forEach((sourceAttr, sourceIndex) => {
215
+ const symbolName = sourceAttr.name.toLowerCase();
216
+ const existingSymbols = hybridScope.getSymbols();
217
+ const alreadyRegistered = existingSymbols.some(([key]) => key === symbolName);
218
+
219
+ if (!alreadyRegistered) {
220
+ hybridScope.registerSymbol(symbolName, (exp, s) =>
221
+ new ColumnReferenceNode(s, exp as AST.ColumnExpr, sourceAttr.type, sourceAttr.id, sourceIndex));
222
+ }
223
+ });
224
+
225
+ // Build HAVING expression with the hybrid scope
186
226
  const havingContext: PlanningContext = {
187
227
  ...selectContext,
188
- scope: aggregateOutputScope,
228
+ scope: hybridScope,
189
229
  aggregates: aggregates.map((agg, index) => {
190
230
  const columnIndex = groupByExpressions.length + index;
191
231
  const attr = aggregateAttributes[columnIndex];
@@ -200,7 +240,7 @@ function buildHavingFilter(
200
240
 
201
241
  const havingExpression = buildExpression(havingContext, havingClause, true);
202
242
 
203
- return new FilterNode(aggregateOutputScope, input, havingExpression);
243
+ return new FilterNode(hybridScope, input, havingExpression);
204
244
  }
205
245
 
206
246
  /**
@@ -234,9 +274,15 @@ export function buildFinalAggregateProjections(
234
274
  const finalContext: PlanningContext = { ...selectContext, scope: aggregateOutputScope };
235
275
  const scalarNode = buildExpression(finalContext, column.expr, true);
236
276
 
277
+ let attrId: number | undefined = undefined;
278
+ if (scalarNode instanceof ColumnReferenceNode) {
279
+ attrId = scalarNode.attributeId;
280
+ }
281
+
237
282
  finalProjections.push({
238
283
  node: scalarNode,
239
- alias: column.alias || (column.expr.type === 'column' ? column.expr.name : undefined)
284
+ alias: column.alias || (column.expr.type === 'column' ? column.expr.name : undefined),
285
+ attributeId: attrId
240
286
  });
241
287
  }
242
288
  }
@@ -27,8 +27,8 @@ export function buildWithContext(
27
27
  contextWithCTEs: PlanningContext;
28
28
  cteNodes: Map<string, CTEPlanNode>;
29
29
  } {
30
- // Start with parent CTEs
31
- const cteNodes: Map<string, CTEPlanNode> = new Map(parentCTEs);
30
+ // Start with parent CTEs - either from parameter or from context
31
+ const cteNodes: Map<string, CTEPlanNode> = new Map(parentCTEs.size > 0 ? parentCTEs : (ctx.cteNodes ?? new Map()));
32
32
  let contextWithCTEs = ctx;
33
33
 
34
34
  if (stmt.withClause) {
@@ -40,11 +40,11 @@ export function buildWithContext(
40
40
 
41
41
  // Create a new scope that includes the CTEs
42
42
  const cteScope = createCTEScope(cteNodes, ctx);
43
- contextWithCTEs = { ...ctx, scope: cteScope };
44
- } else if (parentCTEs.size > 0) {
43
+ contextWithCTEs = { ...ctx, scope: cteScope, cteNodes, cteReferenceCache: ctx.cteReferenceCache };
44
+ } else if (cteNodes.size > 0) {
45
45
  // No WITH clause but we have parent CTEs, create scope for them
46
- const cteScope = createCTEScope(parentCTEs, ctx);
47
- contextWithCTEs = { ...ctx, scope: cteScope };
46
+ const cteScope = createCTEScope(cteNodes, ctx);
47
+ contextWithCTEs = { ...ctx, scope: cteScope, cteNodes, cteReferenceCache: ctx.cteReferenceCache };
48
48
  }
49
49
 
50
50
  return { contextWithCTEs, cteNodes };
@@ -52,6 +52,8 @@ export function buildWithContext(
52
52
 
53
53
  /**
54
54
  * Creates a scope that includes CTE references
55
+ * CRITICAL: Uses stable input attribute IDs only, ignoring any projection output scopes
56
+ * that might cause attribute ID collisions in correlated subqueries
55
57
  */
56
58
  function createCTEScope(
57
59
  cteNodes: Map<string, CTEPlanNode>,
@@ -61,13 +63,21 @@ function createCTEScope(
61
63
 
62
64
  // Register each CTE in the scope
63
65
  for (const [cteName, cteNode] of cteNodes) {
66
+ // CRITICAL: Use only the stable input attributes from the CTE definition
67
+ // Do NOT use any projection output attributes that might have fresh IDs
64
68
  const attributes = cteNode.getAttributes();
65
- cteNode.getType().columns.forEach((col: any, i: number) => {
66
- const attr = attributes[i];
67
- // Register CTE columns with qualified names to avoid collisions
68
- const qualifiedColumnName = `${cteName}.${col.name.toLowerCase()}`;
69
- cteScope.registerSymbol(qualifiedColumnName, (exp, s) =>
70
- new ColumnReferenceNode(s, exp as AST.ColumnExpr, col.type, attr.id, i));
69
+ const columnTypes = cteNode.getType().columns;
70
+
71
+ // Only register columns that are stable input attributes
72
+ // This prevents scope pollution from projection output attributes
73
+ columnTypes.forEach((col: any, i: number) => {
74
+ if (i < attributes.length) {
75
+ const attr = attributes[i];
76
+ // Register CTE columns with qualified names to avoid collisions
77
+ const qualifiedColumnName = `${cteName}.${col.name.toLowerCase()}`;
78
+ cteScope.registerSymbol(qualifiedColumnName, (exp, s) =>
79
+ new ColumnReferenceNode(s, exp as AST.ColumnExpr, col.type, attr.id, i));
80
+ }
71
81
  });
72
82
  }
73
83
 
@@ -20,23 +20,25 @@ export function buildFinalProjections(
20
20
  projections: Projection[],
21
21
  selectScope: any,
22
22
  stmt: AST.SelectStmt,
23
- selectContext: PlanningContext
23
+ selectContext: PlanningContext,
24
+ preserveInputColumns: boolean = true
24
25
  ): {
25
26
  output: RelationalPlanNode;
26
27
  finalContext: PlanningContext;
28
+ projectionScope?: RegisteredScope;
27
29
  preAggregateSort: boolean;
28
30
  } {
29
31
  if (projections.length === 0) {
30
32
  return { output: input, finalContext: selectContext, preAggregateSort: false };
31
33
  }
32
34
 
33
- // Check if ORDER BY should be applied before projection
35
+ // Check if ORDER BY should be applied before projection (using input scope only)
34
36
  const needsPreProjectionSort = shouldApplyOrderByBeforeProjection(stmt, projections);
35
37
  let preAggregateSort = false;
36
38
 
37
39
  let currentInput = input;
38
40
 
39
- // Apply ORDER BY before projection if needed
41
+ // Apply ORDER BY before projection if needed (compile expressions against input scope)
40
42
  if (needsPreProjectionSort && stmt.orderBy && stmt.orderBy.length > 0) {
41
43
  const sortKeys: SortKey[] = stmt.orderBy.map(orderByClause => {
42
44
  const expression = buildExpression(selectContext, orderByClause.expr);
@@ -50,21 +52,17 @@ export function buildFinalProjections(
50
52
  preAggregateSort = true;
51
53
  }
52
54
 
53
- currentInput = new ProjectNode(selectScope, currentInput, projections);
55
+ // Create the ProjectNode only after all expressions are compiled against input scope
56
+ currentInput = new ProjectNode(selectScope, currentInput, projections, undefined, undefined, preserveInputColumns);
54
57
 
55
- // Create a new scope that maps column names to the ProjectNode's output attributes
58
+ // Create projection output scope but DON'T merge it into finalContext yet
59
+ // Let the caller decide when to make these output attributes visible
56
60
  const projectionOutputScope = createProjectionOutputScope(currentInput);
57
61
 
58
- // Update selectContext to use BOTH the projection output scope AND the original scope
59
- let finalContext = selectContext;
60
- if (!needsPreProjectionSort) {
61
- const combinedScope = new MultiScope([projectionOutputScope, selectScope]);
62
- finalContext = { ...selectContext, scope: combinedScope };
63
- }
64
-
65
62
  return {
66
63
  output: currentInput,
67
- finalContext,
64
+ finalContext: selectContext, // Keep unchanged - no premature scope pollution
65
+ projectionScope: projectionOutputScope,
68
66
  preAggregateSort
69
67
  };
70
68
  }
@@ -90,11 +88,19 @@ export function applyOrderBy(
90
88
  input: RelationalPlanNode,
91
89
  stmt: AST.SelectStmt,
92
90
  selectContext: PlanningContext,
93
- preAggregateSort: boolean
91
+ preAggregateSort: boolean,
92
+ projectionScope?: RegisteredScope
94
93
  ): RelationalPlanNode {
95
94
  if (stmt.orderBy && stmt.orderBy.length > 0 && !preAggregateSort) {
95
+ // Merge projection scope if available so ORDER BY can reference output column aliases
96
+ let orderByContext = selectContext;
97
+ if (projectionScope) {
98
+ const combinedScope = new MultiScope([projectionScope, selectContext.scope]);
99
+ orderByContext = { ...selectContext, scope: combinedScope };
100
+ }
101
+
96
102
  const sortKeys: SortKey[] = stmt.orderBy.map(orderByClause => {
97
- const expression = buildExpression(selectContext, orderByClause.expr);
103
+ const expression = buildExpression(orderByContext, orderByClause.expr);
98
104
  return {
99
105
  expression,
100
106
  direction: orderByClause.direction,
@@ -102,7 +108,7 @@ export function applyOrderBy(
102
108
  };
103
109
  });
104
110
 
105
- return new SortNode(selectContext.scope, input, sortKeys);
111
+ return new SortNode(orderByContext.scope, input, sortKeys);
106
112
  }
107
113
  return input;
108
114
  }
@@ -113,13 +119,21 @@ export function applyOrderBy(
113
119
  export function applyLimitOffset(
114
120
  input: RelationalPlanNode,
115
121
  stmt: AST.SelectStmt,
116
- selectContext: PlanningContext
122
+ selectContext: PlanningContext,
123
+ projectionScope?: RegisteredScope
117
124
  ): RelationalPlanNode {
118
125
  if (stmt.limit || stmt.offset) {
119
- const literalNull = new LiteralNode(selectContext.scope, { type: 'literal', value: null });
120
- const limitExpression = stmt.limit ? buildExpression(selectContext, stmt.limit) : literalNull;
121
- const offsetExpression = stmt.offset ? buildExpression(selectContext, stmt.offset) : literalNull;
122
- return new LimitOffsetNode(selectContext.scope, input, limitExpression, offsetExpression);
126
+ // Merge projection scope if available so LIMIT/OFFSET can reference output column aliases
127
+ let limitContext = selectContext;
128
+ if (projectionScope) {
129
+ const combinedScope = new MultiScope([projectionScope, selectContext.scope]);
130
+ limitContext = { ...selectContext, scope: combinedScope };
131
+ }
132
+
133
+ const literalNull = new LiteralNode(limitContext.scope, { type: 'literal', value: null });
134
+ const limitExpression = stmt.limit ? buildExpression(limitContext, stmt.limit) : literalNull;
135
+ const offsetExpression = stmt.offset ? buildExpression(limitContext, stmt.offset) : literalNull;
136
+ return new LimitOffsetNode(limitContext.scope, input, limitExpression, offsetExpression);
123
137
  }
124
138
  return input;
125
139
  }