@quereus/quereus 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. package/README.md +47 -23
  2. package/dist/src/core/database.d.ts +22 -4
  3. package/dist/src/core/database.d.ts.map +1 -1
  4. package/dist/src/core/database.js +44 -6
  5. package/dist/src/core/database.js.map +1 -1
  6. package/dist/src/core/statement.d.ts +0 -7
  7. package/dist/src/core/statement.d.ts.map +1 -1
  8. package/dist/src/core/statement.js +1 -51
  9. package/dist/src/core/statement.js.map +1 -1
  10. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  11. package/dist/src/func/builtins/explain.js +0 -11
  12. package/dist/src/func/builtins/explain.js.map +1 -1
  13. package/dist/src/index.d.ts +13 -5
  14. package/dist/src/index.d.ts.map +1 -1
  15. package/dist/src/index.js +5 -2
  16. package/dist/src/index.js.map +1 -1
  17. package/dist/src/parser/ast.d.ts +9 -2
  18. package/dist/src/parser/ast.d.ts.map +1 -1
  19. package/dist/src/parser/parser.d.ts.map +1 -1
  20. package/dist/src/parser/parser.js +40 -44
  21. package/dist/src/parser/parser.js.map +1 -1
  22. package/dist/src/planner/analysis/const-pass.d.ts.map +1 -1
  23. package/dist/src/planner/analysis/const-pass.js +12 -6
  24. package/dist/src/planner/analysis/const-pass.js.map +1 -1
  25. package/dist/src/planner/building/constraint-builder.d.ts +11 -0
  26. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -0
  27. package/dist/src/planner/building/constraint-builder.js +79 -0
  28. package/dist/src/planner/building/constraint-builder.js.map +1 -0
  29. package/dist/src/planner/building/delete.d.ts.map +1 -1
  30. package/dist/src/planner/building/delete.js +6 -3
  31. package/dist/src/planner/building/delete.js.map +1 -1
  32. package/dist/src/planner/building/expression.d.ts +3 -0
  33. package/dist/src/planner/building/expression.d.ts.map +1 -1
  34. package/dist/src/planner/building/expression.js +33 -7
  35. package/dist/src/planner/building/expression.js.map +1 -1
  36. package/dist/src/planner/building/insert.d.ts.map +1 -1
  37. package/dist/src/planner/building/insert.js +4 -1
  38. package/dist/src/planner/building/insert.js.map +1 -1
  39. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  40. package/dist/src/planner/building/select-aggregates.js +46 -9
  41. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  42. package/dist/src/planner/building/select-context.js +20 -11
  43. package/dist/src/planner/building/select-context.js.map +1 -1
  44. package/dist/src/planner/building/select-modifiers.d.ts +5 -3
  45. package/dist/src/planner/building/select-modifiers.d.ts.map +1 -1
  46. package/dist/src/planner/building/select-modifiers.js +29 -20
  47. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  48. package/dist/src/planner/building/select-projections.d.ts +3 -1
  49. package/dist/src/planner/building/select-projections.d.ts.map +1 -1
  50. package/dist/src/planner/building/select-projections.js +15 -20
  51. package/dist/src/planner/building/select-projections.js.map +1 -1
  52. package/dist/src/planner/building/select-window.d.ts.map +1 -1
  53. package/dist/src/planner/building/select-window.js +6 -3
  54. package/dist/src/planner/building/select-window.js.map +1 -1
  55. package/dist/src/planner/building/select.d.ts +25 -2
  56. package/dist/src/planner/building/select.d.ts.map +1 -1
  57. package/dist/src/planner/building/select.js +147 -24
  58. package/dist/src/planner/building/select.js.map +1 -1
  59. package/dist/src/planner/building/table.d.ts +0 -10
  60. package/dist/src/planner/building/table.d.ts.map +1 -1
  61. package/dist/src/planner/building/table.js +1 -35
  62. package/dist/src/planner/building/table.js.map +1 -1
  63. package/dist/src/planner/building/update.d.ts.map +1 -1
  64. package/dist/src/planner/building/update.js +7 -4
  65. package/dist/src/planner/building/update.js.map +1 -1
  66. package/dist/src/planner/building/with.d.ts.map +1 -1
  67. package/dist/src/planner/building/with.js +7 -8
  68. package/dist/src/planner/building/with.js.map +1 -1
  69. package/dist/src/planner/cache/correlation-detector.d.ts +11 -0
  70. package/dist/src/planner/cache/correlation-detector.d.ts.map +1 -0
  71. package/dist/src/planner/cache/correlation-detector.js +73 -0
  72. package/dist/src/planner/cache/correlation-detector.js.map +1 -0
  73. package/dist/src/planner/cache/materialization-advisory.d.ts +12 -18
  74. package/dist/src/planner/cache/materialization-advisory.d.ts.map +1 -1
  75. package/dist/src/planner/cache/materialization-advisory.js +65 -46
  76. package/dist/src/planner/cache/materialization-advisory.js.map +1 -1
  77. package/dist/src/planner/cache/reference-graph.d.ts +14 -9
  78. package/dist/src/planner/cache/reference-graph.d.ts.map +1 -1
  79. package/dist/src/planner/cache/reference-graph.js +93 -84
  80. package/dist/src/planner/cache/reference-graph.js.map +1 -1
  81. package/dist/src/planner/debug.d.ts +25 -0
  82. package/dist/src/planner/debug.d.ts.map +1 -1
  83. package/dist/src/planner/debug.js +127 -0
  84. package/dist/src/planner/debug.js.map +1 -1
  85. package/dist/src/planner/framework/context.d.ts +11 -0
  86. package/dist/src/planner/framework/context.d.ts.map +1 -1
  87. package/dist/src/planner/framework/context.js +25 -2
  88. package/dist/src/planner/framework/context.js.map +1 -1
  89. package/dist/src/planner/framework/registry.d.ts +3 -7
  90. package/dist/src/planner/framework/registry.d.ts.map +1 -1
  91. package/dist/src/planner/framework/registry.js +20 -31
  92. package/dist/src/planner/framework/registry.js.map +1 -1
  93. package/dist/src/planner/nodes/add-constraint-node.d.ts +2 -1
  94. package/dist/src/planner/nodes/add-constraint-node.d.ts.map +1 -1
  95. package/dist/src/planner/nodes/add-constraint-node.js +3 -0
  96. package/dist/src/planner/nodes/add-constraint-node.js.map +1 -1
  97. package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
  98. package/dist/src/planner/nodes/aggregate-node.js +6 -4
  99. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  100. package/dist/src/planner/nodes/cache-node.d.ts.map +1 -1
  101. package/dist/src/planner/nodes/cache-node.js +2 -2
  102. package/dist/src/planner/nodes/cache-node.js.map +1 -1
  103. package/dist/src/planner/nodes/constraint-check-node.d.ts +11 -4
  104. package/dist/src/planner/nodes/constraint-check-node.d.ts.map +1 -1
  105. package/dist/src/planner/nodes/constraint-check-node.js +38 -12
  106. package/dist/src/planner/nodes/constraint-check-node.js.map +1 -1
  107. package/dist/src/planner/nodes/create-index-node.d.ts +2 -1
  108. package/dist/src/planner/nodes/create-index-node.d.ts.map +1 -1
  109. package/dist/src/planner/nodes/create-index-node.js +3 -0
  110. package/dist/src/planner/nodes/create-index-node.js.map +1 -1
  111. package/dist/src/planner/nodes/create-table-node.d.ts +2 -1
  112. package/dist/src/planner/nodes/create-table-node.d.ts.map +1 -1
  113. package/dist/src/planner/nodes/create-table-node.js +3 -0
  114. package/dist/src/planner/nodes/create-table-node.js.map +1 -1
  115. package/dist/src/planner/nodes/create-view-node.d.ts +2 -1
  116. package/dist/src/planner/nodes/create-view-node.d.ts.map +1 -1
  117. package/dist/src/planner/nodes/create-view-node.js +3 -0
  118. package/dist/src/planner/nodes/create-view-node.js.map +1 -1
  119. package/dist/src/planner/nodes/cte-node.d.ts +1 -1
  120. package/dist/src/planner/nodes/cte-node.d.ts.map +1 -1
  121. package/dist/src/planner/nodes/cte-node.js +33 -12
  122. package/dist/src/planner/nodes/cte-node.js.map +1 -1
  123. package/dist/src/planner/nodes/cte-reference-node.d.ts +18 -4
  124. package/dist/src/planner/nodes/cte-reference-node.d.ts.map +1 -1
  125. package/dist/src/planner/nodes/cte-reference-node.js +40 -10
  126. package/dist/src/planner/nodes/cte-reference-node.js.map +1 -1
  127. package/dist/src/planner/nodes/delete-node.d.ts +4 -3
  128. package/dist/src/planner/nodes/delete-node.d.ts.map +1 -1
  129. package/dist/src/planner/nodes/delete-node.js +20 -6
  130. package/dist/src/planner/nodes/delete-node.js.map +1 -1
  131. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
  132. package/dist/src/planner/nodes/distinct-node.js +2 -2
  133. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  134. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  135. package/dist/src/planner/nodes/dml-executor-node.js +2 -2
  136. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  137. package/dist/src/planner/nodes/drop-table-node.d.ts +2 -1
  138. package/dist/src/planner/nodes/drop-table-node.d.ts.map +1 -1
  139. package/dist/src/planner/nodes/drop-table-node.js +3 -0
  140. package/dist/src/planner/nodes/drop-table-node.js.map +1 -1
  141. package/dist/src/planner/nodes/drop-view-node.d.ts +2 -1
  142. package/dist/src/planner/nodes/drop-view-node.d.ts.map +1 -1
  143. package/dist/src/planner/nodes/drop-view-node.js +3 -0
  144. package/dist/src/planner/nodes/drop-view-node.js.map +1 -1
  145. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  146. package/dist/src/planner/nodes/filter.js +3 -3
  147. package/dist/src/planner/nodes/filter.js.map +1 -1
  148. package/dist/src/planner/nodes/insert-node.d.ts +2 -1
  149. package/dist/src/planner/nodes/insert-node.d.ts.map +1 -1
  150. package/dist/src/planner/nodes/insert-node.js +18 -5
  151. package/dist/src/planner/nodes/insert-node.js.map +1 -1
  152. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts +28 -0
  153. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts.map +1 -0
  154. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js +69 -0
  155. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js.map +1 -0
  156. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  157. package/dist/src/planner/nodes/join-node.js +3 -3
  158. package/dist/src/planner/nodes/join-node.js.map +1 -1
  159. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  160. package/dist/src/planner/nodes/limit-offset.js +2 -2
  161. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  162. package/dist/src/planner/nodes/plan-node-type.d.ts +1 -1
  163. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  164. package/dist/src/planner/nodes/plan-node-type.js +1 -1
  165. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  166. package/dist/src/planner/nodes/plan-node.d.ts +23 -0
  167. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  168. package/dist/src/planner/nodes/plan-node.js +25 -2
  169. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  170. package/dist/src/planner/nodes/project-node.d.ts +5 -1
  171. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  172. package/dist/src/planner/nodes/project-node.js +39 -20
  173. package/dist/src/planner/nodes/project-node.js.map +1 -1
  174. package/dist/src/planner/nodes/recursive-cte-node.d.ts +2 -2
  175. package/dist/src/planner/nodes/recursive-cte-node.d.ts.map +1 -1
  176. package/dist/src/planner/nodes/recursive-cte-node.js +20 -8
  177. package/dist/src/planner/nodes/recursive-cte-node.js.map +1 -1
  178. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  179. package/dist/src/planner/nodes/reference.js +4 -2
  180. package/dist/src/planner/nodes/reference.js.map +1 -1
  181. package/dist/src/planner/nodes/returning-node.d.ts +1 -1
  182. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  183. package/dist/src/planner/nodes/returning-node.js +21 -13
  184. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  185. package/dist/src/planner/nodes/scalar.d.ts +26 -2
  186. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  187. package/dist/src/planner/nodes/scalar.js +82 -10
  188. package/dist/src/planner/nodes/scalar.js.map +1 -1
  189. package/dist/src/planner/nodes/sequencing-node.d.ts.map +1 -1
  190. package/dist/src/planner/nodes/sequencing-node.js +2 -2
  191. package/dist/src/planner/nodes/sequencing-node.js.map +1 -1
  192. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  193. package/dist/src/planner/nodes/set-operation-node.js +3 -3
  194. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  195. package/dist/src/planner/nodes/single-row.d.ts +4 -2
  196. package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
  197. package/dist/src/planner/nodes/single-row.js +3 -0
  198. package/dist/src/planner/nodes/single-row.js.map +1 -1
  199. package/dist/src/planner/nodes/sink-node.d.ts +1 -1
  200. package/dist/src/planner/nodes/sink-node.d.ts.map +1 -1
  201. package/dist/src/planner/nodes/sink-node.js +4 -4
  202. package/dist/src/planner/nodes/sink-node.js.map +1 -1
  203. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  204. package/dist/src/planner/nodes/sort.js +2 -2
  205. package/dist/src/planner/nodes/sort.js.map +1 -1
  206. package/dist/src/planner/nodes/stream-aggregate.d.ts +1 -0
  207. package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
  208. package/dist/src/planner/nodes/stream-aggregate.js +64 -11
  209. package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
  210. package/dist/src/planner/nodes/subquery.d.ts +4 -4
  211. package/dist/src/planner/nodes/subquery.d.ts.map +1 -1
  212. package/dist/src/planner/nodes/subquery.js +68 -23
  213. package/dist/src/planner/nodes/subquery.js.map +1 -1
  214. package/dist/src/planner/nodes/table-access-nodes.d.ts +83 -0
  215. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -0
  216. package/dist/src/planner/nodes/table-access-nodes.js +226 -0
  217. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -0
  218. package/dist/src/planner/nodes/update-node.d.ts +4 -2
  219. package/dist/src/planner/nodes/update-node.d.ts.map +1 -1
  220. package/dist/src/planner/nodes/update-node.js +26 -13
  221. package/dist/src/planner/nodes/update-node.js.map +1 -1
  222. package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
  223. package/dist/src/planner/nodes/window-node.js +25 -23
  224. package/dist/src/planner/nodes/window-node.js.map +1 -1
  225. package/dist/src/planner/optimizer.d.ts.map +1 -1
  226. package/dist/src/planner/optimizer.js +46 -50
  227. package/dist/src/planner/optimizer.js.map +1 -1
  228. package/dist/src/planner/planning-context.d.ts +13 -0
  229. package/dist/src/planner/planning-context.d.ts.map +1 -1
  230. package/dist/src/planner/planning-context.js.map +1 -1
  231. package/dist/src/planner/rules/access/rule-select-access-path.d.ts +1 -1
  232. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  233. package/dist/src/planner/rules/access/rule-select-access-path.js +59 -53
  234. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  235. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -1
  236. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +62 -2
  237. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
  238. package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts.map +1 -1
  239. package/dist/src/planner/rules/cache/rule-materialization-advisory.js +31 -24
  240. package/dist/src/planner/rules/cache/rule-materialization-advisory.js.map +1 -1
  241. package/dist/src/planner/scopes/base.d.ts +0 -10
  242. package/dist/src/planner/scopes/base.d.ts.map +1 -1
  243. package/dist/src/planner/scopes/base.js +0 -14
  244. package/dist/src/planner/scopes/base.js.map +1 -1
  245. package/dist/src/planner/scopes/empty.d.ts +0 -2
  246. package/dist/src/planner/scopes/empty.d.ts.map +1 -1
  247. package/dist/src/planner/scopes/empty.js +0 -8
  248. package/dist/src/planner/scopes/empty.js.map +1 -1
  249. package/dist/src/planner/scopes/multi.d.ts.map +1 -1
  250. package/dist/src/planner/scopes/multi.js +0 -1
  251. package/dist/src/planner/scopes/multi.js.map +1 -1
  252. package/dist/src/planner/scopes/param.d.ts.map +1 -1
  253. package/dist/src/planner/scopes/param.js +0 -1
  254. package/dist/src/planner/scopes/param.js.map +1 -1
  255. package/dist/src/planner/scopes/registered.d.ts +0 -10
  256. package/dist/src/planner/scopes/registered.d.ts.map +1 -1
  257. package/dist/src/planner/scopes/registered.js +1 -17
  258. package/dist/src/planner/scopes/registered.js.map +1 -1
  259. package/dist/src/planner/scopes/scope.d.ts +0 -8
  260. package/dist/src/planner/scopes/scope.d.ts.map +1 -1
  261. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  262. package/dist/src/planner/validation/plan-validator.js +1 -7
  263. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  264. package/dist/src/runtime/context-helpers.d.ts +45 -0
  265. package/dist/src/runtime/context-helpers.d.ts.map +1 -0
  266. package/dist/src/runtime/context-helpers.js +139 -0
  267. package/dist/src/runtime/context-helpers.js.map +1 -0
  268. package/dist/src/runtime/emission-context.d.ts +1 -0
  269. package/dist/src/runtime/emission-context.d.ts.map +1 -1
  270. package/dist/src/runtime/emission-context.js +2 -1
  271. package/dist/src/runtime/emission-context.js.map +1 -1
  272. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  273. package/dist/src/runtime/emit/aggregate.js +119 -86
  274. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  275. package/dist/src/runtime/emit/between.d.ts +5 -0
  276. package/dist/src/runtime/emit/between.d.ts.map +1 -0
  277. package/dist/src/runtime/emit/between.js +38 -0
  278. package/dist/src/runtime/emit/between.js.map +1 -0
  279. package/dist/src/runtime/emit/binary.d.ts +0 -1
  280. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  281. package/dist/src/runtime/emit/binary.js +0 -36
  282. package/dist/src/runtime/emit/binary.js.map +1 -1
  283. package/dist/src/runtime/emit/column-reference.d.ts.map +1 -1
  284. package/dist/src/runtime/emit/column-reference.js +2 -26
  285. package/dist/src/runtime/emit/column-reference.js.map +1 -1
  286. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  287. package/dist/src/runtime/emit/constraint-check.js +14 -121
  288. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  289. package/dist/src/runtime/emit/cte-reference.d.ts.map +1 -1
  290. package/dist/src/runtime/emit/cte-reference.js +16 -48
  291. package/dist/src/runtime/emit/cte-reference.js.map +1 -1
  292. package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
  293. package/dist/src/runtime/emit/distinct.js +2 -8
  294. package/dist/src/runtime/emit/distinct.js.map +1 -1
  295. package/dist/src/runtime/emit/filter.d.ts.map +1 -1
  296. package/dist/src/runtime/emit/filter.js +6 -13
  297. package/dist/src/runtime/emit/filter.js.map +1 -1
  298. package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts +5 -0
  299. package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts.map +1 -0
  300. package/dist/src/runtime/emit/internal-recursive-cte-ref.js +23 -0
  301. package/dist/src/runtime/emit/internal-recursive-cte-ref.js.map +1 -0
  302. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  303. package/dist/src/runtime/emit/join.js +40 -40
  304. package/dist/src/runtime/emit/join.js.map +1 -1
  305. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  306. package/dist/src/runtime/emit/project.js +13 -13
  307. package/dist/src/runtime/emit/project.js.map +1 -1
  308. package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -1
  309. package/dist/src/runtime/emit/recursive-cte.js +3 -14
  310. package/dist/src/runtime/emit/recursive-cte.js.map +1 -1
  311. package/dist/src/runtime/emit/returning.d.ts.map +1 -1
  312. package/dist/src/runtime/emit/returning.js +7 -14
  313. package/dist/src/runtime/emit/returning.js.map +1 -1
  314. package/dist/src/runtime/emit/scan.d.ts +5 -2
  315. package/dist/src/runtime/emit/scan.d.ts.map +1 -1
  316. package/dist/src/runtime/emit/scan.js +21 -17
  317. package/dist/src/runtime/emit/scan.js.map +1 -1
  318. package/dist/src/runtime/emit/sort.d.ts.map +1 -1
  319. package/dist/src/runtime/emit/sort.js +8 -11
  320. package/dist/src/runtime/emit/sort.js.map +1 -1
  321. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  322. package/dist/src/runtime/emit/subquery.js +95 -40
  323. package/dist/src/runtime/emit/subquery.js.map +1 -1
  324. package/dist/src/runtime/emit/table-valued-function.d.ts.map +1 -1
  325. package/dist/src/runtime/emit/table-valued-function.js +7 -22
  326. package/dist/src/runtime/emit/table-valued-function.js.map +1 -1
  327. package/dist/src/runtime/emit/update.d.ts.map +1 -1
  328. package/dist/src/runtime/emit/update.js +20 -27
  329. package/dist/src/runtime/emit/update.js.map +1 -1
  330. package/dist/src/runtime/emit/window.d.ts.map +1 -1
  331. package/dist/src/runtime/emit/window.js +55 -83
  332. package/dist/src/runtime/emit/window.js.map +1 -1
  333. package/dist/src/runtime/emitters.d.ts.map +1 -1
  334. package/dist/src/runtime/emitters.js +49 -1
  335. package/dist/src/runtime/emitters.js.map +1 -1
  336. package/dist/src/runtime/register.d.ts.map +1 -1
  337. package/dist/src/runtime/register.js +5 -4
  338. package/dist/src/runtime/register.js.map +1 -1
  339. package/dist/src/runtime/scheduler.d.ts.map +1 -1
  340. package/dist/src/runtime/scheduler.js +47 -42
  341. package/dist/src/runtime/scheduler.js.map +1 -1
  342. package/dist/src/runtime/types.d.ts +34 -0
  343. package/dist/src/runtime/types.d.ts.map +1 -1
  344. package/dist/src/runtime/types.js +21 -0
  345. package/dist/src/runtime/types.js.map +1 -1
  346. package/dist/src/schema/manager.d.ts.map +1 -1
  347. package/dist/src/schema/manager.js +29 -16
  348. package/dist/src/schema/manager.js.map +1 -1
  349. package/dist/src/util/plugin-loader.d.ts +10 -1
  350. package/dist/src/util/plugin-loader.d.ts.map +1 -1
  351. package/dist/src/util/plugin-loader.js +56 -1
  352. package/dist/src/util/plugin-loader.js.map +1 -1
  353. package/dist/src/util/working-table-iterable.d.ts.map +1 -1
  354. package/dist/src/util/working-table-iterable.js +8 -8
  355. package/dist/src/util/working-table-iterable.js.map +1 -1
  356. package/dist/src/vtab/manifest.d.ts +36 -0
  357. package/dist/src/vtab/manifest.d.ts.map +1 -1
  358. package/package.json +8 -3
  359. package/src/core/database.ts +48 -6
  360. package/src/core/statement.ts +1 -49
  361. package/src/func/builtins/explain.ts +0 -11
  362. package/src/index.ts +39 -5
  363. package/src/parser/ast.ts +11 -2
  364. package/src/parser/parser.ts +40 -47
  365. package/src/planner/analysis/const-pass.ts +281 -270
  366. package/src/planner/building/constraint-builder.ts +114 -0
  367. package/src/planner/building/delete.ts +16 -3
  368. package/src/planner/building/expression.ts +35 -7
  369. package/src/planner/building/insert.ts +14 -1
  370. package/src/planner/building/select-aggregates.ts +57 -11
  371. package/src/planner/building/select-context.ts +22 -12
  372. package/src/planner/building/select-modifiers.ts +35 -21
  373. package/src/planner/building/select-projections.ts +25 -26
  374. package/src/planner/building/select-window.ts +14 -9
  375. package/src/planner/building/select.ts +163 -31
  376. package/src/planner/building/table.ts +1 -40
  377. package/src/planner/building/update.ts +19 -4
  378. package/src/planner/building/with.ts +12 -13
  379. package/src/planner/cache/correlation-detector.ts +83 -0
  380. package/src/planner/cache/materialization-advisory.ts +71 -50
  381. package/src/planner/cache/reference-graph.ts +115 -91
  382. package/src/planner/debug.ts +163 -0
  383. package/src/planner/framework/context.ts +36 -2
  384. package/src/planner/framework/registry.ts +261 -274
  385. package/src/planner/nodes/add-constraint-node.ts +5 -1
  386. package/src/planner/nodes/aggregate-node.ts +6 -4
  387. package/src/planner/nodes/cache-node.ts +2 -2
  388. package/src/planner/nodes/constraint-check-node.ts +47 -13
  389. package/src/planner/nodes/create-index-node.ts +5 -1
  390. package/src/planner/nodes/create-table-node.ts +5 -1
  391. package/src/planner/nodes/create-view-node.ts +5 -1
  392. package/src/planner/nodes/cte-node.ts +45 -14
  393. package/src/planner/nodes/cte-reference-node.ts +49 -13
  394. package/src/planner/nodes/delete-node.ts +31 -7
  395. package/src/planner/nodes/distinct-node.ts +2 -2
  396. package/src/planner/nodes/dml-executor-node.ts +2 -2
  397. package/src/planner/nodes/drop-table-node.ts +5 -1
  398. package/src/planner/nodes/drop-view-node.ts +5 -1
  399. package/src/planner/nodes/filter.ts +3 -3
  400. package/src/planner/nodes/function.ts +93 -93
  401. package/src/planner/nodes/insert-node.ts +28 -5
  402. package/src/planner/nodes/internal-recursive-cte-ref-node.ts +76 -0
  403. package/src/planner/nodes/join-node.ts +3 -3
  404. package/src/planner/nodes/limit-offset.ts +2 -2
  405. package/src/planner/nodes/plan-node-type.ts +1 -1
  406. package/src/planner/nodes/plan-node.ts +39 -2
  407. package/src/planner/nodes/project-node.ts +39 -19
  408. package/src/planner/nodes/recursive-cte-node.ts +37 -9
  409. package/src/planner/nodes/reference.ts +4 -2
  410. package/src/planner/nodes/returning-node.ts +25 -13
  411. package/src/planner/nodes/scalar.ts +95 -11
  412. package/src/planner/nodes/sequencing-node.ts +2 -2
  413. package/src/planner/nodes/set-operation-node.ts +3 -3
  414. package/src/planner/nodes/single-row.ts +7 -2
  415. package/src/planner/nodes/sink-node.ts +5 -5
  416. package/src/planner/nodes/sort.ts +2 -2
  417. package/src/planner/nodes/stream-aggregate.ts +76 -12
  418. package/src/planner/nodes/subquery.ts +90 -27
  419. package/src/planner/nodes/{physical-access-nodes.ts → table-access-nodes.ts} +6 -6
  420. package/src/planner/nodes/update-node.ts +31 -13
  421. package/src/planner/nodes/window-node.ts +28 -22
  422. package/src/planner/optimizer.ts +257 -263
  423. package/src/planner/planning-context.ts +15 -0
  424. package/src/planner/rules/access/rule-select-access-path.ts +68 -64
  425. package/src/planner/rules/aggregate/rule-aggregate-streaming.ts +74 -2
  426. package/src/planner/rules/cache/rule-materialization-advisory.ts +31 -27
  427. package/src/planner/scopes/base.ts +0 -17
  428. package/src/planner/scopes/empty.ts +0 -10
  429. package/src/planner/scopes/multi.ts +0 -1
  430. package/src/planner/scopes/param.ts +0 -1
  431. package/src/planner/scopes/registered.ts +1 -20
  432. package/src/planner/scopes/scope.ts +0 -12
  433. package/src/planner/validation/plan-validator.ts +1 -8
  434. package/src/runtime/context-helpers.ts +191 -0
  435. package/src/runtime/emission-context.ts +5 -2
  436. package/src/runtime/emit/aggregate.ts +131 -85
  437. package/src/runtime/emit/between.ts +51 -0
  438. package/src/runtime/emit/binary.ts +0 -46
  439. package/src/runtime/emit/column-reference.ts +3 -36
  440. package/src/runtime/emit/constraint-check.ts +17 -142
  441. package/src/runtime/emit/cte-reference.ts +23 -60
  442. package/src/runtime/emit/distinct.ts +2 -7
  443. package/src/runtime/emit/filter.ts +6 -13
  444. package/src/runtime/emit/internal-recursive-cte-ref.ts +37 -0
  445. package/src/runtime/emit/join.ts +45 -43
  446. package/src/runtime/emit/project.ts +18 -12
  447. package/src/runtime/emit/recursive-cte.ts +3 -12
  448. package/src/runtime/emit/returning.ts +7 -14
  449. package/src/runtime/emit/scan.ts +25 -23
  450. package/src/runtime/emit/sort.ts +8 -11
  451. package/src/runtime/emit/subquery.ts +108 -48
  452. package/src/runtime/emit/table-valued-function.ts +7 -20
  453. package/src/runtime/emit/update.ts +22 -29
  454. package/src/runtime/emit/window.ts +74 -88
  455. package/src/runtime/emitters.ts +52 -1
  456. package/src/runtime/register.ts +5 -4
  457. package/src/runtime/scheduler.ts +54 -54
  458. package/src/runtime/types.ts +45 -0
  459. package/src/schema/manager.ts +34 -19
  460. package/src/util/plugin-loader.ts +78 -4
  461. package/src/util/working-table-iterable.ts +15 -7
  462. package/src/vtab/manifest.ts +42 -0
  463. package/src/planner/nodes/scan.ts +0 -103
  464. package/src/planner/rules/physical/rule-mark-physical.ts +0 -37
  465. package/src/runtime/emit/table-reference.ts +0 -92
