@quereus/quereus 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (512) hide show
  1. package/README.md +372 -361
  2. package/dist/src/common/errors.d.ts +2 -18
  3. package/dist/src/common/errors.d.ts.map +1 -1
  4. package/dist/src/common/errors.js +6 -29
  5. package/dist/src/common/errors.js.map +1 -1
  6. package/dist/src/common/types.d.ts +8 -0
  7. package/dist/src/common/types.d.ts.map +1 -1
  8. package/dist/src/common/types.js +20 -0
  9. package/dist/src/common/types.js.map +1 -1
  10. package/dist/src/core/database-assertions.d.ts +19 -2
  11. package/dist/src/core/database-assertions.d.ts.map +1 -1
  12. package/dist/src/core/database-assertions.js +113 -32
  13. package/dist/src/core/database-assertions.js.map +1 -1
  14. package/dist/src/core/database-events.d.ts +17 -0
  15. package/dist/src/core/database-events.d.ts.map +1 -1
  16. package/dist/src/core/database-events.js +36 -0
  17. package/dist/src/core/database-events.js.map +1 -1
  18. package/dist/src/core/database.d.ts +11 -0
  19. package/dist/src/core/database.d.ts.map +1 -1
  20. package/dist/src/core/database.js +178 -85
  21. package/dist/src/core/database.js.map +1 -1
  22. package/dist/src/core/statement.d.ts +6 -0
  23. package/dist/src/core/statement.d.ts.map +1 -1
  24. package/dist/src/core/statement.js +42 -56
  25. package/dist/src/core/statement.js.map +1 -1
  26. package/dist/src/emit/ast-stringify.d.ts +1 -0
  27. package/dist/src/emit/ast-stringify.d.ts.map +1 -1
  28. package/dist/src/emit/ast-stringify.js +12 -2
  29. package/dist/src/emit/ast-stringify.js.map +1 -1
  30. package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
  31. package/dist/src/func/builtins/builtin-window-functions.js +75 -0
  32. package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
  33. package/dist/src/func/builtins/conversion.js +9 -12
  34. package/dist/src/func/builtins/conversion.js.map +1 -1
  35. package/dist/src/func/builtins/datetime.js +1 -1
  36. package/dist/src/func/builtins/datetime.js.map +1 -1
  37. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  38. package/dist/src/func/builtins/explain.js +15 -3
  39. package/dist/src/func/builtins/explain.js.map +1 -1
  40. package/dist/src/func/builtins/index.d.ts.map +1 -1
  41. package/dist/src/func/builtins/index.js +1 -11
  42. package/dist/src/func/builtins/index.js.map +1 -1
  43. package/dist/src/func/builtins/json-helpers.js +1 -1
  44. package/dist/src/func/builtins/json-helpers.js.map +1 -1
  45. package/dist/src/func/builtins/json.d.ts.map +1 -1
  46. package/dist/src/func/builtins/json.js +2 -5
  47. package/dist/src/func/builtins/json.js.map +1 -1
  48. package/dist/src/func/builtins/schema.d.ts.map +1 -1
  49. package/dist/src/func/builtins/schema.js +30 -32
  50. package/dist/src/func/builtins/schema.js.map +1 -1
  51. package/dist/src/func/builtins/string.d.ts.map +1 -1
  52. package/dist/src/func/builtins/string.js +40 -64
  53. package/dist/src/func/builtins/string.js.map +1 -1
  54. package/dist/src/func/builtins/timespan.d.ts.map +1 -1
  55. package/dist/src/func/builtins/timespan.js.map +1 -1
  56. package/dist/src/index.d.ts +2 -2
  57. package/dist/src/index.d.ts.map +1 -1
  58. package/dist/src/index.js +2 -2
  59. package/dist/src/index.js.map +1 -1
  60. package/dist/src/parser/ast.d.ts +9 -2
  61. package/dist/src/parser/ast.d.ts.map +1 -1
  62. package/dist/src/parser/lexer.d.ts +1 -0
  63. package/dist/src/parser/lexer.d.ts.map +1 -1
  64. package/dist/src/parser/lexer.js +3 -0
  65. package/dist/src/parser/lexer.js.map +1 -1
  66. package/dist/src/parser/parser.d.ts +11 -1
  67. package/dist/src/parser/parser.d.ts.map +1 -1
  68. package/dist/src/parser/parser.js +75 -135
  69. package/dist/src/parser/parser.js.map +1 -1
  70. package/dist/src/planner/analysis/const-evaluator.d.ts.map +1 -1
  71. package/dist/src/planner/analysis/const-evaluator.js +6 -3
  72. package/dist/src/planner/analysis/const-evaluator.js.map +1 -1
  73. package/dist/src/planner/analysis/constraint-extractor.d.ts +2 -1
  74. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
  75. package/dist/src/planner/analysis/constraint-extractor.js +154 -22
  76. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
  77. package/dist/src/planner/building/alter-table.d.ts.map +1 -1
  78. package/dist/src/planner/building/alter-table.js +18 -1
  79. package/dist/src/planner/building/alter-table.js.map +1 -1
  80. package/dist/src/planner/building/analyze.d.ts +5 -0
  81. package/dist/src/planner/building/analyze.d.ts.map +1 -0
  82. package/dist/src/planner/building/analyze.js +5 -0
  83. package/dist/src/planner/building/analyze.js.map +1 -0
  84. package/dist/src/planner/building/block.d.ts.map +1 -1
  85. package/dist/src/planner/building/block.js +3 -0
  86. package/dist/src/planner/building/block.js.map +1 -1
  87. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
  88. package/dist/src/planner/building/constraint-builder.js +25 -3
  89. package/dist/src/planner/building/constraint-builder.js.map +1 -1
  90. package/dist/src/planner/building/delete.d.ts.map +1 -1
  91. package/dist/src/planner/building/delete.js +11 -0
  92. package/dist/src/planner/building/delete.js.map +1 -1
  93. package/dist/src/planner/building/drop-assertion.d.ts.map +1 -1
  94. package/dist/src/planner/building/drop-assertion.js +2 -1
  95. package/dist/src/planner/building/drop-assertion.js.map +1 -1
  96. package/dist/src/planner/building/expression.d.ts.map +1 -1
  97. package/dist/src/planner/building/expression.js +55 -7
  98. package/dist/src/planner/building/expression.js.map +1 -1
  99. package/dist/src/planner/building/foreign-key-builder.d.ts +16 -0
  100. package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -0
  101. package/dist/src/planner/building/foreign-key-builder.js +269 -0
  102. package/dist/src/planner/building/foreign-key-builder.js.map +1 -0
  103. package/dist/src/planner/building/function-call.d.ts.map +1 -1
  104. package/dist/src/planner/building/function-call.js +3 -2
  105. package/dist/src/planner/building/function-call.js.map +1 -1
  106. package/dist/src/planner/building/insert.d.ts.map +1 -1
  107. package/dist/src/planner/building/insert.js +91 -10
  108. package/dist/src/planner/building/insert.js.map +1 -1
  109. package/dist/src/planner/building/schema-resolution.d.ts +4 -0
  110. package/dist/src/planner/building/schema-resolution.d.ts.map +1 -1
  111. package/dist/src/planner/building/schema-resolution.js +14 -3
  112. package/dist/src/planner/building/schema-resolution.js.map +1 -1
  113. package/dist/src/planner/building/select-aggregates.d.ts +1 -0
  114. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  115. package/dist/src/planner/building/select-aggregates.js +118 -3
  116. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  117. package/dist/src/planner/building/select-modifiers.js +3 -3
  118. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  119. package/dist/src/planner/building/select-window.js +9 -8
  120. package/dist/src/planner/building/select-window.js.map +1 -1
  121. package/dist/src/planner/building/select.d.ts.map +1 -1
  122. package/dist/src/planner/building/select.js +21 -10
  123. package/dist/src/planner/building/select.js.map +1 -1
  124. package/dist/src/planner/building/table.d.ts.map +1 -1
  125. package/dist/src/planner/building/table.js +5 -3
  126. package/dist/src/planner/building/table.js.map +1 -1
  127. package/dist/src/planner/building/update.d.ts.map +1 -1
  128. package/dist/src/planner/building/update.js +30 -1
  129. package/dist/src/planner/building/update.js.map +1 -1
  130. package/dist/src/planner/building/with.js +1 -1
  131. package/dist/src/planner/building/with.js.map +1 -1
  132. package/dist/src/planner/cache/reference-graph.d.ts +1 -1
  133. package/dist/src/planner/cache/reference-graph.js +1 -1
  134. package/dist/src/planner/cost/index.d.ts +10 -3
  135. package/dist/src/planner/cost/index.d.ts.map +1 -1
  136. package/dist/src/planner/cost/index.js +17 -3
  137. package/dist/src/planner/cost/index.js.map +1 -1
  138. package/dist/src/planner/debug.js +1 -1
  139. package/dist/src/planner/debug.js.map +1 -1
  140. package/dist/src/planner/framework/characteristics.d.ts +1 -1
  141. package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
  142. package/dist/src/planner/framework/pass.d.ts +3 -1
  143. package/dist/src/planner/framework/pass.d.ts.map +1 -1
  144. package/dist/src/planner/framework/pass.js +62 -18
  145. package/dist/src/planner/framework/pass.js.map +1 -1
  146. package/dist/src/planner/framework/physical-utils.d.ts +5 -0
  147. package/dist/src/planner/framework/physical-utils.d.ts.map +1 -1
  148. package/dist/src/planner/framework/physical-utils.js +19 -0
  149. package/dist/src/planner/framework/physical-utils.js.map +1 -1
  150. package/dist/src/planner/framework/trace.d.ts.map +1 -1
  151. package/dist/src/planner/framework/trace.js +3 -2
  152. package/dist/src/planner/framework/trace.js.map +1 -1
  153. package/dist/src/planner/nodes/alias-node.d.ts +2 -1
  154. package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
  155. package/dist/src/planner/nodes/alias-node.js +8 -0
  156. package/dist/src/planner/nodes/alias-node.js.map +1 -1
  157. package/dist/src/planner/nodes/alter-table-node.d.ts +42 -0
  158. package/dist/src/planner/nodes/alter-table-node.d.ts.map +1 -0
  159. package/dist/src/planner/nodes/alter-table-node.js +55 -0
  160. package/dist/src/planner/nodes/alter-table-node.js.map +1 -0
  161. package/dist/src/planner/nodes/analyze-node.d.ts +25 -0
  162. package/dist/src/planner/nodes/analyze-node.d.ts.map +1 -0
  163. package/dist/src/planner/nodes/analyze-node.js +83 -0
  164. package/dist/src/planner/nodes/analyze-node.js.map +1 -0
  165. package/dist/src/planner/nodes/bloom-join-node.d.ts +66 -0
  166. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -0
  167. package/dist/src/planner/nodes/bloom-join-node.js +200 -0
  168. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -0
  169. package/dist/src/planner/nodes/constraint-check-node.d.ts +1 -1
  170. package/dist/src/planner/nodes/constraint-check-node.d.ts.map +1 -1
  171. package/dist/src/planner/nodes/cte-reference-node.js +7 -7
  172. package/dist/src/planner/nodes/cte-reference-node.js.map +1 -1
  173. package/dist/src/planner/nodes/join-node.d.ts +9 -1
  174. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  175. package/dist/src/planner/nodes/join-node.js +69 -79
  176. package/dist/src/planner/nodes/join-node.js.map +1 -1
  177. package/dist/src/planner/nodes/merge-join-node.d.ts +60 -0
  178. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -0
  179. package/dist/src/planner/nodes/merge-join-node.js +207 -0
  180. package/dist/src/planner/nodes/merge-join-node.js.map +1 -0
  181. package/dist/src/planner/nodes/plan-node-type.d.ts +1 -0
  182. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  183. package/dist/src/planner/nodes/plan-node-type.js +1 -0
  184. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  185. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  186. package/dist/src/planner/nodes/project-node.js +3 -2
  187. package/dist/src/planner/nodes/project-node.js.map +1 -1
  188. package/dist/src/planner/nodes/reference.d.ts +2 -1
  189. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  190. package/dist/src/planner/nodes/reference.js +6 -2
  191. package/dist/src/planner/nodes/reference.js.map +1 -1
  192. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  193. package/dist/src/planner/nodes/returning-node.js +3 -2
  194. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  195. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  196. package/dist/src/planner/nodes/subquery.js.map +1 -1
  197. package/dist/src/planner/nodes/table-access-nodes.js +1 -1
  198. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  199. package/dist/src/planner/nodes/update-node.d.ts +2 -0
  200. package/dist/src/planner/nodes/update-node.d.ts.map +1 -1
  201. package/dist/src/planner/nodes/update-node.js +2 -1
  202. package/dist/src/planner/nodes/update-node.js.map +1 -1
  203. package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
  204. package/dist/src/planner/nodes/window-function.js +7 -7
  205. package/dist/src/planner/nodes/window-function.js.map +1 -1
  206. package/dist/src/planner/nodes/window-node.d.ts +2 -2
  207. package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
  208. package/dist/src/planner/nodes/window-node.js +9 -14
  209. package/dist/src/planner/nodes/window-node.js.map +1 -1
  210. package/dist/src/planner/optimizer.d.ts.map +1 -1
  211. package/dist/src/planner/optimizer.js +40 -2
  212. package/dist/src/planner/optimizer.js.map +1 -1
  213. package/dist/src/planner/planning-context.d.ts.map +1 -1
  214. package/dist/src/planner/planning-context.js +1 -6
  215. package/dist/src/planner/planning-context.js.map +1 -1
  216. package/dist/src/planner/resolve.d.ts.map +1 -1
  217. package/dist/src/planner/resolve.js.map +1 -1
  218. package/dist/src/planner/rules/access/rule-select-access-path.js +157 -28
  219. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  220. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -1
  221. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +27 -6
  222. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
  223. package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts +19 -0
  224. package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts.map +1 -0
  225. package/dist/src/planner/rules/cache/rule-in-subquery-cache.js +53 -0
  226. package/dist/src/planner/rules/cache/rule-in-subquery-cache.js.map +1 -0
  227. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.d.ts.map +1 -1
  228. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js +5 -0
  229. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js.map +1 -1
  230. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts +18 -0
  231. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts.map +1 -0
  232. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js +37 -0
  233. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js.map +1 -0
  234. package/dist/src/planner/rules/join/rule-join-key-inference.d.ts +8 -3
  235. package/dist/src/planner/rules/join/rule-join-key-inference.d.ts.map +1 -1
  236. package/dist/src/planner/rules/join/rule-join-key-inference.js +28 -17
  237. package/dist/src/planner/rules/join/rule-join-key-inference.js.map +1 -1
  238. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts +16 -0
  239. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -0
  240. package/dist/src/planner/rules/join/rule-join-physical-selection.js +216 -0
  241. package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -0
  242. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.d.ts.map +1 -1
  243. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +34 -4
  244. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
  245. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts +23 -0
  246. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -0
  247. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +293 -0
  248. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -0
  249. package/dist/src/planner/scopes/multi.d.ts +3 -2
  250. package/dist/src/planner/scopes/multi.d.ts.map +1 -1
  251. package/dist/src/planner/scopes/multi.js +32 -7
  252. package/dist/src/planner/scopes/multi.js.map +1 -1
  253. package/dist/src/planner/scopes/shadow.d.ts +20 -0
  254. package/dist/src/planner/scopes/shadow.d.ts.map +1 -0
  255. package/dist/src/planner/scopes/shadow.js +31 -0
  256. package/dist/src/planner/scopes/shadow.js.map +1 -0
  257. package/dist/src/planner/stats/analyze.d.ts +17 -0
  258. package/dist/src/planner/stats/analyze.d.ts.map +1 -0
  259. package/dist/src/planner/stats/analyze.js +114 -0
  260. package/dist/src/planner/stats/analyze.js.map +1 -0
  261. package/dist/src/planner/stats/catalog-stats.d.ts +80 -0
  262. package/dist/src/planner/stats/catalog-stats.d.ts.map +1 -0
  263. package/dist/src/planner/stats/catalog-stats.js +248 -0
  264. package/dist/src/planner/stats/catalog-stats.js.map +1 -0
  265. package/dist/src/planner/stats/histogram.d.ts +24 -0
  266. package/dist/src/planner/stats/histogram.d.ts.map +1 -0
  267. package/dist/src/planner/stats/histogram.js +142 -0
  268. package/dist/src/planner/stats/histogram.js.map +1 -0
  269. package/dist/src/planner/type-utils.d.ts.map +1 -1
  270. package/dist/src/planner/type-utils.js +8 -2
  271. package/dist/src/planner/type-utils.js.map +1 -1
  272. package/dist/src/planner/util/key-utils.d.ts +48 -2
  273. package/dist/src/planner/util/key-utils.d.ts.map +1 -1
  274. package/dist/src/planner/util/key-utils.js +123 -0
  275. package/dist/src/planner/util/key-utils.js.map +1 -1
  276. package/dist/src/planner/validation/determinism-validator.d.ts +9 -0
  277. package/dist/src/planner/validation/determinism-validator.d.ts.map +1 -1
  278. package/dist/src/planner/validation/determinism-validator.js +11 -0
  279. package/dist/src/planner/validation/determinism-validator.js.map +1 -1
  280. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  281. package/dist/src/planner/validation/plan-validator.js +1 -0
  282. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  283. package/dist/src/runtime/context-helpers.d.ts +34 -10
  284. package/dist/src/runtime/context-helpers.d.ts.map +1 -1
  285. package/dist/src/runtime/context-helpers.js +115 -39
  286. package/dist/src/runtime/context-helpers.js.map +1 -1
  287. package/dist/src/runtime/deferred-constraint-queue.d.ts +0 -1
  288. package/dist/src/runtime/deferred-constraint-queue.d.ts.map +1 -1
  289. package/dist/src/runtime/deferred-constraint-queue.js +10 -23
  290. package/dist/src/runtime/deferred-constraint-queue.js.map +1 -1
  291. package/dist/src/runtime/descriptor-helpers.d.ts +7 -0
  292. package/dist/src/runtime/descriptor-helpers.d.ts.map +1 -0
  293. package/dist/src/runtime/descriptor-helpers.js +24 -0
  294. package/dist/src/runtime/descriptor-helpers.js.map +1 -0
  295. package/dist/src/runtime/emission-context.d.ts +7 -1
  296. package/dist/src/runtime/emission-context.d.ts.map +1 -1
  297. package/dist/src/runtime/emission-context.js +16 -0
  298. package/dist/src/runtime/emission-context.js.map +1 -1
  299. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  300. package/dist/src/runtime/emit/aggregate.js +97 -93
  301. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  302. package/dist/src/runtime/emit/alter-table.d.ts +5 -0
  303. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -0
  304. package/dist/src/runtime/emit/alter-table.js +209 -0
  305. package/dist/src/runtime/emit/alter-table.js.map +1 -0
  306. package/dist/src/runtime/emit/analyze.d.ts +9 -0
  307. package/dist/src/runtime/emit/analyze.d.ts.map +1 -0
  308. package/dist/src/runtime/emit/analyze.js +72 -0
  309. package/dist/src/runtime/emit/analyze.js.map +1 -0
  310. package/dist/src/runtime/emit/array-index.d.ts.map +1 -1
  311. package/dist/src/runtime/emit/array-index.js +4 -2
  312. package/dist/src/runtime/emit/array-index.js.map +1 -1
  313. package/dist/src/runtime/emit/between.d.ts.map +1 -1
  314. package/dist/src/runtime/emit/between.js +8 -20
  315. package/dist/src/runtime/emit/between.js.map +1 -1
  316. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  317. package/dist/src/runtime/emit/binary.js +155 -126
  318. package/dist/src/runtime/emit/binary.js.map +1 -1
  319. package/dist/src/runtime/emit/bloom-join.d.ts +12 -0
  320. package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -0
  321. package/dist/src/runtime/emit/bloom-join.js +114 -0
  322. package/dist/src/runtime/emit/bloom-join.js.map +1 -0
  323. package/dist/src/runtime/emit/cache.js +2 -2
  324. package/dist/src/runtime/emit/cache.js.map +1 -1
  325. package/dist/src/runtime/emit/cast.d.ts.map +1 -1
  326. package/dist/src/runtime/emit/cast.js +31 -117
  327. package/dist/src/runtime/emit/cast.js.map +1 -1
  328. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  329. package/dist/src/runtime/emit/constraint-check.js +2 -24
  330. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  331. package/dist/src/runtime/emit/cte-reference.d.ts.map +1 -1
  332. package/dist/src/runtime/emit/cte-reference.js +11 -5
  333. package/dist/src/runtime/emit/cte-reference.js.map +1 -1
  334. package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
  335. package/dist/src/runtime/emit/distinct.js +21 -12
  336. package/dist/src/runtime/emit/distinct.js.map +1 -1
  337. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  338. package/dist/src/runtime/emit/dml-executor.js +5 -1
  339. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  340. package/dist/src/runtime/emit/drop-assertion.d.ts.map +1 -1
  341. package/dist/src/runtime/emit/drop-assertion.js +2 -0
  342. package/dist/src/runtime/emit/drop-assertion.js.map +1 -1
  343. package/dist/src/runtime/emit/filter.d.ts.map +1 -1
  344. package/dist/src/runtime/emit/filter.js +26 -7
  345. package/dist/src/runtime/emit/filter.js.map +1 -1
  346. package/dist/src/runtime/emit/internal-recursive-cte-ref.d.ts.map +1 -1
  347. package/dist/src/runtime/emit/internal-recursive-cte-ref.js +11 -5
  348. package/dist/src/runtime/emit/internal-recursive-cte-ref.js.map +1 -1
  349. package/dist/src/runtime/emit/join.d.ts +1 -1
  350. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  351. package/dist/src/runtime/emit/join.js +44 -33
  352. package/dist/src/runtime/emit/join.js.map +1 -1
  353. package/dist/src/runtime/emit/merge-join.d.ts +14 -0
  354. package/dist/src/runtime/emit/merge-join.d.ts.map +1 -0
  355. package/dist/src/runtime/emit/merge-join.js +152 -0
  356. package/dist/src/runtime/emit/merge-join.js.map +1 -0
  357. package/dist/src/runtime/emit/parameter.d.ts.map +1 -1
  358. package/dist/src/runtime/emit/parameter.js +10 -32
  359. package/dist/src/runtime/emit/parameter.js.map +1 -1
  360. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  361. package/dist/src/runtime/emit/project.js +22 -12
  362. package/dist/src/runtime/emit/project.js.map +1 -1
  363. package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -1
  364. package/dist/src/runtime/emit/recursive-cte.js +5 -9
  365. package/dist/src/runtime/emit/recursive-cte.js.map +1 -1
  366. package/dist/src/runtime/emit/returning.d.ts.map +1 -1
  367. package/dist/src/runtime/emit/returning.js +14 -8
  368. package/dist/src/runtime/emit/returning.js.map +1 -1
  369. package/dist/src/runtime/emit/scan.d.ts.map +1 -1
  370. package/dist/src/runtime/emit/scan.js +4 -1
  371. package/dist/src/runtime/emit/scan.js.map +1 -1
  372. package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
  373. package/dist/src/runtime/emit/set-operation.js +8 -5
  374. package/dist/src/runtime/emit/set-operation.js.map +1 -1
  375. package/dist/src/runtime/emit/sort.js +2 -2
  376. package/dist/src/runtime/emit/sort.js.map +1 -1
  377. package/dist/src/runtime/emit/subquery.js +2 -2
  378. package/dist/src/runtime/emit/subquery.js.map +1 -1
  379. package/dist/src/runtime/emit/table-valued-function.d.ts.map +1 -1
  380. package/dist/src/runtime/emit/table-valued-function.js +21 -7
  381. package/dist/src/runtime/emit/table-valued-function.js.map +1 -1
  382. package/dist/src/runtime/emit/unary.js +2 -2
  383. package/dist/src/runtime/emit/unary.js.map +1 -1
  384. package/dist/src/runtime/emit/update.d.ts.map +1 -1
  385. package/dist/src/runtime/emit/update.js +43 -21
  386. package/dist/src/runtime/emit/update.js.map +1 -1
  387. package/dist/src/runtime/emit/window.d.ts.map +1 -1
  388. package/dist/src/runtime/emit/window.js +368 -126
  389. package/dist/src/runtime/emit/window.js.map +1 -1
  390. package/dist/src/runtime/foreign-key-actions.d.ts +15 -0
  391. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -0
  392. package/dist/src/runtime/foreign-key-actions.js +109 -0
  393. package/dist/src/runtime/foreign-key-actions.js.map +1 -0
  394. package/dist/src/runtime/register.d.ts.map +1 -1
  395. package/dist/src/runtime/register.js +8 -0
  396. package/dist/src/runtime/register.js.map +1 -1
  397. package/dist/src/runtime/scheduler.d.ts.map +1 -1
  398. package/dist/src/runtime/scheduler.js +4 -1
  399. package/dist/src/runtime/scheduler.js.map +1 -1
  400. package/dist/src/runtime/types.d.ts +6 -5
  401. package/dist/src/runtime/types.d.ts.map +1 -1
  402. package/dist/src/runtime/types.js.map +1 -1
  403. package/dist/src/schema/change-events.d.ts +36 -8
  404. package/dist/src/schema/change-events.d.ts.map +1 -1
  405. package/dist/src/schema/change-events.js.map +1 -1
  406. package/dist/src/schema/column.d.ts +5 -1
  407. package/dist/src/schema/column.d.ts.map +1 -1
  408. package/dist/src/schema/column.js +1 -2
  409. package/dist/src/schema/column.js.map +1 -1
  410. package/dist/src/schema/manager.d.ts +54 -4
  411. package/dist/src/schema/manager.d.ts.map +1 -1
  412. package/dist/src/schema/manager.js +353 -313
  413. package/dist/src/schema/manager.js.map +1 -1
  414. package/dist/src/schema/schema-differ.js +3 -3
  415. package/dist/src/schema/schema-differ.js.map +1 -1
  416. package/dist/src/schema/schema.d.ts +1 -1
  417. package/dist/src/schema/schema.js +2 -2
  418. package/dist/src/schema/schema.js.map +1 -1
  419. package/dist/src/schema/table.d.ts +49 -0
  420. package/dist/src/schema/table.d.ts.map +1 -1
  421. package/dist/src/schema/table.js +30 -11
  422. package/dist/src/schema/table.js.map +1 -1
  423. package/dist/src/types/builtin-types.d.ts.map +1 -1
  424. package/dist/src/types/builtin-types.js +26 -95
  425. package/dist/src/types/builtin-types.js.map +1 -1
  426. package/dist/src/types/index.d.ts +1 -1
  427. package/dist/src/types/index.d.ts.map +1 -1
  428. package/dist/src/types/index.js +1 -1
  429. package/dist/src/types/index.js.map +1 -1
  430. package/dist/src/types/json-type.d.ts.map +1 -1
  431. package/dist/src/types/json-type.js +28 -40
  432. package/dist/src/types/json-type.js.map +1 -1
  433. package/dist/src/types/logical-type.d.ts +6 -0
  434. package/dist/src/types/logical-type.d.ts.map +1 -1
  435. package/dist/src/types/logical-type.js +12 -0
  436. package/dist/src/types/logical-type.js.map +1 -1
  437. package/dist/src/types/temporal-types.d.ts.map +1 -1
  438. package/dist/src/types/temporal-types.js +8 -37
  439. package/dist/src/types/temporal-types.js.map +1 -1
  440. package/dist/src/util/coercion.d.ts +4 -5
  441. package/dist/src/util/coercion.d.ts.map +1 -1
  442. package/dist/src/util/coercion.js +10 -14
  443. package/dist/src/util/coercion.js.map +1 -1
  444. package/dist/src/util/comparison.d.ts +34 -21
  445. package/dist/src/util/comparison.d.ts.map +1 -1
  446. package/dist/src/util/comparison.js +77 -43
  447. package/dist/src/util/comparison.js.map +1 -1
  448. package/dist/src/util/environment.d.ts +0 -8
  449. package/dist/src/util/environment.d.ts.map +1 -1
  450. package/dist/src/util/environment.js +0 -12
  451. package/dist/src/util/environment.js.map +1 -1
  452. package/dist/src/util/key-serializer.d.ts +33 -0
  453. package/dist/src/util/key-serializer.d.ts.map +1 -0
  454. package/dist/src/util/key-serializer.js +95 -0
  455. package/dist/src/util/key-serializer.js.map +1 -0
  456. package/dist/src/util/plugin-helper.d.ts.map +1 -1
  457. package/dist/src/util/plugin-helper.js +21 -45
  458. package/dist/src/util/plugin-helper.js.map +1 -1
  459. package/dist/src/util/serialization.d.ts +1 -0
  460. package/dist/src/util/serialization.d.ts.map +1 -1
  461. package/dist/src/util/serialization.js +8 -1
  462. package/dist/src/util/serialization.js.map +1 -1
  463. package/dist/src/util/working-table-iterable.d.ts +6 -5
  464. package/dist/src/util/working-table-iterable.d.ts.map +1 -1
  465. package/dist/src/util/working-table-iterable.js +8 -15
  466. package/dist/src/util/working-table-iterable.js.map +1 -1
  467. package/dist/src/vtab/best-access-plan.d.ts +12 -0
  468. package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
  469. package/dist/src/vtab/best-access-plan.js +22 -0
  470. package/dist/src/vtab/best-access-plan.js.map +1 -1
  471. package/dist/src/vtab/manifest.d.ts +3 -1
  472. package/dist/src/vtab/manifest.d.ts.map +1 -1
  473. package/dist/src/vtab/memory/index.d.ts +2 -2
  474. package/dist/src/vtab/memory/index.d.ts.map +1 -1
  475. package/dist/src/vtab/memory/index.js +4 -7
  476. package/dist/src/vtab/memory/index.js.map +1 -1
  477. package/dist/src/vtab/memory/layer/base-cursor.d.ts.map +1 -1
  478. package/dist/src/vtab/memory/layer/base-cursor.js +37 -9
  479. package/dist/src/vtab/memory/layer/base-cursor.js.map +1 -1
  480. package/dist/src/vtab/memory/layer/base.js +1 -1
  481. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  482. package/dist/src/vtab/memory/layer/manager.d.ts +15 -3
  483. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  484. package/dist/src/vtab/memory/layer/manager.js +85 -37
  485. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  486. package/dist/src/vtab/memory/layer/scan-plan.d.ts +2 -0
  487. package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
  488. package/dist/src/vtab/memory/layer/scan-plan.js +153 -78
  489. package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
  490. package/dist/src/vtab/memory/layer/transaction-cursor.d.ts.map +1 -1
  491. package/dist/src/vtab/memory/layer/transaction-cursor.js +39 -9
  492. package/dist/src/vtab/memory/layer/transaction-cursor.js.map +1 -1
  493. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  494. package/dist/src/vtab/memory/layer/transaction.js +1 -5
  495. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  496. package/dist/src/vtab/memory/module.d.ts +14 -24
  497. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  498. package/dist/src/vtab/memory/module.js +88 -283
  499. package/dist/src/vtab/memory/module.js.map +1 -1
  500. package/dist/src/vtab/memory/table.d.ts +9 -0
  501. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  502. package/dist/src/vtab/memory/table.js +121 -18
  503. package/dist/src/vtab/memory/table.js.map +1 -1
  504. package/dist/src/vtab/memory/types.d.ts +1 -0
  505. package/dist/src/vtab/memory/types.d.ts.map +1 -1
  506. package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
  507. package/dist/src/vtab/module.d.ts +13 -0
  508. package/dist/src/vtab/module.d.ts.map +1 -1
  509. package/dist/src/vtab/table.d.ts +9 -0
  510. package/dist/src/vtab/table.d.ts.map +1 -1
  511. package/dist/src/vtab/table.js.map +1 -1
  512. package/package.json +2 -2
