@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
@@ -9,6 +9,8 @@ import { QuereusError } from '../../common/errors.js';
9
9
  import { StatusCode } from '../../common/types.js';
10
10
  import { AggregateFunctionCallNode } from '../nodes/aggregate-function.js';
11
11
  import { WindowFunctionCallNode } from '../nodes/window-function.js';
12
+ import { type RelationalPlanNode } from '../nodes/plan-node.js';
13
+ import type { Scope } from '../scopes/scope.js';
12
14
 
13
15
  /**
14
16
  * Checks if an expression contains aggregate functions
@@ -53,48 +55,45 @@ export function isWindowExpression(node: ScalarPlanNode): boolean {
53
55
  */
54
56
  export function buildStarProjections(
55
57
  column: { type: 'all'; table?: string },
56
- input: any,
57
- selectScope: any
58
+ source: RelationalPlanNode,
59
+ selectScope: Scope
58
60
  ): Projection[] {
59
- const projections: Projection[] = [];
60
- const inputColumns = input.getType().columns;
61
- const inputAttributes = input.getAttributes();
62
-
63
- if (column.table) {
64
- // Handle qualified SELECT table.*
65
- const inputTableName = input.source?.tableSchema?.name;
66
- const tableMatches = column.table.toLowerCase() === inputTableName?.toLowerCase();
67
- if (!tableMatches) {
68
- throw new QuereusError(
69
- `Table '${column.table}' not found in FROM clause for qualified SELECT *`,
70
- StatusCode.ERROR
71
- );
72
- }
61
+ const allAttributes = source.getAttributes();
62
+
63
+ // Filter by relation name if qualified (e.g., SELECT t1.*)
64
+ const matchingAttributes = column.table
65
+ ? allAttributes.filter(attr =>
66
+ attr.relationName && attr.relationName.toLowerCase() === column.table!.toLowerCase()
67
+ )
68
+ : allAttributes;
69
+
70
+ if (column.table && matchingAttributes.length === 0) {
71
+ throw new QuereusError(
72
+ `Table '${column.table}' not found in FROM clause for qualified SELECT *`,
73
+ StatusCode.ERROR
74
+ );
73
75
  }
74
76
 
75
- // Add a projection for each column in the input relation
76
- inputColumns.forEach((columnDef: any, index: number) => {
77
+ // Convert to projections
78
+ return matchingAttributes.map((attr, index) => {
77
79
  const columnExpr: AST.ColumnExpr = {
78
80
  type: 'column',
79
- name: columnDef.name,
81
+ name: attr.name,
80
82
  };
81
83
 
82
- const attr = inputAttributes[index];
83
84
  const columnRef = new ColumnReferenceNode(
84
85
  selectScope,
85
86
  columnExpr,
86
- columnDef.type,
87
+ attr.type,
87
88
  attr.id,
88
89
  index
89
90
  );
90
91
 
91
- projections.push({
92
+ return {
92
93
  node: columnRef,
93
- alias: columnDef.name
94
- });
94
+ alias: attr.name
95
+ };
95
96
  });
96
-
97
- return projections;
98
97
  }
99
98
 
100
99
  /**
@@ -43,6 +43,17 @@ export function buildWindowPhase(
43
43
  // For now, proceed with WindowNode
44
44
  }
45
45
 
46
+ // CRITICAL: Build window specification expressions using the INPUT scope
47
+ // This ensures expressions reference the correct input attribute IDs,
48
+ // not premature output attribute IDs that don't exist in the runtime context
49
+ const partitionExpressions = windowSpec.partitionBy.map(expr =>
50
+ buildExpression(selectContext, expr, false)
51
+ );
52
+
53
+ const orderByExpressions = windowSpec.orderBy.map(orderClause =>
54
+ buildExpression(selectContext, orderClause.expr, false)
55
+ );
56
+
46
57
  // Create new WindowFunctionCallNode instances with alias information
47
58
  const windowFuncsWithAlias = functions.map(({ func, alias }) =>
48
59
  new WindowFunctionCallNode(
@@ -54,17 +65,9 @@ export function buildWindowPhase(
54
65
  )
55
66
  );
56
67
 
57
- // Build expressions for window specification
58
- const partitionExpressions = windowSpec.partitionBy.map(expr =>
59
- buildExpression(selectContext, expr, false)
60
- );
61
-
62
- const orderByExpressions = windowSpec.orderBy.map(orderClause =>
63
- buildExpression(selectContext, orderClause.expr, false)
64
- );
65
-
66
68
  const functionArguments = buildWindowFunctionArguments(windowFuncsWithAlias, selectContext);
67
69
 
70
+ // Now create the WindowNode with pre-compiled expressions
68
71
  currentInput = new WindowNode(
69
72
  selectContext.scope,
70
73
  currentInput,
@@ -246,3 +249,5 @@ function compareWindowSpecs(originalWindow: any, funcWindow: any): boolean {
246
249
  originalOrder === funcOrder &&
247
250
  originalFrame === funcFrame;
248
251
  }
252
+
253
+
@@ -4,7 +4,7 @@ import { QuereusError } from '../../common/errors.js';
4
4
  import { StatusCode } from '../../common/types.js';
5
5
  import type { PlanningContext } from '../planning-context.js';
6
6
  import { SingleRowNode } from '../nodes/single-row.js';
7
- import { buildTableScan } from './table.js';
7
+ import { buildTableReference } from './table.js';
8
8
  import { AliasedScope } from '../scopes/aliased.js';
9
9
  import { RegisteredScope } from '../scopes/registered.js';
10
10
  import type { Scope } from '../scopes/scope.js';
@@ -14,10 +14,12 @@ import { buildExpression } from './expression.js';
14
14
  import { FilterNode } from '../nodes/filter.js';
15
15
  import { buildTableFunctionCall } from './table-function.js';
16
16
  import { CTEReferenceNode } from '../nodes/cte-reference-node.js';
17
+ import { InternalRecursiveCTERefNode } from '../nodes/internal-recursive-cte-ref-node.js';
17
18
  import type { CTEPlanNode } from '../nodes/cte-node.js';
18
19
  import { JoinNode } from '../nodes/join-node.js';
19
20
  import { ColumnReferenceNode } from '../nodes/reference.js';
20
21
  import { ValuesNode } from '../nodes/values-node.js';
22
+ import { createLogger } from '../../common/logger.js';
21
23
 
22
24
  // Import decomposed functionality
23
25
  import { buildWithContext } from './select-context.js';
@@ -26,16 +28,19 @@ import { analyzeSelectColumns, buildStarProjections } from './select-projections
26
28
  import { buildAggregatePhase, buildFinalAggregateProjections } from './select-aggregates.js';
27
29
  import { buildWindowPhase } from './select-window.js';
28
30
  import { buildFinalProjections, applyDistinct, applyOrderBy, applyLimitOffset } from './select-modifiers.js';
31
+ import { SortNode, type SortKey } from '../nodes/sort.js';
29
32
 
30
33
  import { buildInsertStmt } from './insert.js';
31
34
  import { buildUpdateStmt } from './update.js';
32
35
  import { buildDeleteStmt } from './delete.js';
33
36
 
37
+ const logger = createLogger('planner:cte');
38
+
34
39
  /**
35
40
  * Creates an initial logical query plan for a SELECT statement.
36
41
  *
37
42
  * For this initial version, it only supports simple "SELECT ... FROM one_table" queries,
38
- * effectively returning a TableScanNode for that table.
43
+ * effectively returning a TableReferenceNode for that table.
39
44
  *
40
45
  * @param stmt The AST.SelectStmt to plan.
41
46
  * @param ctx The parent planning context for this SELECT statement.
@@ -46,7 +51,14 @@ import { buildDeleteStmt } from './delete.js';
46
51
  export function buildSelectStmt(
47
52
  ctx: PlanningContext,
48
53
  stmt: AST.SelectStmt,
49
- parentCTEs: Map<string, CTEPlanNode> = new Map()
54
+ parentCTEs: Map<string, CTEPlanNode> = new Map(),
55
+ /**
56
+ * Whether ProjectNodes inside this SELECT should forward all input columns that are not explicitly
57
+ * listed in the projection list. This is desirable for top-level queries (helps ORDER BY, window
58
+ * functions, etc.) but must be switched off for scalar/IN/EXISTS sub-queries which are required to
59
+ * expose only their declared columns.
60
+ */
61
+ preserveInputColumns: boolean = true
50
62
  ): PlanNode {
51
63
 
52
64
  // Phase 0: Handle WITH clause if present
@@ -119,25 +131,82 @@ export function buildSelectStmt(
119
131
  // Build final projections if needed
120
132
  if (aggregateResult.needsFinalProjection) {
121
133
  const finalProjections = buildFinalAggregateProjections(stmt, selectContext, aggregateResult.aggregateScope);
122
- input = new ProjectNode(selectScope, input, finalProjections);
134
+ input = new ProjectNode(selectScope, input, finalProjections, undefined, undefined, preserveInputColumns);
123
135
  }
124
136
  }
125
137
 
126
- // Handle window functions if present
127
- input = buildWindowPhase(input, windowFunctions, selectContext, stmt);
138
+ // Handle window functions if present
139
+ if (hasWindowFunctions) {
140
+ // Check if ORDER BY references columns not in SELECT before applying window functions
141
+ let preWindowSort = false;
142
+ if (stmt.orderBy) {
143
+ const selectedColumns = new Set<string>();
144
+ for (const column of stmt.columns) {
145
+ if (column.type === 'column' && column.expr.type === 'column') {
146
+ selectedColumns.add(column.expr.name.toLowerCase());
147
+ }
148
+ if (column.type === 'column' && column.alias) {
149
+ selectedColumns.add(column.alias.toLowerCase());
150
+ }
151
+ }
152
+
153
+ // Check if ORDER BY references columns not in SELECT
154
+ for (const orderByClause of stmt.orderBy) {
155
+ if (orderByClause.expr.type === 'column') {
156
+ const orderColumn = orderByClause.expr.name.toLowerCase();
157
+ if (!selectedColumns.has(orderColumn)) {
158
+ // Apply ORDER BY before window projections
159
+ const sortKeys: SortKey[] = stmt.orderBy.map(orderBy => ({
160
+ expression: buildExpression(selectContext, orderBy.expr),
161
+ direction: orderBy.direction,
162
+ nulls: orderBy.nulls
163
+ }));
164
+ input = new SortNode(selectContext.scope, input, sortKeys);
165
+ preWindowSort = true;
166
+ break;
167
+ }
168
+ }
169
+ }
170
+ }
171
+
172
+ input = buildWindowPhase(input, windowFunctions, selectContext, stmt);
173
+
174
+ // Update context to include window output columns
175
+ const windowOutputScope = new RegisteredScope(selectContext.scope);
176
+ const windowAttributes = input.getAttributes();
177
+ input.getType().columns.forEach((col, index) => {
178
+ const attr = windowAttributes[index];
179
+ windowOutputScope.registerSymbol(col.name.toLowerCase(), (exp, s) =>
180
+ new ColumnReferenceNode(s, exp as AST.ColumnExpr, col.type, attr.id, index));
181
+ });
182
+
183
+ // Create combined scope that includes both original columns and window output
184
+ const combinedScope = new MultiScope([windowOutputScope, selectScope]);
185
+ selectContext = { ...selectContext, scope: combinedScope };
128
186
 
129
- // Handle final projections for non-aggregate cases
187
+ // Don't apply ORDER BY again if we already did it
188
+ if (preWindowSort) {
189
+ preAggregateSort = true;
190
+ }
191
+ }
192
+
193
+ // Handle final projections for non-aggregate, non-window cases
130
194
  if (!hasAggregates && !hasWindowFunctions) {
131
- const finalResult = buildFinalProjections(input, projections, selectScope, stmt, selectContext);
195
+ const finalResult = buildFinalProjections(input, projections, selectScope, stmt, selectContext, preserveInputColumns);
132
196
  input = finalResult.output;
133
197
  selectContext = finalResult.finalContext;
134
198
  preAggregateSort = finalResult.preAggregateSort;
135
- }
136
199
 
137
- // Apply final modifiers
138
- input = applyDistinct(input, stmt, selectScope);
139
- input = applyOrderBy(input, stmt, selectContext, preAggregateSort);
140
- input = applyLimitOffset(input, stmt, selectContext);
200
+ // Apply final modifiers with projection scope for column alias resolution
201
+ input = applyDistinct(input, stmt, selectScope);
202
+ input = applyOrderBy(input, stmt, selectContext, preAggregateSort, finalResult.projectionScope);
203
+ input = applyLimitOffset(input, stmt, selectContext, finalResult.projectionScope);
204
+ } else {
205
+ // Apply final modifiers without projection scope for aggregate/window cases
206
+ input = applyDistinct(input, stmt, selectScope);
207
+ input = applyOrderBy(input, stmt, selectContext, preAggregateSort);
208
+ input = applyLimitOffset(input, stmt, selectContext);
209
+ }
141
210
 
142
211
  return input;
143
212
  }
@@ -162,6 +231,22 @@ export function buildValuesStmt(
162
231
  return new ValuesNode(ctx.scope, rows);
163
232
  }
164
233
 
234
+ /**
235
+ * Processes a FROM clause item into a relational plan node.
236
+ *
237
+ * Handles different types of FROM items:
238
+ * - Table references - creates a TableReferenceNode
239
+ * - Subqueries - plans the subquery
240
+ * - Joins - builds the join structure
241
+ * - Table functions - creates a table function call node
242
+ *
243
+ * For a simple table reference, this calls buildTableReference which
244
+ * returns a TableReferenceNode for that table.
245
+ *
246
+ * @param fromClause The FROM clause AST node to process
247
+ * @param ctx The planning context
248
+ * @returns A relational plan node representing the FROM clause
249
+ */
165
250
  export function buildFrom(fromClause: AST.FromClause, parentContext: PlanningContext, cteNodes: Map<string, CTEPlanNode> = new Map()): RelationalPlanNode {
166
251
  let fromTable: RelationalPlanNode;
167
252
  let columnScope: Scope;
@@ -169,27 +254,74 @@ export function buildFrom(fromClause: AST.FromClause, parentContext: PlanningCon
169
254
  if (fromClause.type === 'table') {
170
255
  const tableName = fromClause.table.name.toLowerCase();
171
256
 
172
- // Check if this is a CTE reference
257
+ // Check if this is a CTE reference
173
258
  if (cteNodes.has(tableName)) {
174
259
  const cteNode = cteNodes.get(tableName)!;
175
- const cteRefNode = new CTEReferenceNode(parentContext.scope, cteNode, fromClause.alias);
176
-
177
- // Create scope for CTE columns
178
- const cteScope = new RegisteredScope(parentContext.scope);
179
- const cteAttributes = cteNode.getAttributes();
180
- cteNode.getType().columns.forEach((c, i) => {
181
- const attr = cteAttributes[i];
182
- cteScope.registerSymbol(c.name.toLowerCase(), (exp, s) =>
183
- new ColumnReferenceNode(s, exp as AST.ColumnExpr, c.type, attr.id, i));
184
- });
185
-
186
- if (fromClause.alias) {
187
- columnScope = new AliasedScope(cteScope, tableName, fromClause.alias.toLowerCase());
260
+
261
+ // Check if this is an internal recursive CTE reference
262
+ if (cteNode instanceof InternalRecursiveCTERefNode) {
263
+ // For internal recursive references, use the node directly
264
+ fromTable = cteNode;
265
+
266
+ // Create scope for internal recursive CTE columns
267
+ const internalScope = new RegisteredScope(parentContext.scope);
268
+ const internalAttributes = cteNode.getAttributes();
269
+ cteNode.getType().columns.forEach((c, i) => {
270
+ const attr = internalAttributes[i];
271
+ internalScope.registerSymbol(c.name.toLowerCase(), (exp, s) =>
272
+ new ColumnReferenceNode(s, exp as AST.ColumnExpr, c.type, attr.id, i));
273
+ });
274
+
275
+ if (fromClause.alias) {
276
+ columnScope = new AliasedScope(internalScope, tableName, fromClause.alias.toLowerCase());
277
+ } else {
278
+ columnScope = new AliasedScope(internalScope, tableName, tableName);
279
+ }
188
280
  } else {
189
- columnScope = new AliasedScope(cteScope, tableName, tableName);
190
- }
281
+ // Regular CTE reference - cache by CTE name + alias to ensure consistent attribute IDs
282
+ const cacheKey = `${tableName}:${fromClause.alias || tableName}`;
283
+
284
+ // Initialize cache if not exists
285
+ if (!parentContext.cteReferenceCache) {
286
+ parentContext.cteReferenceCache = new Map();
287
+ }
191
288
 
192
- fromTable = cteRefNode;
289
+ let cteRefNode: CTEReferenceNode;
290
+ if (parentContext.cteReferenceCache.has(cacheKey)) {
291
+ cteRefNode = parentContext.cteReferenceCache.get(cacheKey)!;
292
+ const attrs = cteRefNode.getAttributes();
293
+ logger(`Using cached CTE reference ${cacheKey}, attrs=[${attrs.map(a => a.id).join(',')}]`);
294
+ } else {
295
+ cteRefNode = new CTEReferenceNode(parentContext.scope, cteNode, fromClause.alias);
296
+ parentContext.cteReferenceCache.set(cacheKey, cteRefNode);
297
+ const attrs = cteRefNode.getAttributes();
298
+ logger(`Created new CTE reference ${cacheKey}, attrs=[${attrs.map(a => a.id).join(',')}]`);
299
+ }
300
+
301
+ // Create scope for CTE columns using attributes from the reference node
302
+ // CRITICAL: Use a closure to capture the reference node's attributes
303
+ // This ensures all column references use the same attribute IDs
304
+ const cteScope = new RegisteredScope(parentContext.scope);
305
+ const refAttrs = cteRefNode.getAttributes();
306
+ cteRefNode.getType().columns.forEach((c, i) => {
307
+ const attr = refAttrs[i];
308
+ cteScope.registerSymbol(c.name.toLowerCase(), (exp, s) => {
309
+ // Always use the cached reference node's attribute ID
310
+ return new ColumnReferenceNode(s, exp as AST.ColumnExpr, c.type, attr.id, i);
311
+ });
312
+ });
313
+
314
+ if (fromClause.alias) {
315
+ columnScope = new AliasedScope(cteScope, tableName, fromClause.alias.toLowerCase());
316
+ } else {
317
+ columnScope = new AliasedScope(cteScope, tableName, tableName);
318
+ }
319
+
320
+ // CRITICAL: Cache the reference node so later expression compilation uses the same attribute IDs
321
+ (columnScope as any).referenceNode = cteRefNode;
322
+
323
+ fromTable = cteRefNode;
324
+ }
193
325
  } else {
194
326
  // Check if this is a view
195
327
  const schemaName = fromClause.table.schema || parentContext.db.schemaManager.getCurrentSchemaName();
@@ -215,7 +347,7 @@ export function buildFrom(fromClause: AST.FromClause, parentContext: PlanningCon
215
347
  }
216
348
  } else {
217
349
  // Regular table
218
- fromTable = buildTableScan(fromClause, parentContext);
350
+ fromTable = buildTableReference(fromClause, parentContext);
219
351
 
220
352
  // Create scope for table columns
221
353
  const tableScope = new RegisteredScope(parentContext.scope);
@@ -2,10 +2,7 @@ import { QuereusError } from '../../common/errors.js';
2
2
  import { StatusCode } from '../../common/types.js';
3
3
  import type * as AST from '../../parser/ast.js';
4
4
  import { TableReferenceNode } from '../nodes/reference.js';
5
- import { TableScanNode } from '../nodes/scan.js';
6
5
  import type { PlanningContext } from '../planning-context.js';
7
- import type { IndexInfo, IndexConstraintUsage } from '../../vtab/index-info.js';
8
- import type { FilterInfo } from '../../vtab/filter-info.js';
9
6
  import { resolveTableSchema, resolveVtabModule } from './schema-resolution.js';
10
7
 
11
8
  /**
@@ -18,7 +15,7 @@ import { resolveTableSchema, resolveVtabModule } from './schema-resolution.js';
18
15
  */
19
16
  export function buildTableReference(fromClause: AST.FromClause, context: PlanningContext): TableReferenceNode {
20
17
  if (fromClause.type !== 'table') {
21
- throw new QuereusError('planTableScan currently only supports simple table references.', StatusCode.INTERNAL);
18
+ throw new QuereusError('buildTableReference currently only supports simple table references.', StatusCode.INTERNAL);
22
19
  }
23
20
 
24
21
  // Resolve table schema at build time
@@ -35,39 +32,3 @@ export function buildTableReference(fromClause: AST.FromClause, context: Plannin
35
32
  );
36
33
  }
37
34
 
38
- /**
39
- * Plans a table scan operation based on a FROM clause item.
40
- *
41
- * @param fromClause The AST node representing a table in the FROM clause.
42
- * @param context The planning context to resolve table definitions.
43
- * @returns A TableScanNode for the specified table.
44
- * @throws {QuereusError} If the table is not found, the reference is ambiguous, or fromClause is not a simple table.
45
- */
46
- export function buildTableScan(fromClause: AST.FromClause, context: PlanningContext): TableScanNode {
47
- const tableReference = buildTableReference(fromClause, context);
48
-
49
- const defaultIndexInfo: IndexInfo = {
50
- nConstraint: 0,
51
- aConstraint: [],
52
- nOrderBy: 0,
53
- aOrderBy: [],
54
- aConstraintUsage: [] as IndexConstraintUsage[],
55
- idxNum: 0,
56
- idxStr: 'fullscan',
57
- orderByConsumed: false,
58
- estimatedCost: tableReference.estimatedRows ?? 1000,
59
- estimatedRows: BigInt(tableReference.estimatedRows ?? 100),
60
- idxFlags: 0,
61
- colUsed: 0n,
62
- };
63
-
64
- const filterInfo: FilterInfo = {
65
- idxNum: 0,
66
- idxStr: 'fullscan',
67
- constraints: [],
68
- args: [],
69
- indexInfoOutput: defaultIndexInfo,
70
- };
71
-
72
- return new TableScanNode(context.scope, tableReference, filterInfo);
73
- }
@@ -2,7 +2,7 @@ import type * as AST from '../../parser/ast.js';
2
2
  import type { PlanningContext } from '../planning-context.js';
3
3
  import { UpdateNode, type UpdateAssignment } from '../nodes/update-node.js';
4
4
  import { DmlExecutorNode } from '../nodes/dml-executor-node.js';
5
- import { buildTableReference, buildTableScan } from './table.js';
5
+ import { buildTableReference } from './table.js';
6
6
  import { buildExpression } from './expression.js';
7
7
  import { PlanNode, type RelationalPlanNode, type ScalarPlanNode } from '../nodes/plan-node.js';
8
8
  import { FilterNode } from '../nodes/filter.js';
@@ -12,9 +12,10 @@ import { RegisteredScope } from '../scopes/registered.js';
12
12
  import { ColumnReferenceNode } from '../nodes/reference.js';
13
13
  import { SinkNode } from '../nodes/sink-node.js';
14
14
  import { ConstraintCheckNode } from '../nodes/constraint-check-node.js';
15
- import { RowOp } from '../../schema/table.js';
15
+ import { RowOpFlag } from '../../schema/table.js';
16
16
  import { ReturningNode } from '../nodes/returning-node.js';
17
17
  import { buildOldNewRowDescriptors } from '../../util/row-descriptor.js';
18
+ import { buildConstraintChecks } from './constraint-builder.js';
18
19
 
19
20
  export function buildUpdateStmt(
20
21
  ctx: PlanningContext,
@@ -23,7 +24,7 @@ export function buildUpdateStmt(
23
24
  const tableReference = buildTableReference({ type: 'table', table: stmt.table }, ctx);
24
25
 
25
26
  // Plan the source of rows to update. 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);
@@ -78,6 +79,16 @@ export function buildUpdateStmt(
78
79
 
79
80
  const { oldRowDescriptor, newRowDescriptor, flatRowDescriptor } = buildOldNewRowDescriptors(oldAttributes, newAttributes);
80
81
 
82
+ // Build constraint checks at plan time
83
+ const constraintChecks = buildConstraintChecks(
84
+ updateCtx,
85
+ tableReference.tableSchema,
86
+ RowOpFlag.UPDATE,
87
+ oldAttributes,
88
+ newAttributes,
89
+ flatRowDescriptor
90
+ );
91
+
81
92
  if (stmt.returning && stmt.returning.length > 0) {
82
93
  // For RETURNING, create coordinated attribute IDs like we do for INSERT
83
94
  const returningScope = new RegisteredScope(updateCtx.scope);
@@ -205,9 +216,11 @@ export function buildUpdateStmt(
205
216
  updateCtx.scope,
206
217
  updateNodeWithDescriptor,
207
218
  tableReference,
208
- RowOp.UPDATE,
219
+ RowOpFlag.UPDATE,
209
220
  oldRowDescriptor,
210
- newRowDescriptor
221
+ newRowDescriptor,
222
+ flatRowDescriptor,
223
+ constraintChecks
211
224
  );
212
225
 
213
226
  const updateExecutorNode = new DmlExecutorNode(
@@ -239,9 +252,11 @@ export function buildUpdateStmt(
239
252
  updateCtx.scope,
240
253
  updateNode,
241
254
  tableReference,
242
- RowOp.UPDATE,
255
+ RowOpFlag.UPDATE,
243
256
  oldRowDescriptor,
244
- newRowDescriptor
257
+ newRowDescriptor,
258
+ flatRowDescriptor,
259
+ constraintChecks
245
260
  );
246
261
 
247
262
  const updateExecutorNode = new DmlExecutorNode(
@@ -2,6 +2,7 @@ import type * as AST from '../../parser/ast.js';
2
2
  import type { PlanningContext } from '../planning-context.js';
3
3
  import { CTENode, type CTEPlanNode } from '../nodes/cte-node.js';
4
4
  import { RecursiveCTENode } from '../nodes/recursive-cte-node.js';
5
+ import { InternalRecursiveCTERefNode } from '../nodes/internal-recursive-cte-ref-node.js';
5
6
  import { buildSelectStmt } from './select.js';
6
7
  import type { RelationalPlanNode } from '../nodes/plan-node.js';
7
8
  import { QuereusError } from '../../common/errors.js';
@@ -151,27 +152,25 @@ function buildRecursiveCTE(
151
152
  options?.maxRecursion
152
153
  );
153
154
 
154
- // For the recursive case, we need to create a special context where the CTE name
155
+ // For the recursive case, we need to create a special context where the CTE name
155
156
  // references the working table (this will be handled at runtime)
156
157
  const recursiveContext = { ...ctx };
157
158
 
158
- // Create a temporary CTE reference for the recursive case that shares the same tableDescriptor
159
- const tempCteNode = new CTENode(
159
+ // Create an internal recursive reference node that will look up the working table at runtime
160
+ const internalRefNode = new InternalRecursiveCTERefNode(
160
161
  ctx.scope,
161
162
  cte.name,
162
- cte.columns,
163
- baseCaseQuery, // Use base case as template
164
- 'materialized',
165
- true
163
+ recursiveCTENode.getAttributes(),
164
+ recursiveCTENode.getType(),
165
+ recursiveCTENode.tableDescriptor
166
166
  );
167
- // Share the same tableDescriptor for runtime coordination
168
- (tempCteNode as any).tableDescriptor = recursiveCTENode.tableDescriptor;
169
167
 
170
- // Create a map containing the recursive CTE reference
171
- const recursiveCteMap = new Map<string, CTEPlanNode>();
172
- recursiveCteMap.set(cte.name.toLowerCase(), tempCteNode);
168
+ // Build the recursive case query with a simple replacement strategy
169
+ // We'll replace CTE references with the internal recursive reference during the FROM clause processing
170
+ const recursiveCteMap = new Map<string, any>();
171
+ recursiveCteMap.set(cte.name.toLowerCase(), internalRefNode);
173
172
 
174
- // Build the recursive case query with the CTE map so it can find the table reference
173
+ // Build the recursive case query
175
174
  const recursiveCaseQuery = buildSelectStmt(recursiveContext, recursiveCaseStmt, recursiveCteMap) as RelationalPlanNode;
176
175
 
177
176
  // Now update the recursive CTE node with the actual recursive case query
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Utility to detect correlated subqueries
3
+ * A subquery is correlated if it references columns from outer query scopes
4
+ */
5
+
6
+ import { isRelationalNode, type PlanNode, type RelationalPlanNode } from '../nodes/plan-node.js';
7
+ import { PlanNodeType } from '../nodes/plan-node-type.js';
8
+ import type { ColumnReferenceNode } from '../nodes/reference.js';
9
+
10
+ /**
11
+ * Detects if a subquery is correlated by checking if it references any attributes
12
+ * that are not defined within its own scope.
13
+ */
14
+ export function isCorrelatedSubquery(subqueryNode: RelationalPlanNode): boolean {
15
+ // Collect all attributes defined within the subquery
16
+ const definedAttributes = new Set<number>();
17
+ collectDefinedAttributes(subqueryNode, definedAttributes);
18
+
19
+ // Check if any column references use attributes not defined within the subquery
20
+ return hasExternalReferences(subqueryNode, definedAttributes);
21
+ }
22
+
23
+ /**
24
+ * Recursively collect all attributes defined by relational nodes within a subtree
25
+ */
26
+ function collectDefinedAttributes(node: PlanNode, definedAttributes: Set<number>): void {
27
+ // If this is a relational node, add its attributes
28
+ const isRelational = isRelationalNode(node);
29
+ if (isRelational) {
30
+ const attributes = node.getAttributes();
31
+ for (const attr of attributes) {
32
+ definedAttributes.add(attr.id);
33
+ }
34
+ }
35
+
36
+ // Recursively process all children
37
+ const children = node.getChildren();
38
+ for (const child of children) {
39
+ collectDefinedAttributes(child, definedAttributes);
40
+ }
41
+
42
+ // Also process relational children if any
43
+ if (isRelational) {
44
+ const relations = node.getRelations();
45
+ for (const relation of relations) {
46
+ collectDefinedAttributes(relation, definedAttributes);
47
+ }
48
+ }
49
+ }
50
+
51
+ /**
52
+ * Check if the subtree contains any column references to attributes not in the defined set
53
+ */
54
+ function hasExternalReferences(node: PlanNode, definedAttributes: Set<number>): boolean {
55
+ // Check if this is a column reference
56
+ if (node.nodeType === PlanNodeType.ColumnReference) {
57
+ const colRef = node as ColumnReferenceNode;
58
+ // If the referenced attribute is not defined within the subquery, it's an external reference
59
+ if (!definedAttributes.has(colRef.attributeId)) {
60
+ return true; // Found a correlated reference
61
+ }
62
+ }
63
+
64
+ // Check all children
65
+ const children = node.getChildren();
66
+ for (const child of children) {
67
+ if (hasExternalReferences(child, definedAttributes)) {
68
+ return true;
69
+ }
70
+ }
71
+
72
+ // Also check relational children if any
73
+ if (isRelationalNode(node)) {
74
+ const relations = node.getRelations();
75
+ for (const relation of relations) {
76
+ if (hasExternalReferences(relation, definedAttributes)) {
77
+ return true;
78
+ }
79
+ }
80
+ }
81
+
82
+ return false;
83
+ }