@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
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Rule: Select Access Path
3
3
  *
4
- * Transforms: TableScanNode → SeqScanNode | IndexScanNode | IndexSeekNode
4
+ * Transforms: TableReferenceNode → SeqScanNode | IndexScanNode | IndexSeekNode
5
5
  * Conditions: When logical table access needs to be made physical
6
6
  * Benefits: Enables cost-based access path selection and index utilization
7
7
  */
@@ -9,39 +9,36 @@
9
9
  import { createLogger } from '../../../common/logger.js';
10
10
  import type { PlanNode } from '../../nodes/plan-node.js';
11
11
  import type { OptContext } from '../../framework/context.js';
12
- import { TableScanNode } from '../../nodes/scan.js';
13
- import { SeqScanNode, IndexScanNode, IndexSeekNode } from '../../nodes/physical-access-nodes.js';
12
+ import { TableReferenceNode } from '../../nodes/reference.js';
13
+ import { SeqScanNode, IndexScanNode, IndexSeekNode } from '../../nodes/table-access-nodes.js';
14
14
  import { seqScanCost } from '../../cost/index.js';
15
- import type { ColumnMeta, PredicateConstraint, BestAccessPlanRequest, BestAccessPlanResult, ConstraintOp } from '../../../vtab/best-access-plan.js';
15
+ import type { ColumnMeta, PredicateConstraint, BestAccessPlanRequest, BestAccessPlanResult } from '../../../vtab/best-access-plan.js';
16
+ import { FilterInfo } from '../../../vtab/filter-info.js';
17
+ import type { IndexConstraintUsage } from '../../../vtab/index-info.js';
16
18
 
17
19
  const log = createLogger('optimizer:rule:select-access-path');
18
20
 
19
21
  export function ruleSelectAccessPath(node: PlanNode, context: OptContext): PlanNode | null {
20
- // Guard: only apply to TableScanNode
21
- if (!(node instanceof TableScanNode)) {
22
+ // Guard: only apply to TableReferenceNode
23
+ if (!(node instanceof TableReferenceNode)) {
22
24
  return null;
23
25
  }
24
26
 
25
- // Guard: already physical
26
- if (node.physical) {
27
- return null;
28
- }
29
-
30
- log('Selecting access path for table %s', node.source.tableSchema.name);
27
+ log('Selecting access path for table %s', node.tableSchema.name);
31
28
 
32
29
  try {
33
30
  // Get table schema and virtual table module
34
- const tableSchema = node.source.tableSchema;
31
+ const tableSchema = node.tableSchema;
35
32
  const vtabModule = tableSchema.vtabModule;
36
33
 
37
34
  // If no virtual table module, fall back to sequential scan
38
35
  if (!vtabModule || typeof vtabModule !== 'object' || !('getBestAccessPlan' in vtabModule)) {
39
36
  log('No getBestAccessPlan support, using sequential scan for %s', tableSchema.name);
40
- return createSeqScan(node);
37
+ return createSeqScan(node, undefined);
41
38
  }
42
39
 
43
40
  // Extract constraints from current filter info
44
- const constraints = extractConstraintsFromFilterInfo(node, tableSchema);
41
+ const constraints: PredicateConstraint[] = []; // TODO: Extract from parent Filter node if any
45
42
 
46
43
  // Build request for getBestAccessPlan
47
44
  const request: BestAccessPlanRequest = {
@@ -53,7 +50,7 @@ export function ruleSelectAccessPath(node: PlanNode, context: OptContext): PlanN
53
50
  isUnique: col.primaryKey || false // For now, assume only PK columns are unique
54
51
  } as ColumnMeta)),
55
52
  filters: constraints,
56
- estimatedRows: node.source.estimatedRows
53
+ estimatedRows: node.estimatedRows
57
54
  };
58
55
 
59
56
  // Call getBestAccessPlan
@@ -68,58 +65,43 @@ export function ruleSelectAccessPath(node: PlanNode, context: OptContext): PlanN
68
65
  return physicalNode;