@@ -2,10 +2,11 @@ import { emitPlanNode, emitCallFromPlan } from '../emitters.js';
2
2
  import { resolveWindowFunction } from '../../schema/window-function.js';
3
3
  import { QuereusError } from '../../common/errors.js';
4
4
  import { StatusCode } from '../../common/types.js';
5
- import { compareSqlValues, createOrderByComparatorFast, resolveCollation } from '../../util/comparison.js';
5
+ import { createTypedComparator, createOrderByComparatorFast } from '../../util/comparison.js';
6
+ import { resolveKeyNormalizer, serializeKeyNullGrouping } from '../../util/key-serializer.js';
6
7
  import { createLogger } from '../../common/logger.js';
7
8
  import { buildRowDescriptor } from '../../util/row-descriptor.js';
8
- import { withRowContext, withAsyncRowContext } from '../context-helpers.js';
9
+ import { createRowSlot } from '../context-helpers.js';
9
10
  const log = createLogger('runtime:emit:window');
10
11
  export function emitWindow(plan, ctx) {
11
12
  // Get schemas for all window functions in this node
@@ -20,39 +21,71 @@ export function emitWindow(plan, ctx) {
20
21
  const partitionCallbacks = plan.partitionExpressions.map(exprPlan => emitCallFromPlan(exprPlan, ctx));
21
22
  // Emit callbacks for ORDER BY expressions (if any)
22
23
  const orderByCallbacks = plan.orderByExpressions.map(exprPlan => emitCallFromPlan(exprPlan, ctx));
23
- // Emit callbacks for window function arguments
24
- const functionArgCallbacks = plan.functionArguments.map(argPlan => argPlan ? emitCallFromPlan(argPlan, ctx) : null);
24
+ // Emit callbacks for window function arguments (2D: per-function arrays)
25
+ const functionArgCallbacks = plan.functionArguments.map(argPlans => argPlans.map(argPlan => emitCallFromPlan(argPlan, ctx)));
26
+ // Track per-function arg counts for callback reconstruction in run()
27
+ const functionArgCounts = plan.functionArguments.map(args => args.length);
25
28
  // Create row descriptors
26
29
  const sourceRowDescriptor = buildRowDescriptor(plan.source.getAttributes());
27
- const outputRowDescriptor = buildRowDescriptor(plan.getAttributes());
30
+ // Pre-resolve ORDER BY comparators using actual expression types (not hardcoded BINARY)
31
+ const orderByComparators = plan.orderByExpressions.map((exprPlan, i) => {
32
+ const exprType = exprPlan.getType();
33
+ const collationName = exprType.collationName || 'BINARY';
34
+ const collationFunc = ctx.resolveCollation(collationName);
35
+ const orderClause = plan.windowSpec.orderBy[i];
36
+ return createOrderByComparatorFast(orderClause.direction, orderClause.nulls, collationFunc);
37
+ });
38
+ // Pre-resolve typed equality comparators for ORDER BY (used in ranking functions)
39
+ const orderByEqualityComparators = plan.orderByExpressions.map(exprPlan => {
40
+ const exprType = exprPlan.getType();
41
+ const collationFunc = exprType.collationName ? ctx.resolveCollation(exprType.collationName) : undefined;
42
+ return createTypedComparator(exprType.logicalType, collationFunc);
43
+ });
44
+ // Pre-resolve collation normalizers for partition key serialization
45
+ const partitionKeyNormalizers = plan.partitionExpressions.map(exprPlan => resolveKeyNormalizer(exprPlan.getType().collationName));
46
+ // Pre-resolve collation normalizers for ORDER BY key serialization (dense_rank dedup)
47
+ const orderByKeyNormalizers = plan.orderByExpressions.map(exprPlan => resolveKeyNormalizer(exprPlan.getType().collationName));
28
48
  async function* run(rctx, source, ...callbacks) {
29
49
  log('Starting window function execution');
30
50
  // Extract callbacks in order: partitions, orderBy, function args
31
51
  const partitionCallbackList = callbacks.slice(0, partitionCallbacks.length);
32
52
  const orderByCallbackList = callbacks.slice(partitionCallbacks.length, partitionCallbacks.length + orderByCallbacks.length);
33
- const funcArgCallbackList = callbacks.slice(partitionCallbacks.length + orderByCallbacks.length);
53
+ // Reconstruct per-function arg callback arrays from flattened list
54
+ const funcArgCallbackGroups = [];
55
+ let argOffset = partitionCallbacks.length + orderByCallbacks.length;
56
+ for (const count of functionArgCounts) {
57
+ funcArgCallbackGroups.push(callbacks.slice(argOffset, argOffset + count));
58
+ argOffset += count;
59
+ }
34
60
  // Collect all rows (window functions require materialization for frame evaluation)
35
61
  const allRows = [];
36
62
  for await (const row of source) {
37
63
  allRows.push(row);
38
64
  }
39
- if (plan.windowSpec.partitionBy.length === 0) {
40
- // No partitioning - process as single partition
41
- yield* processPartition(allRows, plan, functionSchemas, rctx, sourceRowDescriptor, outputRowDescriptor, partitionCallbackList, orderByCallbackList, funcArgCallbackList);
42
- }
43
- else {
44
- // With partitioning - group by partition keys
45
- const partitions = await groupByPartitions(allRows, partitionCallbackList, rctx, sourceRowDescriptor);
46
- for (const partitionRows of partitions.values()) {
47
- yield* processPartition(partitionRows, plan, functionSchemas, rctx, sourceRowDescriptor, outputRowDescriptor, partitionCallbackList, orderByCallbackList, funcArgCallbackList);
65
+ // Single source slot shared across all partition/sort/ranking/aggregate operations
66
+ const sourceSlot = createRowSlot(rctx, sourceRowDescriptor);
67
+ try {
68
+ if (plan.windowSpec.partitionBy.length === 0) {
69
+ // No partitioning - process as single partition
70
+ yield* processPartition(allRows, plan, functionSchemas, rctx, sourceRowDescriptor, partitionCallbackList, orderByCallbackList, funcArgCallbackGroups, sourceSlot, orderByComparators, orderByEqualityComparators, orderByKeyNormalizers);
48
71
  }
72
+ else {
73
+ // With partitioning - group by partition keys
74
+ const partitions = await groupByPartitions(allRows, partitionCallbackList, rctx, sourceSlot, partitionKeyNormalizers);
75
+ for (const partitionRows of partitions.values()) {
76
+ yield* processPartition(partitionRows, plan, functionSchemas, rctx, sourceRowDescriptor, partitionCallbackList, orderByCallbackList, funcArgCallbackGroups, sourceSlot, orderByComparators, orderByEqualityComparators, orderByKeyNormalizers);
77
+ }
78
+ }
79
+ }
80
+ finally {
81
+ sourceSlot.close();
49
82
  }
50
83
  }
51
- // Collect all callbacks
84
+ // Collect all callbacks (flatten per-function arg arrays)
52
85
  const allCallbacks = [
53
86
  ...partitionCallbacks,
54
87
  ...orderByCallbacks,
55
- ...functionArgCallbacks.filter(cb => cb !== null)
88
+ ...functionArgCallbacks.flat()
56
89
  ];
57
90
  const sourceInstruction = emitPlanNode(plan.source, ctx);
58
91
  return {
@@ -61,15 +94,12 @@ export function emitWindow(plan, ctx) {
61
94
  note: `window(${plan.functions.map(f => f.functionName).join(', ')})`
62
95
  };
63
96
  }
64
- async function groupByPartitions(rows, partitionCallbacks, rctx, sourceRowDescriptor) {
97
+ async function groupByPartitions(rows, partitionCallbacks, rctx, sourceSlot, keyNormalizers) {
65
98
  const partitions = new Map();
66
99
  for (const row of rows) {
67
- const partitionKey = await withAsyncRowContext(rctx, sourceRowDescriptor, () => row, async () => {
68
- // Evaluate partition expressions
69
- const partitionValues = await Promise.all(partitionCallbacks.map(callback => callback(rctx)));
70
- // Create partition key
71
- return partitionValues.map(val => val === null ? 'NULL' : String(val)).join('|');
72
- });
100
+ sourceSlot.set(row);
101
+ const partitionValues = await Promise.all(partitionCallbacks.map(callback => callback(rctx)));
102
+ const partitionKey = serializeKeyNullGrouping(partitionValues, keyNormalizers);
73
103
  if (!partitions.has(partitionKey)) {
74
104
  partitions.set(partitionKey, []);
75
105
  }
@@ -77,59 +107,59 @@ async function groupByPartitions(rows, partitionCallbacks, rctx, sourceRowDescri
77
107
  }
78
108
  return partitions;
79
109
  }
80
- async function* processPartition(partitionRows, plan, functionSchemas, rctx, sourceRowDescriptor, outputRowDescriptor, partitionCallbacks, orderByCallbacks, funcArgCallbacks) {
110
+ async function* processPartition(partitionRows, plan, functionSchemas, rctx, sourceRowDescriptor, partitionCallbacks, orderByCallbacks, funcArgCallbackGroups, sourceSlot, preResolvedOrderByComparators, preResolvedEqualityComparators, orderByKeyNormalizers) {
81
111
  // Sort rows according to ORDER BY specification
82
- const sortedRows = await sortRows(partitionRows, plan.windowSpec.orderBy, orderByCallbacks, rctx, sourceRowDescriptor);
112
+ const sorted = await sortRows(partitionRows, plan.windowSpec.orderBy, orderByCallbacks, rctx, sourceSlot, preResolvedOrderByComparators);
113
+ const sortedRows = sorted.rows;
114
+ const orderByValues = sorted.orderByValues;
115
+ const partitionSize = sortedRows.length;
83
116
  // Process each row in the sorted partition
84
117
  for (let currentIndex = 0; currentIndex < sortedRows.length; currentIndex++) {
85
118
  const currentRow = sortedRows[currentIndex];
86
119
  const outputRow = [...currentRow];
87
- // Set up context for current row
88
- const outputValues = await withRowContext(rctx, sourceRowDescriptor, () => currentRow, async () => {
89
- const values = [];
90
- // Compute each window function
91
- for (let funcIndex = 0; funcIndex < plan.functions.length; funcIndex++) {
92
- const func = plan.functions[funcIndex];
93
- const schema = functionSchemas[funcIndex];
94
- const argCallback = funcArgCallbacks[funcIndex];
95
- let value;
96
- if (schema.kind === 'ranking') {
97
- value = await computeRankingFunction(func.functionName, sortedRows, currentIndex, orderByCallbacks, rctx, sourceRowDescriptor);
98
- }
99
- else if (schema.kind === 'aggregate') {
100
- value = await computeAggregateFunction(schema, argCallback, sortedRows, currentIndex, plan.windowSpec.frame, plan.windowSpec.orderBy.length > 0, rctx, sourceRowDescriptor);
101
- }
102
- else {
103
- throw new QuereusError(`Window function type ${schema.kind} not yet implemented`, StatusCode.UNSUPPORTED);
104
- }
105
- values.push(value);
120
+ // Set source context for current row
121
+ sourceSlot.set(currentRow);
122
+ const values = [];
123
+ // Compute each window function
124
+ for (let funcIndex = 0; funcIndex < plan.functions.length; funcIndex++) {
125
+ const func = plan.functions[funcIndex];
126
+ const schema = functionSchemas[funcIndex];
127
+ const argCallbacks = funcArgCallbackGroups[funcIndex];
128
+ let value;
129
+ if (schema.kind === 'ranking') {
130
+ value = await computeRankingFunction(func.functionName, sortedRows, currentIndex, partitionSize, argCallbacks, orderByCallbacks, rctx, sourceSlot, preResolvedEqualityComparators, orderByKeyNormalizers);
131
+ }
132
+ else if (schema.kind === 'aggregate') {
133
+ value = await computeAggregateFunction(schema, argCallbacks[0] ?? null, sortedRows, currentIndex, plan.windowSpec.frame, plan.windowSpec.orderBy.length > 0, orderByValues, preResolvedEqualityComparators, rctx, sourceSlot);
134
+ }
135
+ else if (schema.kind === 'navigation') {
136
+ value = await computeNavigationFunction(func.functionName, sortedRows, currentIndex, argCallbacks, rctx, sourceSlot);
106
137
  }
107
- return values;
108
- });
138
+ else if (schema.kind === 'value') {
139
+ value = await computeValueFunction(func.functionName, sortedRows, currentIndex, argCallbacks, plan.windowSpec.frame, plan.windowSpec.orderBy.length > 0, orderByValues, preResolvedEqualityComparators, rctx, sourceSlot);
140
+ }
141
+ else {
142
+ throw new QuereusError(`Window function type ${schema.kind} not yet implemented`, StatusCode.UNSUPPORTED);
143
+ }
144
+ // Restore current row context after helper may have changed it
145
+ sourceSlot.set(currentRow);
146
+ values.push(value);
147
+ }
109
148
  // Add computed values to output row
110
- outputRow.push(...outputValues);
111
- // Yield the output row
112
- yield await withRowContext(rctx, outputRowDescriptor, () => outputRow, () => outputRow);
149
+ outputRow.push(...values);
150
+ yield outputRow;
113
151
  }
114
152
  }
115
- async function sortRows(rows, orderBy, orderByCallbacks, rctx, sourceRowDescriptor) {
153
+ async function sortRows(rows, orderBy, orderByCallbacks, rctx, sourceSlot, preResolvedComparators) {
116
154
  if (orderBy.length === 0) {
117
- return rows; // No sorting needed
155
+ return { rows, orderByValues: rows.map(() => []) };
118
156
  }
119
- // Pre-create optimized comparators for all ORDER BY expressions with resolved collations
120
- const orderByComparators = orderBy.map(orderClause => {
121
- // TODO: Extract actual collation from order clause expression
122
- // For now, use BINARY collation (most common case)
123
- const collationFunc = resolveCollation('BINARY');
124
- return createOrderByComparatorFast(orderClause.direction, orderClause.nulls, collationFunc);
125
- });
126
157
  // Pre-evaluate ORDER BY values for all rows to avoid async in sort
127
158
  const rowsWithValues = await Promise.all(rows.map(async (row) => {
159
+ sourceSlot.set(row);
128
160
  const values = await Promise.all(orderByCallbacks.map(async (callback) => {
129
- return await withAsyncRowContext(rctx, sourceRowDescriptor, () => row, async () => {
130
- const result = callback(rctx);
131
- return await Promise.resolve(result);
132
- });
161
+ const result = callback(rctx);
162
+ return await Promise.resolve(result);
133
163
  }));
134
164
  return { row, values };
135
165
  }));
@@ -137,7 +167,7 @@ async function sortRows(rows, orderBy, orderByCallbacks, rctx, sourceRowDescript
137
167
  rowsWithValues.sort((a, b) => {
138
168
  // Compare each ORDER BY expression in sequence
139
169
  for (let i = 0; i < orderBy.length; i++) {
140
- const comparator = orderByComparators[i];
170
+ const comparator = preResolvedComparators[i];
141
171
  const valueA = a.values[i];
142
172
  const valueB = b.values[i];
143
173
  // Use pre-created optimized comparator
@@ -150,24 +180,17 @@ async function sortRows(rows, orderBy, orderByCallbacks, rctx, sourceRowDescript
150
180
  }
151
181
  return 0; // All ORDER BY expressions are equal
152
182
  });
153
- // Extract just the rows in sorted order
154
- return rowsWithValues.map(item => item.row);
183
+ return {
184
+ rows: rowsWithValues.map(item => item.row),
185
+ orderByValues: rowsWithValues.map(item => item.values)
186
+ };
155
187
  }
156
- async function computeRankingFunction(functionName, sortedRows, currentIndex, orderByCallbacks, rctx, sourceRowDescriptor) {
188
+ async function computeRankingFunction(functionName, sortedRows, currentIndex, partitionSize, argCallbacks, orderByCallbacks, rctx, sourceSlot, equalityComparators, orderByKeyNormalizers) {
157
189
  switch (functionName.toLowerCase()) {
158
190
  case 'row_number':
159
191
  return currentIndex + 1;
160
192
  case 'rank': {
161
- // Find rank by counting how many rows come before this one in sort order
162
- let rank = 1;
163
- const currentRow = sortedRows[currentIndex];
164
- for (let i = 0; i < currentIndex; i++) {
165
- const prevRow = sortedRows[i];
166
- if (!(await areRowsEqualInOrderBy(prevRow, currentRow, orderByCallbacks, rctx, sourceRowDescriptor))) {
167
- rank = i + 2; // Rank is 1-based and accounts for ties
168
- }
169
- }
170
- return rank;
193
+ return computeRank(sortedRows, currentIndex, orderByCallbacks, rctx, sourceSlot, equalityComparators);
171
194
  }
172
195
  case 'dense_rank': {
173
196
  // Count distinct values that come before this one
@@ -176,9 +199,9 @@ async function computeRankingFunction(functionName, sortedRows, currentIndex, or
176
199
  const seenValues = new Set();
177
200
  for (let i = 0; i < currentIndex; i++) {
178
201
  const prevRow = sortedRows[i];
179
- if (!(await areRowsEqualInOrderBy(prevRow, currentRow, orderByCallbacks, rctx, sourceRowDescriptor))) {
202
+ if (!(await areRowsEqualInOrderBy(prevRow, currentRow, orderByCallbacks, rctx, sourceSlot, equalityComparators))) {
180
203
  // Create a key for this distinct set of ORDER BY values
181
- const key = await getOrderByKey(prevRow, orderByCallbacks, rctx, sourceRowDescriptor);
204
+ const key = await getOrderByKey(prevRow, orderByCallbacks, rctx, sourceSlot, orderByKeyNormalizers);
182
205
  if (!seenValues.has(key)) {
183
206
  seenValues.add(key);
184
207
  denseRank++;
@@ -187,36 +210,134 @@ async function computeRankingFunction(functionName, sortedRows, currentIndex, or
187
210
  }
188
211
  return denseRank;
189
212
  }
213
+ case 'ntile': {
214
+ // Evaluate the bucket count argument
215
+ const nValue = argCallbacks.length > 0
216
+ ? await Promise.resolve(argCallbacks[0](rctx))
217
+ : 1;
218
+ const n = Number(nValue) || 1;
219
+ if (n <= 0)
220
+ return 1;
221
+ // Divide partition into n roughly equal groups
222
+ const q = Math.floor(partitionSize / n);
223
+ const r = partitionSize % n;
224
+ // First r groups have (q+1) rows, remaining have q rows
225
+ if (currentIndex < r * (q + 1)) {
226
+ return Math.floor(currentIndex / (q + 1)) + 1;
227
+ }
228
+ else {
229
+ return r + Math.floor((currentIndex - r * (q + 1)) / q) + 1;
230
+ }
231
+ }
232
+ case 'percent_rank': {
233
+ if (partitionSize <= 1)
234
+ return 0;
235
+ const rank = await computeRank(sortedRows, currentIndex, orderByCallbacks, rctx, sourceSlot, equalityComparators);
236
+ return (rank - 1) / (partitionSize - 1);
237
+ }
238
+ case 'cume_dist': {
239
+ // CUME_DIST = (number of rows <= current row) / partitionSize
240
+ // = (index of last peer + 1) / partitionSize
241
+ const currentRow = sortedRows[currentIndex];
242
+ let lastPeerIndex = currentIndex;
243
+ for (let i = currentIndex + 1; i < partitionSize; i++) {
244
+ if (await areRowsEqualInOrderBy(sortedRows[i], currentRow, orderByCallbacks, rctx, sourceSlot, equalityComparators)) {
245
+ lastPeerIndex = i;
246
+ }
247
+ else {
248
+ break;
249
+ }
250
+ }
251
+ return (lastPeerIndex + 1) / partitionSize;
252
+ }
190
253
  default:
191
254
  throw new QuereusError(`Ranking function ${functionName} not implemented`, StatusCode.UNSUPPORTED);
192
255
  }
193
256
  }
194
- async function computeAggregateFunction(schema, argCallback, sortedRows, currentIndex, frame, hasOrderBy, rctx, sourceRowDescriptor) {
195
- // Determine frame bounds
196
- const frameBounds = getFrameBounds(frame, sortedRows.length, currentIndex, hasOrderBy);
257
+ /** Compute RANK() value extracted for reuse by PERCENT_RANK */
258
+ async function computeRank(sortedRows, currentIndex, orderByCallbacks, rctx, sourceSlot, equalityComparators) {
259
+ let rank = 1;
260
+ const currentRow = sortedRows[currentIndex];
261
+ for (let i = 0; i < currentIndex; i++) {
262
+ const prevRow = sortedRows[i];
263
+ if (!(await areRowsEqualInOrderBy(prevRow, currentRow, orderByCallbacks, rctx, sourceSlot, equalityComparators))) {
264
+ rank = i + 2; // Rank is 1-based and accounts for ties
265
+ }
266
+ }
267
+ return rank;
268
+ }
269
+ async function computeNavigationFunction(functionName, sortedRows, currentIndex, argCallbacks, rctx, sourceSlot) {
270
+ const exprCallback = argCallbacks[0];
271
+ if (!exprCallback) {
272
+ throw new QuereusError(`${functionName} requires at least one argument`, StatusCode.ERROR);
273
+ }
274
+ // Evaluate offset (2nd arg, default 1)
275
+ let offset = 1;
276
+ if (argCallbacks.length >= 2) {
277
+ const offsetValue = await Promise.resolve(argCallbacks[1](rctx));
278
+ offset = Number(offsetValue) || 0;
279
+ }
280
+ // Evaluate default value (3rd arg, default null)
281
+ let defaultValue = null;
282
+ if (argCallbacks.length >= 3) {
283
+ defaultValue = await Promise.resolve(argCallbacks[2](rctx));
284
+ }
285
+ const name = functionName.toLowerCase();
286
+ const targetIndex = name === 'lag'
287
+ ? currentIndex - offset
288
+ : currentIndex + offset; // 'lead'
289
+ if (targetIndex < 0 || targetIndex >= sortedRows.length) {
290
+ return defaultValue;
291
+ }
292
+ // Evaluate expression on the target row
293
+ sourceSlot.set(sortedRows[targetIndex]);
294
+ return await Promise.resolve(exprCallback(rctx));
295
+ }
296
+ async function computeValueFunction(functionName, sortedRows, currentIndex, argCallbacks, frame, hasOrderBy, orderByValues, equalityComparators, rctx, sourceSlot) {
297
+ const exprCallback = argCallbacks[0];
298
+ if (!exprCallback) {
299
+ throw new QuereusError(`${functionName} requires one argument`, StatusCode.ERROR);
300
+ }
301
+ const frameBounds = getFrameBounds(frame, sortedRows.length, currentIndex, hasOrderBy, orderByValues, equalityComparators);
302
+ const name = functionName.toLowerCase();
303
+ let targetIndex;
304
+ if (name === 'first_value') {
305
+ targetIndex = frameBounds.start;
306
+ }
307
+ else {
308
+ // last_value
309
+ targetIndex = frameBounds.end;
310
+ }
311
+ // Handle empty frame
312
+ if (targetIndex < 0 || targetIndex >= sortedRows.length || frameBounds.start > frameBounds.end) {
313
+ return null;
314
+ }
315
+ sourceSlot.set(sortedRows[targetIndex]);
316
+ return await Promise.resolve(exprCallback(rctx));
317
+ }
318
+ async function computeAggregateFunction(schema, argCallback, sortedRows, currentIndex, frame, hasOrderBy, orderByValues, equalityComparators, rctx, sourceSlot) {
319
+ const frameBounds = getFrameBounds(frame, sortedRows.length, currentIndex, hasOrderBy, orderByValues, equalityComparators);
197
320
  let accumulator = null;
198
321
  let rowCount = 0;
199
322
  // Process rows within the frame
200
323
  for (let i = frameBounds.start; i <= frameBounds.end; i++) {
201
324
  const frameRow = sortedRows[i];
202
- await withAsyncRowContext(rctx, sourceRowDescriptor, () => frameRow, async () => {
203
- let argValue = null;
204
- // Get argument value if callback exists
205
- if (argCallback) {
206
- const result = argCallback(rctx);
207
- argValue = await Promise.resolve(result);
208
- }
209
- // Apply aggregate step function
210
- if (schema.step) {
211
- accumulator = schema.step(accumulator, argValue);
212
- rowCount++;
213
- }
214
- });
325
+ sourceSlot.set(frameRow);
326
+ let argValue = null;
327
+ // Get argument value if callback exists
328
+ if (argCallback) {
329
+ argValue = await Promise.resolve(argCallback(rctx));
330
+ }
331
+ // Apply aggregate step function
332
+ if (schema.step) {
333
+ accumulator = schema.step(accumulator, argValue);
334
+ rowCount++;
335
+ }
215
336
  }
216
337
  // Apply final function
217
338
  return schema.final ? schema.final(accumulator, rowCount) : accumulator;
218
339
  }
219
- function getFrameBounds(frame, totalRows, currentIndex, hasOrderBy = true) {
340
+ function getFrameBounds(frame, totalRows, currentIndex, hasOrderBy = true, orderByValues = [], equalityComparators = []) {
220
341
  if (!frame) {
221
342
  if (!hasOrderBy) {
222
343
  // No ORDER BY: default frame is entire partition (all rows)
@@ -224,9 +345,12 @@ function getFrameBounds(frame, totalRows, currentIndex, hasOrderBy = true) {
224
345
  }
225
346
  else {
226
347
  // With ORDER BY: default frame is RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
227
- return { start: 0, end: currentIndex };
348
+ // In RANGE mode, CURRENT ROW means all peer rows (same ORDER BY values)
349
+ const lastPeer = findLastPeer(currentIndex, totalRows, orderByValues, equalityComparators);
350
+ return { start: 0, end: lastPeer };
228
351
  }
229
352
  }
353
+ const isRange = frame.type === 'range';
230
354
  let start;
231
355
  let end;
232
356
  // Calculate start bound
@@ -234,16 +358,27 @@ function getFrameBounds(frame, totalRows, currentIndex, hasOrderBy = true) {
234
358
  start = 0;
235
359
  }
236
360
  else if (frame.start.type === 'currentRow') {
237
- start = currentIndex;
361
+ start = isRange
362
+ ? findFirstPeer(currentIndex, totalRows, orderByValues, equalityComparators)
363
+ : currentIndex;
238
364
  }
239
365
  else if (frame.start.type === 'preceding') {
240
- // TODO: Evaluate frame.start.value expression
241
- const offset = 1; // For now, hard-coded for the test
242
- start = Math.max(0, currentIndex - offset);
366
+ const offset = getFrameOffset(frame.start.value);
367
+ if (isRange) {
368
+ start = findRangeOffsetStart(currentIndex, totalRows, orderByValues, -offset);
369
+ }
370
+ else {
371
+ start = Math.max(0, currentIndex - offset);
372
+ }
243
373
  }
244
374
  else if (frame.start.type === 'following') {
245
- const offset = 1; // TODO: Evaluate frame.start.value expression
246
- start = Math.min(totalRows - 1, currentIndex + offset);
375
+ const offset = getFrameOffset(frame.start.value);
376
+ if (isRange) {
377
+ start = findRangeOffsetStart(currentIndex, totalRows, orderByValues, offset);
378
+ }
379
+ else {
380
+ start = Math.min(totalRows - 1, currentIndex + offset);
381
+ }
247
382
  }
248
383
  else {
249
384
  start = 0;
@@ -251,50 +386,157 @@ function getFrameBounds(frame, totalRows, currentIndex, hasOrderBy = true) {
251
386
  // Calculate end bound
252
387
  if (frame.end === null) {
253
388
  // Single bound frame - end is current row
254
- end = currentIndex;
389
+ end = isRange
390
+ ? findLastPeer(currentIndex, totalRows, orderByValues, equalityComparators)
391
+ : currentIndex;
255
392
  }
256
393
  else if (frame.end.type === 'unboundedFollowing') {
257
394
  end = totalRows - 1;
258
395
  }
259
396
  else if (frame.end.type === 'currentRow') {
260
- end = currentIndex;
397
+ end = isRange
398
+ ? findLastPeer(currentIndex, totalRows, orderByValues, equalityComparators)
399
+ : currentIndex;
261
400
  }
262
401
  else if (frame.end.type === 'preceding') {
263
- const offset = 1; // TODO: Evaluate frame.end.value expression
264
- end = Math.max(0, currentIndex - offset);
402
+ const offset = getFrameOffset(frame.end.value);
403
+ if (isRange) {
404
+ end = findRangeOffsetEnd(currentIndex, totalRows, orderByValues, -offset);
405
+ }
406
+ else {
407
+ end = Math.max(0, currentIndex - offset);
408
+ }
265
409
  }
266
410
  else if (frame.end.type === 'following') {
267
- const offset = 1; // TODO: Evaluate frame.end.value expression
268
- end = Math.min(totalRows - 1, currentIndex + offset);
411
+ const offset = getFrameOffset(frame.end.value);
412
+ if (isRange) {
413
+ end = findRangeOffsetEnd(currentIndex, totalRows, orderByValues, offset);
414
+ }
415
+ else {
416
+ end = Math.min(totalRows - 1, currentIndex + offset);
417
+ }
269
418
  }
270
419
  else {
271
420
  end = currentIndex;
272
421
  }
422
+ // Empty frame when bounds invert
423
+ if (start > end) {
424
+ return { start: currentIndex + 1, end: currentIndex };
425
+ }
273
426
  return { start, end };
274
427
  }
275
- async function areRowsEqualInOrderBy(rowA, rowB, orderByCallbacks, rctx, sourceRowDescriptor) {
276
- for (const callback of orderByCallbacks) {
428
+ /** Find the first row in the peer group (rows with same ORDER BY values) */
429
+ function findFirstPeer(currentIndex, _totalRows, orderByValues, equalityComparators) {
430
+ const currentVals = orderByValues[currentIndex];
431
+ let first = currentIndex;
432
+ while (first > 0 && arePeerRows(orderByValues[first - 1], currentVals, equalityComparators)) {
433
+ first--;
434
+ }
435
+ return first;
436
+ }
437
+ /** Find the last row in the peer group */
438
+ function findLastPeer(currentIndex, totalRows, orderByValues, equalityComparators) {
439
+ const currentVals = orderByValues[currentIndex];
440
+ let last = currentIndex;
441
+ while (last < totalRows - 1 && arePeerRows(orderByValues[last + 1], currentVals, equalityComparators)) {
442
+ last++;
443
+ }
444
+ return last;
445
+ }
446
+ /** Check if two rows have equal ORDER BY values */
447
+ function arePeerRows(valsA, valsB, equalityComparators) {
448
+ for (let i = 0; i < equalityComparators.length; i++) {
449
+ if (equalityComparators[i](valsA[i], valsB[i]) !== 0)
450
+ return false;
451
+ }
452
+ return true;
453
+ }
454
+ /**
455
+ * For RANGE N PRECEDING/FOLLOWING: find the first row whose ORDER BY value
456
+ * is >= (currentValue + offset). Uses the first ORDER BY expression only
457
+ * (SQL standard requires single ORDER BY for numeric RANGE offsets).
458
+ */
459
+ function findRangeOffsetStart(currentIndex, totalRows, orderByValues, offset // negative for PRECEDING, positive for FOLLOWING
460
+ ) {
461
+ const currentVal = Number(orderByValues[currentIndex][0]);
462
+ if (!Number.isFinite(currentVal))
463
+ return currentIndex;
464
+ const targetVal = currentVal + offset;
465
+ // Scan from beginning to find first row >= targetVal
466
+ for (let i = 0; i < totalRows; i++) {
467
+ const rowVal = Number(orderByValues[i][0]);
468
+ if (Number.isFinite(rowVal) && rowVal >= targetVal) {
469
+ return i;
470
+ }
471
+ }
472
+ return totalRows; // No matching row (empty frame start)
473
+ }
474
+ /**
475
+ * For RANGE N PRECEDING/FOLLOWING: find the last row whose ORDER BY value
476
+ * is <= (currentValue + offset).
477
+ */
478
+ function findRangeOffsetEnd(currentIndex, totalRows, orderByValues, offset) {
479
+ const currentVal = Number(orderByValues[currentIndex][0]);
480
+ if (!Number.isFinite(currentVal))
481
+ return currentIndex;
482
+ const targetVal = currentVal + offset;
483
+ // Scan from end to find last row <= targetVal
484
+ for (let i = totalRows - 1; i >= 0; i--) {
485
+ const rowVal = Number(orderByValues[i][0]);
486
+ if (Number.isFinite(rowVal) && rowVal <= targetVal) {
487
+ return i;
488
+ }
489
+ }
490
+ return -1; // No matching row (empty frame end)
491
+ }
492
+ function getFrameOffset(expr) {
493
+ // SQL grammar for frame offsets is typically an unsigned integer literal.
494
+ // Quereus currently supports literal numeric offsets and unary +/- on literals.
495
+ const value = tryExtractNumericLiteral(expr);
496
+ if (value === undefined) {
497
+ throw new QuereusError('Window frame offsets must be constant numeric literals', StatusCode.UNSUPPORTED);
498
+ }
499
+ if (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {
500
+ throw new QuereusError(`Invalid window frame offset: ${value}. Must be a non-negative integer.`, StatusCode.ERROR);
501
+ }
502
+ return value;
503
+ }
504
+ function tryExtractNumericLiteral(expr) {
505
+ if (expr.type === 'literal') {
506
+ const v = expr.value;
507
+ if (typeof v === 'number')
508
+ return v;
509
+ if (typeof v === 'bigint')
510
+ return Number(v);
511
+ return undefined;
512
+ }
513
+ if (expr.type === 'unary' && (expr.operator === '+' || expr.operator === '-')) {
514
+ const inner = tryExtractNumericLiteral(expr.expr);
515
+ if (inner === undefined)
516
+ return undefined;
517
+ return expr.operator === '-' ? -inner : inner;
518
+ }
519
+ return undefined;
520
+ }
521
+ async function areRowsEqualInOrderBy(rowA, rowB, orderByCallbacks, rctx, sourceSlot, equalityComparators) {
522
+ for (let i = 0; i < orderByCallbacks.length; i++) {
523
+ const callback = orderByCallbacks[i];
277
524
  // Get value for row A
278
- const valueA = await withAsyncRowContext(rctx, sourceRowDescriptor, () => rowA, async () => {
279
- const result = callback(rctx);
280
- return await Promise.resolve(result);
281
- });
525
+ sourceSlot.set(rowA);
526
+ const valueA = await Promise.resolve(callback(rctx));
282
527
  // Get value for row B
283
- const valueB = await withAsyncRowContext(rctx, sourceRowDescriptor, () => rowB, async () => {
284
- const result = callback(rctx);
285
- return await Promise.resolve(result);
286
- });
287
- // If any ORDER BY expression differs, rows are not equal
288
- if (compareSqlValues(valueA, valueB) !== 0) {
528
+ sourceSlot.set(rowB);
529
+ const valueB = await Promise.resolve(callback(rctx));
530
+ // If any ORDER BY expression differs, rows are not equal (using pre-resolved typed comparator)
531
+ if (equalityComparators[i](valueA, valueB) !== 0) {
289
532
  return false;
290
533
  }
291
534
  }
292
535
  return true; // All ORDER BY expressions are equal
293
536
  }
294
- async function getOrderByKey(row, orderByCallbacks, rctx, sourceRowDescriptor) {
295
- return await withAsyncRowContext(rctx, sourceRowDescriptor, () => row, async () => {
296
- const values = await Promise.all(orderByCallbacks.map(callback => Promise.resolve(callback(rctx))));
297
- return values.map(val => val === null ? 'NULL' : String(val)).join('|');
298
- });
537
+ async function getOrderByKey(row, orderByCallbacks, rctx, sourceSlot, keyNormalizers) {
538
+ sourceSlot.set(row);
539
+ const values = await Promise.all(orderByCallbacks.map(callback => Promise.resolve(callback(rctx))));
540
+ return serializeKeyNullGrouping(values, keyNormalizers);
299
541
  }
300
542
  //# sourceMappingURL=window.js.map