@quereus/quereus 4.3.2 → 4.4.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 (396) hide show
  1. package/README.md +5 -0
  2. package/dist/src/common/types.d.ts +9 -0
  3. package/dist/src/common/types.d.ts.map +1 -1
  4. package/dist/src/common/types.js.map +1 -1
  5. package/dist/src/core/database-events.d.ts +49 -0
  6. package/dist/src/core/database-events.d.ts.map +1 -1
  7. package/dist/src/core/database-events.js +148 -0
  8. package/dist/src/core/database-events.js.map +1 -1
  9. package/dist/src/core/database-external-changes.d.ts +2 -2
  10. package/dist/src/core/database-external-changes.d.ts.map +1 -1
  11. package/dist/src/core/database-external-changes.js +12 -9
  12. package/dist/src/core/database-external-changes.js.map +1 -1
  13. package/dist/src/core/database-materialized-views-apply.d.ts +156 -14
  14. package/dist/src/core/database-materialized-views-apply.d.ts.map +1 -1
  15. package/dist/src/core/database-materialized-views-apply.js +370 -65
  16. package/dist/src/core/database-materialized-views-apply.js.map +1 -1
  17. package/dist/src/core/database-materialized-views-plan-builders.d.ts +66 -1
  18. package/dist/src/core/database-materialized-views-plan-builders.d.ts.map +1 -1
  19. package/dist/src/core/database-materialized-views-plan-builders.js +368 -8
  20. package/dist/src/core/database-materialized-views-plan-builders.js.map +1 -1
  21. package/dist/src/core/database-materialized-views-plans.d.ts +257 -30
  22. package/dist/src/core/database-materialized-views-plans.d.ts.map +1 -1
  23. package/dist/src/core/database-materialized-views.d.ts +99 -42
  24. package/dist/src/core/database-materialized-views.d.ts.map +1 -1
  25. package/dist/src/core/database-materialized-views.js +198 -121
  26. package/dist/src/core/database-materialized-views.js.map +1 -1
  27. package/dist/src/core/database.d.ts +5 -0
  28. package/dist/src/core/database.d.ts.map +1 -1
  29. package/dist/src/core/database.js +41 -18
  30. package/dist/src/core/database.js.map +1 -1
  31. package/dist/src/core/internal-statement-cache.d.ts +18 -0
  32. package/dist/src/core/internal-statement-cache.d.ts.map +1 -0
  33. package/dist/src/core/internal-statement-cache.js +211 -0
  34. package/dist/src/core/internal-statement-cache.js.map +1 -0
  35. package/dist/src/func/builtins/aggregate.d.ts +13 -12
  36. package/dist/src/func/builtins/aggregate.d.ts.map +1 -1
  37. package/dist/src/func/builtins/aggregate.js +146 -62
  38. package/dist/src/func/builtins/aggregate.js.map +1 -1
  39. package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
  40. package/dist/src/func/builtins/builtin-window-functions.js +63 -48
  41. package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
  42. package/dist/src/func/registration.d.ts +19 -1
  43. package/dist/src/func/registration.d.ts.map +1 -1
  44. package/dist/src/func/registration.js +41 -0
  45. package/dist/src/func/registration.js.map +1 -1
  46. package/dist/src/index.d.ts +8 -8
  47. package/dist/src/index.d.ts.map +1 -1
  48. package/dist/src/index.js +12 -11
  49. package/dist/src/index.js.map +1 -1
  50. package/dist/src/parser/parser.d.ts +6 -0
  51. package/dist/src/parser/parser.d.ts.map +1 -1
  52. package/dist/src/parser/parser.js +45 -34
  53. package/dist/src/parser/parser.js.map +1 -1
  54. package/dist/src/planner/analysis/comparison-collation.d.ts +2 -0
  55. package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -1
  56. package/dist/src/planner/analysis/comparison-collation.js +1 -1
  57. package/dist/src/planner/analysis/comparison-collation.js.map +1 -1
  58. package/dist/src/planner/analysis/equi-correlation.d.ts +26 -0
  59. package/dist/src/planner/analysis/equi-correlation.d.ts.map +1 -0
  60. package/dist/src/planner/analysis/equi-correlation.js +62 -0
  61. package/dist/src/planner/analysis/equi-correlation.js.map +1 -0
  62. package/dist/src/planner/analysis/expression-fingerprint.d.ts.map +1 -1
  63. package/dist/src/planner/analysis/expression-fingerprint.js +29 -0
  64. package/dist/src/planner/analysis/expression-fingerprint.js.map +1 -1
  65. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts +60 -18
  66. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts.map +1 -1
  67. package/dist/src/planner/analysis/query-rewrite-matcher.js +95 -42
  68. package/dist/src/planner/analysis/query-rewrite-matcher.js.map +1 -1
  69. package/dist/src/planner/analysis/sat-checker.d.ts.map +1 -1
  70. package/dist/src/planner/analysis/sat-checker.js +43 -4
  71. package/dist/src/planner/analysis/sat-checker.js.map +1 -1
  72. package/dist/src/planner/analysis/scalar-subqueries.d.ts +28 -0
  73. package/dist/src/planner/analysis/scalar-subqueries.d.ts.map +1 -0
  74. package/dist/src/planner/analysis/scalar-subqueries.js +60 -0
  75. package/dist/src/planner/analysis/scalar-subqueries.js.map +1 -0
  76. package/dist/src/planner/building/delete.d.ts.map +1 -1
  77. package/dist/src/planner/building/delete.js +10 -3
  78. package/dist/src/planner/building/delete.js.map +1 -1
  79. package/dist/src/planner/building/expression.d.ts.map +1 -1
  80. package/dist/src/planner/building/expression.js +87 -6
  81. package/dist/src/planner/building/expression.js.map +1 -1
  82. package/dist/src/planner/building/foreign-key-builder.d.ts +44 -1
  83. package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -1
  84. package/dist/src/planner/building/foreign-key-builder.js +54 -0
  85. package/dist/src/planner/building/foreign-key-builder.js.map +1 -1
  86. package/dist/src/planner/building/insert.d.ts.map +1 -1
  87. package/dist/src/planner/building/insert.js +9 -12
  88. package/dist/src/planner/building/insert.js.map +1 -1
  89. package/dist/src/planner/building/select.d.ts.map +1 -1
  90. package/dist/src/planner/building/select.js +15 -1
  91. package/dist/src/planner/building/select.js.map +1 -1
  92. package/dist/src/planner/building/update.d.ts.map +1 -1
  93. package/dist/src/planner/building/update.js +13 -4
  94. package/dist/src/planner/building/update.js.map +1 -1
  95. package/dist/src/planner/building/with.d.ts.map +1 -1
  96. package/dist/src/planner/building/with.js +5 -8
  97. package/dist/src/planner/building/with.js.map +1 -1
  98. package/dist/src/planner/cache/materialization-advisory.d.ts +33 -0
  99. package/dist/src/planner/cache/materialization-advisory.d.ts.map +1 -1
  100. package/dist/src/planner/cache/materialization-advisory.js +164 -28
  101. package/dist/src/planner/cache/materialization-advisory.js.map +1 -1
  102. package/dist/src/planner/cache/reference-graph.d.ts +0 -4
  103. package/dist/src/planner/cache/reference-graph.d.ts.map +1 -1
  104. package/dist/src/planner/cache/reference-graph.js +5 -13
  105. package/dist/src/planner/cache/reference-graph.js.map +1 -1
  106. package/dist/src/planner/cost/index.d.ts +28 -7
  107. package/dist/src/planner/cost/index.d.ts.map +1 -1
  108. package/dist/src/planner/cost/index.js +26 -0
  109. package/dist/src/planner/cost/index.js.map +1 -1
  110. package/dist/src/planner/framework/pass.js +3 -3
  111. package/dist/src/planner/nodes/cache-node.d.ts +18 -2
  112. package/dist/src/planner/nodes/cache-node.d.ts.map +1 -1
  113. package/dist/src/planner/nodes/cache-node.js +42 -3
  114. package/dist/src/planner/nodes/cache-node.js.map +1 -1
  115. package/dist/src/planner/nodes/cte-node.d.ts +15 -1
  116. package/dist/src/planner/nodes/cte-node.d.ts.map +1 -1
  117. package/dist/src/planner/nodes/cte-node.js +12 -2
  118. package/dist/src/planner/nodes/cte-node.js.map +1 -1
  119. package/dist/src/planner/nodes/dml-executor-node.d.ts +0 -9
  120. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  121. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  122. package/dist/src/planner/nodes/recursive-cte-node.d.ts +30 -1
  123. package/dist/src/planner/nodes/recursive-cte-node.d.ts.map +1 -1
  124. package/dist/src/planner/nodes/recursive-cte-node.js +30 -3
  125. package/dist/src/planner/nodes/recursive-cte-node.js.map +1 -1
  126. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  127. package/dist/src/planner/nodes/scalar.js +26 -3
  128. package/dist/src/planner/nodes/scalar.js.map +1 -1
  129. package/dist/src/planner/optimizer.d.ts.map +1 -1
  130. package/dist/src/planner/optimizer.js +129 -8
  131. package/dist/src/planner/optimizer.js.map +1 -1
  132. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  133. package/dist/src/planner/rules/access/rule-select-access-path.js +43 -18
  134. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  135. package/dist/src/planner/rules/cache/rule-cte-optimization.d.ts.map +1 -1
  136. package/dist/src/planner/rules/cache/rule-cte-optimization.js +8 -1
  137. package/dist/src/planner/rules/cache/rule-cte-optimization.js.map +1 -1
  138. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts.map +1 -1
  139. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js +72 -54
  140. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js.map +1 -1
  141. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.d.ts.map +1 -1
  142. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js +6 -0
  143. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js.map +1 -1
  144. package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.d.ts +25 -0
  145. package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.d.ts.map +1 -0
  146. package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.js +176 -0
  147. package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.js.map +1 -0
  148. package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.d.ts +31 -0
  149. package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.d.ts.map +1 -0
  150. package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.js +68 -0
  151. package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.js.map +1 -0
  152. package/dist/src/planner/rules/join/rule-fanout-lookup-join.d.ts.map +1 -1
  153. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js +1 -54
  154. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js.map +1 -1
  155. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +8 -1
  156. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -1
  157. package/dist/src/planner/rules/subquery/rule-scalar-agg-decorrelation.d.ts +191 -0
  158. package/dist/src/planner/rules/subquery/rule-scalar-agg-decorrelation.d.ts.map +1 -0
  159. package/dist/src/planner/rules/subquery/rule-scalar-agg-decorrelation.js +627 -0
  160. package/dist/src/planner/rules/subquery/rule-scalar-agg-decorrelation.js.map +1 -0
  161. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts +10 -1
  162. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
  163. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +242 -51
  164. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
  165. package/dist/src/runtime/cache/shared-cache.d.ts +7 -0
  166. package/dist/src/runtime/cache/shared-cache.d.ts.map +1 -1
  167. package/dist/src/runtime/cache/shared-cache.js +34 -1
  168. package/dist/src/runtime/cache/shared-cache.js.map +1 -1
  169. package/dist/src/runtime/deferred-constraint-queue.d.ts.map +1 -1
  170. package/dist/src/runtime/deferred-constraint-queue.js +10 -0
  171. package/dist/src/runtime/deferred-constraint-queue.js.map +1 -1
  172. package/dist/src/runtime/emit/aggregate-setup.d.ts +49 -0
  173. package/dist/src/runtime/emit/aggregate-setup.d.ts.map +1 -0
  174. package/dist/src/runtime/emit/aggregate-setup.js +99 -0
  175. package/dist/src/runtime/emit/aggregate-setup.js.map +1 -0
  176. package/dist/src/runtime/emit/aggregate.d.ts +2 -3
  177. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  178. package/dist/src/runtime/emit/aggregate.js +10 -84
  179. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  180. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  181. package/dist/src/runtime/emit/alter-table.js +348 -165
  182. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  183. package/dist/src/runtime/emit/asof-scan.d.ts.map +1 -1
  184. package/dist/src/runtime/emit/asof-scan.js +6 -0
  185. package/dist/src/runtime/emit/asof-scan.js.map +1 -1
  186. package/dist/src/runtime/emit/between.d.ts.map +1 -1
  187. package/dist/src/runtime/emit/between.js +32 -3
  188. package/dist/src/runtime/emit/between.js.map +1 -1
  189. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  190. package/dist/src/runtime/emit/binary.js +22 -2
  191. package/dist/src/runtime/emit/binary.js.map +1 -1
  192. package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -1
  193. package/dist/src/runtime/emit/bloom-join.js +24 -3
  194. package/dist/src/runtime/emit/bloom-join.js.map +1 -1
  195. package/dist/src/runtime/emit/cache.d.ts +7 -3
  196. package/dist/src/runtime/emit/cache.d.ts.map +1 -1
  197. package/dist/src/runtime/emit/cache.js +23 -6
  198. package/dist/src/runtime/emit/cache.js.map +1 -1
  199. package/dist/src/runtime/emit/cast.d.ts.map +1 -1
  200. package/dist/src/runtime/emit/cast.js +10 -23
  201. package/dist/src/runtime/emit/cast.js.map +1 -1
  202. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  203. package/dist/src/runtime/emit/constraint-check.js +41 -44
  204. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  205. package/dist/src/runtime/emit/create-view.d.ts.map +1 -1
  206. package/dist/src/runtime/emit/create-view.js +6 -0
  207. package/dist/src/runtime/emit/create-view.js.map +1 -1
  208. package/dist/src/runtime/emit/cte.d.ts.map +1 -1
  209. package/dist/src/runtime/emit/cte.js +43 -20
  210. package/dist/src/runtime/emit/cte.js.map +1 -1
  211. package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
  212. package/dist/src/runtime/emit/distinct.js +6 -3
  213. package/dist/src/runtime/emit/distinct.js.map +1 -1
  214. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  215. package/dist/src/runtime/emit/dml-executor.js +241 -115
  216. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  217. package/dist/src/runtime/emit/hash-aggregate.d.ts.map +1 -1
  218. package/dist/src/runtime/emit/hash-aggregate.js +16 -65
  219. package/dist/src/runtime/emit/hash-aggregate.js.map +1 -1
  220. package/dist/src/runtime/emit/insert.d.ts.map +1 -1
  221. package/dist/src/runtime/emit/insert.js +18 -7
  222. package/dist/src/runtime/emit/insert.js.map +1 -1
  223. package/dist/src/runtime/emit/join.js +5 -0
  224. package/dist/src/runtime/emit/join.js.map +1 -1
  225. package/dist/src/runtime/emit/materialized-view-helpers.d.ts +14 -1
  226. package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -1
  227. package/dist/src/runtime/emit/materialized-view-helpers.js +38 -7
  228. package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -1
  229. package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -1
  230. package/dist/src/runtime/emit/materialized-view.js +47 -6
  231. package/dist/src/runtime/emit/materialized-view.js.map +1 -1
  232. package/dist/src/runtime/emit/merge-join.d.ts.map +1 -1
  233. package/dist/src/runtime/emit/merge-join.js +18 -8
  234. package/dist/src/runtime/emit/merge-join.js.map +1 -1
  235. package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -1
  236. package/dist/src/runtime/emit/recursive-cte.js +59 -1
  237. package/dist/src/runtime/emit/recursive-cte.js.map +1 -1
  238. package/dist/src/runtime/emit/set-object-tags.d.ts +8 -0
  239. package/dist/src/runtime/emit/set-object-tags.d.ts.map +1 -1
  240. package/dist/src/runtime/emit/set-object-tags.js +8 -0
  241. package/dist/src/runtime/emit/set-object-tags.js.map +1 -1
  242. package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
  243. package/dist/src/runtime/emit/set-operation.js +7 -4
  244. package/dist/src/runtime/emit/set-operation.js.map +1 -1
  245. package/dist/src/runtime/emit/sort.d.ts.map +1 -1
  246. package/dist/src/runtime/emit/sort.js +5 -2
  247. package/dist/src/runtime/emit/sort.js.map +1 -1
  248. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  249. package/dist/src/runtime/emit/subquery.js +113 -13
  250. package/dist/src/runtime/emit/subquery.js.map +1 -1
  251. package/dist/src/runtime/emit/temporal-arithmetic.d.ts +7 -0
  252. package/dist/src/runtime/emit/temporal-arithmetic.d.ts.map +1 -1
  253. package/dist/src/runtime/emit/temporal-arithmetic.js +15 -7
  254. package/dist/src/runtime/emit/temporal-arithmetic.js.map +1 -1
  255. package/dist/src/runtime/emit/update.d.ts.map +1 -1
  256. package/dist/src/runtime/emit/update.js +44 -3
  257. package/dist/src/runtime/emit/update.js.map +1 -1
  258. package/dist/src/runtime/emit/window.d.ts.map +1 -1
  259. package/dist/src/runtime/emit/window.js +72 -55
  260. package/dist/src/runtime/emit/window.js.map +1 -1
  261. package/dist/src/runtime/foreign-key-actions.d.ts +36 -1
  262. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
  263. package/dist/src/runtime/foreign-key-actions.js +238 -116
  264. package/dist/src/runtime/foreign-key-actions.js.map +1 -1
  265. package/dist/src/runtime/parallel-driver.d.ts +20 -1
  266. package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
  267. package/dist/src/runtime/parallel-driver.js +23 -1
  268. package/dist/src/runtime/parallel-driver.js.map +1 -1
  269. package/dist/src/runtime/types.d.ts +54 -0
  270. package/dist/src/runtime/types.d.ts.map +1 -1
  271. package/dist/src/runtime/types.js.map +1 -1
  272. package/dist/src/schema/catalog-persistability.d.ts +58 -0
  273. package/dist/src/schema/catalog-persistability.d.ts.map +1 -0
  274. package/dist/src/schema/catalog-persistability.js +87 -0
  275. package/dist/src/schema/catalog-persistability.js.map +1 -0
  276. package/dist/src/schema/catalog.d.ts +17 -1
  277. package/dist/src/schema/catalog.d.ts.map +1 -1
  278. package/dist/src/schema/catalog.js +25 -3
  279. package/dist/src/schema/catalog.js.map +1 -1
  280. package/dist/src/schema/constraint-builder.d.ts +20 -22
  281. package/dist/src/schema/constraint-builder.d.ts.map +1 -1
  282. package/dist/src/schema/constraint-builder.js +43 -36
  283. package/dist/src/schema/constraint-builder.js.map +1 -1
  284. package/dist/src/schema/ddl-generator.d.ts +23 -0
  285. package/dist/src/schema/ddl-generator.d.ts.map +1 -1
  286. package/dist/src/schema/ddl-generator.js +27 -0
  287. package/dist/src/schema/ddl-generator.js.map +1 -1
  288. package/dist/src/schema/function.d.ts +109 -1
  289. package/dist/src/schema/function.d.ts.map +1 -1
  290. package/dist/src/schema/function.js.map +1 -1
  291. package/dist/src/schema/manager.d.ts +28 -0
  292. package/dist/src/schema/manager.d.ts.map +1 -1
  293. package/dist/src/schema/manager.js +82 -14
  294. package/dist/src/schema/manager.js.map +1 -1
  295. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  296. package/dist/src/schema/schema-differ.js +51 -12
  297. package/dist/src/schema/schema-differ.js.map +1 -1
  298. package/dist/src/schema/unique-enforcement.d.ts +31 -0
  299. package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
  300. package/dist/src/schema/unique-enforcement.js +37 -1
  301. package/dist/src/schema/unique-enforcement.js.map +1 -1
  302. package/dist/src/schema/window-function.d.ts +30 -10
  303. package/dist/src/schema/window-function.d.ts.map +1 -1
  304. package/dist/src/schema/window-function.js +20 -16
  305. package/dist/src/schema/window-function.js.map +1 -1
  306. package/dist/src/types/cast-semantics.d.ts +43 -0
  307. package/dist/src/types/cast-semantics.d.ts.map +1 -0
  308. package/dist/src/types/cast-semantics.js +59 -0
  309. package/dist/src/types/cast-semantics.js.map +1 -0
  310. package/dist/src/types/index.d.ts +1 -1
  311. package/dist/src/types/index.d.ts.map +1 -1
  312. package/dist/src/types/index.js +1 -1
  313. package/dist/src/types/index.js.map +1 -1
  314. package/dist/src/types/json-type.d.ts.map +1 -1
  315. package/dist/src/types/json-type.js +31 -10
  316. package/dist/src/types/json-type.js.map +1 -1
  317. package/dist/src/types/logical-type.d.ts +22 -0
  318. package/dist/src/types/logical-type.d.ts.map +1 -1
  319. package/dist/src/types/logical-type.js.map +1 -1
  320. package/dist/src/types/temporal-types.d.ts.map +1 -1
  321. package/dist/src/types/temporal-types.js +33 -11
  322. package/dist/src/types/temporal-types.js.map +1 -1
  323. package/dist/src/types/validation.d.ts +39 -1
  324. package/dist/src/types/validation.d.ts.map +1 -1
  325. package/dist/src/types/validation.js +60 -0
  326. package/dist/src/types/validation.js.map +1 -1
  327. package/dist/src/util/ast-spine-clone.d.ts +23 -0
  328. package/dist/src/util/ast-spine-clone.d.ts.map +1 -0
  329. package/dist/src/util/ast-spine-clone.js +41 -0
  330. package/dist/src/util/ast-spine-clone.js.map +1 -0
  331. package/dist/src/util/coercion.d.ts +13 -0
  332. package/dist/src/util/coercion.d.ts.map +1 -1
  333. package/dist/src/util/coercion.js +10 -1
  334. package/dist/src/util/coercion.js.map +1 -1
  335. package/dist/src/util/comparison.d.ts +89 -0
  336. package/dist/src/util/comparison.d.ts.map +1 -1
  337. package/dist/src/util/comparison.js +156 -27
  338. package/dist/src/util/comparison.js.map +1 -1
  339. package/dist/src/vtab/manifest.d.ts +7 -0
  340. package/dist/src/vtab/manifest.d.ts.map +1 -1
  341. package/dist/src/vtab/memory/connection.d.ts +14 -1
  342. package/dist/src/vtab/memory/connection.d.ts.map +1 -1
  343. package/dist/src/vtab/memory/connection.js +20 -2
  344. package/dist/src/vtab/memory/connection.js.map +1 -1
  345. package/dist/src/vtab/memory/layer/base.d.ts +6 -1
  346. package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
  347. package/dist/src/vtab/memory/layer/base.js +14 -5
  348. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  349. package/dist/src/vtab/memory/layer/connection.d.ts +17 -0
  350. package/dist/src/vtab/memory/layer/connection.d.ts.map +1 -1
  351. package/dist/src/vtab/memory/layer/connection.js +26 -0
  352. package/dist/src/vtab/memory/layer/connection.js.map +1 -1
  353. package/dist/src/vtab/memory/layer/manager.d.ts +96 -13
  354. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  355. package/dist/src/vtab/memory/layer/manager.js +595 -119
  356. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  357. package/dist/src/vtab/memory/layer/plan-filter.d.ts +41 -20
  358. package/dist/src/vtab/memory/layer/plan-filter.d.ts.map +1 -1
  359. package/dist/src/vtab/memory/layer/plan-filter.js +57 -27
  360. package/dist/src/vtab/memory/layer/plan-filter.js.map +1 -1
  361. package/dist/src/vtab/memory/layer/row-convert.d.ts +21 -0
  362. package/dist/src/vtab/memory/layer/row-convert.d.ts.map +1 -0
  363. package/dist/src/vtab/memory/layer/row-convert.js +30 -0
  364. package/dist/src/vtab/memory/layer/row-convert.js.map +1 -0
  365. package/dist/src/vtab/memory/layer/scan-layer.d.ts +6 -3
  366. package/dist/src/vtab/memory/layer/scan-layer.d.ts.map +1 -1
  367. package/dist/src/vtab/memory/layer/scan-layer.js +69 -36
  368. package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
  369. package/dist/src/vtab/memory/layer/transaction.d.ts +127 -13
  370. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  371. package/dist/src/vtab/memory/layer/transaction.js +214 -65
  372. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  373. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  374. package/dist/src/vtab/memory/module.js +9 -2
  375. package/dist/src/vtab/memory/module.js.map +1 -1
  376. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  377. package/dist/src/vtab/memory/table.js +3 -2
  378. package/dist/src/vtab/memory/table.js.map +1 -1
  379. package/dist/src/vtab/memory/types.d.ts +27 -1
  380. package/dist/src/vtab/memory/types.d.ts.map +1 -1
  381. package/dist/src/vtab/memory/types.js +16 -1
  382. package/dist/src/vtab/memory/types.js.map +1 -1
  383. package/dist/src/vtab/memory/utils/primary-key.d.ts +9 -0
  384. package/dist/src/vtab/memory/utils/primary-key.d.ts.map +1 -1
  385. package/dist/src/vtab/memory/utils/primary-key.js +11 -0
  386. package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
  387. package/dist/src/vtab/module.d.ts +63 -0
  388. package/dist/src/vtab/module.d.ts.map +1 -1
  389. package/dist/src/vtab/table.d.ts +24 -6
  390. package/dist/src/vtab/table.d.ts.map +1 -1
  391. package/dist/src/vtab/table.js.map +1 -1
  392. package/package.json +3 -3
  393. package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts +0 -19
  394. package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts.map +0 -1
  395. package/dist/src/planner/rules/cache/rule-in-subquery-cache.js +0 -53
  396. package/dist/src/planner/rules/cache/rule-in-subquery-cache.js.map +0 -1