69
66
 
70
67
  } catch (error) {
71
- log('Error selecting access path for %s: %s', node.source.tableSchema.name, error);
68
+ log('Error selecting access path for %s: %s', node.tableSchema.name, error);
72
69
  // Fall back to sequential scan on error
73
70
  return createSeqScan(node);
74
71
  }
75
72
  }
76
73
 
77
- /**
78
- * Extract predicate constraints from FilterInfo
79
- */
80
- function extractConstraintsFromFilterInfo(node: TableScanNode, _tableSchema: any): PredicateConstraint[] {
81
- const constraints: PredicateConstraint[] = [];
82
-
83
- // Extract from FilterInfo.indexInfoOutput.aConstraint if available
84
- const indexConstraints = node.filterInfo.indexInfoOutput.aConstraint;
85
- if (indexConstraints) {
86
- for (let i = 0; i < indexConstraints.length; i++) {
87
- const constraint = indexConstraints[i];
88
-
89
- if (constraint && constraint.usable) {
90
- constraints.push({
91
- columnIndex: constraint.iColumn,
92
- op: mapConstraintOp(constraint.op),
93
- usable: constraint.usable,
94
- // Note: actual value would need to be extracted from args
95
- value: undefined
96
- });
97
- }
98
- }
99
- }
100
-
101
- return constraints;
102
- }
103
-
104
- /**
105
- * Map internal constraint op to public constraint op
106
- */
107
- function mapConstraintOp(_internalOp: number): ConstraintOp {
108
- // This mapping would need to be based on the actual constants used
109
- // For now, assume equality - in a real implementation this would map
110
- // from IndexConstraintOp constants to ConstraintOp
111
- return '=';
112
- }
113
-
114
74
  /**
115
75
  * Select the appropriate physical node based on access plan
116
76
  */
