@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,93 +1,93 @@
1
- import type { ScalarType } from '../../common/datatype.js';
2
- import type * as AST from '../../parser/ast.js';
3
- import type { Scope } from '../scopes/scope.js';
4
- import { PlanNode, type NaryScalarNode, type ScalarPlanNode, type PhysicalProperties } from './plan-node.js';
5
- import { PlanNodeType } from './plan-node-type.js';
6
- import { formatExpressionList, formatScalarType } from '../../util/plan-formatter.js';
7
- import type { FunctionSchema } from '../../schema/function.js';
8
- import { FunctionFlags } from '../../common/constants.js';
9
-
10
- export class ScalarFunctionCallNode extends PlanNode implements NaryScalarNode {
11
- override readonly nodeType = PlanNodeType.ScalarFunctionCall;
12
-
13
- constructor(
14
- scope: Scope,
15
- public readonly expression: AST.FunctionExpr,
16
- public readonly functionSchema: FunctionSchema,
17
- public readonly operands: ScalarPlanNode[]
18
- ) {
19
- super(scope);
20
- }
21
-
22
- getType(): ScalarType {
23
- return this.functionSchema.returnType as ScalarType;
24
- }
25
-
26
- getChildren(): readonly ScalarPlanNode[] {
27
- return this.operands;
28
- }
29
-
30
- getRelations(): readonly [] {
31
- return [];
32
- }
33
-
34
- withChildren(newChildren: readonly PlanNode[]): PlanNode {
35
- if (newChildren.length !== this.operands.length) {
36
- throw new Error(`ScalarFunctionCallNode expects ${this.operands.length} children, got ${newChildren.length}`);
37
- }
38
-
39
- // Type check
40
- for (const child of newChildren) {
41
- if (!('expression' in child)) {
42
- throw new Error('ScalarFunctionCallNode: all children must be ScalarPlanNodes');
43
- }
44
- }
45
-
46
- // Check if anything changed
47
- const childrenChanged = newChildren.some((child, i) => child !== this.operands[i]);
48
- if (!childrenChanged) {
49
- return this;
50
- }
51
-
52
- // Create new instance
53
- return new ScalarFunctionCallNode(
54
- this.scope,
55
- this.expression,
56
- this.functionSchema,
57
- newChildren as ScalarPlanNode[]
58
- );
59
- }
60
-
61
- override toString(): string {
62
- return `${this.expression.name}(${formatExpressionList(this.operands)})`;
63
- }
64
-
65
- override computePhysical(_childrenPhysical: PhysicalProperties[]): Partial<PhysicalProperties> {
66
- // Function calls derive properties from their arguments and the function itself
67
- const result: Partial<PhysicalProperties> = {};
68
-
69
- // Use function schema to determine deterministic and readonly properties
70
- const functionIsDeterministic = (this.functionSchema.flags & FunctionFlags.DETERMINISTIC) !== 0;
71
- const functionIsReadonly = (this.functionSchema.returnType as ScalarType).isReadOnly ?? true;
72
-
73
- // Function is deterministic only if both function and all arguments are deterministic
74
- if (!functionIsDeterministic) {
75
- result.deterministic = false;
76
- }
77
-
78
- // Function is readonly only if both function and all arguments are readonly
79
- if (!functionIsReadonly) {
80
- result.readonly = false;
81
- }
82
-
83
- return result;
84
- }
85
-
86
- override getLogicalAttributes(): Record<string, unknown> {
87
- return {
88
- function: this.expression.name,
89
- arguments: this.operands.map(op => op.toString()),
90
- resultType: formatScalarType(this.functionSchema.returnType as ScalarType)
91
- };
92
- }
93
- }
1
+ import type { ScalarType } from '../../common/datatype.js';
2
+ import type * as AST from '../../parser/ast.js';
3
+ import type { Scope } from '../scopes/scope.js';
4
+ import { PlanNode, type NaryScalarNode, type ScalarPlanNode, type PhysicalProperties } from './plan-node.js';
5
+ import { PlanNodeType } from './plan-node-type.js';
6
+ import { formatExpressionList, formatScalarType } from '../../util/plan-formatter.js';
7
+ import type { FunctionSchema } from '../../schema/function.js';
8
+ import { FunctionFlags } from '../../common/constants.js';
9
+
10
+ export class ScalarFunctionCallNode extends PlanNode implements NaryScalarNode {
11
+ override readonly nodeType = PlanNodeType.ScalarFunctionCall;
12
+
13
+ constructor(
14
+ scope: Scope,
15
+ public readonly expression: AST.FunctionExpr,
16
+ public readonly functionSchema: FunctionSchema,
17
+ public readonly operands: ScalarPlanNode[]
18
+ ) {
19
+ super(scope);
20
+ }
21
+
22
+ getType(): ScalarType {
23
+ return this.functionSchema.returnType as ScalarType;
24
+ }
25
+
26
+ getChildren(): readonly ScalarPlanNode[] {
27
+ return this.operands;
28
+ }
29
+
30
+ getRelations(): readonly [] {
31
+ return [];
32
+ }
33
+
34
+ withChildren(newChildren: readonly PlanNode[]): PlanNode {
35
+ if (newChildren.length !== this.operands.length) {
36
+ throw new Error(`ScalarFunctionCallNode expects ${this.operands.length} children, got ${newChildren.length}`);
37
+ }
38
+
39
+ // Type check
40
+ for (const child of newChildren) {
41
+ if (!('expression' in child)) {
42
+ throw new Error('ScalarFunctionCallNode: all children must be ScalarPlanNodes');
43
+ }
44
+ }
45
+
46
+ // Check if anything changed
47
+ const childrenChanged = newChildren.some((child, i) => child !== this.operands[i]);
48
+ if (!childrenChanged) {
49
+ return this;
50
+ }
51
+
52
+ // Create new instance
53
+ return new ScalarFunctionCallNode(
54
+ this.scope,
55
+ this.expression,
56
+ this.functionSchema,
57
+ newChildren as ScalarPlanNode[]
58
+ );
59
+ }
60
+
61
+ override toString(): string {
62
+ return `${this.expression.name}(${formatExpressionList(this.operands)})`;
63
+ }
64
+
65
+ override computePhysical(_childrenPhysical: PhysicalProperties[]): Partial<PhysicalProperties> {
66
+ // Function calls derive properties from their arguments and the function itself
67
+ const result: Partial<PhysicalProperties> = {};
68
+
69
+ // Use function schema to determine deterministic and readonly properties
70
+ const functionIsDeterministic = (this.functionSchema.flags & FunctionFlags.DETERMINISTIC) !== 0;
71
+ const functionIsReadonly = (this.functionSchema.returnType as ScalarType).isReadOnly ?? true;
72
+
73
+ // Function is deterministic only if both function and all arguments are deterministic
74
+ if (!functionIsDeterministic) {
75
+ result.deterministic = false;
76
+ }
77
+
78
+ // Function is readonly only if both function and all arguments are readonly
79
+ if (!functionIsReadonly) {
80
+ result.readonly = false;
81
+ }
82
+
83
+ return result;
84
+ }
85
+
86
+ override getLogicalAttributes(): Record<string, unknown> {
87
+ return {
88
+ function: this.expression.name,
89
+ arguments: this.operands.map(op => op.toString()),
90
+ resultType: formatScalarType(this.functionSchema.returnType as ScalarType)
91
+ };
92
+ }
93
+ }
@@ -1,5 +1,5 @@
1
1
  import type { Scope } from '../scopes/scope.js';