@@ -8,7 +8,7 @@ import type { CollationResolver } from '../../../types/logical-type.js';
8
8
  /**
9
9
  * Pending change for event emission.
10
10
  */
11
- interface PendingChange {
11
+ export interface PendingChange {
12
12
  type: 'insert' | 'update' | 'delete';
13
13
  pk: BTreeKeyForPrimary;
14
14
  oldRow?: Row;
@@ -27,6 +27,25 @@ export interface OwnWrite {
27
27
  /** New row for an upsert; absent for a delete. */
28
28
  newRow?: Row;
29
29
  }
30
+ /**
31
+ * One layer's net own-writes at the post-ADD/DROP-COLUMN arity, computed fallibly by
32
+ * {@link TransactionLayer.prepareReshapedColumns} and installed infallibly by
33
+ * {@link TransactionLayer.installReshapedColumns} — see those methods for why the
34
+ * two phases are split.
35
+ */
36
+ export interface PreparedColumnReshape {
37
+ /** Keys this layer's net effect deletes. Key values are invariant under a column-set change. */
38
+ survivingDeletions: BTreeKeyForPrimary[];
39
+ /** This layer's net effective rows, rewritten to the new column set. */
40
+ upserts: Row[];
41
+ /**
42
+ * The layer's {@link PendingChange} event log with every row image rewritten to the
43
+ * new column set, or null when change tracking is disabled. Unlike the own-write
44
+ * collapse above, the log is NOT deduplicated — every recorded write stays a
45
+ * separate event, because that is the delivered contract.
46
+ */
47
+ reshapedPendingChanges: PendingChange[] | null;
48
+ }
30
49
  /**
31
50
  * Represents a set of modifications (inserts, updates, deletes) applied
32
51
  * on top of a parent Layer using inherited BTrees with copy-on-write semantics.
@@ -46,8 +65,10 @@ export declare class TransactionLayer implements Layer {
46
65
  * Schema when this layer was started. Replaced when DDL runs inside this layer's own
47
66
  * transaction: by {@link adoptSchema} for additive index/constraint DDL, a secondary-index
48
67
  * re-key from `alter column … set collate`, and index/constraint removal (`drop index` /
49
- * `drop constraint`), and by {@link rekeyPrimaryKey} when that collate change lands on a
50
- * primary-key column. The column set is identical across every such swap.
68
+ * `drop constraint`); by {@link rekeyPrimaryKey} when that collate change lands on a
69
+ * primary-key column; and by {@link installReshapedColumns} when `add column` / `drop
70
+ * column` changes the column set itself. Every swap except the last keeps the column set
71
+ * identical.
51
72
  */
52
73
  private tableSchemaAtCreation;
53
74
  /**
@@ -78,12 +99,17 @@ export declare class TransactionLayer implements Layer {
78
99
  * `IndexSchema` (so an index scan raises "Secondary index not found") nor the derived
79
100
  * `uniqueConstraints` entry (so `checkUniqueConstraints` silently skips it and a
80
101
  * colliding insert is accepted).
81
- * - **Re-keying** (`alter column … set collate`): an index whose `IndexSchema` object
82
- * is no longer the one this layer holds is REPLACED. `BaseLayer.rebuildAllSecondaryIndexes`
83
- * hands every index a fresh BTree under the new collation, so a layer that kept its old
84
- * `MemoryIndex` would go on comparing under the old collation over an orphaned tree —
85
- * and, once it becomes the committed head at commit, would shadow the base's rebuilt
86
- * structures entirely.
102
+ * - **Re-keying** (`alter column … set collate`, or an `alter column … set data type` that
103
+ * keeps the physical storage class but moves to a differently-ordering logical type —
104
+ * text timespan, where 'PT1H' and 'PT60M' are one value): an index whose `IndexSchema`
105
+ * object is no longer the one this layer holds is REPLACED.
106
+ * `BaseLayer.rebuildAllSecondaryIndexes` hands every index a fresh BTree under the new
107
+ * comparator, so a layer that kept its old `MemoryIndex` would go on comparing the old way
108
+ * over an orphaned tree — and, once it becomes the committed head at commit, would shadow
109
+ * the base's rebuilt structures entirely. The retype has no index-column field to change
110
+ * (an index column carries no logical type; it reads the column's), so
111
+ * `MemoryTableManager.alterColumn` rebuilds the `IndexSchema` objects purely to raise this
112
+ * signal — see its `structuresRekeyed` branch.
87
113
  * - **Removal** (`drop index` / `drop constraint`): an index whose name the new schema no
88
114
  * longer declares is DROPPED from {@link secondaryIndexes}. Without it the layer keeps the
89
115
  * derived `uniqueConstraints` entry in its frozen schema and goes on enforcing a constraint
@@ -104,8 +130,10 @@ export declare class TransactionLayer implements Layer {
104
130
  *
105
131
  * Never applied to a column-set or primary-key change: either would invalidate
106
132
  * {@link pkFunctions} and the primary tree. A PK-column collation change goes to
107
- * {@link rekeyPrimaryKey} instead, and `ensureSchemaChangeSafety` raises BUSY when any
108
- * connection other than the DDL issuer holds a pending layer.
133
+ * {@link rekeyPrimaryKey} instead, a column-set change (`add column` / `drop column`) to
134
+ * {@link prepareReshapedColumns} / {@link installReshapedColumns}, and
135
+ * `ensureSchemaChangeSafety` raises BUSY when any connection other than the DDL issuer
136
+ * holds a pending layer.
109
137
  */
110
138
  adoptSchema(newSchema: TableSchema): void;
111
139
  /**
@@ -145,6 +173,31 @@ export declare class TransactionLayer implements Layer {
145
173
  * is the row it removed.
146
174
  */
147
175
  rekeyPrimaryKey(newSchema: TableSchema): void;
176
+ /**
177
+ * A fresh primary tree inheriting copy-on-write from the parent's CURRENT one, keyed by this
178
+ * layer's current {@link pkFunctions}. Callers must have installed the post-DDL `pkFunctions`
179
+ * first, and the parent must already carry the DDL (every whole-layer rebuild runs oldest-first).
180
+ */
181
+ private newPrimaryTreeOverParent;
182
+ /**
183
+ * Shared tail of the three whole-layer rebuilds — {@link rekeyPrimaryKey},
184
+ * {@link convertColumn}, {@link installReshapedColumns}. Each has already swapped in its new
185
+ * schema (and, where the key changed, its new {@link pkFunctions}) and collapsed
186
+ * {@link ownWrites} to the net per-key effect passed here; this replays that effect into a
187
+ * tree built over the parent's fresh one, installs it, rewrites the own-write log to match,
188
+ * and rebuilds every secondary index.
189
+ *
190
+ * Every index is rebuilt unconditionally, not only those over an altered column: each inherits
191
+ * the parent's freshly-rebuilt tree, and each index's key encoding and PK bookkeeping derive
192
+ * from `pkFunctions`.
193
+ *
194
+ * A deletion an upsert has since re-occupied is dropped from the log — keeping it would make
195
+ * the log claim both a deletion and an upsert of the same key. Only {@link rekeyPrimaryKey}
196
+ * can produce that collision (two old keys collapsing under the new comparator); where key
197
+ * values are invariant a key is classified as either a deletion or an upsert, never both, so
198
+ * the filter is a no-op.
199
+ */
200
+ private installNetOwnWrites;
148
201
  /**
149
202
  * Adopts an `alter column … set data type` / `set not null` backfill conversion applied while
150
203
  * THIS layer's transaction is still open: swaps in the new schema and rewrites the CONVERTED value
@@ -154,11 +207,16 @@ export declare class TransactionLayer implements Layer {
154
207
  * layer, not the base.
155
208
  *
156
209
  * NON-primary-key column, or a key column whose bytes are unchanged. `MemoryTableManager.alterColumn`
157
- * rejects a physical retype of a key column before any mutation, and SET NOT NULL leaves the key
210
+ * rejects any retype of a key column before any mutation, and SET NOT NULL leaves the key
158
211
  * bytes intact, so the primary key encoding is unchanged: {@link pkFunctions} and the primary tree
159
212
  * keep their keys, and only the value at `colIndex` moves. (Contrast {@link rekeyPrimaryKey}, which
160
213
  * must rebuild the tree because the keys themselves change.)
161
214
  *
215
+ * Subsumes {@link adoptSchema} for a same-storage-class retype that ALSO moves the comparator
216
+ * (text → date/timespan): `tableSchemaAtCreation` is swapped to `newSchema` and every secondary
217
+ * index is rebuilt from scratch against it below, so the layer's structures pick up the new
218
+ * comparators along with the converted values.
219
+ *
162
220
  * Like {@link adoptSchema} / {@link rekeyPrimaryKey}, the caller MUST apply this oldest-first
163
221
  * (base already converted): the layer's copy-on-write base inherits the parent's already-converted
164
222
  * rows, so only this layer's OWN writes are rewritten here.
@@ -175,6 +233,53 @@ export declare class TransactionLayer implements Layer {
175
233
  * double-fault a value the transaction cannot see. It matches the base rewrite's same-reasoned skip.
176
234
  */
177
235
  convertColumn(colIndex: number, convert: (v: SqlValue) => SqlValue, newSchema: TableSchema, convertNulls?: boolean): void;
236
+ /**
237
+ * Computes — without mutating anything — what {@link installReshapedColumns} will install
238
+ * for an `alter table … add column` / `drop column` applied while THIS layer's transaction
239
+ * is still open: the net per-key effect of the layer's own writes, with each surviving row
240
+ * run through `reshapeRow` to the new column set.
241
+ *
242
+ * Split from the install (unlike {@link convertColumn}, which mutates in one pass) because
243
+ * this rewrite can FAIL: an ADD COLUMN with a per-row `default (new.<col>)` expression
244
+ * evaluates that expression against each pending row, and it can throw — or produce NULL
245
+ * for a NOT NULL column — on a pending row even when every committed row backfilled cleanly.
246
+ * The rewrite is async for the same reason (`convertColumn`'s value map is a pure function;
247
+ * a backfill evaluator is engine-supplied and may await). `MemoryTableManager` therefore runs
248
+ * every prepare — one per open layer — BEFORE the first mutation anywhere (base included), so
249
+ * a failure rejects the whole ALTER with every structure untouched; there is no undo for a
250
+ * half-reshaped layer chain.
251
+ *
252
+ * Own writes collapse to one entry per key exactly as {@link convertColumn}'s pass does: a
253
+ * column-set change leaves every primary key VALUE untouched (ADD introduces a column no key
254
+ * reads — even when it is inserted ahead of one, which only renumbers the key's *indices*;
255
+ * dropping a PK column is rejected upstream), so a key is either finally-deleted or
256
+ * finally-upserted, never both, and no key can collapse onto another.
257
+ */
258
+ prepareReshapedColumns(reshapeRow: (row: Row) => Row | Promise<Row>, reshapeEventRow: (row: Row) => Row | Promise<Row>): Promise<PreparedColumnReshape>;
259
+ /**
260
+ * Adopts an `alter table … add column` / `drop column` applied while THIS layer's
261
+ * transaction is still open, installing what {@link prepareReshapedColumns} computed:
262
+ * swaps in the new schema, rebuilds the primary tree over the parent's already-reshaped
263
+ * one, replays the layer's net own-writes at the new arity, and rebuilds every secondary
264
+ * index. Synchronous and mutation-only — everything fallible ran in the prepare phase.
265
+ *
266
+ * {@link pkFunctions} is REBUILT (unlike {@link convertColumn}, which keeps it): a column-set
267
+ * change can shift the primary key's column *indices* — DROP COLUMN renumbers
268
+ * `primaryKeyDefinition` past the dropped slot, and an ADD COLUMN placed AHEAD of a key
269
+ * column (`insertAtIndex`, module-API only) renumbers it past the inserted slot — so the row
270
+ * extractor changes even though the key *values* do not. Because the values are invariant
271
+ * under both ADD (the new column is not part of any key, wherever it lands) and DROP
272
+ * (dropping a PK column is rejected upstream), tree ordering is preserved and the
273
+ * `primaryKey` values recorded in {@link ownWrites} stay valid — no re-key of the kind
274
+ * {@link rekeyPrimaryKey} performs is needed, and the prepared deletions apply verbatim.
275
+ *
276
+ * Like every other open-layer adoption, the caller MUST apply this to the whole parent
277
+ * chain oldest-first (base already reshaped): the rebuilt tree inherits copy-on-write from
278
+ * the parent's NEW tree, so the parent's must already hold rows at the new arity. The
279
+ * rewritten {@link ownWrites} log — carrying reshaped rows — is what the commit-time rebase
280
+ * and any later `create index` ({@link reindexOwnWrites}) replay.
281
+ */
282
+ installReshapedColumns(newSchema: TableSchema, prepared: PreparedColumnReshape): void;
178
283
  /**
179
284
  * Brings a newly-inherited `MemoryIndex` (built over the parent's tree, which
180
285
  * already covers the parent chain's effective rows) up to date with this layer's own
@@ -208,6 +313,16 @@ export declare class TransactionLayer implements Layer {
208
313
  * Get pending changes for event emission.
209
314
  */
210
315
  getPendingChanges(): readonly PendingChange[];
316
+ /**
317
+ * Drops the pending-change event log (tracking stays enabled). Called when this
318
+ * layer's content is drained into the base by ALTER's consolidation
319
+ * (`MemoryTableManager.consolidateToBaseLayer`): its events were already delivered
320
+ * when the layer originally committed, but the layer can remain in the DDL
321
+ * connection's open-transaction parent chain — and once the base becomes the
322
+ * committed head, the commit-time collection (`collectPendingChanges`) walks that
323
+ * chain all the way down to the base and would re-deliver them.
324
+ */
325
+ clearPendingChanges(): void;
211
326
  /** This layer's own structural writes, oldest-first — the rebase replay source. */
212
327
  getOwnWrites(): readonly OwnWrite[];
213
328
  getPkExtractorsAndComparators(schema: TableSchema): PkExtractorsAndComparators;
@@ -225,5 +340,4 @@ export declare class TransactionLayer implements Layer {
225
340
  */
226
341
  clearBase(): void;
227
342
  }
228
- export {};
229
343
  //# sourceMappingURL=transaction.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../../../../src/vtab/memory/layer/transaction.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../../../../src/vtab/memory/layer/transaction.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import { createLogger } from '../../../common/logger.js';
4
4
  import { createPrimaryKeyFunctions } from '../utils/primary-key.js';
5
5
  import { QuereusError } from '../../../common/errors.js';
6
6
  import { StatusCode } from '../../../common/types.js';
7
+ import { convertRowAtIndex } from './row-convert.js';
7
8
  const log = createLogger('vtab:memory:layer:transaction');
8
9
  const warnLog = log.extend('warn');
9
10
  let transactionLayerCounter = 1000;
@@ -26,8 +27,10 @@ export class TransactionLayer {
26
27
  * Schema when this layer was started. Replaced when DDL runs inside this layer's own
27
28
  * transaction: by {@link adoptSchema} for additive index/constraint DDL, a secondary-index
28
29
  * re-key from `alter column … set collate`, and index/constraint removal (`drop index` /
29
- * `drop constraint`), and by {@link rekeyPrimaryKey} when that collate change lands on a
30
- * primary-key column. The column set is identical across every such swap.
30
+ * `drop constraint`); by {@link rekeyPrimaryKey} when that collate change lands on a
31
+ * primary-key column; and by {@link installReshapedColumns} when `add column` / `drop
32
+ * column` changes the column set itself. Every swap except the last keeps the column set
33
+ * identical.
31
34
  */
32
35
  tableSchemaAtCreation;
33
36
  /**
@@ -104,12 +107,17 @@ export class TransactionLayer {
104
107
  * `IndexSchema` (so an index scan raises "Secondary index not found") nor the derived
105
108
  * `uniqueConstraints` entry (so `checkUniqueConstraints` silently skips it and a
106
109
  * colliding insert is accepted).
107
- * - **Re-keying** (`alter column … set collate`): an index whose `IndexSchema` object
108
- * is no longer the one this layer holds is REPLACED. `BaseLayer.rebuildAllSecondaryIndexes`
109
- * hands every index a fresh BTree under the new collation, so a layer that kept its old
110
- * `MemoryIndex` would go on comparing under the old collation over an orphaned tree —
111
- * and, once it becomes the committed head at commit, would shadow the base's rebuilt
112
- * structures entirely.
110
+ * - **Re-keying** (`alter column … set collate`, or an `alter column … set data type` that
111
+ * keeps the physical storage class but moves to a differently-ordering logical type —
112
+ * text timespan, where 'PT1H' and 'PT60M' are one value): an index whose `IndexSchema`
113
+ * object is no longer the one this layer holds is REPLACED.
114
+ * `BaseLayer.rebuildAllSecondaryIndexes` hands every index a fresh BTree under the new
115
+ * comparator, so a layer that kept its old `MemoryIndex` would go on comparing the old way
116
+ * over an orphaned tree — and, once it becomes the committed head at commit, would shadow
117
+ * the base's rebuilt structures entirely. The retype has no index-column field to change
118
+ * (an index column carries no logical type; it reads the column's), so
119
+ * `MemoryTableManager.alterColumn` rebuilds the `IndexSchema` objects purely to raise this
120
+ * signal — see its `structuresRekeyed` branch.
113
121
  * - **Removal** (`drop index` / `drop constraint`): an index whose name the new schema no
114
122
  * longer declares is DROPPED from {@link secondaryIndexes}. Without it the layer keeps the
115
123
  * derived `uniqueConstraints` entry in its frozen schema and goes on enforcing a constraint
@@ -130,8 +138,10 @@ export class TransactionLayer {
130
138
  *
131
139
  * Never applied to a column-set or primary-key change: either would invalidate
132
140
  * {@link pkFunctions} and the primary tree. A PK-column collation change goes to
133
- * {@link rekeyPrimaryKey} instead, and `ensureSchemaChangeSafety` raises BUSY when any
134
- * connection other than the DDL issuer holds a pending layer.
141
+ * {@link rekeyPrimaryKey} instead, a column-set change (`add column` / `drop column`) to
142
+ * {@link prepareReshapedColumns} / {@link installReshapedColumns}, and
143
+ * `ensureSchemaChangeSafety` raises BUSY when any connection other than the DDL issuer
144
+ * holds a pending layer.
135
145
  */
136
146
  adoptSchema(newSchema) {
137
147
  const oldSchema = this.tableSchemaAtCreation;
@@ -194,13 +204,14 @@ export class TransactionLayer {
194
204
  * is the row it removed.
195
205
  */
196
206
  rekeyPrimaryKey(newSchema) {
207
+ // The pending-change EVENT log is deliberately NOT rewritten here: a collation
208
+ // change moves only the comparator — every stored value and every key value is
209
+ // untouched — so the recorded `pk`/`oldRow`/`newRow` images stay accurate as-is.
210
+ // (Contrast convertColumn / installReshapedColumns, which do rewrite the log.)
197
211
  const preRekeyTree = this.primaryModifications;
198
212
  const preRekeyEncode = this.pkFunctions.encode;
199
213
  this.tableSchemaAtCreation = newSchema;
200
214
  this.pkFunctions = createPrimaryKeyFunctions(newSchema, this.collationResolver);
201
- const { extractFromRow, compare } = this.pkFunctions;
202
- const parentPrimaryTree = this.parentLayer.getModificationTree('primary');
203
- const rekeyed = new BTree((value) => extractFromRow(value), compare, { base: parentPrimaryTree || undefined });
204
215
  // Net per-key effect of this layer's own writes, read out of the pre-rekey tree
205
216
  // (`get` traverses the inheritance chain, so it yields the layer's EFFECTIVE row).
206
217
  const deletions = [];
@@ -217,29 +228,55 @@ export class TransactionLayer {
217
228
  else
218
229
  upserts.push(effectiveRow);
219
230
  }
231
+ this.installNetOwnWrites(deletions, upserts);
232
+ }
233
+ /**
234
+ * A fresh primary tree inheriting copy-on-write from the parent's CURRENT one, keyed by this
235
+ * layer's current {@link pkFunctions}. Callers must have installed the post-DDL `pkFunctions`
236
+ * first, and the parent must already carry the DDL (every whole-layer rebuild runs oldest-first).
237
+ */
238
+ newPrimaryTreeOverParent() {
239
+ const { extractFromRow, compare } = this.pkFunctions;
240
+ return new BTree((value) => extractFromRow(value), compare, { base: this.parentLayer.getModificationTree('primary') || undefined });
241
+ }
242
+ /**
243
+ * Shared tail of the three whole-layer rebuilds — {@link rekeyPrimaryKey},
244
+ * {@link convertColumn}, {@link installReshapedColumns}. Each has already swapped in its new
245
+ * schema (and, where the key changed, its new {@link pkFunctions}) and collapsed
246
+ * {@link ownWrites} to the net per-key effect passed here; this replays that effect into a
247
+ * tree built over the parent's fresh one, installs it, rewrites the own-write log to match,
248
+ * and rebuilds every secondary index.
249
+ *
250
+ * Every index is rebuilt unconditionally, not only those over an altered column: each inherits
251
+ * the parent's freshly-rebuilt tree, and each index's key encoding and PK bookkeeping derive
252
+ * from `pkFunctions`.
253
+ *
254
+ * A deletion an upsert has since re-occupied is dropped from the log — keeping it would make
255
+ * the log claim both a deletion and an upsert of the same key. Only {@link rekeyPrimaryKey}
256
+ * can produce that collision (two old keys collapsing under the new comparator); where key
257
+ * values are invariant a key is classified as either a deletion or an upsert, never both, so
258
+ * the filter is a no-op.
259
+ */
260
+ installNetOwnWrites(deletions, upserts) {
261
+ const rebuilt = this.newPrimaryTreeOverParent();
220
262
  for (const primaryKey of deletions) {
221
- const path = rekeyed.find(primaryKey);
263
+ const path = rebuilt.find(primaryKey);
222
264
  if (path.on)
223
- rekeyed.deleteAt(path);
265
+ rebuilt.deleteAt(path);
224
266
  }
225
267
  for (const row of upserts) {
226
- rekeyed.upsert(row);
268
+ rebuilt.upsert(row);
227
269
  }
228
- this.primaryModifications = rekeyed;
229
- // A deleted key an upsert has since re-occupied (`update t set v='A' where v='a'` under
230
- // NOCASE) is no longer a deletion of anything: keeping it would make the log claim both
231
- // a deletion and an upsert of the same key.
232
- const survivingDeletions = deletions.filter(primaryKey => rekeyed.get(primaryKey) === undefined);
270
+ this.primaryModifications = rebuilt;
271
+ const { extractFromRow } = this.pkFunctions;
233
272
  this.ownWrites.length = 0;
234
- for (const primaryKey of survivingDeletions) {
235
- this.ownWrites.push({ type: 'delete', primaryKey });
273
+ for (const primaryKey of deletions) {
274
+ if (rebuilt.get(primaryKey) === undefined)
275
+ this.ownWrites.push({ type: 'delete', primaryKey });
236
276
  }
237
277
  for (const row of upserts) {
238
278
  this.ownWrites.push({ type: 'upsert', primaryKey: extractFromRow(row), newRow: row });
239
279
  }
240
- // Every secondary index's key encoding and PK bookkeeping derive from `pkFunctions`,
241
- // and each inherits the parent's freshly-rebuilt tree — so all of them are rebuilt,
242
- // including ones the altered column does not appear in.
243
280
  this.secondaryIndexes = new Map();
244
281
  this.initializeSecondaryIndexes();
245
282
  for (const index of this.secondaryIndexes.values()) {
@@ -255,11 +292,16 @@ export class TransactionLayer {
255
292
  * layer, not the base.
256
293
  *
257
294
  * NON-primary-key column, or a key column whose bytes are unchanged. `MemoryTableManager.alterColumn`
258
- * rejects a physical retype of a key column before any mutation, and SET NOT NULL leaves the key
295
+ * rejects any retype of a key column before any mutation, and SET NOT NULL leaves the key
259
296
  * bytes intact, so the primary key encoding is unchanged: {@link pkFunctions} and the primary tree
260
297
  * keep their keys, and only the value at `colIndex` moves. (Contrast {@link rekeyPrimaryKey}, which
261
298
  * must rebuild the tree because the keys themselves change.)
262
299
  *
300
+ * Subsumes {@link adoptSchema} for a same-storage-class retype that ALSO moves the comparator
301
+ * (text → date/timespan): `tableSchemaAtCreation` is swapped to `newSchema` and every secondary
302
+ * index is rebuilt from scratch against it below, so the layer's structures pick up the new
303
+ * comparators along with the converted values.
304
+ *
263
305
  * Like {@link adoptSchema} / {@link rekeyPrimaryKey}, the caller MUST apply this oldest-first
264
306
  * (base already converted): the layer's copy-on-write base inherits the parent's already-converted
265
307
  * rows, so only this layer's OWN writes are rewritten here.
@@ -280,15 +322,12 @@ export class TransactionLayer {
280
322
  this.tableSchemaAtCreation = newSchema;
281
323
  // The parent's primary tree has been REPLACED by the conversion (base rebuilt from fresh
282
324
  // rows, or a parent layer already converted oldest-first), so this layer's own tree — which
283
- // derived from the OLD one — must be rebuilt over the parent's NEW tree, exactly as
284
- // rekeyPrimaryKey does. The PK is unchanged (a key-column retype is rejected upstream), so
285
- // pkFunctions and the keys stay; only the value at colIndex moves.
286
- const { extractFromRow, compare } = this.pkFunctions;
287
- const parentPrimaryTree = this.parentLayer.getModificationTree('primary');
288
- const rebuilt = new BTree((value) => extractFromRow(value), compare, { base: parentPrimaryTree || undefined });
289
- // Net per-key effect of this layer's own writes, read out of the pre-conversion tree. The PK
290
- // is unchanged, so a key is either finally-deleted or finally-upserted, never both — no key
291
- // can collapse onto another (unlike rekeyPrimaryKey).
325
+ // derived from the OLD one — must be rebuilt over the parent's NEW tree; installNetOwnWrites
326
+ // below does that. The PK is unchanged (a key-column retype is rejected upstream), so
327
+ // pkFunctions and the keys stay; only the value at colIndex moves — which also means a key
328
+ // is either finally-deleted or finally-upserted, never both, and no key can collapse onto
329
+ // another (unlike rekeyPrimaryKey). The net per-key effect is read out of the
330
+ // pre-conversion tree.
292
331
  const seen = new Set();
293
332
  const survivingDeletions = [];
294
333
  const upserts = [];
@@ -304,42 +343,139 @@ export class TransactionLayer {
304
343
  survivingDeletions.push(write.primaryKey);
305
344
  continue;
306
345
  }
307
- const oldVal = effectiveRow[colIndex];
308
346
  let newRow = effectiveRow;
309
- if (oldVal !== null || convertNulls) {
310
- try {
311
- const newVal = convert(oldVal);
312
- newRow = effectiveRow.map((v, i) => i === colIndex ? newVal : v);
313
- }
314
- catch {
315
- // Shadowed unconvertible own value — leave as-is (see method doc).
316
- }
347
+ try {
348
+ newRow = convertRowAtIndex(effectiveRow, colIndex, convert, convertNulls);
349
+ }
350
+ catch {
351
+ // Shadowed unconvertible own value — leave as-is (see method doc).
317
352
  }
318
353
  upserts.push(newRow);
319
354
  }
320
- for (const primaryKey of survivingDeletions) {
321
- const path = rebuilt.find(primaryKey);
322
- if (path.on)
323
- rebuilt.deleteAt(path);
324
- }
325
- for (const row of upserts) {
326
- rebuilt.upsert(row);
355
+ this.installNetOwnWrites(survivingDeletions, upserts);
356
+ // Rewrite the pending-change EVENT log's images too, so the events emitted at this
357
+ // table's commit carry the post-conversion values the committed rows hold. Best-effort,
358
+ // per image: the log holds historical images (including superseded intermediate ones the
359
+ // net rewrite above never touches), so an unconvertible value keeps its raw form rather
360
+ // than failing the ALTER. One entry per recorded write is kept — no dedup, unlike the
361
+ // own-write collapse — because every recorded write is a separately delivered event.
362
+ if (this.pendingChanges) {
363
+ this.pendingChanges = this.pendingChanges.map(change => {
364
+ const remapImage = (row) => {
365
+ if (!row)
366
+ return row;
367
+ try {
368
+ return convertRowAtIndex(row, colIndex, convert, convertNulls);
369
+ }
370
+ catch {
371
+ return row;
372
+ }
373
+ };
374
+ return { ...change, oldRow: remapImage(change.oldRow), newRow: remapImage(change.newRow) };
375
+ });
327
376
  }
328
- this.primaryModifications = rebuilt;
329
- this.ownWrites.length = 0;
330
- for (const primaryKey of survivingDeletions) {
331
- this.ownWrites.push({ type: 'delete', primaryKey });
377
+ }
378
+ /**
379
+ * Computes without mutating anything — what {@link installReshapedColumns} will install
380
+ * for an `alter table … add column` / `drop column` applied while THIS layer's transaction
381
+ * is still open: the net per-key effect of the layer's own writes, with each surviving row
382
+ * run through `reshapeRow` to the new column set.
383
+ *
384
+ * Split from the install (unlike {@link convertColumn}, which mutates in one pass) because
385
+ * this rewrite can FAIL: an ADD COLUMN with a per-row `default (new.<col>)` expression
386
+ * evaluates that expression against each pending row, and it can throw — or produce NULL
387
+ * for a NOT NULL column — on a pending row even when every committed row backfilled cleanly.
388
+ * The rewrite is async for the same reason (`convertColumn`'s value map is a pure function;
389
+ * a backfill evaluator is engine-supplied and may await). `MemoryTableManager` therefore runs
390
+ * every prepare — one per open layer — BEFORE the first mutation anywhere (base included), so
391
+ * a failure rejects the whole ALTER with every structure untouched; there is no undo for a
392
+ * half-reshaped layer chain.
393
+ *
394
+ * Own writes collapse to one entry per key exactly as {@link convertColumn}'s pass does: a
395
+ * column-set change leaves every primary key VALUE untouched (ADD introduces a column no key
396
+ * reads — even when it is inserted ahead of one, which only renumbers the key's *indices*;
397
+ * dropping a PK column is rejected upstream), so a key is either finally-deleted or
398
+ * finally-upserted, never both, and no key can collapse onto another.
399
+ */
400
+ async prepareReshapedColumns(reshapeRow, reshapeEventRow) {
401
+ const seen = new Set();
402
+ const survivingDeletions = [];
403
+ const upserts = [];
404
+ for (const write of this.ownWrites) {
405
+ const encoded = this.pkFunctions.encode(write.primaryKey);
406
+ if (seen.has(encoded))
407
+ continue;
408
+ seen.add(encoded);
409
+ // `get` traverses the inheritance chain, so this is the layer's EFFECTIVE row:
410
+ // undefined when the layer deleted the key, the layer's own row otherwise.
411
+ const effectiveRow = this.primaryModifications.get(write.primaryKey);
412
+ if (effectiveRow === undefined) {
413
+ survivingDeletions.push(write.primaryKey);
414
+ continue;
415
+ }
416
+ upserts.push(await reshapeRow(effectiveRow));
332
417
  }
333
- for (const row of upserts) {
334
- this.ownWrites.push({ type: 'upsert', primaryKey: extractFromRow(row), newRow: row });
418
+ // Reshape the pending-change EVENT log alongside — through `reshapeEventRow`, the
419
+ // BEST-EFFORT variant of `reshapeRow`, deliberately the opposite posture: `reshapeRow`
420
+ // rewrites the layer's net effective rows and its failure MUST reject the ALTER, while
421
+ // the log holds historical images (including superseded intermediate ones the net
422
+ // rewrite never touches) that a backfill evaluator can legitimately fail on. The
423
+ // caller supplies a `reshapeEventRow` that falls back rather than throws (ADD COLUMN
424
+ // fills NULL when the evaluator fails); a throw that still escapes leaves that image
425
+ // at the old arity (logged) and never rejects the ALTER. One entry per recorded write
426
+ // is kept — no dedup, unlike the own-write collapse above — because every recorded
427
+ // write is a separately delivered event.
428
+ let reshapedPendingChanges = null;
429
+ if (this.pendingChanges) {
430
+ reshapedPendingChanges = [];
431
+ for (const change of this.pendingChanges) {
432
+ const next = { ...change };
433
+ try {
434
+ if (change.oldRow)
435
+ next.oldRow = await reshapeEventRow(change.oldRow);
436
+ if (change.newRow)
437
+ next.newRow = await reshapeEventRow(change.newRow);
438
+ }
439
+ catch (e) {
440
+ warnLog('Pending-change reshape failed on %s; leaving image at the old arity: %O', this.tableSchemaAtCreation.name, e);
441
+ }
442
+ reshapedPendingChanges.push(next);
443
+ }
335
444
  }
336
- // Any secondary index on the column holds keys extracted from the OLD value. Rebuild every
337
- // index over the parent's freshly-converted trees (matching the base's unconditional rebuild),
338
- // then re-file this layer's own converted writes.
339
- this.secondaryIndexes = new Map();
340
- this.initializeSecondaryIndexes();
341
- for (const index of this.secondaryIndexes.values()) {
342
- this.reindexOwnWrites(index);
445
+ return { survivingDeletions, upserts, reshapedPendingChanges };
446
+ }
447
+ /**
448
+ * Adopts an `alter table … add column` / `drop column` applied while THIS layer's
449
+ * transaction is still open, installing what {@link prepareReshapedColumns} computed:
450
+ * swaps in the new schema, rebuilds the primary tree over the parent's already-reshaped
451
+ * one, replays the layer's net own-writes at the new arity, and rebuilds every secondary
452
+ * index. Synchronous and mutation-only — everything fallible ran in the prepare phase.
453
+ *
454
+ * {@link pkFunctions} is REBUILT (unlike {@link convertColumn}, which keeps it): a column-set
455
+ * change can shift the primary key's column *indices* — DROP COLUMN renumbers
456
+ * `primaryKeyDefinition` past the dropped slot, and an ADD COLUMN placed AHEAD of a key
457
+ * column (`insertAtIndex`, module-API only) renumbers it past the inserted slot — so the row
458
+ * extractor changes even though the key *values* do not. Because the values are invariant
459
+ * under both ADD (the new column is not part of any key, wherever it lands) and DROP
460
+ * (dropping a PK column is rejected upstream), tree ordering is preserved and the
461
+ * `primaryKey` values recorded in {@link ownWrites} stay valid — no re-key of the kind
462
+ * {@link rekeyPrimaryKey} performs is needed, and the prepared deletions apply verbatim.
463
+ *
464
+ * Like every other open-layer adoption, the caller MUST apply this to the whole parent
465
+ * chain oldest-first (base already reshaped): the rebuilt tree inherits copy-on-write from
466
+ * the parent's NEW tree, so the parent's must already hold rows at the new arity. The
467
+ * rewritten {@link ownWrites} log — carrying reshaped rows — is what the commit-time rebase
468
+ * and any later `create index` ({@link reindexOwnWrites}) replay.
469
+ */
470
+ installReshapedColumns(newSchema, prepared) {
471
+ this.tableSchemaAtCreation = newSchema;
472
+ this.pkFunctions = createPrimaryKeyFunctions(newSchema, this.collationResolver);
473
+ this.installNetOwnWrites(prepared.survivingDeletions, prepared.upserts);
474
+ // Install the reshaped event log the prepare phase computed (null ⇔ tracking
475
+ // disabled), so the events emitted at this table's commit describe rows in the
476
+ // post-ALTER column set.
477
+ if (prepared.reshapedPendingChanges !== null) {
478
+ this.pendingChanges = prepared.reshapedPendingChanges;
343
479
  }
344
480
  }
345
481
  /**
@@ -414,6 +550,19 @@ export class TransactionLayer {
414
550
  getPendingChanges() {
415
551
  return this.pendingChanges ?? [];
416
552
  }
553
+ /**
554
+ * Drops the pending-change event log (tracking stays enabled). Called when this
555
+ * layer's content is drained into the base by ALTER's consolidation
556
+ * (`MemoryTableManager.consolidateToBaseLayer`): its events were already delivered
557
+ * when the layer originally committed, but the layer can remain in the DDL
558
+ * connection's open-transaction parent chain — and once the base becomes the
559
+ * committed head, the commit-time collection (`collectPendingChanges`) walks that
560
+ * chain all the way down to the base and would re-deliver them.
561
+ */
562
+ clearPendingChanges() {
563
+ if (this.pendingChanges)
564
+ this.pendingChanges = [];
565
+ }
417
566
  /** This layer's own structural writes, oldest-first — the rebase replay source. */
418
567
  getOwnWrites() {
419
568
  return this.ownWrites;