@@ -1,263 +1,257 @@
1
- import { createLogger } from '../common/logger.js';
2
- import { PlanNode } from './nodes/plan-node.js';
3
- import { PlanNodeType } from './nodes/plan-node-type.js';
4
- import { OptimizerTuning, DEFAULT_TUNING } from './optimizer-tuning.js';
5
-
6
- // Re-export for convenience
7
- export { DEFAULT_TUNING };
8
-
9
- import { applyRules, clearVisitedRules, registerRules, createRule } from './framework/registry.js';
10
- import { tracePhaseStart, tracePhaseEnd, traceNodeStart, traceNodeEnd } from './framework/trace.js';
11
- import { defaultStatsProvider, type StatsProvider } from './stats/index.js';
12
- import { createOptContext, type OptContext } from './framework/context.js';
13
- // Phase 2 rules
14
- import { ruleMaterializationAdvisory } from './rules/cache/rule-materialization-advisory.js';
15
- // Phase 1.5 rules
16
- import { ruleSelectAccessPath } from './rules/access/rule-select-access-path.js';
17
- // Core optimization rules
18
- import { ruleAggregateStreaming } from './rules/aggregate/rule-aggregate-streaming.js';
19
- // Constraint rules removed - now handled in builders for correctness
20
- import { ruleCteOptimization } from './rules/cache/rule-cte-optimization.js';
21
- import { ruleMutatingSubqueryCache } from './rules/cache/rule-mutating-subquery-cache.js';
22
- import { ruleMarkPhysical } from './rules/physical/rule-mark-physical.js';
23
- // Phase 3 rules
24
- import { validatePhysicalTree } from './validation/plan-validator.js';
25
- import { Database } from '../core/database.js';
26
- import { performConstantFolding } from './analysis/const-pass.js';
27
- import { createRuntimeExpressionEvaluator } from './analysis/const-evaluator.js';
28
-
29
- const log = createLogger('optimizer');
30
-
31
- /**
32
- * The query optimizer transforms logical plan trees into physical plan trees
33
- */
34
- export class Optimizer {
35
- private readonly stats: StatsProvider;
36
-
37
- constructor(
38
- public readonly tuning: OptimizerTuning = DEFAULT_TUNING,
39
- stats?: StatsProvider
40
- ) {
41
- this.stats = stats ?? defaultStatsProvider;
42
-
43
- // Ensure global framework rules are registered once
44
- Optimizer.ensureGlobalRulesRegistered();
45
- }
46
-
47
- private static globalRulesRegistered = false;
48
-
49
- /**
50
- * Ensure global framework rules are registered only once
51
- */
52
- private static ensureGlobalRulesRegistered(): void {
53
- if (Optimizer.globalRulesRegistered) {
54
- return;
55
- }
56
- Optimizer.globalRulesRegistered = true;
57
-
58
- const toRegister = [];
59
-
60
- // Single-pass constant folding is now done before rules, so no individual rules needed
61
-
62
- // Core optimization rules (converted from old system)
63
- toRegister.push(createRule(
64
- 'aggregate-streaming',
65
- PlanNodeType.Aggregate,
66
- 'impl',
67
- ruleAggregateStreaming,
68
- 40 // High priority - fundamental logical→physical transformation
69
- ));
70
-
71
- // Mutating subquery cache injection - critical for correctness
72
- toRegister.push(createRule(
73
- 'mutating-subquery-cache',
74
- PlanNodeType.Join,
75
- 'rewrite',
76
- ruleMutatingSubqueryCache,
77
- 20 // Very high priority - correctness fix to prevent multiple execution
78
- ));
79
-
80
- toRegister.push(createRule(
81
- 'cte-optimization',
82
- PlanNodeType.CTE,
83
- 'impl',
84
- ruleCteOptimization,
85
- 70 // Lower priority - caching optimization
86
- ));
87
-
88
- // toRegister.push(createRule(
89
- // 'project-optimization',
90
- // PlanNodeType.Project,
91
- // 'impl',
92
- // ruleProjectOptimization,
93
- // 50 // Medium priority - basic optimization
94
- // ));
95
-
96
- // toRegister.push(createRule(
97
- // 'filter-optimization',
98
- // PlanNodeType.Filter,
99
- // 'impl',
100
- // ruleFilterOptimization,
101
- // 50 // Medium priority - basic optimization
102
- // ));
103
-
104
- // Phase 1.5 rules
105
- toRegister.push(createRule(
106
- 'select-access-path',
107
- PlanNodeType.TableScan,
108
- 'impl',
109
- ruleSelectAccessPath,
110
- 30 // High priority - fundamental access path selection
111
- ));
112
-
113
- // Phase 2 rules
114
- toRegister.push(createRule(
115
- 'materialization-advisory',
116
- PlanNodeType.Block, // Apply to root-level nodes
117
- 'rewrite',
118
- ruleMaterializationAdvisory,
119
- 90 // Low priority - run last for global analysis
120
- ));
121
-
122
- // Fallback rule - must run last with lowest priority
123
- // We need to register this for multiple node types that might need fallback handling
124
- const fallbackNodeTypes = [
125
- // Relational nodes
126
- PlanNodeType.TableScan, PlanNodeType.Values, PlanNodeType.TableFunctionCall,
127
- PlanNodeType.Join, PlanNodeType.NestedLoopJoin, PlanNodeType.SingleRow,
128
- PlanNodeType.SetOperation, PlanNodeType.Distinct, PlanNodeType.LimitOffset,
129
- PlanNodeType.Window, PlanNodeType.Block, PlanNodeType.CTEReference,
130
- PlanNodeType.Cache, PlanNodeType.Sequencing, PlanNodeType.UpdateExecutor,
131
- // Scalar nodes
132
- PlanNodeType.Literal, PlanNodeType.ColumnReference, PlanNodeType.ParameterReference,
133
- PlanNodeType.BinaryOp, PlanNodeType.UnaryOp, PlanNodeType.CaseExpr,
134
- PlanNodeType.Cast, PlanNodeType.Collate, PlanNodeType.ScalarFunctionCall,
135
- PlanNodeType.Between, PlanNodeType.IsNull, PlanNodeType.IsNotNull, PlanNodeType.Like,
136
- PlanNodeType.ScalarSubquery, PlanNodeType.WindowFunctionCall, PlanNodeType.ArrayIndex
137
- ];
138
-
139
- for (const nodeType of fallbackNodeTypes) {
140
- toRegister.push(createRule(
141
- `mark-physical-${nodeType.toLowerCase()}`,
142
- nodeType,
143
- 'impl',
144
- ruleMarkPhysical,
145
- 100 // Lowest priority - absolute fallback
146
- ));
147
- }
148
-
149
- // Register all rules at once
150
- registerRules(toRegister);
151
- }
152
-
153
- /**
154
- * Optimize a plan tree by applying transformation rules
155
- */
156
- optimize(plan: PlanNode, db: Database): PlanNode {
157
- log('Starting optimization of plan', plan.nodeType);
158
-
159
- // Clear rule tracking from previous runs
160
- clearVisitedRules();
161
-
162
- // Create optimization context
163
- const context = createOptContext(this, this.stats, this.tuning, db);
164
-
165
- tracePhaseStart('optimization');
166
- try {
167
- // Phase 0: Single-pass constant folding before other rules
168
- log('Running constant folding pre-pass');
169
- const constantFoldedPlan = this.performConstantFolding(plan, context);
170
-
171
- // Continue with rule-based optimization
172
- const result = this.optimizeNode(constantFoldedPlan, context);
173
-
174
- // Phase 3: Validate the physical plan before returning
175
- if (this.tuning.debug.validatePlan) {
176
- log('Running plan validation');
177
- try {
178
- validatePhysicalTree(result);
179
- log('Plan validation passed');
180
- } catch (error) {
181
- log('Plan validation failed: %s', error);
182
- throw error;
183
- }
184
- }
185
-
186
- return result;
187
- } finally {
188
- tracePhaseEnd('optimization');
189
- }
190
- }
191
-
192
- /**
193
- * Perform single-pass constant folding over the entire plan tree
194
- */
195
- private performConstantFolding(plan: PlanNode, context: OptContext): PlanNode {
196
- try {
197
- // Create runtime expression evaluator
198
- const evaluator = createRuntimeExpressionEvaluator(context.db);
199
-
200
- // Perform single-pass constant folding
201
- const result = performConstantFolding(plan, evaluator);
202
-
203
- log('Constant folding completed');
204
- return result;
205
- } catch (error) {
206
- log('Constant folding failed: %s', error);
207
- // Return original plan on failure
208
- return plan;
209
- }
210
- }
211
-
212
- optimizeNode(node: PlanNode, context: OptContext): PlanNode {
213
- traceNodeStart(node);
214
-
215
- // If already physical, just recurse on children
216
- if (node.physical) {
217
- const result = this.optimizeChildren(node, context);
218
- traceNodeEnd(node, result);
219
- return result;
220
- }
221
-
222
- // First optimize all children
223
- const optimizedNode = this.optimizeChildren(node, context);
224
-
225
- // Apply rules
226
- const rulesApplied = applyRules(optimizedNode, context);
227
-
228
- if (rulesApplied !== optimizedNode) {
229
- // Rules transformed the node
230
- log(`Rules applied to ${optimizedNode.nodeType}, transformed to ${rulesApplied.nodeType}`);
231
- traceNodeEnd(node, rulesApplied);
232
- return rulesApplied;
233
- }
234
-
235
- // No rule applied - assume node is physical
236
- traceNodeEnd(node, optimizedNode);
237
- return optimizedNode;
238
- }
239
-
240
- private optimizeChildren(node: PlanNode, context: OptContext): PlanNode {
241
- // Generic tree walk using withChildren
242
- const originalChildren = node.getChildren();
243
- const optimizedChildren = originalChildren.map(child => this.optimizeNode(child, context));
244
-
245
- // Check if any children changed
246
- const childrenChanged = optimizedChildren.some((child, i) => child !== originalChildren[i]);
247
-
248
- if (!childrenChanged) {
249
- return node; // No changes
250
- }
251
-
252
- // Use withChildren to create new node with optimized children
253
- // withChildren is a required contract - any errors should propagate
254
- return node.withChildren(optimizedChildren);
255
- }
256
-
257
- /**
258
- * Get the statistics provider
259
- */
260
- getStats(): StatsProvider {
261
- return this.stats;
262
- }
263
- }
1
+ import { createLogger } from '../common/logger.js';
2
+ import { PlanNode } from './nodes/plan-node.js';
3
+ import { PlanNodeType } from './nodes/plan-node-type.js';
4
+ import { OptimizerTuning, DEFAULT_TUNING } from './optimizer-tuning.js';
5
+
6
+ // Re-export for convenience
7
+ export { DEFAULT_TUNING };
8
+
9
+ import { applyRules, registerRules, createRule } from './framework/registry.js';
10
+ import { tracePhaseStart, tracePhaseEnd, traceNodeStart, traceNodeEnd } from './framework/trace.js';
11
+ import { defaultStatsProvider, type StatsProvider } from './stats/index.js';
12
+ import { createOptContext, type OptContext } from './framework/context.js';
13
+ // Phase 2 rules
14
+ import { ruleMaterializationAdvisory } from './rules/cache/rule-materialization-advisory.js';
15
+ // Phase 1.5 rules
16
+ import { ruleSelectAccessPath } from './rules/access/rule-select-access-path.js';
17
+ // Core optimization rules
18
+ import { ruleAggregateStreaming } from './rules/aggregate/rule-aggregate-streaming.js';
19
+ // Constraint rules removed - now handled in builders for correctness
20
+ import { ruleCteOptimization } from './rules/cache/rule-cte-optimization.js';
21
+ import { ruleMutatingSubqueryCache } from './rules/cache/rule-mutating-subquery-cache.js';
22
+ // Phase 3 rules
23
+ import { validatePhysicalTree } from './validation/plan-validator.js';
24
+ import { Database } from '../core/database.js';
25
+ import { performConstantFolding } from './analysis/const-pass.js';
26
+ import { createRuntimeExpressionEvaluator } from './analysis/const-evaluator.js';
27
+
28
+ const log = createLogger('optimizer');
29
+
30
+ /**
31
+ * The query optimizer transforms logical plan trees into physical plan trees
32
+ */
33
+ export class Optimizer {
34
+ private readonly stats: StatsProvider;
35
+
36
+ constructor(
37
+ public readonly tuning: OptimizerTuning = DEFAULT_TUNING,
38
+ stats?: StatsProvider
39
+ ) {
40
+ this.stats = stats ?? defaultStatsProvider;
41
+
42
+ // Ensure global framework rules are registered once
43
+ Optimizer.ensureGlobalRulesRegistered();
44
+ }
45
+
46
+ private static globalRulesRegistered = false;
47
+
48
+ /**
49
+ * Ensure global framework rules are registered only once
50
+ */
51
+ private static ensureGlobalRulesRegistered(): void {
52
+ if (Optimizer.globalRulesRegistered) {
53
+ return;
54
+ }
55
+ Optimizer.globalRulesRegistered = true;
56
+
57
+ const toRegister = [];
58
+
59
+ // Note: Single-pass constant folding is done before rules
60
+
61
+ // Mutating subquery cache injection - critical for correctness
62
+ toRegister.push(createRule(
63
+ 'mutating-subquery-cache',
64
+ PlanNodeType.Join,
65
+ 'rewrite',
66
+ ruleMutatingSubqueryCache,
67
+ 20 // Very high priority - correctness fix to prevent multiple execution
68
+ ));
69
+
70
+ // Phase 1.5 rules
71
+ toRegister.push(createRule(
72
+ 'select-access-path',
73
+ PlanNodeType.TableReference,
74
+ 'impl',
75
+ ruleSelectAccessPath,
76
+ 25 // High priority - fundamental access path selection
77
+ ));
78
+
79
+ // Core optimization rules (converted from old system)
80
+ toRegister.push(createRule(
81
+ 'aggregate-streaming',
82
+ PlanNodeType.Aggregate,
83
+ 'impl',
84
+ ruleAggregateStreaming,
85
+ 40 // High priority - fundamental logical→physical transformation
86
+ ));
87
+
88
+ // toRegister.push(createRule(
89
+ // 'project-optimization',
90
+ // PlanNodeType.Project,
91
+ // 'impl',
92
+ // ruleProjectOptimization,
93
+ // 50 // Medium priority - basic optimization
94
+ // ));
95
+
96
+ // toRegister.push(createRule(
97
+ // 'filter-optimization',
98
+ // PlanNodeType.Filter,
99
+ // 'impl',
100
+ // ruleFilterOptimization,
101
+ // 50 // Medium priority - basic optimization
102
+ // ));
103
+
104
+ toRegister.push(createRule(
105
+ 'cte-optimization',
106
+ PlanNodeType.CTE,
107
+ 'impl',
108
+ ruleCteOptimization,
109
+ 70 // Lower priority - caching optimization
110
+ ));
111
+
112
+ // Phase 2 rules - Materialization advisory
113
+ // TODO: Can we apply this more generally rather than assuming certain node types?
114
+ // Register for all node types that can have relational children
115
+ const nodeTypesWithRelationalChildren = [
116
+ PlanNodeType.Block, // Contains statements
117
+ PlanNodeType.ScalarSubquery, // Contains relational subquery
118
+ PlanNodeType.Exists, // Contains relational subquery
119
+ PlanNodeType.In, // Can contain relational subquery
120
+ PlanNodeType.Insert, // Has source relation
121
+ PlanNodeType.Update, // Has source relation
122
+ PlanNodeType.Delete, // Has source relation
123
+ PlanNodeType.CTE, // Has definition relation
124
+ PlanNodeType.RecursiveCTE, // Has anchor/recursive relations
125
+ PlanNodeType.Returning, // Wraps DML operations
126
+ // Scalar nodes that might contain subqueries
127
+ PlanNodeType.ScalarFunctionCall, // Function args might be subqueries
128
+ PlanNodeType.CaseExpr, // CASE conditions might be subqueries
129
+ ];
130
+
131
+ for (const nodeType of nodeTypesWithRelationalChildren) {
132
+ toRegister.push(createRule(
133
+ 'materialization-advisory',
134
+ nodeType,
135
+ 'rewrite',
136
+ ruleMaterializationAdvisory,
137
+ 90 // Low priority - run last for global analysis
138
+ ));
139
+ }
140
+
141
+ // Register all rules at once
142
+ registerRules(toRegister);
143
+ }
144
+
145
+ /**
146
+ * Optimize a plan tree by applying transformation rules
147
+ */
148
+ optimize(plan: PlanNode, db: Database): PlanNode {
149
+ log('Starting optimization of plan', plan.nodeType);
150
+
151
+ // Create optimization context
152
+ const context = createOptContext(this, this.stats, this.tuning, db);
153
+
154
+ tracePhaseStart('optimization');
155
+ try {
156
+ // Phase 0: Single-pass constant folding before other rules
157
+ log('Running constant folding pre-pass');
158
+ const constantFoldedPlan = this.performConstantFolding(plan, context);
159
+
160
+ // Continue with rule-based optimization
161
+ const result = this.optimizeNode(constantFoldedPlan, context);
162
+
163
+ // Phase 3: Validate the physical plan before returning
164
+ if (this.tuning.debug.validatePlan) {
165
+ log('Running plan validation');
166
+ try {
167
+ validatePhysicalTree(result);
168
+ log('Plan validation passed');
169
+ } catch (error) {
170
+ log('Plan validation failed: %s', error);
171
+ throw error;
172
+ }
173
+ }
174
+
175
+ return result;
176
+ } finally {
177
+ tracePhaseEnd('optimization');
178
+ }
179
+ }
180
+
181
+ /**
182
+ * Perform single-pass constant folding over the entire plan tree
183
+ */
184
+ private performConstantFolding(plan: PlanNode, context: OptContext): PlanNode {
185
+ // Create runtime expression evaluator
186
+ const evaluator = createRuntimeExpressionEvaluator(context.db);
187
+
188
+ // Perform single-pass constant folding
189
+ const result = performConstantFolding(plan, evaluator);
190
+
191
+ log('Constant folding completed');
192
+ return result;
193
+ }
194
+
195
+ optimizeNode(node: PlanNode, context: OptContext): PlanNode {
196
+ traceNodeStart(node);
197
+
198
+ // Check if we've already optimized this exact node instance
199
+ const cached = context.optimizedNodes.get(node.id);
200
+ if (cached) {
201
+ log('Reusing optimized version of shared node %s (%s)', node.id, node.nodeType);
202
+ traceNodeEnd(node, cached);
203
+ return cached;
204
+ }
205
+
206
+ // Note: We removed the broken `if (node.physical)` check here
207
+ // The `physical` property is always truthy (it returns a PhysicalProperties object)
208
+ // Physical vs logical distinction should be handled by the rules themselves
209
+
210
+ // First optimize all children
211
+ const optimizedNode = this.optimizeChildren(node, context);
212
+
213
+ // Apply rules
214
+ const rulesApplied = applyRules(optimizedNode, context);
215
+
216
+ if (rulesApplied !== optimizedNode) {
217
+ // Rules transformed the node
218
+ log(`Rules applied to ${optimizedNode.nodeType}, transformed to ${rulesApplied.nodeType}`);
219
+ traceNodeEnd(node, rulesApplied);
220
+
221
+ // Cache the final result
222
+ context.optimizedNodes.set(node.id, rulesApplied);
223
+ return rulesApplied;
224
+ }
225
+
226
+ // No rule applied - assume node is physical
227
+ traceNodeEnd(node, optimizedNode);
228
+
229
+ // Cache the result even if no rules applied
230
+ context.optimizedNodes.set(node.id, optimizedNode);
231
+ return optimizedNode;
232
+ }
233
+
234
+ private optimizeChildren(node: PlanNode, context: OptContext): PlanNode {
235
+ // Generic tree walk using withChildren
236
+ const originalChildren = node.getChildren();
237
+ const optimizedChildren = originalChildren.map(child => this.optimizeNode(child, context));
238
+
239
+ // Check if any children changed
240
+ const childrenChanged = optimizedChildren.some((child, i) => child !== originalChildren[i]);
241
+
242
+ if (!childrenChanged) {
243
+ return node; // No changes
244
+ }
245
+
246
+ // Use withChildren to create new node with optimized children
247
+ // withChildren is a required contract - any errors should propagate
248
+ return node.withChildren(optimizedChildren);
249
+ }
250
+
251
+ /**
252
+ * Get the statistics provider
253
+ */
254
+ getStats(): StatsProvider {
255
+ return this.stats;
256
+ }
257
+ }
@@ -3,6 +3,8 @@ import type { Database } from '../core/database.js';
3
3
  import type { SchemaManager } from '../schema/manager.js';