2
- import { PlanNode, type RelationalPlanNode, type Attribute, type RowDescriptor } from './plan-node.js';
2
+ import { PlanNode, type RelationalPlanNode, type Attribute, type RowDescriptor, type PhysicalProperties, isRelationalNode } from './plan-node.js';
3
3
  import { PlanNodeType } from './plan-node-type.js';
4
4
  import type { TableReferenceNode } from './reference.js';
5
5
  import type { ColumnDef, RelationType } from '../../common/datatype.js';
@@ -67,14 +67,37 @@ export class InsertNode extends PlanNode implements RelationalPlanNode {
67
67
  }
68
68
 
69
69
  override getChildren(): readonly PlanNode[] {
70
- return [];
70
+ // Return the source relation as a child so optimizer can traverse it
71
+ return [this.source];
71
72
  }
72
73
 
73
74
  withChildren(newChildren: readonly PlanNode[]): PlanNode {
74
- if (newChildren.length !== 0) {
75
- throw new Error(`InsertNode expects 0 children, got ${newChildren.length}`);
75
+ if (newChildren.length !== 1) {
76
+ throw new Error(`InsertNode expects 1 child (source), got ${newChildren.length}`);
76
77
  }
77
- return this; // No children in getChildren(), source is accessed via getRelations()
78
+
79
+ const newSource = newChildren[0] as RelationalPlanNode;
80
+ if (!isRelationalNode(newSource)) {
81
+ throw new Error('InsertNode: child must be a RelationalPlanNode');
82
+ }
83
+
84
+ if (newSource === this.source) {
85
+ return this;
86
+ }
87
+
88
+ return new InsertNode(
89
+ this.scope,
90
+ this.table,
91
+ this.targetColumns,
92
+ newSource,
93
+ this.flatRowDescriptor
94
+ );
95
+ }
96
+
97
+ computePhysical(): Partial<PhysicalProperties> {
98
+ return {
99
+ readonly: false, // INSERT has side effects
100
+ };
78
101
  }
79
102
 
80
103
  override toString(): string {
@@ -0,0 +1,76 @@
1
+ import { ZeroAryRelationalBase, type Attribute, type TableDescriptor } from './plan-node.js';
2
+ import type { RelationType } from '../../common/datatype.js';
3
+ import { PlanNodeType } from './plan-node-type.js';
4
+ import type { Scope } from '../scopes/scope.js';
5
+ import { Cached } from '../../util/cached.js';
6
+
7
+ /**
8
+ * Plan node for internal recursive CTE references.
9
+ * This represents a reference to the working table within a recursive CTE's recursive case.
10
+ * Unlike CTEReferenceNode, this doesn't materialize the CTE but looks up the working table
11
+ * from the runtime table context.
12
+ */
13
+ export class InternalRecursiveCTERefNode extends ZeroAryRelationalBase {
14
+ readonly nodeType = PlanNodeType.InternalRecursiveCTERef;
15
+
16
+ private attributesCache: Cached<Attribute[]>;
17
+ private typeCache: Cached<RelationType>;
18
+
19
+ constructor(
20
+ scope: Scope,
21
+ public readonly cteName: string,
22
+ public readonly attributes: Attribute[],
23
+ public readonly relationType: RelationType,
24
+ public readonly workingTableDescriptor: TableDescriptor,
25
+ public readonly alias?: string
26
+ ) {
27
+ super(scope, 0.01); // Very low cost since we're just reading from working table
28
+ this.attributesCache = new Cached(() => this.buildAttributes());
29
+ this.typeCache = new Cached(() => this.buildType());
30
+ }
31
+
32
+ private buildAttributes(): Attribute[] {
33
+ // Return the attributes as provided, with proper source relation
34
+ return this.attributes.map((attr: any) => ({
35
+ id: attr.id,
36
+ name: attr.name,
37
+ type: attr.type,
38
+ sourceRelation: `recursive_ref:${this.cteName}`
39
+ }));
40
+ }
41
+
42
+ private buildType(): RelationType {
43
+ return {
44
+ typeClass: 'relation',
45
+ isReadOnly: true, // Working table is read-only from recursive case perspective
46
+ isSet: this.relationType.isSet,
47
+ columns: this.getAttributes().map((attr: any) => ({
48
+ name: attr.name,
49
+ type: attr.type
50
+ })),
51
+ keys: [],
52
+ rowConstraints: []
53
+ };
54
+ }
55
+
56
+ getAttributes(): Attribute[] {
57
+ return this.attributesCache.value;
58
+ }
59
+
60
+ getType(): RelationType {
61
+ return this.typeCache.value;
62
+ }
63
+
64
+ toString(): string {
65
+ const aliasText = this.alias ? ` AS ${this.alias}` : '';
66
+ return `INTERNAL_RECURSIVE_REF ${this.cteName}${aliasText}`;
67
+ }
68
+
69
+ getLogicalAttributes(): Record<string, unknown> {
70
+ return {
71
+ cteName: this.cteName,
72
+ alias: this.alias,
73
+ workingTableDescriptor: this.workingTableDescriptor
74
+ };
75
+ }
76
+ }
@@ -1,4 +1,4 @@
1
- import { PlanNode } from './plan-node.js';
1
+ import { isRelationalNode, PlanNode } from './plan-node.js';
2
2
  import type { RelationalPlanNode, Attribute, BinaryRelationalNode, ScalarPlanNode } from './plan-node.js';
3
3
  import type { RelationType } from '../../common/datatype.js';
4
4
  import { PlanNodeType } from './plan-node-type.js';
@@ -131,10 +131,10 @@ export class JoinNode extends PlanNode implements BinaryRelationalNode {
131
131
  const [newLeft, newRight, newCondition] = newChildren;
132
132
 
133
133
  // Type check
134
- if (!('getAttributes' in newLeft) || typeof (newLeft as any).getAttributes !== 'function') {
134
+ if (!isRelationalNode(newLeft)) {
135
135
  quereusError('JoinNode: first child must be a RelationalPlanNode', StatusCode.INTERNAL);
136
136
  }
137
- if (!('getAttributes' in newRight) || typeof (newRight as any).getAttributes !== 'function') {
137
+ if (!isRelationalNode(newRight)) {
138
138
  quereusError('JoinNode: second child must be a RelationalPlanNode', StatusCode.INTERNAL);
139
139
  }
140
140
  if (newCondition && !('expression' in newCondition)) {
@@ -1,5 +1,5 @@
1
1
  import { PlanNodeType } from './plan-node-type.js';
2
- import { PlanNode, type RelationalPlanNode, type UnaryRelationalNode, type ScalarPlanNode, type Attribute } from './plan-node.js';
2
+ import { PlanNode, type RelationalPlanNode, type UnaryRelationalNode, type ScalarPlanNode, type Attribute, isRelationalNode } from './plan-node.js';
3
3
  import type { RelationType } from '../../common/datatype.js';
4
4
  import type { Scope } from '../scopes/scope.js';
5
5
  import { formatExpression } from '../../util/plan-formatter.js';
@@ -88,7 +88,7 @@ export class LimitOffsetNode extends PlanNode implements UnaryRelationalNode {
88
88
  const [newSource, ...restChildren] = newChildren;
89
89
 
90
90
  // Type check
91
- if (!('getAttributes' in newSource) || typeof (newSource as any).getAttributes !== 'function') {
91
+ if (!isRelationalNode(newSource)) {
92
92
  quereusError('LimitOffsetNode: first child must be a RelationalPlanNode', StatusCode.INTERNAL);
93
93
  }
94
94
 
@@ -3,7 +3,6 @@ export enum PlanNodeType {
3
3
  Block = 'Block',
4
4
  TableReference = 'TableReference',
5
5
  CTEReference = 'CTEReference',
6
- TableScan = 'TableScan',
7
6
  TableSeek = 'TableSeek',
8
7
  Filter = 'Filter',
9
8
  Project = 'Project',
@@ -16,6 +15,7 @@ export enum PlanNodeType {
16
15
  SetOperation = 'SetOperation',
17
16
  CTE = 'CTE',
18
17
  RecursiveCTE = 'RecursiveCTE',
18
+ InternalRecursiveCTERef = 'InternalRecursiveCTERef',
19
19
  In = 'In',
20
20
  Exists = 'Exists',
21
21
  Sequencing = 'Sequencing',
@@ -74,6 +74,8 @@ export interface Attribute {
74
74
  type: ScalarType;
75
75
  /** Source relation that originally produced this column */
76
76
  sourceRelation?: string;
77
+ /** Relation name for qualified access (e.g. table name or alias) */
78
+ relationName?: string;
77
79
  }
78
80
 
79
81
  /**
@@ -126,7 +128,7 @@ export abstract class PlanNode {
126
128
  */
127
129
  getRelations(): readonly RelationalPlanNode[] {
128
130
  return this.getChildren()
129
- .filter((c): c is RelationalPlanNode => 'getAttributes' in c && typeof (c as any).getAttributes === 'function');
131
+ .filter(isRelationalNode);
130
132
  }
131
133
 
132
134
  /**
@@ -195,7 +197,7 @@ export abstract class PlanNode {
195
197
  deterministic: childrenPhysical.every(child => child.deterministic),
196
198
  idempotent: childrenPhysical.every(child => child.idempotent),
197
199
  readonly: childrenPhysical.every(child => child.readonly),
198
- constant: childrenPhysical.every(child => child.constant),
200
+ // constant: DON'T INHERIT - only ValueNodes can be directly constant
199
201
  }
200
202
  : DEFAULT_PHYSICAL;
201
203
 
@@ -269,6 +271,13 @@ export interface RelationalPlanNode extends PlanNode {
269
271
  getAttributes(): Attribute[];
270
272
  }
271
273
 
274
+ /**
275
+ * Check if a node is relational (can be cached)
276
+ */
277
+ export function isRelationalNode(node: PlanNode): node is RelationalPlanNode {
278
+ return node.getType().typeClass === 'relation';
279
+ }
280
+
272
281
  /**
273
282
  * Base interface for PlanNodes that produce a scalar value (Expression Nodes).
274
283
  * Note: this is an interface that concrete ScalarNode classes will implement.
@@ -278,6 +287,13 @@ export interface ScalarPlanNode extends PlanNode {
278
287
  getType(): ScalarType;
279
288
  }
280
289
 
290
+ /**
291
+ * Check if a node is a scalar node
292
+ */
293
+ export function isScalarNode(node: PlanNode): node is ScalarPlanNode {
294
+ return node.getType().typeClass === 'scalar';
295
+ }
296
+
281
297
  // --- Arity-based Base Abstractions (Interfaces, to be implemented by concrete node classes) ---
282
298
 
283
299
  /** A relational plan node that has no relational inputs (a leaf in the relational algebra tree).
@@ -322,6 +338,11 @@ export interface BinaryScalarNode extends ScalarPlanNode {
322
338
  getChildren(): readonly [ScalarPlanNode, ScalarPlanNode];
323
339
  }
324
340
 
341
+ /** A scalar plan node that operates on three scalar inputs. */
342
+ export interface TernaryScalarNode extends ScalarPlanNode {
343
+ getChildren(): readonly [ScalarPlanNode, ScalarPlanNode, ScalarPlanNode];
344
+ }
345
+
325
346
  /** A scalar plan node that operates on N scalar inputs. */
326
347
  export interface NaryScalarNode extends ScalarPlanNode {
327
348
  readonly operands: ReadonlyArray<ScalarPlanNode>;
@@ -442,6 +463,22 @@ export abstract class BinaryScalarBase extends PlanNode implements BinaryScalarN
442
463
  abstract withChildren(newChildren: readonly PlanNode[]): PlanNode;
443
464
  }
444
465
 
466
+ /**
467
+ * Base class for scalar nodes with three scalar inputs
468
+ */
469
+ export abstract class TernaryScalarBase extends PlanNode implements TernaryScalarNode {
470
+ abstract readonly expression: Expression;
471
+ abstract getType(): ScalarType;
472
+ abstract getChildren(): readonly [ScalarPlanNode, ScalarPlanNode, ScalarPlanNode];
473
+
474
+ withChildren(newChildren: readonly PlanNode[]): PlanNode {
475
+ if (newChildren.length !== 3) {
476
+ quereusError(`${this.nodeType} expects 3 children, got ${newChildren.length}`);
477
+ }
478
+ return this;
479
+ }
480
+ }
481
+
445
482
  /**
446
483
  * Base class for scalar nodes with N scalar inputs
447
484
  */
@@ -1,5 +1,5 @@
1
1
  import { PlanNodeType } from './plan-node-type.js';
2
- import { PlanNode, type RelationalPlanNode, type UnaryRelationalNode, type ScalarPlanNode, type Attribute } from './plan-node.js';
2
+ import { PlanNode, type RelationalPlanNode, type UnaryRelationalNode, type ScalarPlanNode, type Attribute, isRelationalNode } from './plan-node.js';
3
3
  import type { RelationType } from '../../common/datatype.js';
4
4
  import type { Scope } from '../scopes/scope.js';
5
5
  import { Cached } from '../../util/cached.js';
@@ -32,7 +32,9 @@ export class ProjectNode extends PlanNode implements UnaryRelationalNode {
32
32
  public readonly projections: ReadonlyArray<Projection>,
33
33
  estimatedCostOverride?: number,
34
34
  /** Optional predefined attributes for preserving IDs during optimization */
35
- predefinedAttributes?: Attribute[]
35
+ predefinedAttributes?: Attribute[],
36
+ /** Whether to preserve input columns in the output (default: true) */
37
+ public readonly preserveInputColumns: boolean = true
36
38
  ) {
37
39
  super(scope, estimatedCostOverride);
38
40
 
@@ -97,35 +99,52 @@ export class ProjectNode extends PlanNode implements UnaryRelationalNode {
97
99
  // Get the computed column names from the type
98
100
  const outputType = this.getType();
99
101
 
100
- // For each projection, preserve attribute ID if it's a simple column reference
102
+ // If preserveInputColumns is false, only create attributes for projections
103
+ if (!this.preserveInputColumns) {
104
+ return this.projections.map((proj, index) => ({
105
+ id: proj.attributeId ?? PlanNode.nextAttrId(),
106
+ name: outputType.columns[index].name,
107
+ type: proj.node.getType(),
108
+ sourceRelation: `${this.nodeType}:${this.id}`,
109
+ relationName: 'projection'
110
+ }));
111
+ }
112
+
113
+ // For each projection, preserve attribute ID for simple column references
101
114
  return this.projections.map((proj, index) => {
102
- // Check if projection has a predefined attribute ID
115
+ // Use predefined attribute ID if supplied (optimizer path)
103
116
  if (proj.attributeId !== undefined) {
104
117
  return {
105
118
  id: proj.attributeId,
106
119
  name: outputType.columns[index].name,
107
120
  type: proj.node.getType(),
108
- sourceRelation: `${this.nodeType}:${this.id}`
121
+ sourceRelation: `${this.nodeType}:${this.id}`,
122
+ relationName: 'projection'
109
123
  };
110
124
  }
111
125
 
112
- // If this projection is a simple column reference, preserve its attribute ID
113
126
  if (proj.node instanceof ColumnReferenceNode) {
127
+ // Always preserve the original attribute ID so that any reference
128
+ // to the underlying column (e.g., in ORDER BY) remains valid even
129
+ // after aliasing. The alias is purely a name change, not a new column.
130
+ const colRef = proj.node as ColumnReferenceNode;
114
131
  return {
115
- id: proj.node.attributeId,
116
- name: outputType.columns[index].name, // Use the deduplicated name
117
- type: proj.node.getType(),
118
- sourceRelation: `${this.nodeType}:${this.id}`
119
- };
120
- } else {
121
- // For computed expressions, generate new attribute ID
122
- return {
123
- id: PlanNode.nextAttrId(),
124
- name: outputType.columns[index].name, // Use the deduplicated name
132
+ id: colRef.attributeId,
133
+ name: outputType.columns[index].name,
125
134
  type: proj.node.getType(),
126
- sourceRelation: `${this.nodeType}:${this.id}`
135
+ sourceRelation: `${this.nodeType}:${this.id}`,
136
+ relationName: 'projection'
127
137
  };
128
138
  }
139
+
140
+ // Computed expression or aliased column – generate fresh attribute ID
141
+ return {
142
+ id: PlanNode.nextAttrId(),
143
+ name: outputType.columns[index].name,
144
+ type: proj.node.getType(),
145
+ sourceRelation: `${this.nodeType}:${this.id}`,
146
+ relationName: 'projection'
147
+ };
129
148
  });
130
149
  });
131
150
  }
@@ -189,7 +208,7 @@ export class ProjectNode extends PlanNode implements UnaryRelationalNode {
189
208
  const [newSource, ...newProjectionNodes] = newChildren;
190
209
 
191
210
  // Type check
192
- if (!('getAttributes' in newSource) || typeof (newSource as any).getAttributes !== 'function') {
211
+ if (!isRelationalNode(newSource)) {
193
212
  quereusError('ProjectNode: first child must be a RelationalPlanNode', StatusCode.INTERNAL);
194
213
  }
195
214
 
@@ -217,7 +236,8 @@ export class ProjectNode extends PlanNode implements UnaryRelationalNode {
217
236
  newSource as RelationalPlanNode,
218
237
  newProjections,
219
238
  undefined, // estimatedCostOverride
220
- originalAttributes // Pass original attributes to preserve IDs
239
+ originalAttributes, // Pass original attributes to preserve IDs
240
+ this.preserveInputColumns // Preserve the flag
221
241
  );
222
242
  }
223
243
  }
@@ -1,4 +1,4 @@
1
- import { PlanNode, type RelationalPlanNode, type Attribute, type TableDescriptor } from './plan-node.js';
1
+ import { PlanNode, type RelationalPlanNode, type Attribute, type TableDescriptor, isRelationalNode } from './plan-node.js';
2
2
  import type { RelationType } from '../../common/datatype.js';
3
3
  import { PlanNodeType } from './plan-node-type.js';
4
4
  import type { Scope } from '../scopes/scope.js';
@@ -12,7 +12,7 @@ import type { CTEPlanNode } from './cte-node.js';
12
12
  export class RecursiveCTENode extends PlanNode implements CTEPlanNode {
13
13
  readonly nodeType = PlanNodeType.RecursiveCTE;
14
14
  readonly isRecursive = true; // Always true for recursive CTEs
15
- readonly tableDescriptor: TableDescriptor = {}; // Identity object for table context lookup
15
+ readonly tableDescriptor: TableDescriptor;
16
16
 
17
17
  private attributesCache: Cached<Attribute[]>;
18
18
  private typeCache: Cached<RelationType>;
@@ -26,10 +26,12 @@ export class RecursiveCTENode extends PlanNode implements CTEPlanNode {
26
26
  recursiveCaseQuery: RelationalPlanNode,
27
27
  public readonly isUnionAll: boolean,
28
28
  public readonly materializationHint: 'materialized' | 'not_materialized' | undefined = 'materialized',
29
- public readonly maxRecursion?: number
29
+ public readonly maxRecursion?: number,
30
+ tableDescriptor?: TableDescriptor
30
31
  ) {
31
32
  super(scope, baseCaseQuery.getTotalCost() + recursiveCaseQuery.getTotalCost() + 50); // Higher cost for recursion
32
33
  this._recursiveCaseQuery = recursiveCaseQuery;
34
+ this.tableDescriptor = tableDescriptor || {}; // Identity object for table context lookup
33
35
  this.attributesCache = new Cached(() => this.buildAttributes());
34
36
  this.typeCache = new Cached(() => this.buildType());
35
37
  }
@@ -58,7 +60,7 @@ export class RecursiveCTENode extends PlanNode implements CTEPlanNode {
58
60
  const columnNames = this.columns || baseCaseType.columns.map((c: any) => c.name);
59
61
 
60
62
  return baseCaseAttributes.map((attr: any, index: number) => ({
61
- id: PlanNode.nextAttrId(),
63
+ id: attr.id, // Preserve original attribute ID for proper context resolution
62
64
  name: columnNames[index] || attr.name,
63
65
  type: attr.type,
64
66
  sourceRelation: `recursive_cte:${this.cteName}`
@@ -87,8 +89,8 @@ export class RecursiveCTENode extends PlanNode implements CTEPlanNode {
87
89
  return this.typeCache.value;
88
90
  }
89
91
 
90
- getChildren(): readonly [] {
91
- return [];
92
+ getChildren(): readonly [RelationalPlanNode, RelationalPlanNode] {
93
+ return [this.baseCaseQuery, this.recursiveCaseQuery];
92
94
  }
93
95
 
94
96
  // For recursive CTEs, we consider the base case as the primary source
@@ -101,10 +103,36 @@ export class RecursiveCTENode extends PlanNode implements CTEPlanNode {
101
103
  }
102
104
 
103
105
  withChildren(newChildren: readonly PlanNode[]): PlanNode {
104
- if (newChildren.length !== 0) {
105
- throw new Error(`RecursiveCTENode expects 0 children, got ${newChildren.length}`);
106
+ if (newChildren.length !== 2) {
107
+ throw new Error(`RecursiveCTENode expects 2 children, got ${newChildren.length}`);
106
108
  }
107
- return this; // No children in getChildren(), sources are accessed via getRelations()
109
+
110
+ const [newBaseCaseQuery, newRecursiveCaseQuery] = newChildren;
111
+
112
+ // Type check
113
+ if (!isRelationalNode(newBaseCaseQuery) || !isRelationalNode(newRecursiveCaseQuery)) {
114
+ throw new Error('RecursiveCTENode: children must be RelationalPlanNodes');
115
+ }
116
+
117
+ // Return same instance if nothing changed
118
+ if (newBaseCaseQuery === this.baseCaseQuery && newRecursiveCaseQuery === this.recursiveCaseQuery) {
119
+ return this;
120
+ }
121
+
122
+ // Create new instance with updated children
123
+ const newNode = new RecursiveCTENode(
124
+ this.scope,
125
+ this.cteName,
126
+ this.columns,
127
+ newBaseCaseQuery as RelationalPlanNode,
128
+ newRecursiveCaseQuery as RelationalPlanNode,
129
+ this.isUnionAll,
130
+ this.materializationHint,
131
+ this.maxRecursion,
132
+ this.tableDescriptor
133
+ );
134
+
135
+ return newNode;
108
136
  }
109
137
 
110
138
  override toString(): string {
@@ -41,7 +41,8 @@ export class TableReferenceNode extends PlanNode implements ZeroAryRelationalNod
41
41
  isReadOnly: false,
42
42
  collationName: column.collation
43
43
  },
44
- sourceRelation: `${this.tableSchema.schemaName}.${this.tableSchema.name}`
44
+ sourceRelation: `${this.tableSchema.schemaName}.${this.tableSchema.name}`,
45
+ relationName: this.tableSchema.name
45
46
  }));
46
47
  });
47
48
  }
@@ -108,7 +109,8 @@ export class TableFunctionReferenceNode extends PlanNode implements ZeroAryRelat
108
109
  id: PlanNode.nextAttrId(),
109
110
  name: column.name,
110
111
  type: column.type,
111
- sourceRelation: `${this.functionSchema.name}()`
112
+ sourceRelation: `${this.functionSchema.name}()`,
113
+ relationName: this.functionSchema.name
112
114
  }));
113
115
  }
114
116
  return [];