117
77
  function selectPhysicalNode(
118
- originalNode: TableScanNode,
78
+ originalNode: TableReferenceNode,
119
79
  accessPlan: BestAccessPlanResult,
120
80
  constraints: PredicateConstraint[]
121
81
  ): SeqScanNode | IndexScanNode | IndexSeekNode {
122
82
 
83
+ // Create a default FilterInfo for the physical nodes
84
+ const filterInfo: FilterInfo = {
85
+ idxNum: 0,
86
+ idxStr: 'fullscan',
87
+ constraints: [],
88
+ args: [],
89
+ indexInfoOutput: {
90
+ nConstraint: 0,
91
+ aConstraint: [],
92
+ nOrderBy: 0,
93
+ aOrderBy: [],
94
+ aConstraintUsage: [] as IndexConstraintUsage[],
95
+ idxNum: 0,
96
+ idxStr: 'fullscan',
97
+ orderByConsumed: false,
98
+ estimatedCost: accessPlan.cost,
99
+ estimatedRows: BigInt(accessPlan.rows || 1000),
100
+ idxFlags: 0,
101
+ colUsed: 0n,
102
+ }
103
+ };
104
+
123
105
  // Analyze the access plan to determine node type
124
106
  const hasEqualityConstraints = constraints.some(c => c.op === '=' && accessPlan.handledFilters[constraints.indexOf(c)]);
125
107
  const hasRangeConstraints = constraints.some(c => ['>', '>=', '<', '<='].includes(c.op) && accessPlan.handledFilters[constraints.indexOf(c)]);
@@ -136,8 +118,8 @@ function selectPhysicalNode(
136
118
  log('Using index seek (equality constraint, small result)');
137
119
  return new IndexSeekNode(
138
120
  originalNode.scope,
139
- originalNode.source,
140
- originalNode.filterInfo,
121
+ originalNode,
122
+ filterInfo,
141
123
  'primary', // Default to primary index
142
124
  [], // seekKeys would be populated from constraints
143
125
  false, // not a range
@@ -149,8 +131,8 @@ function selectPhysicalNode(
149
131
  log('Using index scan (range constraints or ordering)');
150
132
  return new IndexScanNode(
151
133
  originalNode.scope,
152
- originalNode.source,
153
- originalNode.filterInfo,
134
+ originalNode,
135
+ filterInfo,
154
136
  'primary', // Default to primary index
155
137
  providesOrdering,
156
138
  accessPlan.cost
@@ -158,21 +140,43 @@ function selectPhysicalNode(
158
140
  } else {
159
141
  // Fall back to sequential scan
160
142
  log('Using sequential scan (no beneficial index access)');
161
- return createSeqScan(originalNode, accessPlan.cost);
143
+ return createSeqScan(originalNode, filterInfo, accessPlan.cost);
162
144
  }
163
145
  }
164
146
 
165
147
  /**
166
148
  * Create a sequential scan node
167
149
  */
168
- function createSeqScan(originalNode: TableScanNode, cost?: number): SeqScanNode {
169
- const tableRows = originalNode.source.estimatedRows || 1000;
150
+ function createSeqScan(originalNode: TableReferenceNode, filterInfo?: FilterInfo, cost?: number): SeqScanNode {
151
+ const tableRows = originalNode.estimatedRows || 1000;
170
152
  const scanCost = cost ?? seqScanCost(tableRows);
171
153
 
154
+ // Create default FilterInfo if not provided
155
+ const effectiveFilterInfo = filterInfo || {
156
+ idxNum: 0,
157
+ idxStr: 'fullscan',
158
+ constraints: [],
159
+ args: [],
160
+ indexInfoOutput: {
161
+ nConstraint: 0,
162
+ aConstraint: [],
163
+ nOrderBy: 0,
164
+ aOrderBy: [],
165
+ aConstraintUsage: [] as IndexConstraintUsage[],
166
+ idxNum: 0,
167
+ idxStr: 'fullscan',
168
+ orderByConsumed: false,
169
+ estimatedCost: scanCost,
170
+ estimatedRows: BigInt(tableRows),
171
+ idxFlags: 0,
172
+ colUsed: 0n,
173
+ }
174
+ };
175
+
172
176
  const seqScan = new SeqScanNode(
173
177
  originalNode.scope,
174
- originalNode.source,
175
- originalNode.filterInfo,
178
+ originalNode,
179
+ effectiveFilterInfo,
176
180
  scanCost
177
181
  );
178
182
 
@@ -42,13 +42,49 @@ export function ruleAggregateStreaming(node: PlanNode, _context: OptContext): Pl
42
42
 
43
43
  const sortNode = new SortNode(node.scope, source, sortKeys);
44
44
 
45
+ // Create combined attributes: AggregateNode attributes + source attributes
46
+ // This ensures both GROUP BY/aggregate AND source column attribute IDs are preserved
47
+ const aggregateAttrs = node.getAttributes();
48
+ const sourceAttrs = node.source.getAttributes();
49
+
50
+ // Deduplicate by column NAME to avoid duplicate columns like 'id'
51
+ // (The same logical column can have different attribute IDs between aggregate and source)
52
+ const seenNames = new Set<string>();
53
+ const combinedAttrs: typeof aggregateAttrs = [];
54
+
55
+ // Add aggregate attributes first (GROUP BY + aggregates)
56
+ for (const attr of aggregateAttrs) {
57
+ combinedAttrs.push(attr);
58
+ seenNames.add(attr.name);
59
+ }
60
+
61
+ // Add source attributes that aren't already present by name
62
+ for (const attr of sourceAttrs) {
63
+ if (!seenNames.has(attr.name)) {
64
+ combinedAttrs.push(attr);
65
+ seenNames.add(attr.name);
66
+ }
67
+ }
68
+
69
+ // Final safety-pass: filter duplicates that may have slipped through
70
+ const uniqueByName = new Set<string>();
71
+ const deduped: typeof combinedAttrs = [];
72
+ for (const attr of combinedAttrs) {
73
+ if (!uniqueByName.has(attr.name)) {
74
+ deduped.push(attr);
75
+ uniqueByName.add(attr.name);
76
+ }
77
+ }
78
+
79
+ const finalAttrs = deduped;
80
+
45
81
  const result = new StreamAggregateNode(
46
82
  node.scope,
47
83
  sortNode,
48
84
  node.groupBy,
49
85
  node.aggregates,
50
86
  undefined, // estimatedCostOverride
51
- node.getAttributes() // **CRITICAL**: Preserve original attribute IDs
87
+ finalAttrs // unique list
52
88
  );
53
89
 
54
90
  // Let framework set physical properties via markPhysical()
@@ -58,13 +94,49 @@ export function ruleAggregateStreaming(node: PlanNode, _context: OptContext): Pl
58
94
  return result;
59
95
  } else {
60
96
  // No GROUP BY - can stream aggregate without sorting
97
+ // Create combined attributes: AggregateNode attributes + source attributes
98
+ // This ensures both GROUP BY/aggregate AND source column attribute IDs are preserved
99
+ const aggregateAttrs = node.getAttributes();
100
+ const sourceAttrs = node.source.getAttributes();
101
+
102
+ // Deduplicate by column NAME to avoid duplicate columns like 'id'
103
+ // (The same logical column can have different attribute IDs between aggregate and source)
104
+ const seenNames = new Set<string>();
105
+ const combinedAttrs: typeof aggregateAttrs = [];
106
+
107
+ // Add aggregate attributes first (GROUP BY + aggregates)
108
+ for (const attr of aggregateAttrs) {
109
+ combinedAttrs.push(attr);
110
+ seenNames.add(attr.name);
111
+ }
112
+
113
+ // Add source attributes that aren't already present by name
114
+ for (const attr of sourceAttrs) {
115
+ if (!seenNames.has(attr.name)) {
116
+ combinedAttrs.push(attr);
117
+ seenNames.add(attr.name);
118
+ }
119
+ }
120
+
121
+ // Final safety-pass: filter duplicates that may have slipped through
122
+ const uniqueByName = new Set<string>();
123
+ const deduped: typeof combinedAttrs = [];
124
+ for (const attr of combinedAttrs) {
125
+ if (!uniqueByName.has(attr.name)) {
126
+ deduped.push(attr);
127
+ uniqueByName.add(attr.name);
128
+ }
129
+ }
130
+
131
+ const finalAttrs = deduped;
132
+
61
133
  const result = new StreamAggregateNode(
62
134
  node.scope,
63
135
  source,
64
136
  node.groupBy,
65
137
  node.aggregates,
66
138
  undefined, // estimatedCostOverride
67
- node.getAttributes() // **CRITICAL**: Preserve original attribute IDs
139
+ finalAttrs // unique list
68
140
  );
69
141
 
70
142
  // Let framework set physical properties via markPhysical()
@@ -14,46 +14,50 @@ import { MaterializationAdvisory } from '../../cache/materialization-advisory.js
14
14
  const log = createLogger('optimizer:rule:materialization-advisory');
15
15
 
16
16
  export function ruleMaterializationAdvisory(node: PlanNode, context: OptContext): PlanNode | null {
17
- // This is a global rule that analyzes the entire tree
18
- // It should only be applied to root nodes to avoid duplicate analysis
17
+ // Apply this rule when we're at a non-relational node that has relational children
18
+ // This captures transitions into relational subtrees (queries, subqueries, CTEs, etc.)
19
19
 
20
- // Simple heuristic: only apply to certain root-level node types
21
- // to avoid analyzing the same tree multiple times
22
- const rootNodeTypes = new Set([
23
- 'Select', 'Insert', 'Update', 'Delete', 'Block', 'CTE'
24
- ]);
20
+ // Check if this is a non-relational node
21
+ const nodeType = node.getType();
22
+ if (nodeType.typeClass === 'relation') {
23
+ // This is already a relational node, don't apply here
24
+ return null;
25
+ }
25
26
 
26
- if (!rootNodeTypes.has(node.nodeType)) {
27
+ // Check if this node has any relational children
28
+ const relations = node.getRelations();
29
+ if (relations.length === 0) {
30
+ // No relational children, nothing to analyze
27
31
  return null;
28
32
  }
29
33
 
30
- log('Applying materialization advisory to tree rooted at %s', node.nodeType);
34
+ log('Applying materialization advisory at transition from %s to relational children', node.nodeType);
31
35
 
32
36
  try {
33
37
  // Create advisory with current tuning parameters
34
38
  const advisory = new MaterializationAdvisory(context.tuning);
35
39
 
36
- // Analyze the tree for caching opportunities
37
- const recommendations = advisory.analyzeTree(node);
38
-
39
- // Count how many cache recommendations were made
40
- const cacheCount = Array.from(recommendations.values())
41
- .filter(rec => rec.shouldCache).length;
40
+ // We need to analyze and potentially transform each relational subtree
41
+ let anyTransformed = false;
42
42
 
43
- if (cacheCount === 0) {
44
- log('No caching opportunities identified');
45
- return null;
43
+ // For each relational child, analyze and transform its entire subtree
44
+ for (const relation of relations) {
45
+ const transformedRelation = advisory.analyzeAndTransform(relation);
46
+ if (transformedRelation !== relation) {
47
+ anyTransformed = true;
48
+ log('Transformed relational subtree under %s', node.nodeType);
49
+ }
46
50
  }
47
51
 
48
- log('Found %d caching opportunities', cacheCount);
49
-
50
- // Apply the caching recommendations
51
- const cachedTree = advisory.applyCaching(node, recommendations);
52
-
53
- // If the tree was modified, return the new tree
54
- if (cachedTree !== node) {
55
- log('Applied materialization advisory, tree modified');
56
- return cachedTree;
52
+ // If any relational children were transformed, we need to return a transformed node
53
+ // However, since we can't easily reconstruct the parent node with new relational children
54
+ // (as discussed in the earlier implementation), we'll analyze the entire node
55
+ if (anyTransformed) {
56
+ // Re-analyze the entire tree rooted at this node
57
+ const fullTransform = advisory.analyzeAndTransform(node);
58
+ if (fullTransform !== node) {
59
+ return fullTransform;
60
+ }
57
61
  }
58
62
 
59
63
  return null;
@@ -6,22 +6,5 @@ import { type Scope, Ambiguous } from './scope.js';
6
6
  * Scope that tracks references.
7
7
  */
8
8
  export abstract class BaseScope implements Scope {
9
- /** References that have been resolved through this scope. */
10
- private _references: PlanNode[] = [];
11
-
12
9
  abstract resolveSymbol(symbolKey: string, expression: AST.Expression): PlanNode | typeof Ambiguous | undefined;
13
-
14
- /**
15
- * Returns all references that have been resolved through this scope.
16
- * This includes references from both this scope and any parent scopes.
17
- *
18
- * @returns An array of all resolved references.
19
- */
20
- getReferences(): readonly PlanNode[] {
21
- return this._references;
22
- }
23
-
24
- addReference(reference: PlanNode): void {
25
- this._references.push(reference);
26
- }
27
10
  }
@@ -1,5 +1,3 @@
1
- import { QuereusError } from '../../common/errors.js';
2
- import { StatusCode } from '../../common/types.js';
3
1
  import * as AST from '../../parser/ast.js';
4
2
  import type { PlanNode } from '../nodes/plan-node.js';
5
3
  import { type Scope, Ambiguous } from './scope.js';
@@ -10,13 +8,5 @@ export class EmptyScope implements Scope {
10
8
  return undefined;
11
9
  }
12
10
 
13
- getReferences(): readonly PlanNode[] {
14
- return [];
15
- }
16
-
17
- addReference(_reference: PlanNode): void {
18
- throw new QuereusError('EmptyScope does not support adding references.', StatusCode.MISUSE);
19
- }
20
-
21
11
  static readonly instance = new EmptyScope();
22
12
  }
@@ -31,7 +31,6 @@ export class MultiScope extends BaseScope {
31
31
  return Ambiguous;
32
32
  }
33
33
  if (result) {
34
- this.addReference(result);
35
34
  return result;
36
35
  }
37
36
  }
@@ -76,7 +76,6 @@ export class ParameterScope extends BaseScope {
76
76
  return this.parentScope.resolveSymbol(symbolKey, expression);
77
77
  }
78
78
 
79
- this.addReference(parameterNode!);
80
79
  return parameterNode;
81
80
  }
82
81
 
@@ -10,9 +10,6 @@ import { type ReferenceCallback, type Scope, Ambiguous } from './scope.js';
10
10
  * based on the current position in the PlanNode tree.
11
11
  */
12
12
  export class RegisteredScope implements Scope {
13
- /** References that have been resolved through this scope. */
14
- private _references: PlanNode[] = [];
15
-
16
13
  /** Symbols that have been registered in this scope. */
17
14
  private registeredSymbols: Map<string, ReferenceCallback> = new Map();
18
15
 
@@ -43,9 +40,7 @@ export class RegisteredScope implements Scope {
43
40
  resolveSymbol(symbolKey: string, expression: AST.Expression): PlanNode | typeof Ambiguous | undefined {
44
41
  const reference = this.registeredSymbols.get(symbolKey.toLowerCase());
45
42
  if (reference) {
46
- const node = reference(expression, this);
47
- this.addReference(node);
48
- return node;
43
+ return reference(expression, this);
49
44
  }
50
45
  if (this.parent) {
51
46
  return this.parent.resolveSymbol(symbolKey, expression);
@@ -53,20 +48,6 @@ export class RegisteredScope implements Scope {
53
48
  return undefined;
54
49
  }
55
50
 
56
- /**
57
- * Returns all references that have been resolved through this scope.
58
- * This includes references from both this scope and any parent scopes.
59
- *
60
- * @returns An array of all resolved references.
61
- */
62
- getReferences(): readonly PlanNode[] {
63
- return this._references;
64
- }
65
-
66
- addReference(reference: PlanNode): void {
67
- this._references.push(reference);
68
- }
69
-
70
51
  /**
71
52
  * Returns all symbols that have been registered in this scope.
72
53
  *
@@ -13,16 +13,4 @@ export type ReferenceCallback = (expression: AST.Expression, currentScope: Scope
13
13
  */
14
14
  export interface Scope {
15
15
  resolveSymbol(symbolKey: string, expression: AST.Expression): PlanNode | typeof Ambiguous | undefined;
16
-
17
- /**
18
- * Returns all references that have been resolved through this scope.
19
- * This includes references from both this scope and any parent scopes.
20
- *
21
- * @returns An array of all resolved references.
22
- */
23
- getReferences(): readonly PlanNode[];
24
-
25
- addReference(reference: PlanNode): void;
26
16
  }
27
-
28
-
@@ -3,7 +3,7 @@
3
3
  * Validates that a plan tree meets all invariants before emission
4
4
  */
5
5
 
6
- import { PlanNode, type RelationalPlanNode } from '../nodes/plan-node.js';
6
+ import { isRelationalNode, PlanNode, type RelationalPlanNode } from '../nodes/plan-node.js';
7
7
  import { PlanNodeType } from '../nodes/plan-node-type.js';
8
8
  import { QuereusError } from '../../common/errors.js';
9
9
  import { StatusCode } from '../../common/types.js';
@@ -299,13 +299,6 @@ function validateOrdering(ordering: any[], columnCount: number, nodePath: string
299
299
  }
300
300
  }
301
301
 
302
- /**
303
- * Check if a node is a relational node
304
- */
305
- function isRelationalNode(node: PlanNode): boolean {
306
- return 'getAttributes' in node && typeof (node as any).getAttributes === 'function';
307
- }
308
-
309
302
  /**
310
303
  * Check if a node type is a DDL node that doesn't produce attributes
311
304
  */