4
4
  import type { Scope } from './scopes/scope.js';
5
5
  import type { ScalarPlanNode } from './nodes/plan-node.js';
6
+ import type { CTEPlanNode } from './nodes/cte-node.js';
7
+ import type { CTEReferenceNode } from './nodes/cte-reference-node.js';
6
8
 
7
9
  /**
8
10
  * Debug options for query planning and execution.
@@ -156,6 +158,13 @@ export interface PlanningContext {
156
158
  attributeId: number;
157
159
  }>;
158
160
 
161
+ /**
162
+ * Active CTEs available in the current planning context.
163
+ * This map contains all CTEs from the current WITH clause and any parent WITH clauses,
164
+ * allowing subqueries in expressions to resolve CTE references correctly.
165
+ */
166
+ readonly cteNodes?: Map<string, CTEPlanNode>;
167
+
159
168
  /**
160
169
  * Schema dependency tracker for this planning session.
161
170
  */
@@ -165,4 +174,10 @@ export interface PlanningContext {
165
174
  * Schema object cache for resolved objects during planning.
166
175
  */
167
176
  readonly schemaCache: Map<string, any>;
177
+
178
+ /**
179
+ * Cache for CTE reference nodes to ensure consistent attribute IDs across multiple references
180
+ * to the same CTE with the same alias. Key format: "cteName:alias"
181
+ */
182
+ cteReferenceCache?: Map<string, CTEReferenceNode>;
168
183
  }