@quereus/quereus 4.3.1 → 4.4.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 (788) hide show
  1. package/README.md +25 -7
  2. package/dist/src/common/types.d.ts +9 -59
  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-assertions.d.ts +2 -2
  6. package/dist/src/core/database-assertions.d.ts.map +1 -1
  7. package/dist/src/core/database-assertions.js +4 -3
  8. package/dist/src/core/database-assertions.js.map +1 -1
  9. package/dist/src/core/database-external-changes.d.ts +3 -3
  10. package/dist/src/core/database-external-changes.d.ts.map +1 -1
  11. package/dist/src/core/database-external-changes.js +13 -10
  12. package/dist/src/core/database-external-changes.js.map +1 -1
  13. package/dist/src/core/database-internal.d.ts.map +1 -1
  14. package/dist/src/core/database-materialized-views-analysis.d.ts +199 -0
  15. package/dist/src/core/database-materialized-views-analysis.d.ts.map +1 -0
  16. package/dist/src/core/database-materialized-views-analysis.js +502 -0
  17. package/dist/src/core/database-materialized-views-analysis.js.map +1 -0
  18. package/dist/src/core/database-materialized-views-apply.d.ts +422 -0
  19. package/dist/src/core/database-materialized-views-apply.d.ts.map +1 -0
  20. package/dist/src/core/database-materialized-views-apply.js +929 -0
  21. package/dist/src/core/database-materialized-views-apply.js.map +1 -0
  22. package/dist/src/core/database-materialized-views-plan-builders.d.ts +267 -0
  23. package/dist/src/core/database-materialized-views-plan-builders.d.ts.map +1 -0
  24. package/dist/src/core/database-materialized-views-plan-builders.js +1423 -0
  25. package/dist/src/core/database-materialized-views-plan-builders.js.map +1 -0
  26. package/dist/src/core/database-materialized-views-plans.d.ts +641 -0
  27. package/dist/src/core/database-materialized-views-plans.d.ts.map +1 -0
  28. package/dist/src/core/database-materialized-views-plans.js +13 -0
  29. package/dist/src/core/database-materialized-views-plans.js.map +1 -0
  30. package/dist/src/core/database-materialized-views.d.ts +108 -860
  31. package/dist/src/core/database-materialized-views.d.ts.map +1 -1
  32. package/dist/src/core/database-materialized-views.js +212 -2165
  33. package/dist/src/core/database-materialized-views.js.map +1 -1
  34. package/dist/src/core/database-transaction.d.ts +10 -1
  35. package/dist/src/core/database-transaction.d.ts.map +1 -1
  36. package/dist/src/core/database-transaction.js +16 -4
  37. package/dist/src/core/database-transaction.js.map +1 -1
  38. package/dist/src/core/database-watchers.d.ts.map +1 -1
  39. package/dist/src/core/database-watchers.js +2 -1
  40. package/dist/src/core/database-watchers.js.map +1 -1
  41. package/dist/src/core/database.d.ts +99 -13
  42. package/dist/src/core/database.d.ts.map +1 -1
  43. package/dist/src/core/database.js +270 -50
  44. package/dist/src/core/database.js.map +1 -1
  45. package/dist/src/core/derived-row-validator.d.ts +1 -1
  46. package/dist/src/core/derived-row-validator.d.ts.map +1 -1
  47. package/dist/src/core/derived-row-validator.js +5 -3
  48. package/dist/src/core/derived-row-validator.js.map +1 -1
  49. package/dist/src/core/statement.d.ts +8 -0
  50. package/dist/src/core/statement.d.ts.map +1 -1
  51. package/dist/src/core/statement.js +98 -18
  52. package/dist/src/core/statement.js.map +1 -1
  53. package/dist/src/emit/ast-stringify.d.ts.map +1 -1
  54. package/dist/src/emit/ast-stringify.js +24 -13
  55. package/dist/src/emit/ast-stringify.js.map +1 -1
  56. package/dist/src/func/builtins/aggregate.d.ts.map +1 -1
  57. package/dist/src/func/builtins/aggregate.js +127 -21
  58. package/dist/src/func/builtins/aggregate.js.map +1 -1
  59. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  60. package/dist/src/func/builtins/explain.js +2 -1
  61. package/dist/src/func/builtins/explain.js.map +1 -1
  62. package/dist/src/func/builtins/json.d.ts.map +1 -1
  63. package/dist/src/func/builtins/json.js +2 -1
  64. package/dist/src/func/builtins/json.js.map +1 -1
  65. package/dist/src/func/builtins/mutation.d.ts.map +1 -1
  66. package/dist/src/func/builtins/mutation.js +3 -2
  67. package/dist/src/func/builtins/mutation.js.map +1 -1
  68. package/dist/src/func/registration.d.ts +6 -1
  69. package/dist/src/func/registration.d.ts.map +1 -1
  70. package/dist/src/func/registration.js +16 -0
  71. package/dist/src/func/registration.js.map +1 -1
  72. package/dist/src/index.d.ts +16 -6
  73. package/dist/src/index.d.ts.map +1 -1
  74. package/dist/src/index.js +33 -7
  75. package/dist/src/index.js.map +1 -1
  76. package/dist/src/parser/ast.d.ts +2 -2
  77. package/dist/src/parser/lexer.d.ts +11 -1
  78. package/dist/src/parser/lexer.d.ts.map +1 -1
  79. package/dist/src/parser/lexer.js +40 -34
  80. package/dist/src/parser/lexer.js.map +1 -1
  81. package/dist/src/parser/parser.d.ts.map +1 -1
  82. package/dist/src/parser/parser.js +16 -9
  83. package/dist/src/parser/parser.js.map +1 -1
  84. package/dist/src/planner/analysis/authored-inverse.js +1 -1
  85. package/dist/src/planner/analysis/comparison-collation.d.ts +52 -0
  86. package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -1
  87. package/dist/src/planner/analysis/comparison-collation.js +84 -7
  88. package/dist/src/planner/analysis/comparison-collation.js.map +1 -1
  89. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
  90. package/dist/src/planner/analysis/constraint-extractor.js +64 -17
  91. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
  92. package/dist/src/planner/analysis/coverage-prover.d.ts +1 -1
  93. package/dist/src/planner/analysis/coverage-prover.js +1 -1
  94. package/dist/src/planner/analysis/equi-correlation.d.ts +26 -0
  95. package/dist/src/planner/analysis/equi-correlation.d.ts.map +1 -0
  96. package/dist/src/planner/analysis/equi-correlation.js +62 -0
  97. package/dist/src/planner/analysis/equi-correlation.js.map +1 -0
  98. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts +54 -18
  99. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts.map +1 -1
  100. package/dist/src/planner/analysis/query-rewrite-matcher.js +86 -42
  101. package/dist/src/planner/analysis/query-rewrite-matcher.js.map +1 -1
  102. package/dist/src/planner/analysis/sat-checker.d.ts +8 -1
  103. package/dist/src/planner/analysis/sat-checker.d.ts.map +1 -1
  104. package/dist/src/planner/analysis/sat-checker.js +117 -22
  105. package/dist/src/planner/analysis/sat-checker.js.map +1 -1
  106. package/dist/src/planner/analysis/scalar-invertibility.d.ts +13 -4
  107. package/dist/src/planner/analysis/scalar-invertibility.d.ts.map +1 -1
  108. package/dist/src/planner/analysis/scalar-invertibility.js +12 -3
  109. package/dist/src/planner/analysis/scalar-invertibility.js.map +1 -1
  110. package/dist/src/planner/analysis/scalar-subqueries.d.ts +28 -0
  111. package/dist/src/planner/analysis/scalar-subqueries.d.ts.map +1 -0
  112. package/dist/src/planner/analysis/scalar-subqueries.js +60 -0
  113. package/dist/src/planner/analysis/scalar-subqueries.js.map +1 -0
  114. package/dist/src/planner/analysis/update-lineage.d.ts +1 -1
  115. package/dist/src/planner/analysis/update-lineage.js +1 -1
  116. package/dist/src/planner/analysis/update-lineage.js.map +1 -1
  117. package/dist/src/planner/analysis/view-complement.d.ts +2 -2
  118. package/dist/src/planner/building/delete.js +2 -2
  119. package/dist/src/planner/building/delete.js.map +1 -1
  120. package/dist/src/planner/building/dml-target.d.ts +2 -2
  121. package/dist/src/planner/building/dml-target.js +2 -2
  122. package/dist/src/planner/building/insert.d.ts.map +1 -1
  123. package/dist/src/planner/building/insert.js +53 -2
  124. package/dist/src/planner/building/insert.js.map +1 -1
  125. package/dist/src/planner/building/schema-resolution.d.ts +3 -0
  126. package/dist/src/planner/building/schema-resolution.d.ts.map +1 -1
  127. package/dist/src/planner/building/schema-resolution.js +4 -5
  128. package/dist/src/planner/building/schema-resolution.js.map +1 -1
  129. package/dist/src/planner/building/select.d.ts.map +1 -1
  130. package/dist/src/planner/building/select.js +18 -4
  131. package/dist/src/planner/building/select.js.map +1 -1
  132. package/dist/src/planner/building/update.js +2 -2
  133. package/dist/src/planner/building/update.js.map +1 -1
  134. package/dist/src/planner/building/view-mutation-builder.js +7 -7
  135. package/dist/src/planner/building/view-mutation-builder.js.map +1 -1
  136. package/dist/src/planner/building/with.d.ts.map +1 -1
  137. package/dist/src/planner/building/with.js +5 -8
  138. package/dist/src/planner/building/with.js.map +1 -1
  139. package/dist/src/planner/cache/materialization-advisory.d.ts +34 -2
  140. package/dist/src/planner/cache/materialization-advisory.d.ts.map +1 -1
  141. package/dist/src/planner/cache/materialization-advisory.js +185 -42
  142. package/dist/src/planner/cache/materialization-advisory.js.map +1 -1
  143. package/dist/src/planner/cache/reference-graph.d.ts +14 -5
  144. package/dist/src/planner/cache/reference-graph.d.ts.map +1 -1
  145. package/dist/src/planner/cache/reference-graph.js +31 -39
  146. package/dist/src/planner/cache/reference-graph.js.map +1 -1
  147. package/dist/src/planner/cost/index.d.ts +30 -5
  148. package/dist/src/planner/cost/index.d.ts.map +1 -1
  149. package/dist/src/planner/cost/index.js +26 -0
  150. package/dist/src/planner/cost/index.js.map +1 -1
  151. package/dist/src/planner/debug.d.ts +3 -2
  152. package/dist/src/planner/debug.d.ts.map +1 -1
  153. package/dist/src/planner/debug.js +9 -3
  154. package/dist/src/planner/debug.js.map +1 -1
  155. package/dist/src/planner/framework/characteristics.d.ts +46 -19
  156. package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
  157. package/dist/src/planner/framework/characteristics.js +50 -134
  158. package/dist/src/planner/framework/characteristics.js.map +1 -1
  159. package/dist/src/planner/framework/context.d.ts +8 -44
  160. package/dist/src/planner/framework/context.d.ts.map +1 -1
  161. package/dist/src/planner/framework/context.js +0 -91
  162. package/dist/src/planner/framework/context.js.map +1 -1
  163. package/dist/src/planner/framework/pass.d.ts +7 -0
  164. package/dist/src/planner/framework/pass.d.ts.map +1 -1
  165. package/dist/src/planner/framework/pass.js +84 -0
  166. package/dist/src/planner/framework/pass.js.map +1 -1
  167. package/dist/src/planner/framework/registry.d.ts +13 -42
  168. package/dist/src/planner/framework/registry.d.ts.map +1 -1
  169. package/dist/src/planner/framework/registry.js +14 -182
  170. package/dist/src/planner/framework/registry.js.map +1 -1
  171. package/dist/src/planner/mutation/backward-body.d.ts +2 -2
  172. package/dist/src/planner/mutation/cte-flatten.js +1 -1
  173. package/dist/src/planner/mutation/decomposition.d.ts +2 -2
  174. package/dist/src/planner/mutation/decomposition.js +1 -1
  175. package/dist/src/planner/mutation/lens-enforcement.d.ts.map +1 -1
  176. package/dist/src/planner/mutation/lens-enforcement.js +2 -1
  177. package/dist/src/planner/mutation/lens-enforcement.js.map +1 -1
  178. package/dist/src/planner/mutation/multi-source.d.ts +8 -8
  179. package/dist/src/planner/mutation/multi-source.js +11 -11
  180. package/dist/src/planner/mutation/multi-source.js.map +1 -1
  181. package/dist/src/planner/mutation/propagate.d.ts +1 -1
  182. package/dist/src/planner/mutation/propagate.js +1 -1
  183. package/dist/src/planner/mutation/scope-transform.d.ts +2 -2
  184. package/dist/src/planner/mutation/scope-transform.js +3 -3
  185. package/dist/src/planner/mutation/scope-transform.js.map +1 -1
  186. package/dist/src/planner/mutation/set-op.d.ts +1 -1
  187. package/dist/src/planner/mutation/set-op.d.ts.map +1 -1
  188. package/dist/src/planner/mutation/set-op.js +3 -2
  189. package/dist/src/planner/mutation/set-op.js.map +1 -1
  190. package/dist/src/planner/mutation/single-source.d.ts +3 -3
  191. package/dist/src/planner/mutation/single-source.js +9 -9
  192. package/dist/src/planner/mutation/single-source.js.map +1 -1
  193. package/dist/src/planner/nodes/aggregate-function.d.ts +3 -1
  194. package/dist/src/planner/nodes/aggregate-function.d.ts.map +1 -1
  195. package/dist/src/planner/nodes/aggregate-function.js +1 -0
  196. package/dist/src/planner/nodes/aggregate-function.js.map +1 -1
  197. package/dist/src/planner/nodes/aggregate-node.d.ts +1 -0
  198. package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
  199. package/dist/src/planner/nodes/aggregate-node.js +8 -1
  200. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  201. package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
  202. package/dist/src/planner/nodes/alias-node.js +3 -1
  203. package/dist/src/planner/nodes/alias-node.js.map +1 -1
  204. package/dist/src/planner/nodes/asof-scan-node.d.ts.map +1 -1
  205. package/dist/src/planner/nodes/asof-scan-node.js +3 -2
  206. package/dist/src/planner/nodes/asof-scan-node.js.map +1 -1
  207. package/dist/src/planner/nodes/asserted-keys-node.d.ts +1 -1
  208. package/dist/src/planner/nodes/asserted-keys-node.d.ts.map +1 -1
  209. package/dist/src/planner/nodes/asserted-keys-node.js +5 -2
  210. package/dist/src/planner/nodes/asserted-keys-node.js.map +1 -1
  211. package/dist/src/planner/nodes/async-gather-node.d.ts.map +1 -1
  212. package/dist/src/planner/nodes/async-gather-node.js +3 -1
  213. package/dist/src/planner/nodes/async-gather-node.js.map +1 -1
  214. package/dist/src/planner/nodes/block.js +3 -3
  215. package/dist/src/planner/nodes/block.js.map +1 -1
  216. package/dist/src/planner/nodes/bloom-join-node.d.ts +2 -0
  217. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
  218. package/dist/src/planner/nodes/bloom-join-node.js +5 -1
  219. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
  220. package/dist/src/planner/nodes/cache-node.d.ts +19 -2
  221. package/dist/src/planner/nodes/cache-node.d.ts.map +1 -1
  222. package/dist/src/planner/nodes/cache-node.js +43 -3
  223. package/dist/src/planner/nodes/cache-node.js.map +1 -1
  224. package/dist/src/planner/nodes/cte-node.d.ts +16 -1
  225. package/dist/src/planner/nodes/cte-node.d.ts.map +1 -1
  226. package/dist/src/planner/nodes/cte-node.js +16 -3
  227. package/dist/src/planner/nodes/cte-node.js.map +1 -1
  228. package/dist/src/planner/nodes/distinct-node.js +3 -3
  229. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  230. package/dist/src/planner/nodes/dml-executor-node.d.ts +21 -0
  231. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  232. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  233. package/dist/src/planner/nodes/envelope-scan-node.d.ts +1 -1
  234. package/dist/src/planner/nodes/envelope-scan-node.js +1 -1
  235. package/dist/src/planner/nodes/fanout-lookup-join-node.d.ts.map +1 -1
  236. package/dist/src/planner/nodes/fanout-lookup-join-node.js +4 -2
  237. package/dist/src/planner/nodes/fanout-lookup-join-node.js.map +1 -1
  238. package/dist/src/planner/nodes/filter.d.ts +10 -2
  239. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  240. package/dist/src/planner/nodes/filter.js +81 -14
  241. package/dist/src/planner/nodes/filter.js.map +1 -1
  242. package/dist/src/planner/nodes/hash-aggregate.d.ts +12 -1
  243. package/dist/src/planner/nodes/hash-aggregate.d.ts.map +1 -1
  244. package/dist/src/planner/nodes/hash-aggregate.js +28 -1
  245. package/dist/src/planner/nodes/hash-aggregate.js.map +1 -1
  246. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts +3 -1
  247. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.d.ts.map +1 -1
  248. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js +1 -0
  249. package/dist/src/planner/nodes/internal-recursive-cte-ref-node.js.map +1 -1
  250. package/dist/src/planner/nodes/join-node.d.ts +3 -1
  251. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  252. package/dist/src/planner/nodes/join-node.js +5 -5
  253. package/dist/src/planner/nodes/join-node.js.map +1 -1
  254. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts.map +1 -1
  255. package/dist/src/planner/nodes/lens-auxiliary-access-node.js +4 -1
  256. package/dist/src/planner/nodes/lens-auxiliary-access-node.js.map +1 -1
  257. package/dist/src/planner/nodes/limit-offset.d.ts +1 -0
  258. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  259. package/dist/src/planner/nodes/limit-offset.js +4 -3
  260. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  261. package/dist/src/planner/nodes/merge-join-node.d.ts +2 -0
  262. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
  263. package/dist/src/planner/nodes/merge-join-node.js +6 -1
  264. package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
  265. package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
  266. package/dist/src/planner/nodes/ordinal-slice-node.js +3 -1
  267. package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
  268. package/dist/src/planner/nodes/plan-node.d.ts +68 -5
  269. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  270. package/dist/src/planner/nodes/plan-node.js +137 -24
  271. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  272. package/dist/src/planner/nodes/project-node.d.ts +3 -2
  273. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  274. package/dist/src/planner/nodes/project-node.js +1 -0
  275. package/dist/src/planner/nodes/project-node.js.map +1 -1
  276. package/dist/src/planner/nodes/recursive-cte-node.d.ts +30 -1
  277. package/dist/src/planner/nodes/recursive-cte-node.d.ts.map +1 -1
  278. package/dist/src/planner/nodes/recursive-cte-node.js +38 -5
  279. package/dist/src/planner/nodes/recursive-cte-node.js.map +1 -1
  280. package/dist/src/planner/nodes/reference.d.ts +5 -1
  281. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  282. package/dist/src/planner/nodes/reference.js +3 -0
  283. package/dist/src/planner/nodes/reference.js.map +1 -1
  284. package/dist/src/planner/nodes/remote-query-node.d.ts.map +1 -1
  285. package/dist/src/planner/nodes/remote-query-node.js +3 -1
  286. package/dist/src/planner/nodes/remote-query-node.js.map +1 -1
  287. package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -1
  288. package/dist/src/planner/nodes/retrieve-node.js +3 -1
  289. package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
  290. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  291. package/dist/src/planner/nodes/set-operation-node.js +3 -1
  292. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  293. package/dist/src/planner/nodes/sink-node.d.ts.map +1 -1
  294. package/dist/src/planner/nodes/sink-node.js +3 -1
  295. package/dist/src/planner/nodes/sink-node.js.map +1 -1
  296. package/dist/src/planner/nodes/sort.d.ts +2 -1
  297. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  298. package/dist/src/planner/nodes/sort.js +9 -5
  299. package/dist/src/planner/nodes/sort.js.map +1 -1
  300. package/dist/src/planner/nodes/stream-aggregate.d.ts +12 -1
  301. package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
  302. package/dist/src/planner/nodes/stream-aggregate.js +32 -3
  303. package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
  304. package/dist/src/planner/nodes/table-access-nodes.d.ts +2 -1
  305. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
  306. package/dist/src/planner/nodes/table-access-nodes.js +2 -0
  307. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  308. package/dist/src/planner/nodes/view-mutation-node.d.ts +2 -2
  309. package/dist/src/planner/nodes/view-mutation-node.d.ts.map +1 -1
  310. package/dist/src/planner/nodes/view-mutation-node.js +5 -1
  311. package/dist/src/planner/nodes/view-mutation-node.js.map +1 -1
  312. package/dist/src/planner/nodes/window-function.d.ts +3 -1
  313. package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
  314. package/dist/src/planner/nodes/window-function.js +1 -0
  315. package/dist/src/planner/nodes/window-function.js.map +1 -1
  316. package/dist/src/planner/optimizer.d.ts +52 -8
  317. package/dist/src/planner/optimizer.d.ts.map +1 -1
  318. package/dist/src/planner/optimizer.js +1014 -895
  319. package/dist/src/planner/optimizer.js.map +1 -1
  320. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  321. package/dist/src/planner/rules/access/rule-select-access-path.js +235 -202
  322. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  323. package/dist/src/planner/rules/cache/rule-cte-optimization.d.ts.map +1 -1
  324. package/dist/src/planner/rules/cache/rule-cte-optimization.js +8 -1
  325. package/dist/src/planner/rules/cache/rule-cte-optimization.js.map +1 -1
  326. package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts +7 -0
  327. package/dist/src/planner/rules/cache/rule-in-subquery-cache.d.ts.map +1 -1
  328. package/dist/src/planner/rules/cache/rule-in-subquery-cache.js +14 -1
  329. package/dist/src/planner/rules/cache/rule-in-subquery-cache.js.map +1 -1
  330. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts +2 -2
  331. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts.map +1 -1
  332. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js +55 -56
  333. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js.map +1 -1
  334. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.d.ts.map +1 -1
  335. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js +6 -0
  336. package/dist/src/planner/rules/cache/rule-mutating-subquery-cache.js.map +1 -1
  337. package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.d.ts +25 -0
  338. package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.d.ts.map +1 -0
  339. package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.js +176 -0
  340. package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.js.map +1 -0
  341. package/dist/src/planner/rules/cache/rule-scalar-cse.d.ts +1 -1
  342. package/dist/src/planner/rules/cache/rule-scalar-cse.js +1 -1
  343. package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.d.ts +29 -0
  344. package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.d.ts.map +1 -0
  345. package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.js +66 -0
  346. package/dist/src/planner/rules/cache/rule-scalar-subquery-cache.js.map +1 -0
  347. package/dist/src/planner/rules/join/rule-fanout-batched-outer.d.ts +1 -1
  348. package/dist/src/planner/rules/join/rule-fanout-batched-outer.js +1 -1
  349. package/dist/src/planner/rules/join/rule-fanout-lookup-join.d.ts.map +1 -1
  350. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js +1 -54
  351. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js.map +1 -1
  352. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts +1 -1
  353. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js +1 -1
  354. package/dist/src/planner/rules/join/rule-join-elimination.d.ts +1 -1
  355. package/dist/src/planner/rules/join/rule-join-elimination.js +1 -1
  356. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js +5 -6
  357. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js.map +1 -1
  358. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts +1 -1
  359. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +1 -1
  360. package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts +2 -2
  361. package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts.map +1 -1
  362. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js +4 -3
  363. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js.map +1 -1
  364. package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts +19 -0
  365. package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts.map +1 -0
  366. package/dist/src/planner/rules/predicate/rule-filter-selectivity.js +48 -0
  367. package/dist/src/planner/rules/predicate/rule-filter-selectivity.js.map +1 -0
  368. package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.js +12 -1
  369. package/dist/src/planner/rules/predicate/rule-sargable-range-rewrite.js.map +1 -1
  370. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.d.ts.map +1 -1
  371. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +22 -20
  372. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
  373. package/dist/src/planner/rules/shared/index-style-context.d.ts +39 -0
  374. package/dist/src/planner/rules/shared/index-style-context.d.ts.map +1 -0
  375. package/dist/src/planner/rules/shared/index-style-context.js +26 -0
  376. package/dist/src/planner/rules/shared/index-style-context.js.map +1 -0
  377. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts +1 -1
  378. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js +1 -1
  379. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts +1 -1
  380. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js +1 -1
  381. package/dist/src/planner/rules/subquery/rule-scalar-agg-decorrelation.d.ts +191 -0
  382. package/dist/src/planner/rules/subquery/rule-scalar-agg-decorrelation.d.ts.map +1 -0
  383. package/dist/src/planner/rules/subquery/rule-scalar-agg-decorrelation.js +623 -0
  384. package/dist/src/planner/rules/subquery/rule-scalar-agg-decorrelation.js.map +1 -0
  385. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts +10 -1
  386. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
  387. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +242 -51
  388. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
  389. package/dist/src/planner/stats/analyze.d.ts.map +1 -1
  390. package/dist/src/planner/stats/analyze.js +2 -20
  391. package/dist/src/planner/stats/analyze.js.map +1 -1
  392. package/dist/src/planner/stats/histogram.d.ts.map +1 -1
  393. package/dist/src/planner/stats/histogram.js +4 -0
  394. package/dist/src/planner/stats/histogram.js.map +1 -1
  395. package/dist/src/planner/util/fd-utils.d.ts +2 -3
  396. package/dist/src/planner/util/fd-utils.d.ts.map +1 -1
  397. package/dist/src/planner/util/fd-utils.js +2 -3
  398. package/dist/src/planner/util/fd-utils.js.map +1 -1
  399. package/dist/src/planner/validation/plan-validator.d.ts +16 -0
  400. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  401. package/dist/src/planner/validation/plan-validator.js +36 -0
  402. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  403. package/dist/src/runtime/async-util.d.ts +26 -0
  404. package/dist/src/runtime/async-util.d.ts.map +1 -1
  405. package/dist/src/runtime/async-util.js +139 -55
  406. package/dist/src/runtime/async-util.js.map +1 -1
  407. package/dist/src/runtime/cache/shared-cache.d.ts +7 -0
  408. package/dist/src/runtime/cache/shared-cache.d.ts.map +1 -1
  409. package/dist/src/runtime/cache/shared-cache.js +34 -1
  410. package/dist/src/runtime/cache/shared-cache.js.map +1 -1
  411. package/dist/src/runtime/context-helpers.d.ts +32 -4
  412. package/dist/src/runtime/context-helpers.d.ts.map +1 -1
  413. package/dist/src/runtime/context-helpers.js +26 -9
  414. package/dist/src/runtime/context-helpers.js.map +1 -1
  415. package/dist/src/runtime/deferred-constraint-queue.d.ts.map +1 -1
  416. package/dist/src/runtime/deferred-constraint-queue.js +2 -1
  417. package/dist/src/runtime/deferred-constraint-queue.js.map +1 -1
  418. package/dist/src/runtime/emission-context.d.ts +27 -3
  419. package/dist/src/runtime/emission-context.d.ts.map +1 -1
  420. package/dist/src/runtime/emission-context.js +38 -7
  421. package/dist/src/runtime/emission-context.js.map +1 -1
  422. package/dist/src/runtime/emit/add-constraint.d.ts.map +1 -1
  423. package/dist/src/runtime/emit/add-constraint.js +7 -1
  424. package/dist/src/runtime/emit/add-constraint.js.map +1 -1
  425. package/dist/src/runtime/emit/aggregate.d.ts +2 -3
  426. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  427. package/dist/src/runtime/emit/aggregate.js +23 -28
  428. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  429. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  430. package/dist/src/runtime/emit/alter-table.js +98 -9
  431. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  432. package/dist/src/runtime/emit/analyze.d.ts.map +1 -1
  433. package/dist/src/runtime/emit/analyze.js +2 -1
  434. package/dist/src/runtime/emit/analyze.js.map +1 -1
  435. package/dist/src/runtime/emit/asof-scan.d.ts.map +1 -1
  436. package/dist/src/runtime/emit/asof-scan.js +13 -10
  437. package/dist/src/runtime/emit/asof-scan.js.map +1 -1
  438. package/dist/src/runtime/emit/async-gather.d.ts.map +1 -1
  439. package/dist/src/runtime/emit/async-gather.js +4 -3
  440. package/dist/src/runtime/emit/async-gather.js.map +1 -1
  441. package/dist/src/runtime/emit/between.d.ts.map +1 -1
  442. package/dist/src/runtime/emit/between.js +2 -1
  443. package/dist/src/runtime/emit/between.js.map +1 -1
  444. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  445. package/dist/src/runtime/emit/binary.js +122 -14
  446. package/dist/src/runtime/emit/binary.js.map +1 -1
  447. package/dist/src/runtime/emit/block.d.ts.map +1 -1
  448. package/dist/src/runtime/emit/block.js +2 -1
  449. package/dist/src/runtime/emit/block.js.map +1 -1
  450. package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -1
  451. package/dist/src/runtime/emit/bloom-join.js +20 -8
  452. package/dist/src/runtime/emit/bloom-join.js.map +1 -1
  453. package/dist/src/runtime/emit/cache.d.ts +7 -3
  454. package/dist/src/runtime/emit/cache.d.ts.map +1 -1
  455. package/dist/src/runtime/emit/cache.js +25 -7
  456. package/dist/src/runtime/emit/cache.js.map +1 -1
  457. package/dist/src/runtime/emit/case.d.ts.map +1 -1
  458. package/dist/src/runtime/emit/case.js +66 -45
  459. package/dist/src/runtime/emit/case.js.map +1 -1
  460. package/dist/src/runtime/emit/cast.d.ts.map +1 -1
  461. package/dist/src/runtime/emit/cast.js +2 -1
  462. package/dist/src/runtime/emit/cast.js.map +1 -1
  463. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  464. package/dist/src/runtime/emit/constraint-check.js +13 -7
  465. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  466. package/dist/src/runtime/emit/create-assertion.d.ts.map +1 -1
  467. package/dist/src/runtime/emit/create-assertion.js +2 -1
  468. package/dist/src/runtime/emit/create-assertion.js.map +1 -1
  469. package/dist/src/runtime/emit/create-index.d.ts.map +1 -1
  470. package/dist/src/runtime/emit/create-index.js +12 -1
  471. package/dist/src/runtime/emit/create-index.js.map +1 -1
  472. package/dist/src/runtime/emit/create-table.d.ts.map +1 -1
  473. package/dist/src/runtime/emit/create-table.js +12 -1
  474. package/dist/src/runtime/emit/create-table.js.map +1 -1
  475. package/dist/src/runtime/emit/cte-reference.d.ts.map +1 -1
  476. package/dist/src/runtime/emit/cte-reference.js +2 -1
  477. package/dist/src/runtime/emit/cte-reference.js.map +1 -1
  478. package/dist/src/runtime/emit/cte.d.ts.map +1 -1
  479. package/dist/src/runtime/emit/cte.js +45 -21
  480. package/dist/src/runtime/emit/cte.js.map +1 -1
  481. package/dist/src/runtime/emit/ddl-transaction-policy.d.ts +50 -0
  482. package/dist/src/runtime/emit/ddl-transaction-policy.d.ts.map +1 -0
  483. package/dist/src/runtime/emit/ddl-transaction-policy.js +69 -0
  484. package/dist/src/runtime/emit/ddl-transaction-policy.js.map +1 -0
  485. package/dist/src/runtime/emit/delete.d.ts.map +1 -1
  486. package/dist/src/runtime/emit/delete.js +2 -1
  487. package/dist/src/runtime/emit/delete.js.map +1 -1
  488. package/dist/src/runtime/emit/distinct.d.ts.map +1 -1
  489. package/dist/src/runtime/emit/distinct.js +2 -1
  490. package/dist/src/runtime/emit/distinct.js.map +1 -1
  491. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  492. package/dist/src/runtime/emit/dml-executor.js +138 -74
  493. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  494. package/dist/src/runtime/emit/drop-assertion.d.ts.map +1 -1
  495. package/dist/src/runtime/emit/drop-assertion.js +2 -1
  496. package/dist/src/runtime/emit/drop-assertion.js.map +1 -1
  497. package/dist/src/runtime/emit/drop-index.d.ts.map +1 -1
  498. package/dist/src/runtime/emit/drop-index.js +17 -1
  499. package/dist/src/runtime/emit/drop-index.js.map +1 -1
  500. package/dist/src/runtime/emit/drop-table.d.ts.map +1 -1
  501. package/dist/src/runtime/emit/drop-table.js +11 -1
  502. package/dist/src/runtime/emit/drop-table.js.map +1 -1
  503. package/dist/src/runtime/emit/eager-prefetch.d.ts.map +1 -1
  504. package/dist/src/runtime/emit/eager-prefetch.js +2 -1
  505. package/dist/src/runtime/emit/eager-prefetch.js.map +1 -1
  506. package/dist/src/runtime/emit/envelope-scan.d.ts.map +1 -1
  507. package/dist/src/runtime/emit/envelope-scan.js +2 -1
  508. package/dist/src/runtime/emit/envelope-scan.js.map +1 -1
  509. package/dist/src/runtime/emit/fanout-lookup-join.d.ts.map +1 -1
  510. package/dist/src/runtime/emit/fanout-lookup-join.js +3 -2
  511. package/dist/src/runtime/emit/fanout-lookup-join.js.map +1 -1
  512. package/dist/src/runtime/emit/filter.d.ts.map +1 -1
  513. package/dist/src/runtime/emit/filter.js +8 -3
  514. package/dist/src/runtime/emit/filter.js.map +1 -1
  515. package/dist/src/runtime/emit/hash-aggregate.d.ts.map +1 -1
  516. package/dist/src/runtime/emit/hash-aggregate.js +16 -11
  517. package/dist/src/runtime/emit/hash-aggregate.js.map +1 -1
  518. package/dist/src/runtime/emit/insert.d.ts.map +1 -1
  519. package/dist/src/runtime/emit/insert.js +2 -1
  520. package/dist/src/runtime/emit/insert.js.map +1 -1
  521. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  522. package/dist/src/runtime/emit/join.js +20 -6
  523. package/dist/src/runtime/emit/join.js.map +1 -1
  524. package/dist/src/runtime/emit/limit-offset.d.ts.map +1 -1
  525. package/dist/src/runtime/emit/limit-offset.js +2 -1
  526. package/dist/src/runtime/emit/limit-offset.js.map +1 -1
  527. package/dist/src/runtime/emit/literal.d.ts.map +1 -1
  528. package/dist/src/runtime/emit/literal.js +2 -1
  529. package/dist/src/runtime/emit/literal.js.map +1 -1
  530. package/dist/src/runtime/emit/materialized-view-helpers.d.ts +22 -0
  531. package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -1
  532. package/dist/src/runtime/emit/materialized-view-helpers.js +128 -16
  533. package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -1
  534. package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -1
  535. package/dist/src/runtime/emit/materialized-view.js +6 -0
  536. package/dist/src/runtime/emit/materialized-view.js.map +1 -1
  537. package/dist/src/runtime/emit/merge-join.d.ts.map +1 -1
  538. package/dist/src/runtime/emit/merge-join.js +14 -4
  539. package/dist/src/runtime/emit/merge-join.js.map +1 -1
  540. package/dist/src/runtime/emit/ordinal-slice.d.ts.map +1 -1
  541. package/dist/src/runtime/emit/ordinal-slice.js +2 -1
  542. package/dist/src/runtime/emit/ordinal-slice.js.map +1 -1
  543. package/dist/src/runtime/emit/pragma.d.ts.map +1 -1
  544. package/dist/src/runtime/emit/pragma.js +2 -1
  545. package/dist/src/runtime/emit/pragma.js.map +1 -1
  546. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  547. package/dist/src/runtime/emit/project.js +7 -2
  548. package/dist/src/runtime/emit/project.js.map +1 -1
  549. package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -1
  550. package/dist/src/runtime/emit/recursive-cte.js +61 -2
  551. package/dist/src/runtime/emit/recursive-cte.js.map +1 -1
  552. package/dist/src/runtime/emit/returning.d.ts.map +1 -1
  553. package/dist/src/runtime/emit/returning.js +7 -2
  554. package/dist/src/runtime/emit/returning.js.map +1 -1
  555. package/dist/src/runtime/emit/scalar-function.d.ts.map +1 -1
  556. package/dist/src/runtime/emit/scalar-function.js +2 -1
  557. package/dist/src/runtime/emit/scalar-function.js.map +1 -1
  558. package/dist/src/runtime/emit/scan.d.ts.map +1 -1
  559. package/dist/src/runtime/emit/scan.js +55 -17
  560. package/dist/src/runtime/emit/scan.js.map +1 -1
  561. package/dist/src/runtime/emit/schema-declarative.d.ts.map +1 -1
  562. package/dist/src/runtime/emit/schema-declarative.js +6 -5
  563. package/dist/src/runtime/emit/schema-declarative.js.map +1 -1
  564. package/dist/src/runtime/emit/sequencing.d.ts.map +1 -1
  565. package/dist/src/runtime/emit/sequencing.js +2 -1
  566. package/dist/src/runtime/emit/sequencing.js.map +1 -1
  567. package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
  568. package/dist/src/runtime/emit/set-operation.js +6 -5
  569. package/dist/src/runtime/emit/set-operation.js.map +1 -1
  570. package/dist/src/runtime/emit/sink.d.ts.map +1 -1
  571. package/dist/src/runtime/emit/sink.js +2 -1
  572. package/dist/src/runtime/emit/sink.js.map +1 -1
  573. package/dist/src/runtime/emit/sort.d.ts.map +1 -1
  574. package/dist/src/runtime/emit/sort.js +2 -1
  575. package/dist/src/runtime/emit/sort.js.map +1 -1
  576. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  577. package/dist/src/runtime/emit/subquery.js +42 -23
  578. package/dist/src/runtime/emit/subquery.js.map +1 -1
  579. package/dist/src/runtime/emit/table-valued-function.d.ts.map +1 -1
  580. package/dist/src/runtime/emit/table-valued-function.js +2 -1
  581. package/dist/src/runtime/emit/table-valued-function.js.map +1 -1
  582. package/dist/src/runtime/emit/temporal-arithmetic.d.ts.map +1 -1
  583. package/dist/src/runtime/emit/temporal-arithmetic.js +2 -1
  584. package/dist/src/runtime/emit/temporal-arithmetic.js.map +1 -1
  585. package/dist/src/runtime/emit/transaction.d.ts.map +1 -1
  586. package/dist/src/runtime/emit/transaction.js +2 -1
  587. package/dist/src/runtime/emit/transaction.js.map +1 -1
  588. package/dist/src/runtime/emit/unary.d.ts.map +1 -1
  589. package/dist/src/runtime/emit/unary.js +2 -1
  590. package/dist/src/runtime/emit/unary.js.map +1 -1
  591. package/dist/src/runtime/emit/update.d.ts.map +1 -1
  592. package/dist/src/runtime/emit/update.js +2 -1
  593. package/dist/src/runtime/emit/update.js.map +1 -1
  594. package/dist/src/runtime/emit/values.d.ts.map +1 -1
  595. package/dist/src/runtime/emit/values.js +2 -1
  596. package/dist/src/runtime/emit/values.js.map +1 -1
  597. package/dist/src/runtime/emit/view-mutation.d.ts +1 -1
  598. package/dist/src/runtime/emit/view-mutation.d.ts.map +1 -1
  599. package/dist/src/runtime/emit/view-mutation.js +6 -3
  600. package/dist/src/runtime/emit/view-mutation.js.map +1 -1
  601. package/dist/src/runtime/emit/window.d.ts.map +1 -1
  602. package/dist/src/runtime/emit/window.js +26 -9
  603. package/dist/src/runtime/emit/window.js.map +1 -1
  604. package/dist/src/runtime/emitters.d.ts +11 -3
  605. package/dist/src/runtime/emitters.d.ts.map +1 -1
  606. package/dist/src/runtime/emitters.js +13 -22
  607. package/dist/src/runtime/emitters.js.map +1 -1
  608. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
  609. package/dist/src/runtime/foreign-key-actions.js +39 -13
  610. package/dist/src/runtime/foreign-key-actions.js.map +1 -1
  611. package/dist/src/runtime/parallel-driver.d.ts +32 -4
  612. package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
  613. package/dist/src/runtime/parallel-driver.js +88 -18
  614. package/dist/src/runtime/parallel-driver.js.map +1 -1
  615. package/dist/src/runtime/scheduler.d.ts +56 -7
  616. package/dist/src/runtime/scheduler.d.ts.map +1 -1
  617. package/dist/src/runtime/scheduler.js +223 -200
  618. package/dist/src/runtime/scheduler.js.map +1 -1
  619. package/dist/src/runtime/strict-flags.d.ts +22 -0
  620. package/dist/src/runtime/strict-flags.d.ts.map +1 -0
  621. package/dist/src/runtime/strict-flags.js +26 -0
  622. package/dist/src/runtime/strict-flags.js.map +1 -0
  623. package/dist/src/runtime/strict-fork.d.ts +4 -4
  624. package/dist/src/runtime/strict-fork.d.ts.map +1 -1
  625. package/dist/src/runtime/strict-fork.js +175 -31
  626. package/dist/src/runtime/strict-fork.js.map +1 -1
  627. package/dist/src/runtime/types.d.ts +102 -4
  628. package/dist/src/runtime/types.d.ts.map +1 -1
  629. package/dist/src/runtime/types.js +37 -0
  630. package/dist/src/runtime/types.js.map +1 -1
  631. package/dist/src/runtime/utils.d.ts.map +1 -1
  632. package/dist/src/runtime/utils.js +8 -17
  633. package/dist/src/runtime/utils.js.map +1 -1
  634. package/dist/src/schema/column.d.ts +8 -0
  635. package/dist/src/schema/column.d.ts.map +1 -1
  636. package/dist/src/schema/column.js.map +1 -1
  637. package/dist/src/schema/ddl-generator.js +5 -0
  638. package/dist/src/schema/ddl-generator.js.map +1 -1
  639. package/dist/src/schema/function.d.ts +79 -0
  640. package/dist/src/schema/function.d.ts.map +1 -1
  641. package/dist/src/schema/function.js.map +1 -1
  642. package/dist/src/schema/lens-compiler.js +2 -2
  643. package/dist/src/schema/lens-compiler.js.map +1 -1
  644. package/dist/src/schema/lens-prover.d.ts.map +1 -1
  645. package/dist/src/schema/lens-prover.js +2 -3
  646. package/dist/src/schema/lens-prover.js.map +1 -1
  647. package/dist/src/schema/lens.d.ts +1 -1
  648. package/dist/src/schema/manager.d.ts.map +1 -1
  649. package/dist/src/schema/manager.js +7 -2
  650. package/dist/src/schema/manager.js.map +1 -1
  651. package/dist/src/schema/rename-rewriter.d.ts +61 -0
  652. package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
  653. package/dist/src/schema/rename-rewriter.js +77 -0
  654. package/dist/src/schema/rename-rewriter.js.map +1 -1
  655. package/dist/src/schema/table.d.ts +36 -8
  656. package/dist/src/schema/table.d.ts.map +1 -1
  657. package/dist/src/schema/table.js +61 -11
  658. package/dist/src/schema/table.js.map +1 -1
  659. package/dist/src/schema/unique-enforcement.d.ts +28 -5
  660. package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
  661. package/dist/src/schema/unique-enforcement.js +37 -5
  662. package/dist/src/schema/unique-enforcement.js.map +1 -1
  663. package/dist/src/schema/view.d.ts +1 -1
  664. package/dist/src/schema/view.js +1 -1
  665. package/dist/src/types/json-type.d.ts.map +1 -1
  666. package/dist/src/types/json-type.js +18 -8
  667. package/dist/src/types/json-type.js.map +1 -1
  668. package/dist/src/types/logical-type.d.ts +26 -0
  669. package/dist/src/types/logical-type.d.ts.map +1 -1
  670. package/dist/src/types/logical-type.js.map +1 -1
  671. package/dist/src/util/comparison.d.ts +83 -59
  672. package/dist/src/util/comparison.d.ts.map +1 -1
  673. package/dist/src/util/comparison.js +191 -131
  674. package/dist/src/util/comparison.js.map +1 -1
  675. package/dist/src/util/json-canonical.d.ts +34 -0
  676. package/dist/src/util/json-canonical.d.ts.map +1 -0
  677. package/dist/src/util/json-canonical.js +32 -0
  678. package/dist/src/util/json-canonical.js.map +1 -0
  679. package/dist/src/util/key-serializer.d.ts +10 -3
  680. package/dist/src/util/key-serializer.d.ts.map +1 -1
  681. package/dist/src/util/key-serializer.js +43 -17
  682. package/dist/src/util/key-serializer.js.map +1 -1
  683. package/dist/src/util/key-tuple-codec.d.ts +37 -0
  684. package/dist/src/util/key-tuple-codec.d.ts.map +1 -0
  685. package/dist/src/util/key-tuple-codec.js +65 -0
  686. package/dist/src/util/key-tuple-codec.js.map +1 -0
  687. package/dist/src/util/latches.d.ts +29 -3
  688. package/dist/src/util/latches.d.ts.map +1 -1
  689. package/dist/src/util/latches.js +60 -6
  690. package/dist/src/util/latches.js.map +1 -1
  691. package/dist/src/util/patterns.d.ts +22 -8
  692. package/dist/src/util/patterns.d.ts.map +1 -1
  693. package/dist/src/util/patterns.js +87 -16
  694. package/dist/src/util/patterns.js.map +1 -1
  695. package/dist/src/util/qualified-name.d.ts +10 -0
  696. package/dist/src/util/qualified-name.d.ts.map +1 -0
  697. package/dist/src/util/qualified-name.js +15 -0
  698. package/dist/src/util/qualified-name.js.map +1 -0
  699. package/dist/src/vtab/backing-host.d.ts +8 -1
  700. package/dist/src/vtab/backing-host.d.ts.map +1 -1
  701. package/dist/src/vtab/backing-host.js +7 -0
  702. package/dist/src/vtab/backing-host.js.map +1 -1
  703. package/dist/src/vtab/best-access-plan.d.ts +18 -0
  704. package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
  705. package/dist/src/vtab/best-access-plan.js +15 -0
  706. package/dist/src/vtab/best-access-plan.js.map +1 -1
  707. package/dist/src/vtab/capabilities.d.ts +44 -0
  708. package/dist/src/vtab/capabilities.d.ts.map +1 -1
  709. package/dist/src/vtab/filter-info.d.ts +42 -0
  710. package/dist/src/vtab/filter-info.d.ts.map +1 -1
  711. package/dist/src/vtab/filter-info.js +137 -1
  712. package/dist/src/vtab/filter-info.js.map +1 -1
  713. package/dist/src/vtab/idx-str.d.ts +62 -0
  714. package/dist/src/vtab/idx-str.d.ts.map +1 -0
  715. package/dist/src/vtab/idx-str.js +130 -0
  716. package/dist/src/vtab/idx-str.js.map +1 -0
  717. package/dist/src/vtab/index-descriptor.d.ts +122 -0
  718. package/dist/src/vtab/index-descriptor.d.ts.map +1 -0
  719. package/dist/src/vtab/index-descriptor.js +104 -0
  720. package/dist/src/vtab/index-descriptor.js.map +1 -0
  721. package/dist/src/vtab/mapping-advertisement.d.ts +1 -1
  722. package/dist/src/vtab/memory/index.d.ts +12 -4
  723. package/dist/src/vtab/memory/index.d.ts.map +1 -1
  724. package/dist/src/vtab/memory/index.js +17 -9
  725. package/dist/src/vtab/memory/index.js.map +1 -1
  726. package/dist/src/vtab/memory/layer/base.d.ts +85 -31
  727. package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
  728. package/dist/src/vtab/memory/layer/base.js +127 -86
  729. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  730. package/dist/src/vtab/memory/layer/connection.d.ts +27 -0
  731. package/dist/src/vtab/memory/layer/connection.d.ts.map +1 -1
  732. package/dist/src/vtab/memory/layer/connection.js +36 -1
  733. package/dist/src/vtab/memory/layer/connection.js.map +1 -1
  734. package/dist/src/vtab/memory/layer/interface.d.ts +24 -4
  735. package/dist/src/vtab/memory/layer/interface.d.ts.map +1 -1
  736. package/dist/src/vtab/memory/layer/manager.d.ts +212 -16
  737. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  738. package/dist/src/vtab/memory/layer/manager.js +754 -170
  739. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  740. package/dist/src/vtab/memory/layer/plan-filter.d.ts +26 -1
  741. package/dist/src/vtab/memory/layer/plan-filter.d.ts.map +1 -1
  742. package/dist/src/vtab/memory/layer/plan-filter.js +29 -11
  743. package/dist/src/vtab/memory/layer/plan-filter.js.map +1 -1
  744. package/dist/src/vtab/memory/layer/safe-iterate.d.ts +2 -2
  745. package/dist/src/vtab/memory/layer/safe-iterate.d.ts.map +1 -1
  746. package/dist/src/vtab/memory/layer/safe-iterate.js +2 -2
  747. package/dist/src/vtab/memory/layer/safe-iterate.js.map +1 -1
  748. package/dist/src/vtab/memory/layer/scan-layer.d.ts +5 -1
  749. package/dist/src/vtab/memory/layer/scan-layer.d.ts.map +1 -1
  750. package/dist/src/vtab/memory/layer/scan-layer.js +59 -24
  751. package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
  752. package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
  753. package/dist/src/vtab/memory/layer/scan-plan.js +13 -21
  754. package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
  755. package/dist/src/vtab/memory/layer/transaction.d.ts +169 -7
  756. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  757. package/dist/src/vtab/memory/layer/transaction.js +334 -9
  758. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  759. package/dist/src/vtab/memory/module.d.ts +11 -4
  760. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  761. package/dist/src/vtab/memory/module.js +35 -16
  762. package/dist/src/vtab/memory/module.js.map +1 -1
  763. package/dist/src/vtab/memory/table.d.ts +30 -4
  764. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  765. package/dist/src/vtab/memory/table.js +63 -15
  766. package/dist/src/vtab/memory/table.js.map +1 -1
  767. package/dist/src/vtab/memory/utils/predicate.d.ts +9 -1
  768. package/dist/src/vtab/memory/utils/predicate.d.ts.map +1 -1
  769. package/dist/src/vtab/memory/utils/predicate.js +35 -14
  770. package/dist/src/vtab/memory/utils/predicate.js.map +1 -1
  771. package/dist/src/vtab/memory/utils/primary-key-encode.d.ts.map +1 -1
  772. package/dist/src/vtab/memory/utils/primary-key-encode.js +12 -6
  773. package/dist/src/vtab/memory/utils/primary-key-encode.js.map +1 -1
  774. package/dist/src/vtab/memory/utils/primary-key.d.ts +6 -1
  775. package/dist/src/vtab/memory/utils/primary-key.d.ts.map +1 -1
  776. package/dist/src/vtab/memory/utils/primary-key.js +12 -8
  777. package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
  778. package/dist/src/vtab/module.d.ts +38 -14
  779. package/dist/src/vtab/module.d.ts.map +1 -1
  780. package/dist/src/vtab/table.d.ts +41 -2
  781. package/dist/src/vtab/table.d.ts.map +1 -1
  782. package/dist/src/vtab/table.js +19 -0
  783. package/dist/src/vtab/table.js.map +1 -1
  784. package/package.json +5 -4
  785. package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts +0 -18
  786. package/dist/src/planner/rules/cache/rule-materialization-advisory.d.ts.map +0 -1
  787. package/dist/src/planner/rules/cache/rule-materialization-advisory.js +0 -65
  788. package/dist/src/planner/rules/cache/rule-materialization-advisory.js.map +0 -1
@@ -38,399 +38,12 @@
38
38
  * (reads-own-writes) and is committed/rolled-back in lockstep with the source write by
39
39
  * the coordinated commit (see {@link MaterializedViewManager.buildMaintenancePlan}).
40
40
  */
41
- import type { SchemaManager } from '../schema/manager.js';
42
41
  import { type SqlValue, type Row } from '../common/types.js';
43
- import { Scheduler } from '../runtime/scheduler.js';
44
- import type { BindingMode } from '../planner/analysis/binding-extractor.js';
45
- import { type MaintenanceSourceStats, type MaintenanceStrategy } from '../planner/cost/index.js';
46
- import { type DerivedRowConstraintValidator } from './derived-row-validator.js';
47
42
  import type { BackingRowChange } from '../vtab/backing-host.js';
48
- import type { VirtualTableConnection } from '../vtab/connection.js';
49
- import { type CompiledPredicate } from '../vtab/memory/utils/predicate.js';
50
43
  import type { MaintainedTableSchema } from '../schema/derivation.js';
51
44
  import type { UniqueConstraintSchema } from '../schema/table.js';
52
- import type { Database } from './database.js';
53
- import type { DatabaseEventEmitter } from './database-events.js';
54
- import type * as AST from '../parser/ast.js';
55
- /**
56
- * Database internals the materialized-view manager needs. Mirrors
57
- * `AssertionEvaluatorContext` / `WatcherManagerContext` — keeps the manager
58
- * decoupled from the full `Database`.
59
- */
60
- export interface MaterializedViewManagerContext {
61
- readonly schemaManager: SchemaManager;
62
- readonly optimizer: Database['optimizer'];
63
- /** Database event emitter — the row-time collision telemetry channel
64
- * ({@link MaterializedViewManager.detectAndReportCoarseningCollisions}) queues
65
- * {@link MaintenanceCollisionEvent}s here. Already exposed for the transaction
66
- * manager; reused narrowly. */
67
- getEventEmitter(): DatabaseEventEmitter;
68
- _buildPlan(statements: AST.Statement[]): import('./database.js').BuildPlanResult;
69
- _findTable(tableName: string, schemaName?: string): ReturnType<Database['_findTable']>;
70
- /** Backing-connection resolution for row-time write-through (see {@link MaterializedViewManager.getBackingConnection}). */
71
- getConnectionsForTable(tableName: string): VirtualTableConnection[];
72
- registerConnection(connection: VirtualTableConnection): Promise<void>;
73
- }
74
- /**
75
- * A compiled per-MV maintenance plan — how {@link MaterializedViewManager.applyMaintenancePlan}
76
- * keeps an MV's backing table consistent with a source row-write. A tagged union over
77
- * the maintenance strategies the incremental substrate names (the spike's
78
- * `incremental-maintenance-substrate-spike` design). The builder
79
- * ({@link MaterializedViewManager.buildMaintenancePlan}) produces four bounded-delta arms:
80
- * `'inverse-projection'` (the covering-index shape), `'residual-recompute'` (single-source
81
- * aggregates), `'prefix-delete'` (single-source lateral-TVF fan-out), and `'join-residual'`
82
- * (the provably-1:1 inner join) — each applied **per source row, immediately**. The
83
- * `'full-rebuild'` floor (the always-correct convergence point for bodies no bounded-delta
84
- * arm fits) is the fall-through the builder routes to whenever no bounded-delta arm matches;
85
- * it is the one **deferred** arm — marked dirty per row and rebuilt once per statement at
86
- * {@link MaterializedViewManager.flushDeferredRebuilds}.
87
- */
88
- export type MaintenancePlan = InverseProjectionPlan | FullRebuildPlan | ResidualRecomputePlan | PrefixDeletePlan | JoinResidualPlan;
89
- /**
90
- * Structural subset of the fields the forward (driving-source) residual-recompute
91
- * apply path reads — shared by the aggregate {@link ResidualRecomputePlan} and the
92
- * 1:1-join {@link JoinResidualPlan} so both drive {@link MaterializedViewManager.applyForwardResidual}
93
- * unchanged. For an aggregate the forward key is the group key (`'gk'`); for a join
94
- * it is the driving table `T`'s PK (`'pk'`).
95
- */
96
- interface ForwardResidualPlan {
97
- mv: MaintainedTableSchema;
98
- backingSchema: string;
99
- backingTableName: string;
100
- /** Cached scheduler for the key-filtered residual (the body with `injectKeyFilter`
101
- * applied on the driving source). Re-run per affected key, bound through the live txn. */
102
- residualScheduler: Scheduler;
103
- bindParamPrefix: 'gk' | 'pk';
104
- /** Source-column indices of the forward binding key (group columns / `T`'s PK columns). */
105
- bindColumns: number[];
106
- backingPkDefinition: ReadonlyArray<{
107
- index: number;
108
- desc?: boolean;
109
- collation?: string;
110
- }>;
111
- backingPkSourceCols: number[];
112
- }
113
- /**
114
- * The shipped covering-index maintenance arm (the former `RowTimeMaintenancePlan`,
115
- * verbatim). Per source row-write the backing delta is a pure projection of the
116
- * changed row: project the source row to a backing row (a per-column projector —
117
- * passthrough columns *and* deterministic scalar expressions over the source row),
118
- * key it by the backing physical PK, and (if the partial predicate admits it) delete
119
- * the old image / upsert the new image. No body re-execution, no scan — see
120
- * `docs/materialized-views.md` § Row-time refresh.
121
- */
122
- /**
123
- * How a single backing output column is derived from the changed source row — a pure
124
- * per-row (per-statement) function. `'passthrough'` copies a source column (the column
125
- * permutation that *every* PK / UNIQUE-covered column must use, so the backing key and
126
- * the inverse-projection conflict map are recoverable); `'expr'` evaluates a
127
- * deterministic scalar expression over the source row (a non-key derived column —
128
- * `materialized-view-rowtime-expression-projections`). `eval` is the runtime-compiled
129
- * evaluator (see {@link compileSourceRowEvaluator}), so a computed backing value is
130
- * exactly what `select <body>` would produce.
131
- */
132
- export type BackingProjector = {
133
- readonly kind: 'passthrough';
134
- readonly sourceCol: number;
135
- } | {
136
- readonly kind: 'expr';
137
- readonly eval: (sourceRow: Row) => SqlValue;
138
- };
139
- /**
140
- * One **weakened** column of a coarsened backing key K′, precomputed once at
141
- * registration for the row-time collision telemetry
142
- * ({@link MaterializedViewManager.detectAndReportCoarseningCollisions}). Carries the
143
- * backing column index to read from each {@link BackingRowChange} image, the
144
- * **source** (pre-coarsening, stricter) collation the divergence test compares
145
- * under, the **output** (coarsened) collation the backing key enforces, and the
146
- * column name for the {@link MaintenanceCollisionEvent} payload. Derived from
147
- * `mv.derivation.coarsenedKey.weakened` (column names) via `mv.columnIndexMap`.
148
- */
149
- interface CoarseningWatchColumn {
150
- /** Backing column index (= body output column index) the weakened K′ column lands at. */
151
- readonly index: number;
152
- /** Source key enforcement collation (pre-coarsening); the divergence test compares under it. */
153
- readonly sourceCollation: string;
154
- /** Output (coarsened) collation the backing key enforces. */
155
- readonly outputCollation: string;
156
- /** Backing/output column name (for the event payload's `weakenedColumns`). */
157
- readonly column: string;
158
- }
159
- /**
160
- * Common identity + cost-gate fields shared by every {@link MaintenancePlan} arm.
161
- * `chosenStrategy` / `sourceStats` are set once by the create-time cost gate
162
- * ({@link MaterializedViewManager.buildMaintenancePlan}, via `selectMaintenanceStrategy`)
163
- * and are not re-evaluated per write, except for the residual → rebuild demotion
164
- * (`shouldDegradeToRebuild`; dormant until the residual arm is reachable).
165
- */
166
- interface MaintenancePlanCommon {
167
- /** The MV this plan maintains. */
168
- mv: MaintainedTableSchema;
169
- /** Lowercased `schema.table` of the single source `T`. */
170
- sourceBase: string;
171
- backingSchema: string;
172
- backingTableName: string;
173
- /** Strategy the cost gate chose: argmin `maintenanceCost` over the body's sound strategies. */
174
- chosenStrategy: MaintenanceStrategy;
175
- /** Create-time cost inputs (StatsProvider + forward optimizer), retained so the DML
176
- * boundary can re-cost residual vs. rebuild against the actual changeCardinality. */
177
- sourceStats: MaintenanceSourceStats;
178
- /** Compiled declared-CHECK/FK validator over derived row images — present ONLY
179
- * when the maintained table declares ≥1 applicable CHECK or ≥1 FK (the
180
- * zero-overhead gate: MV-sugar backings and constraint-less maintained tables
181
- * carry `undefined` and pay nothing per write). Built once at registration
182
- * ({@link MaterializedViewManager.registerMaterializedView}); applied to each
183
- * insert/update {@link BackingRowChange} before the cascade. */
184
- derivedRowValidator?: DerivedRowConstraintValidator;
185
- /** Precomputed weakened-K′-column watch list for row-time collision telemetry —
186
- * present ONLY when `mv.derivation.coarsenedKey` is stamped (the zero-overhead
187
- * gate: a provable-key / refining-lineage-key MV carries `undefined` and pays
188
- * nothing per write — detection short-circuits on this field). Built once at
189
- * registration ({@link MaterializedViewManager.registerMaterializedView} →
190
- * {@link MaterializedViewManager.buildCoarseningWatch}); read by
191
- * {@link MaterializedViewManager.detectAndReportCoarseningCollisions} from both
192
- * the bounded-delta and full-rebuild maintenance arms. */
193
- coarseningWatch?: ReadonlyArray<CoarseningWatchColumn>;
194
- }
195
- export interface InverseProjectionPlan extends MaintenancePlanCommon {
196
- readonly kind: 'inverse-projection';
197
- /** Backing-table physical primary-key definition (the column order the btree keys on). */
198
- backingPkDefinition: ReadonlyArray<{
199
- index: number;
200
- desc?: boolean;
201
- collation?: string;
202
- }>;
203
- /** `projectors[j]` derives backing output column `j` from the changed source row —
204
- * either a passthrough copy of a source column or a deterministic scalar expression
205
- * over the source row. Every PK / backing-key column is `'passthrough'` (eligibility
206
- * rejects a computed column that lands in the backing key); non-key columns may be
207
- * `'expr'`. {@link MaterializedViewManager.lookupCoveringConflicts} reads only the
208
- * passthrough projectors for its inverse (source↔backing) map. */
209
- projectors: BackingProjector[];
210
- /** Partial-WHERE predicate evaluated on a single source row; absent ⇒ every row
211
- * is in scope. A source row contributes a backing row only when this is
212
- * unambiguously TRUE (mirrors partial-UNIQUE / partial-index semantics). */
213
- predicate?: CompiledPredicate;
214
- }
215
- /**
216
- * The always-correct **floor**: a body for which no bounded-delta arm is sound is
217
- * maintained by re-evaluating it in full per writing statement and replacing the backing
218
- * transactionally (a single `'replace-all'` {@link MaintenanceOp} — a keyed diff against
219
- * the backing's pending layer, so the delta still commits/rolls-back with the source
220
- * write and still drives the MV-over-MV cascade). The whole optimized body is compiled
221
- * once at registration into {@link bodyScheduler}; {@link MaterializedViewManager.applyFullRebuild}
222
- * runs it to completion against live source state and diffs the result into the backing.
223
- *
224
- * Reachability: `buildMaintenancePlan` routes a body here whenever no bounded-delta arm
225
- * fits ({@link MaterializedViewManager.tryBuildBoundedDeltaArm} returns `null`). It is the
226
- * one **deferred** arm — marked dirty per source row and rebuilt exactly once at the
227
- * end-of-statement flush ({@link MaterializedViewManager.flushDeferredRebuilds}), so a bulk
228
- * write is O(body) not O(rows × body). See `docs/materialized-views.md` § Full-rebuild floor.
229
- */
230
- export interface FullRebuildPlan extends MaintenancePlanCommon {
231
- readonly kind: 'full-rebuild';
232
- /** The optimized body compiled once at registration — the **whole** body (no
233
- * `injectKeyFilter`), with the read-side MV rewrite suppressed so it reads its sources,
234
- * not the backing it populates. Re-run to completion per writing statement, bound
235
- * through the live transaction (reads-own-writes), to recompute every backing row. */
236
- bodyScheduler: Scheduler;
237
- /** Every source base (lowercased `schema.table`) the body reads — set-op legs, every
238
- * join source, etc. The plan is indexed under each in `rowTimeBySource` (via
239
- * {@link planSourceBases}), so a write to **any** of them triggers a rebuild; missing
240
- * one would leave the MV stale on that source's writes. `sourceBase` (the
241
- * {@link MaintenancePlanCommon} field) holds the first of these for parity. */
242
- sourceBases: string[];
243
- }
244
- /**
245
- * The general-body residual-recompute arm: per source change, derive the affected
246
- * binding key(s) from the changed row, run a key-filtered residual of the body against
247
- * **live mid-transaction source state**, and apply the keyed diff — upsert the recomputed
248
- * slice (replacing the old row at the same backing key; a value-identical recompute is
249
- * suppressed by the host, see vtab/backing-host.ts) or, when the residual returns
250
- * nothing, delete the emptied key. Wired for the **single-source aggregate** shape
251
- * (`select g1,… , agg(…) from T [where P] group by g1,…` over bare group columns) by
252
- * `materialized-view-rowtime-residual-recompute`; the 1:1 row-preserving join shape
253
- * (`'row'` binding) reuses the same kernel in a follow-on ticket.
254
- *
255
- * The residual is the body with a key-equality filter injected on `T`'s
256
- * `TableReferenceNode` via {@link injectKeyFilter} (parameterized `gk0…` for a group
257
- * binding, `pk0…` for a row binding), compiled + cached once at registration and run
258
- * synchronously through the live transaction so the source read is reads-own-writes —
259
- * the synchronous analogue of `database-assertions.ts`'s residual path.
260
- *
261
- * It carries the {@link BindingMode} the spike names as the convergence point (built
262
- * directly from the body's shape — for an aggregate, the bare GROUP BY columns; NOT
263
- * via `extractBindings`, whose `'group'` classification additionally requires the group
264
- * key to cover a source unique key and so reports `'global'` for the common
265
- * `group by <non-key>` body). `degradeToRebuild` is the cost gate's full-rebuild escape
266
- * flag — dormant in v1 (the per-row recompute is correct without batching, and the
267
- * full-rebuild arm is unwired).
268
- */
269
- export interface ResidualRecomputePlan extends MaintenancePlanCommon {
270
- readonly kind: 'residual-recompute';
271
- binding: BindingMode;
272
- degradeToRebuild: boolean;
273
- /** Cached scheduler for the key-filtered residual (the body with `injectKeyFilter`
274
- * applied on `T`). Re-run per affected key tuple, bound through the live transaction. */
275
- residualScheduler: Scheduler;
276
- /** Bind-parameter prefix the residual was compiled with: `'gk'` (group) / `'pk'` (row). */
277
- bindParamPrefix: 'gk' | 'pk';
278
- /** Source-column indices of the binding key (group columns / row key columns). The
279
- * affected key tuple is `bindColumns.map(c => changedRow[c])`, bound to `${prefix}{i}`. */
280
- bindColumns: number[];
281
- /** Backing-table physical primary-key definition (the column order the btree keys on). */
282
- backingPkDefinition: ReadonlyArray<{
283
- index: number;
284
- desc?: boolean;
285
- collation?: string;
286
- }>;
287
- /** Source column projected (passthrough) into each backing-PK column, in
288
- * `backingPkDefinition` order. The old backing slice's delete key for a changed row
289
- * `R` is `buildPrimaryKeyFromValues(backingPkSourceCols.map(sc => R[sc]), backingPkDefinition)`. */
290
- backingPkSourceCols: number[];
291
- }
292
- /**
293
- * The single-source lateral-TVF fan-out arm: a body of the shape
294
- * `select T.pk…, …, f.* from T cross join lateral tvf(<args over T>) f`, where each base
295
- * row of `T` fans out to **N** backing rows (one per row the TVF emits for it). The
296
- * backing PK is the **composite product key** `(T.pk ∪ tvf-key)` that
297
- * `optimizer-keyed-cross-product-join-keys` advertises through `keysOf` over the lateral
298
- * join, with the base PK as its **leading prefix** (asserted at build).
299
- *
300
- * Per changed base row, maintenance is a **keyed diff of the recomputed fan-out against
301
- * the existing effective slice for the base-PK prefix** (read via the host's
302
- * `scanEffective`, since one base row owns many backing rows sharing the prefix): re-run
303
- * the TVF fan-out **residual** for that base row, delete only the existing keys the
304
- * recompute no longer produces, and **upsert** each recomputed row (value-identical
305
- * upserts are suppressed by the host). An UPDATE diffs both the OLD and NEW base keys
306
- * (the base PK may move); a DELETE diffs the old slice to all-deletes; an INSERT diffs
307
- * against an empty slice. This reuses the residual kernel of {@link ResidualRecomputePlan}
308
- * unchanged — the affected-key derivation, the `injectKeyFilter` residual (pinned to the
309
- * base `TableReferenceNode` with the `'pk'` prefix), reads-own-writes execution, the cost
310
- * gate — and differs only in the **prefix-slice** diff (vs point-key) and the **N-row**
311
- * residual (vs ≤1). The body's WHERE, if any, is part of the residual (so an out-of-scope
312
- * base row fans out to zero rows), exactly as in the aggregate arm.
313
- *
314
- * `chosenStrategy` is `'residual-recompute'` (the shared key-filtered re-execution cost
315
- * shape — the fan-out factor is unknown at create); `kind` is `'prefix-delete'` (the
316
- * apply-arm dispatcher). `degradeToRebuild` is dormant (as in the aggregate arm).
317
- */
318
- export interface PrefixDeletePlan extends MaintenancePlanCommon {
319
- readonly kind: 'prefix-delete';
320
- /** Substrate parity (the base-PK 'row' binding); unread by the apply path, which uses
321
- * `bindColumns` / `backingPrefixSourceCols`. */
322
- binding: BindingMode;
323
- degradeToRebuild: boolean;
324
- /** Cached scheduler for the base-PK-keyed residual (the body with `injectKeyFilter`
325
- * applied on `T`, `'pk'` prefix). Re-run per affected base key; fans out to N rows. */
326
- residualScheduler: Scheduler;
327
- bindParamPrefix: 'pk';
328
- /** Source-`T` PK column indices (the base key). The affected key tuple is
329
- * `bindColumns.map(c => changedRow[c])`, bound to `pk{i}`. */
330
- bindColumns: number[];
331
- /** Full backing-table physical primary key (base-PK prefix ++ TVF-key tail). */
332
- backingPkDefinition: ReadonlyArray<{
333
- index: number;
334
- desc?: boolean;
335
- collation?: string;
336
- }>;
337
- /** Number of leading backing-PK columns that form the base-PK prefix (= `bindColumns.length`). */
338
- basePrefixLength: number;
339
- /** Source-`T` column projected into each leading (base-prefix) backing-PK column, in
340
- * backing-PK order. The by-prefix delete key for a changed row `R` is
341
- * `backingPrefixSourceCols.map(sc => R[sc])`. */
342
- backingPrefixSourceCols: number[];
343
- }
344
- /**
345
- * The 1:1 row-preserving **inner/cross join** arm: a body
346
- * `select … from T join P on T.fk = P.id` where `T` contributes **exactly one** MV row
347
- * per governed `T` row (proven by {@link proveOneToOneJoin} — no row loss via NOT-NULL
348
- * FK→PK referential integrity, no fan-out via `isUnique(T.pk)` at the join frame). The
349
- * backing is keyed on `T`'s PK (the composite product key `keysOf` advertises across the
350
- * 1:1 join collapses to `T`'s PK), so each changed `T` row maps to one backing row.
351
- *
352
- * Reuses the residual kernel of {@link ResidualRecomputePlan} on its **driving (`T`)**
353
- * side via {@link ForwardResidualPlan}: a `T`-keyed (`'pk'`) residual recomputes the one
354
- * joined row for a changed `T` row (run residual → upsert the recomputed row, or delete
355
- * the key when it returns nothing), identical to a `'row'`-binding aggregate of size 1.
356
- * `applyForwardResidual` drives it.
357
- *
358
- * The **lookup (`P`)** side is the join arm's distinct problem: the MV's `sourceTables`
359
- * includes `P`, so a write to `P` also fires maintenance, but the forward residual is
360
- * keyed on `T`'s PK and a `P` row joins *many* `T` rows. This plan therefore carries a
361
- * **second residual keyed on `P`'s PK** (`lookupResidualScheduler`): for a `P` change it
362
- * runs `… where P.pk = :pk0` (the body **including** its WHERE) against live state,
363
- * returning every currently in-scope joined row (each carrying its `T.pk` backing key), and
364
- * **upserts** each.
365
- *
366
- * **WHERE handling — bounded-delta over a partial-WHERE 1:1 join.** A body WHERE is
367
- * classified at build by which base table(s) its columns reference
368
- * ({@link MaterializedViewManager.buildJoinResidualPlan}):
369
- * - **`T`-only predicate** — no extra machinery. The forward (`T`) residual already injects
370
- * + applies the WHERE (an out-of-scope `T` row recomputes to zero residual rows ⇒ its
371
- * delete-without-upsert removes the backing row), and a `T`-column predicate cannot move
372
- * the membership set `{ T : T.fk = P.pk }`, so the lookup side stays **upsert-only**
373
- * (`lookupMembershipResidualScheduler` absent) — sound for the same reason the no-WHERE
374
- * arm is.
375
- * - **`P`-referencing predicate** (or both sides) — a `P` write can flip a row's WHERE truth
376
- * and so add/remove a backing row, which upsert-only could never delete. The lookup side
377
- * becomes **delete-capable**: `lookupMembershipResidualScheduler` is the body with
378
- * `injectKeyFilter` on `P` but the WHERE **stripped** (membership only). Per affected `P`
379
- * key {@link MaterializedViewManager.applyLookupResidual} diffs it against the in-scope
380
- * `lookupResidualScheduler` (WHERE retained): membership keys the in-scope recompute no
381
- * longer produces are deleted, the in-scope rows are upserted — a keyed diff that converges
382
- * the membership both ways without churning the unchanged rows.
383
- *
384
- * Still inner/cross only; outer joins and **fanning** (non-1:1) joins continue to fall to the
385
- * full-rebuild floor. See `docs/incremental-maintenance.md` § join-residual and the soundness
386
- * note in {@link MaterializedViewManager.applyLookupResidual}.
387
- */
388
- export interface JoinResidualPlan extends MaintenancePlanCommon, ForwardResidualPlan {
389
- readonly kind: 'join-residual';
390
- /** Substrate parity: the driving `T`'s `'row'`/PK binding. */
391
- binding: BindingMode;
392
- degradeToRebuild: boolean;
393
- bindParamPrefix: 'pk';
394
- /** Lowercased `schema.table` of the lookup source `P` (distinct from `sourceBase` = `T`). */
395
- lookupBase: string;
396
- /** Cached scheduler for the in-scope lookup-keyed residual (the body — WHERE **retained** —
397
- * with `injectKeyFilter` applied on `P`, `'pk'` prefix). Re-run per affected `P` key;
398
- * returns the currently in-scope joined rows to upsert. */
399
- lookupResidualScheduler: Scheduler;
400
- /** Delete-capable lookup membership residual (the body with the WHERE **stripped** and
401
- * `injectKeyFilter` on `P`). Present **iff** the body WHERE references `P`: the lookup side
402
- * must then delete the backing key of every currently-referencing `T` row (regardless of
403
- * scope) before re-upserting the in-scope survivors, so a `P` write that flips a row's WHERE
404
- * membership adds/removes its backing row. Absent for a no-WHERE or `T`-only-WHERE body
405
- * (the lookup side is sound upsert-only — membership cannot move on a `P` write). */
406
- lookupMembershipResidualScheduler?: Scheduler;
407
- /** Source-`P` PK column indices (the lookup key). The affected key tuple for a `P`
408
- * change is `lookupBindColumns.map(c => changedRow[c])`, bound to `pk{i}`. */
409
- lookupBindColumns: number[];
410
- lookupBindParamPrefix: 'pk';
411
- }
412
- /**
413
- * Per-statement cache of resolved backing {@link VirtualTableConnection}s, keyed by the
414
- * lowercased backing `schema.table`. Created **once per DML generator run** (one
415
- * statement) and threaded through the maintenance path so the backing-connection
416
- * resolution — a scan over *all* the Database's active connections in
417
- * {@link MaterializedViewManager.getBackingConnection} — is paid once per
418
- * (statement, backing) instead of once per source row. This amortizes the dominant
419
- * per-row overhead of a bulk `insert`/`update`/`delete` over a covered table.
420
- *
421
- * It is purely a resolution cache: each **bounded-delta** arm's per-row ops are still
422
- * applied **immediately** to the cached connection's pending transaction layer, so a later
423
- * same-statement row's enforcement scan (`lookupCoveringConflicts`) still observes every
424
- * earlier row's backing write. The one exception is the **full-rebuild** arm, which the DML
425
- * boundary defers to a single end-of-statement {@link MaterializedViewManager.flushDeferredRebuilds}
426
- * (tracked in a separate per-statement dirty set, not this cache) — sound because a
427
- * full-rebuild MV is never a covering structure, so no enforcement scan depends on its
428
- * per-row visibility. See `docs/materialized-views.md` § Synchronous, transactional,
429
- * per-statement. Because the cache is scoped to one generator run, the connection it holds
430
- * cannot be torn down mid-statement; the cold enforcement/eviction paths that omit the cache
431
- * re-resolve the *same* connection deterministically, so reads-own-writes is unaffected.
432
- */
433
- export type BackingConnectionCache = Map<string, VirtualTableConnection>;
45
+ import type { MaterializedViewManagerContext, ResidualKeyBatch, BackingConnectionCache } from './database-materialized-views-plans.js';
46
+ export type { BackingConnectionCache, ResidualKeyBatch } from './database-materialized-views-plans.js';
434
47
  export declare class MaterializedViewManager {
435
48
  private readonly ctx;
436
49
  private unsubscribeSchemaChanges;
@@ -624,48 +237,95 @@ export declare class MaterializedViewManager {
624
237
  * too. Omitted by the cold enforcement/eviction callers, which re-resolve the same
625
238
  * connection deterministically.
626
239
  *
627
- * `deferred` is the optional per-statement deferred-rebuild set (MV keys). A
628
- * `'full-rebuild'` plan re-evaluates the WHOLE body, so applying it per source row is
629
- * O(rows × body) pathological. When the DML boundary supplies a `deferred` set, a
630
- * full-rebuild plan is instead marked dirty here (no per-row apply) and rebuilt exactly
631
- * once at the end-of-statement {@link flushDeferredRebuilds} boundary. The bounded-delta
632
- * arms stay per-row-immediate (cheap, and the covering-UNIQUE enforcement scan depends on
633
- * their per-row backing visibility; a full-rebuild MV is never a covering structure, so
634
- * deferring it cannot starve that scan). A cold caller without a `deferred` set falls
635
- * through to an inline rebuild a safe, unamortized fallback that the
636
- * enforcement/eviction callers never actually reach (they never name a full-rebuild MV).
637
- */
638
- maintainRowTime(sourceBase: string, change: BackingRowChange, cache?: BackingConnectionCache, deferred?: Set<string>, depth?: number): Promise<void>;
639
- /**
640
- * Flush the per-statement deferred full-rebuild set at the end-of-statement boundary:
641
- * rebuild every dirtied full-rebuild MV exactly once (not once per source row) and
642
- * cascade each rebuild's effective {@link BackingRowChange}(s) onward so MV-over-MV
643
- * consumers converge.
644
- *
645
- * Drained as a worklist over the producer→consumer DAG. Each rebuild calls
646
- * {@link applyFullRebuild} (re-run the whole body against live mid-transaction source
647
- * state → a `'replace-all'` diff) and routes the realized delta back through
648
- * {@link maintainRowTime} with the SAME `deferred` set: an incremental consumer applies
649
- * inline; a full-rebuild consumer re-dirties into the drain (rebuilt in a later round,
650
- * after its producer's delta has landed). The drain proceeds in **rounds** — each round
651
- * snapshots the current dirty set, clears it, and rebuilds each member, collecting the
652
- * next round's re-dirties — so a consumer is never permanently stale (a producer rebuilt
653
- * in the same round re-dirties it for the next), and convergence takes at most one round
654
- * per level of the full-rebuild sub-DAG.
240
+ * `deferred` is the optional per-statement deferred-rebuild set (MV keys) and
241
+ * `residualBatch` the optional per-statement residual key batch. A `'full-rebuild'`
242
+ * plan re-evaluates the WHOLE body, so applying it per source row is O(rows × body)
243
+ * pathological; when the DML boundary supplies a `deferred` set it is instead marked
244
+ * dirty here (no per-row apply) and rebuilt exactly once at the end-of-statement
245
+ * {@link flushDeferredMaintenance} boundary. The three **residual** arms
246
+ * (`'residual-recompute'`, `'prefix-delete'`, `'join-residual'`) are likewise per-key
247
+ * recomputes whose per-row apply costs a scheduler run each; when the DML boundary
248
+ * supplies a `residualBatch`, they accumulate their affected binding keys (deduped
249
+ * across the statement) and recompute once per distinct key at the same flush.
250
+ * `'inverse-projection'` alone stays per-row-immediate: its delta is a cheap pure
251
+ * projection AND the covering-UNIQUE enforcement scan depends on its per-row backing
252
+ * visibility ({@link lookupCoveringConflicts} reads only inverse-projection backings,
253
+ * so deferring the other arms cannot starve that scan
254
+ * {@link findRowTimeCoveringStructure} declines them). A cold caller without the
255
+ * per-statement structures falls through to the inline per-change apply — a safe,
256
+ * unamortized fallback (the enforcement/eviction callers only ever name
257
+ * inverse-projection MVs, but the fallback stays correct for every arm).
258
+ */
259
+ maintainRowTime(sourceBase: string, change: BackingRowChange, cache?: BackingConnectionCache, deferred?: Set<string>, residualBatch?: ResidualKeyBatch, depth?: number): Promise<void>;
260
+ /**
261
+ * The invariant pipeline every realized maintenance delta runs, in order: coarsening
262
+ * collision telemetry (observe-only; gated on `coarseningWatch`), the NOT-NULL
263
+ * ordering-seeded-PK guard (no-op unless the MV carries the skew), derived-row
264
+ * CHECK/FK validation (no-op for a constraint-less table; BEFORE the cascade so a
265
+ * consumer never consumes an invalid producer row), parent-side referential
266
+ * enforcement (RESTRICT-walk then declared actions, after `M`'s own image is
267
+ * validated), then the MV-over-MV cascade — each effective {@link BackingRowChange}
268
+ * routed back through {@link maintainRowTime} with the SAME per-statement structures,
269
+ * so a residual consumer accumulates into the batch and a full-rebuild consumer
270
+ * re-dirties the deferred set. Shared verbatim by the per-row inline path and the
271
+ * end-of-statement flush ({@link flushDeferredMaintenance}, which calls with
272
+ * `depth = 0` — its own round bound {@link assertFlushRounds} replaces the recursion
273
+ * bound {@link assertCascadeDepth} there).
274
+ */
275
+ private postApplyBackingChanges;
276
+ /**
277
+ * Flush the per-statement deferred maintenance at the end-of-statement boundary:
278
+ * recompute every accumulated residual key exactly once per distinct key
279
+ * ({@link applyResidualBatch}) and rebuild every dirtied full-rebuild MV exactly once
280
+ * (not once per source row), cascading each apply's effective
281
+ * {@link BackingRowChange}(s) onward so MV-over-MV consumers converge.
282
+ *
283
+ * Drained as a worklist over the producer→consumer DAG. Each apply routes its realized
284
+ * delta back through {@link maintainRowTime} with the SAME `deferred` set and
285
+ * `residualBatch`: an inverse-projection consumer applies inline; a residual consumer
286
+ * accumulates its keys into the batch and a full-rebuild consumer re-dirties into the
287
+ * drain (recomputed in a later round, after its producer's delta has landed). The drain
288
+ * proceeds in **rounds** — each round snapshots both structures, clears them, and
289
+ * applies each member, collecting the next round's re-accumulations — so a consumer is
290
+ * never permanently stale (a producer flushed in the same round re-accumulates it for
291
+ * the next), and convergence takes at most one round per level of the deferred sub-DAG.
292
+ * Residual entries drain before rebuilds within a round (arbitrary for correctness —
293
+ * every apply reads live state — but it lets a same-round rebuild read its residual
294
+ * producers' already-flushed backings, saving a round in mixed chains).
655
295
  *
656
296
  * Termination: the dependency DAG is acyclic (a consumer MV requires its producer to
657
- * pre-exist), so the longest full-rebuild chain — hence the round count — is bounded by
297
+ * pre-exist), so the longest deferred chain — hence the round count — is bounded by
658
298
  * the registered-row-time-MV count. Exceeding it signals a structurally-impossible cycle
659
299
  * and fails loud ({@link assertFlushRounds}) — the worklist analogue of
660
300
  * {@link assertCascadeDepth}. This should never fire.
661
301
  *
662
302
  * The DML executor calls this INSIDE the statement-atomicity savepoint (after the row
663
- * loop, before the savepoint release), so a failed rebuild rolls the whole statement
664
- * back. An empty set is a no-op (no overhead on statements touching no full-rebuild MV).
665
- */
666
- flushDeferredRebuilds(deferred: Set<string>, cache?: BackingConnectionCache): Promise<void>;
667
- /**
668
- * Round backstop for {@link flushDeferredRebuilds}. The full-rebuild sub-DAG is acyclic,
303
+ * loop, before the savepoint release), so a failed recompute/rebuild including a
304
+ * derived-row validation failure or parent-side RESTRICT over the flushed delta rolls
305
+ * the whole statement back with the same attribution as the per-row path. Empty
306
+ * structures are a no-op (no overhead on statements touching no deferred MV).
307
+ */
308
+ flushDeferredMaintenance(deferred: Set<string>, residualBatch: ResidualKeyBatch, cache?: BackingConnectionCache): Promise<void>;
309
+ /**
310
+ * Flush one residual-arm MV's accumulated statement keys: run the residual variant
311
+ * once per distinct key against live post-statement state and apply all resulting ops
312
+ * in one {@link BackingHost.applyMaintenance} call (upsert recomputed slices, delete
313
+ * emptied keys — the same keyed diff the per-row path applies, evaluated once per key
314
+ * instead of once per touching row).
315
+ *
316
+ * **Per-statement rebuild demotion** ({@link shouldDegradeToRebuild}, re-costed here
317
+ * against the statement's ACTUAL distinct-key count and the plan's create-time
318
+ * {@link MaintenancePlanCommon.sourceStats}): when k residual runs cost more than one
319
+ * whole-body rebuild — a statement touching most groups — run the plan's
320
+ * {@link ResidualArmCommon.fullRebuildScheduler} and apply a single `'replace-all'`
321
+ * keyed diff instead. Stateless: the stored strategy is unchanged, so a later
322
+ * low-cardinality statement reverts to per-key residuals. Kept on the manager
323
+ * (delegating op computation to the apply-module free helpers) so the statement-flush
324
+ * suites can instrument it alongside {@link applyFullRebuild}.
325
+ */
326
+ private applyResidualBatch;
327
+ /**
328
+ * Round backstop for {@link flushDeferredMaintenance}. The full-rebuild sub-DAG is acyclic,
669
329
  * so the drain converges in at most one round per chain level — bounded by the row-time
670
330
  * MV count. A round count beyond that (`+1` slack for an initial dirty set already
671
331
  * spanning multiple levels) signals a structural impossibility (a cycle) — fail loud
@@ -690,276 +350,19 @@ export declare class MaterializedViewManager {
690
350
  * `'full-rebuild'` (the floor — re-evaluate the whole body and replace the backing). The
691
351
  * floor ignores the specific `change` (it rebuilds wholesale); the others derive a
692
352
  * bounded per-row delta from it.
693
- */
694
- private applyMaintenancePlan;
695
- /**
696
- * Compute an `'inverse-projection'` plan's per-row backing delta, apply it, and
697
- * return the **effective** {@link BackingRowChange}(s) the backing layer realized.
698
- * An out-of-scope row (or a delete of an absent backing key) yields no change. This
699
- * body is the shipped covering-index maintenance, lifted verbatim from the former
700
- * `applyRowTimeChange`, plus the equal-image short-circuit: an UPDATE whose old and
701
- * new projected images are value-identical (both in scope) projects to NO backing
702
- * delta — the dominant no-op echo (a source update touching only unprojected columns,
703
- * or rewriting a projected column to its existing value) is suppressed before any
704
- * backing-connection work. Accurate by the maintenance invariant (the backing row IS
705
- * the old image's projection), so nothing would have changed; the host's
706
- * value-identical upsert skip (vtab/backing-host.ts) remains the effective-state
707
- * backstop for the paths that do emit ops.
708
- */
709
- private applyInverseProjection;
710
- /**
711
- * Validate the row images a maintenance apply WROTE (insert/update
712
- * {@link BackingRowChange}s — a delete writes no image) against the plan's
713
- * compiled {@link DerivedRowConstraintValidator}. Inline checks abort the
714
- * writing statement with the maintained-table-attributed CONSTRAINT error;
715
- * auto-deferred checks (subquery CHECK, every child-side FK) queue to the
716
- * deferred-constraint queue and validate at commit. Deferred entries are
717
- * pinned to the backing connection the maintenance write used (resolved from
718
- * the per-statement cache, or re-resolved deterministically — the same
719
- * connection either way) so commit-time evaluation reads the same pending
720
- * state, mirroring the DML pipeline's active-connection capture.
721
- */
722
- private validateDerivedChanges;
723
- /**
724
- * Fire **parent-side** referential enforcement over the backing rows a maintenance
725
- * apply REMOVED or re-keyed (delete / key-update {@link BackingRowChange}s — an insert
726
- * has no parent-side action). When the maintained table `M` is the PARENT (FK target)
727
- * of an FK declared on an ordinary table `C` (`create table C (… references M(col) …)`),
728
- * a maintenance-driven delete/key-update of the referenced `M` row would silently orphan
729
- * `C`'s rows, bypassing the declared RESTRICT / referential action. This is the
730
- * **dual** of {@link validateDerivedChanges} (constraints declared *on* `M`); the FK here
731
- * lives on `C` and references `M`, so it is invisible to `M`'s own plan/validator.
732
- *
733
- * It reuses the SAME shared referential-action engine the DML executor and the
734
- * external-change ingestion seam use — no third copy — applying its two functions over
735
- * each backing change exactly as `database-external-changes.ts` does:
736
- * - {@link assertTransitiveRestrictsForParentMutation} — pre-walk the transitive cascade
737
- * closure and throw a CONSTRAINT error naming `M` on any surviving RESTRICT child;
738
- * - {@link executeForeignKeyActionsAndLens} — run declared CASCADE / SET NULL / SET DEFAULT,
739
- * re-entering the DML executor (the already-holding-the-mutex variant) for each cascaded
740
- * child write, so `C`'s own constraints, watches, nested cascades, and (if `C` is itself
741
- * an MV source) its own maintenance all fire.
742
353
  *
743
- * Ordering: called AFTER the backing delta has landed in the pending layer (the RESTRICT
744
- * walk runs POST-application the child rows it keys off still exist because the cascade
745
- * has not run yet) and AFTER `M`'s own image is validated, matching the DML executor's
746
- * per-change order (capture → MV maintenance FK actions) and the external-changes seam.
747
- * `lensRouted = false`: a maintenance backing write is a physical basis write (maintained
748
- * tables are not lens basis spines). A surviving RESTRICT throws up through
749
- * {@link maintainRowTime} → the DML executor → the statement, rolling back the source write
750
- * attributed to `M`.
751
- *
752
- * Gate: a cheap `foreign_keys`-pragma early-return keeps the pragma-off path free (the
753
- * engine also early-returns, but skipping the `getTable` + loop avoids all per-change work).
754
- * NOT gated on `plan.derivedRowValidator` — that gate is child-side (constraints *on* `M`);
755
- * an inbound FK lives on `C` and leaves `M`'s plan untouched. Beyond the gate it fires
756
- * unconditionally per delete/update change, but the engine no longer pays an `O(catalog)`
757
- * scan: both calls route through `SchemaManager.getReferencingForeignKeys`, the precomputed
758
- * reverse-FK index, so an `M` that nothing references resolves to the shared empty bucket and
759
- * each call early-returns in O(1) — a maintained table with no inbound FK (the common case)
760
- * pays only the pragma check plus one map lookup per delete/key-update change.
761
- */
762
- private enforceParentSideReferentialActions;
763
- /**
764
- * Resolve the {@link BackingHost} capability surface for a backing table —
765
- * see `vtab/backing-host.ts` for the contract. The host is resolved fresh per
766
- * use (a map lookup on the owning module), so a drop+recreate of the backing
767
- * always yields the new incarnation's host.
354
+ * The dispatch stays on the manager (the per-arm appliers live in
355
+ * database-materialized-views-apply.ts as free functions over the manager context); it
356
+ * is the seam the row-time equivalence suite instruments to observe the effective
357
+ * changes a maintenance apply realizes.
768
358
  */
769
- private backingHost;
770
- /**
771
- * Obtain (lazily create + register) the backing table's
772
- * {@link VirtualTableConnection} for the current transaction. Reuses the same
773
- * connection a `select` from the MV resolves to (so reads-own-writes holds) —
774
- * matched among the Database's registered connections by
775
- * {@link BackingHost.ownsConnection}, which is pinned to the live backing
776
- * incarnation; a freshly created connection is registered with the Database so
777
- * the coordinated commit/rollback covers its pending state in lockstep with the
778
- * source write.
779
- *
780
- * When an optional per-statement {@link BackingConnectionCache} is supplied, the
781
- * scan over the Database's active connections (the dominant per-row cost on a bulk
782
- * write) is paid once per (statement, backing): a hit returns the cached connection
783
- * directly, and a miss caches whichever connection the scan resolves — or the one it
784
- * lazily creates + registers. Caching the resolved/created connection is sound
785
- * because the scan is deterministic within a statement (nothing interleaves between
786
- * a statement's rows to change which connection a `select` from the MV picks), so the
787
- * cache holds exactly what an uncached re-resolution would return.
788
- */
789
- private getBackingConnection;
790
- /**
791
- * Build the row-time maintenance plan for an MV — **cost-gated, with a floor, never a
792
- * shape allowlist**. The builder tries to match a bounded-delta arm by shape
793
- * ({@link tryBuildBoundedDeltaArm}); a body that matches **none** falls through to the
794
- * always-correct {@link buildFullRebuildPlan} floor (re-evaluate the whole body, replace
795
- * the backing transactionally). **No body is rejected for its shape.** Only four
796
- * create-time rejections remain, all non-shape:
797
- * - a **non-deterministic** body without `pragma nondeterministic_schema` — a hard reject
798
- * in the matched arm (so the arm-specific determinism diagnostic survives) or, for a
799
- * body matching no arm, in the floor's whole-body determinism check;
800
- * - a **bag** (no provable unique key) — the floor's `keysOf` reject (a duplicate-producing
801
- * body usually fails the set contract earlier, at create-fill);
802
- * - a body with **no relational output**;
803
- * - a **full-rebuild-only body over a source past the size threshold**
804
- * ({@link isFullRebuildPathological}, the `materialized_view_rebuild_row_threshold` option).
805
- *
806
- * The single source may itself be another MV's backing table (an MV-over-MV body):
807
- * `building/select.ts` rewrites a reference to `mv1` into a `TableReference` against
808
- * `mv1`'s backing table, so the source base is `mv1`'s backing base and the same checks
809
- * evaluate against the (keyed `memory`) backing schema unchanged. A write to `mv1` then
810
- * drives `mv2` via the cascade in {@link maintainRowTime}.
811
- *
812
- * Eligibility is a *cost choice* among the body's structurally-sound strategies
813
- * ({@link selectMaintenanceStrategy}): the bounded-delta arms are preferred by the argmin
814
- * cost gate, and full-rebuild is selected exactly when no bounded-delta arm is sound (an
815
- * empty sound set resolves to the floor) — so an existing eligible shape is unaffected.
816
- */
817
- private buildMaintenancePlan;
818
- /**
819
- * Route the analyzed body to the matching bounded-delta arm, or return `null` when its
820
- * shape fits **no** bounded-delta arm (the caller then builds the full-rebuild floor).
821
- * Each arm builder likewise returns `null` on a sub-shape mismatch and falls through
822
- * here. The arms keep only **determinism** as a hard reject (so their arm-specific
823
- * determinism diagnostic survives — see the individual builders); every other mismatch
824
- * is a `null` fall-through. Bag / no-output / size rejects live in the floor.
825
- */
826
- private tryBuildBoundedDeltaArm;
827
- /**
828
- * Build an `'inverse-projection'` plan for the covering-index shape: a single
829
- * row-preserving source `T` with a primary key, a linear
830
- * `TableReference → optional Filter → Project → optional Sort` body, a projection that
831
- * resolves every source PK column (and every backing-key column) to a **passthrough**
832
- * source column — non-key columns may instead be a **deterministic scalar expression**
833
- * over the source row — and a partial WHERE evaluable on a single source row. Returns
834
- * `null` on any **shape** mismatch (the caller falls through to the full-rebuild floor);
835
- * a **non-deterministic** computed column is the one hard reject (its arm-specific
836
- * determinism diagnostic must survive rather than fall through to the floor's generic one).
837
- */
838
- private buildInverseProjectionPlan;
839
- /**
840
- * Build a `'residual-recompute'` plan for a single-source aggregate body
841
- * (`select g1,…, agg(…) from T [where P] group by g1,…` over **bare** group columns),
842
- * or return `null` on a shape mismatch (the caller falls through to the full-rebuild
843
- * floor). Each changed source row belongs to exactly one group `(g1,…)`; maintaining the
844
- * MV means recomputing that group's backing row from live state — delete the old slice,
845
- * run the group-keyed residual, upsert the recomputed slice (zero rows when the group
846
- * emptied). See {@link ResidualRecomputePlan} and `docs/incremental-maintenance.md`
847
- * § residual-recompute.
848
- *
849
- * A **non-deterministic** group/aggregate expression is the one hard reject (the
850
- * arm-specific determinism diagnostic must survive); every other mismatch — a scalar
851
- * aggregate, a computed group key, a backing key that is not the group key — returns
852
- * `null` → the floor.
853
- *
854
- * NOTE: the group binding is derived **directly** from the aggregate node's bare GROUP
855
- * BY columns, not via `extractBindings`. `analyzeRowSpecific`'s `'group'` classification
856
- * additionally requires the group key to cover a *source* unique key (so it reports
857
- * `'global'` for the common `group by <non-key>` body), which is the wrong test here —
858
- * the backing is keyed by the group key regardless of whether it is a source key.
859
- */
860
- private buildAggregateResidualPlan;
861
- /**
862
- * Build a `'join-residual'` plan for a provably-1:1 row-preserving **inner/cross join**
863
- * body (`select … from T join P on T.fk = P.id`), or return `null` on a shape mismatch
864
- * (the caller falls through to the full-rebuild floor). The driving table `T` is the one
865
- * whose PK the optimizer surfaced as the backing key (the 1:1 join collapses the composite
866
- * product key to `T`'s PK); the other base ref is the lookup `P`. See {@link JoinResidualPlan}
867
- * and `docs/incremental-maintenance.md` § join-residual.
868
- *
869
- * Soundness gates (a mismatch on any returns `null` → floor): exactly two base tables; no
870
- * aggregate over the join; the backing PK is exactly `T`'s PK projected as passthrough
871
- * columns (so each changed `T` row maps to one backing row and the reverse residual's rows
872
- * carry the backing key); the join is provably 1:1 on `T` ({@link proveOneToOneJoin} — no
873
- * row loss via NOT-NULL FK→PK RI, no fan-out via the join-frame `isUnique(T.pk)`); and the
874
- * join is **inner/cross** (an outer join would make the lookup-side reverse residual unsound
875
- * — filtering `P` drops the null-extended rows). A **non-deterministic** projection is the
876
- * one hard reject (its arm-specific determinism diagnostic must survive).
877
- *
878
- * **A body WHERE is now accepted** (it is no longer a blanket reject): the predicate is
879
- * classified by which base table(s) its columns reference (reusing the per-base-ref
880
- * attribute→source-column maps below). A `T`-only predicate needs nothing extra — the
881
- * forward residual already carries it and the membership set `{ T : T.fk = P.pk }` cannot
882
- * move on a `P` write, so the lookup side stays upsert-only. A predicate referencing `P` (or
883
- * both sides) switches the lookup side to a **delete-capable** reverse residual by building
884
- * `lookupMembershipResidualScheduler` (the body with the WHERE stripped, keyed on `P`). See
885
- * {@link JoinResidualPlan}'s "WHERE handling" note and {@link applyLookupResidual}.
886
- */
887
- private buildJoinResidualPlan;
888
- /**
889
- * Compile the **lookup membership** residual for the join-residual arm's delete-capable
890
- * lookup side: the MV body with its top-level WHERE **stripped** (membership only) and a
891
- * key-equality filter injected on the lookup `P`, keyed `pk0…`. The WHERE is stripped at the
892
- * AST level (a shallow clone dropping `where`) and the body re-built + re-analyzed, so only
893
- * the WHERE is removed — the join, its `ON` condition, and any projection sub-expressions are
894
- * preserved. Re-analysis assigns fresh node ids, so `P`'s reference is re-located by base name
895
- * to compute the injection target. Returns `null` if the lookup ref or the key-filter
896
- * injection could not be resolved (the caller then falls to the full-rebuild floor).
897
- *
898
- * Run per affected `P` key, this residual returns **every** `T` row currently joined to `P`
899
- * via the join's `ON` condition — irrespective of the WHERE — so {@link applyLookupResidual}
900
- * can delete each one's `T.pk` backing key before the in-scope residual re-upserts the
901
- * survivors (the membership set the WHERE-bearing reverse residual would otherwise never
902
- * shrink).
903
- */
904
- private compileLookupMembershipResidual;
905
- /**
906
- * Build a `'full-rebuild'` plan — the always-correct floor — for an MV whose body matches
907
- * no bounded-delta arm, or throw with a non-shape diagnostic. This is the fall-through
908
- * builder {@link tryBuildBoundedDeltaArm} routes to on a `null` (no bounded-delta arm fits).
909
- * See {@link FullRebuildPlan} and `docs/materialized-views.md` § Full-rebuild floor /
910
- * § Primary key inference.
911
- *
912
- * Create-time rejections (none shape-based — the floor accepts general bodies):
913
- * - **bag** body with no provable unique key (`keysOf` over the optimized body root is
914
- * empty) — there is no row identity to materialize on. `keysOf` already gates its
915
- * all-columns fallback on `isSet`, so a non-empty result is a real key (a true column
916
- * key OR the all-columns key of a provable set) and an empty result is exactly a bag.
917
- * (A duplicate-producing body usually fails the set contract earlier, at create-fill.)
918
- * - **non-deterministic** body (any `random()`/`now()`/volatile UDF anywhere in the plan)
919
- * without `pragma nondeterministic_schema` — no maintenance could keep it equal to its
920
- * plain view (mirrors the per-arm determinism rejects and the DDL determinism gate);
921
- * - body with **no relational output** (degenerate);
922
- * - **size**: full-rebuild is the only sound strategy *and* the **largest** participating
923
- * source exceeds the `materialized_view_rebuild_row_threshold` option
924
- * ({@link isFullRebuildPathological}) — every DML write would re-scan that source.
925
- * `0` disables the size reject (accept any size).
926
- */
927
- private buildFullRebuildPlan;
928
- /**
929
- * Compile the key-filtered residual for a binding into a reusable {@link Scheduler}:
930
- * the analyzed body with a key-equality filter injected on `T`'s `TableReferenceNode`
931
- * (parameterized `${paramPrefix}0…`), then optimized + emitted. Mirrors the assertion
932
- * evaluator's residual compilation (`database-assertions.ts`) so the two cannot drift.
933
- * Returns `null` if `injectKeyFilter` could not target `T` (the arm builder then falls
934
- * through to the full-rebuild floor).
935
- */
936
- private compileResidual;
937
- /**
938
- * Execute a cached key-filtered residual for one affected key tuple, returning its
939
- * result rows (0 or 1 for the aggregate shape; 0..N for the lateral-TVF fan-out shape).
940
- * Bound through a fresh {@link RuntimeContext} on the live `db` so the residual's source
941
- * scan reuses `T`'s transaction connection and reads this statement's pending writes
942
- * (reads-own-writes) — the synchronous analogue of
943
- * `database-assertions.ts:executeResidualPerTuple`. Shared by the residual-recompute
944
- * (`'gk'`) and prefix-delete (`'pk'`) arms.
945
- */
946
- private runResidual;
947
- /**
948
- * Run a cached maintenance scheduler to completion against **live mid-transaction source
949
- * state** and collect its result rows. Bound through a fresh strict {@link RuntimeContext}
950
- * on the live `db` so the scan reuses the source's transaction connection and reads this
951
- * statement's pending writes (reads-own-writes). The no-`stmt`, fresh-context shape is the
952
- * synchronous analogue of `database-assertions.ts:executeResidualPerTuple`. Shared by the
953
- * key-filtered residual arms ({@link runResidual}, parameterized) and the whole-body
954
- * full-rebuild arm ({@link applyFullRebuild}, no params).
955
- */
956
- private runScheduler;
359
+ private applyMaintenancePlan;
957
360
  /**
958
361
  * Maintain a `'full-rebuild'` MV: re-evaluate the **whole** body against live
959
362
  * mid-transaction source state and replace the backing transactionally. Run the cached
960
363
  * {@link FullRebuildPlan.bodyScheduler} to completion (no params — reads-own-writes via
961
364
  * the same fresh-context path the residual arms use), collect every recomputed row, and
962
- * apply a single `'replace-all'` {@link MaintenanceOp}: a keyed diff (by backing PK) of
365
+ * apply a single `'replace-all'` MaintenanceOp: a keyed diff (by backing PK) of
963
366
  * the recomputed rows against the backing's current pending-layer contents (insert/
964
367
  * update/delete, identical rows skipped). The diff rides the backing's **pending**
965
368
  * `TransactionLayer`, so it commits/rolls-back in lockstep with the source write, and the
@@ -967,176 +370,20 @@ export declare class MaterializedViewManager {
967
370
  *
968
371
  * Unlike the bounded-delta arms this ignores the specific changed row — the floor
969
372
  * rebuilds wholesale. It is therefore deferred to a single end-of-statement flush
970
- * ({@link flushDeferredRebuilds}) rather than run per source row, so a bulk statement
373
+ * ({@link flushDeferredMaintenance}) rather than run per source row, so a bulk statement
971
374
  * rebuilds exactly once; this is that one rebuild. An empty body (zero rows) yields a
972
- * `'replace-all' []`, which empties the backing.
375
+ * `'replace-all' []`, which empties the backing. Kept on the manager (delegating the
376
+ * scan / backing write to the apply-module free helpers) so the per-statement-flush
377
+ * deferral suite can instrument it to count rebuilds.
973
378
  */
974
379
  private applyFullRebuild;
975
380
  /**
976
- * Compute a **forward** key-filtered residual plan's per-row backing delta and apply it:
977
- * derive the affected binding key(s) from the changed row (OLD ∪ NEW, deduped), re-run
978
- * the key-filtered residual against live source state for each, and apply the **keyed
979
- * diff**: a non-empty recomputed slice is upserted (the backing key IS the affected key,
980
- * so the upsert replaces the old row wholesale — no delete-first — and the host's
981
- * value-identical upsert skip turns a no-op recompute into ZERO effective changes
982
- * instead of delete+insert churn); an emptied slice (residual returns nothing) emits the
983
- * point delete, removing the stale backing row (nothing reported if it was already
984
- * absent). Returns the effective {@link BackingRowChange}(s) the backing layer realized,
985
- * for the MV-over-MV cascade — a real same-key change now reports one `update`.
986
- *
987
- * Shared by the single-source aggregate (`'residual-recompute'`, group key, ≤1 row per
988
- * key) and the 1:1-join (`'join-residual'`, the driving table `T`'s PK, exactly the one
989
- * joined row per key) arms — both bind on the forward driving source via
990
- * {@link ForwardResidualPlan}; the only difference is the binding (group vs PK).
991
- *
992
- * Per-row recompute is correct without per-statement batching: every change to a key
993
- * triggers a full recompute of that key's slice from live (reads-own-writes) state, so
994
- * the last change to touch a key writes the authoritative backing row. Batching/dedup
995
- * across a whole statement is an affordability optimization deferred with the
996
- * statement-flush boundary (see the ticket handoff).
997
- */
998
- private applyForwardResidual;
999
- /**
1000
- * True iff `row`'s backing primary-key columns equal `keyVals` (the affected binding
1001
- * key, in `backingPkDefinition` order), under each column's collation. Used to keep
1002
- * only the residual row(s) belonging to the recomputed key — see
1003
- * {@link applyForwardResidual}.
1004
- */
1005
- private residualRowMatchesKey;
1006
- /**
1007
- * Dispatch a `'join-residual'` plan on **which source changed**. A write to the driving
1008
- * table `T` (`changedBase === plan.sourceBase`) is the forward case — recompute the one
1009
- * joined row keyed on `T`'s PK, identical to a size-1 `'row'`-binding residual — so it
1010
- * delegates straight to {@link applyForwardResidual} (delete old backing slice → run the
1011
- * `T`-keyed residual → upsert). A write to the lookup table `P` is the reverse case,
1012
- * handled by {@link applyLookupResidual}.
1013
- */
1014
- private applyJoinResidual;
1015
- /**
1016
- * Maintain a `'join-residual'` MV for a **lookup-side (`P`)** change: refresh the joined
1017
- * rows referencing each affected `P` key. Derive the affected `P` key(s) from the changed
1018
- * row (OLD ∪ NEW, deduped on `P`'s PK), and for each run the in-scope lookup-keyed residual
1019
- * (`… where P.pk = :pk0`, the body's WHERE retained) against live source state — returning
1020
- * every currently in-scope joined row, each carrying its `T.pk` backing key — and **upsert**
1021
- * each.
1022
- *
1023
- * **Upsert-only is sound for a no-WHERE / `T`-only-WHERE body.** For an inner/cross join with
1024
- * enforced RI and a predicate that cannot reference `P`, the *set* of backing rows referencing
1025
- * a given `P` row is `{ T : T.fk = P.pk }`, determined entirely by `T.fk` (a `T` column the
1026
- * `P` write cannot change), and the WHERE — over `T` only — cannot flip on a `P` write. So a
1027
- * `P` change can only re-derive the lookup-projected columns of those existing backing rows
1028
- * (an upsert at the unchanged `T.pk` key), never add or remove one: a `P` insert with no
1029
- * referencing `T` rows yields an empty residual (no-op); a `P` delete is only admissible (RI)
1030
- * when no `T` references it (empty residual); a `P` payload update upserts the affected rows
1031
- * with the new value.
1032
- *
1033
- * **A `P`-referencing WHERE needs the delete-capable pass.** When the body WHERE references
1034
- * `P`, a `P` write can flip a joined row's WHERE truth and so add or remove its backing row —
1035
- * which the in-scope upsert above (it returns *only* in-scope rows) could never delete. The
1036
- * builder then supplies `lookupMembershipResidualScheduler` (the body with the WHERE stripped,
1037
- * keyed on `P`). Per affected `P` key this runs both residuals against the same live state and
1038
- * applies the **keyed diff**: it **deletes** only the membership keys the in-scope recompute no
1039
- * longer produces (rows that left scope — the delete keys come from live `T` via the join, so
1040
- * they match existing backing keys and touch nothing belonging to another `P`; membership and
1041
- * in-scope rows read the same live state, so their key bytes match exactly), and **upserts**
1042
- * every in-scope row. A row leaving scope is deleted (removed); a row entering scope is
1043
- * upserted (added); an unchanged in-scope row's upsert is suppressed by the host's
1044
- * value-identical skip (vtab/backing-host.ts) — ZERO effective changes instead of the former
1045
- * delete+insert refresh churn; a changed in-scope row reports one `update`. The membership
1046
- * residual MUST ignore the WHERE — else a row leaving scope would never be deleted.
1047
- *
1048
- * A `T`-side membership change (insert/delete/FK-move) is the *forward* path's job and fires
1049
- * its own maintenance. Returns the effective {@link BackingRowChange}(s) for the MV-over-MV
1050
- * cascade. Per-row recompute is correct without batching for the same
1051
- * last-write-wins-against-live-state reason as {@link applyForwardResidual}.
1052
- */
1053
- private applyLookupResidual;
1054
- /**
1055
- * Build a `'prefix-delete'` plan for a single-source lateral-TVF fan-out body
1056
- * (`select T.pk…, …, f.* from T cross join lateral tvf(<args over T>) f`), or return
1057
- * `null` on a shape mismatch (the caller falls through to the full-rebuild floor). The
1058
- * backing PK is the composite product key `(T.pk ∪ tvf-key)` that `keysOf` advertises
1059
- * through the lateral join; the base PK is its leading prefix. See {@link PrefixDeletePlan}
1060
- * and `docs/incremental-maintenance.md` § prefix-delete.
1061
- *
1062
- * Soundness gates (a mismatch on any returns `null` → floor): exactly one lateral TVF and
1063
- * one join (no nested/multi TVF, no aggregate over the fan-out); the TVF advertises a
1064
- * per-call key; the base PK projected and forming the **leading prefix** of the backing PK
1065
- * with a non-empty TVF-key tail (so each base row's fan-out rows are individually
1066
- * addressable and a by-prefix delete selects exactly one base row's slice). An `order by`
1067
- * over the fan-out that reorders the composite key so the base PK no longer leads is a
1068
- * `null` fall-through (the floor maintains it wholesale). The body's WHERE, if any, is part
1069
- * of the residual (so an out-of-scope base row fans out to zero rows), exactly as in the
1070
- * aggregate arm. A **non-deterministic** TVF / argument is the one hard reject (its
1071
- * arm-specific determinism diagnostic must survive).
1072
- */
1073
- private buildLateralTvfPrefixDeletePlan;
1074
- /**
1075
- * Compute a `'prefix-delete'` plan's per-row backing delta and apply it: derive the
1076
- * affected base key(s) from the changed row (OLD ∪ NEW, deduped on the base key), and
1077
- * for each — re-run the base-PK-keyed residual against live source state and apply the
1078
- * **keyed diff against the existing effective fan-out slice** (read via the host's
1079
- * `scanEffective` with the base prefix, pending over committed — the same contiguous
1080
- * range the former wholesale `'delete-by-prefix'` removed): delete ONLY the existing
1081
- * keys the recompute no longer produces, upsert every recomputed row (the host's
1082
- * value-identical skip suppresses the unchanged ones). A base-PK-changing UPDATE
1083
- * recomputes both the OLD base key (slice diffs to all-deletes; the residual returns
1084
- * nothing for the now-absent old PK) and the NEW base key (new fan-out upserted); a
1085
- * DELETE diffs the old slice to all-deletes; an INSERT diffs against an empty slice
1086
- * (all upserts). An emptied/shrunk fan-out keeps the delete-without-upsert exactly —
1087
- * a disappearance is never "skipped". Returns the effective
1088
- * {@link BackingRowChange}(s) the backing layer realized, for the MV-over-MV cascade.
1089
- *
1090
- * Prefix-scan soundness is unchanged from the wholesale arm: the diff's slice read
1091
- * uses the same binary `equalityPrefix` scan `'delete-by-prefix'` used, sound under
1092
- * the build-time collation gate (the backing base-PK prefix inherits the source PK
1093
- * collation, and source-PK uniqueness collapses each collation class to one binary
1094
- * value). The stored slice's prefix bytes always equal the OLD image's (the slice was
1095
- * projected from that very source row), and OLD ∪ NEW both iterate, so a case-only
1096
- * base-PK rewrite still converges: the OLD-prefix pass pairs the slice with the
1097
- * recomputed rows (key pairing is collation-aware — the btree's identity — so a
1098
- * collation-equal key is REPLACED by its upsert, never also deleted) and the byte
1099
- * change surfaces as `update`s that re-key the stored bytes.
1100
- *
1101
- * Structurally the same as {@link applyForwardResidual}, differing only in the
1102
- * **prefix-slice** diff (one base row owns N backing rows sharing the prefix) and the
1103
- * **N-row** residual. Per-row recompute is correct without per-statement batching: the
1104
- * residual reads live (reads-own-writes) state, so the last write to a base key produces
1105
- * the authoritative slice. (Statement-level dedup of distinct base keys is the same
1106
- * affordability optimization deferred for the aggregate arm.)
1107
- */
1108
- private applyPrefixDelete;
1109
- /**
1110
- * True iff two backing rows agree on every backing-PK column under that column's
1111
- * collation — the btree's key identity. Pairs an existing slice row with the
1112
- * recomputed row that replaces it in {@link applyPrefixDelete}'s keyed diff.
1113
- */
1114
- private backingPkEqual;
1115
- /**
1116
- * True iff `row`'s **leading** (base-prefix) backing-PK columns equal `prefixVals` (the
1117
- * affected base key, in backing-PK order), under each column's collation. Keeps only the
1118
- * residual fan-out row(s) belonging to the recomputed base key — see
1119
- * {@link applyPrefixDelete}.
1120
- */
1121
- private residualRowMatchesBasePrefix;
1122
- /**
1123
- * Assemble {@link MaintenanceSourceStats} for the cost gate from the optimizer's
1124
- * StatsProvider and tuning. `tableRows` / `distinctGroupsEstimate` come from the
1125
- * provider (heuristic defaults when absent); `forwardBodyCost` is estimated from the
1126
- * forward cost helpers (a scan + optional filter + projection of the source — the
1127
- * covering-index body shape); `fallbackRatio` carries the detection kernel's
1128
- * `deltaPerRowFallbackRatio` for the no-stats residual path.
1129
- */
1130
- /**
1131
- * The CURRENT `TableSchema` of a source `TableReferenceNode`, re-resolved through the
1132
- * schema manager. A plan node captures the schema as of plan-build; a later `analyze`
1133
- * replaces the catalog entry with one carrying fresh `statistics`, so the stale captured
1134
- * schema would report pre-`analyze` row counts. Re-resolving keeps the floor's size gate
1135
- * on the live source size. Falls back to the node's captured schema if the name no longer
1136
- * resolves (it always should — the body planned).
381
+ * Run a whole-body scheduler to completion against live mid-transaction source state
382
+ * and apply the single `'replace-all'` keyed diff. The shared kernel of the
383
+ * full-rebuild floor ({@link applyFullRebuild}) and the residual arms' per-statement
384
+ * rebuild demotion ({@link applyResidualBatch}).
1137
385
  */
1138
- private liveSourceSchema;
1139
- private estimateMaintenanceStats;
386
+ private applyReplaceAll;
1140
387
  /**
1141
388
  * Resolve the linked, enforcement-ready covering MV for a UNIQUE constraint on
1142
389
  * `schema.table`, or `undefined`. The constraint's `coveringStructureName`
@@ -1144,13 +391,15 @@ export declare class MaterializedViewManager {
1144
391
  * this confirms a live row-time plan exists for the source, the MV is not
1145
392
  * `stale` (structural breakage), and the plan is **per-row maintained** — only
1146
393
  * then is its backing table row-time consistent enough to answer conflict
1147
- * resolution. A `'full-rebuild'` plan is deferred to the end-of-statement flush
1148
- * (its backing lags the source mid-statement), so it can never serve as a
1149
- * covering structure for a synchronous per-row UNIQUE probe it is skipped here
1150
- * regardless of any (informational) `coveringStructureName` link, which keeps the
1151
- * eligibility flip from opening a stale-read enforcement path. O(1) negative fast
1152
- * path off {@link rowTimeBySource} so a source table with no row-time covering MV
1153
- * pays a single map lookup and stays on the synchronous index/scan path.
394
+ * resolution. Only the `'inverse-projection'` arm qualifies: every other arm
395
+ * the `'full-rebuild'` floor and the residual arms is deferred to the
396
+ * end-of-statement flush (its backing lags the source mid-statement), so it can
397
+ * never serve as a covering structure for a synchronous per-row UNIQUE probe —
398
+ * all are skipped here regardless of any (informational) `coveringStructureName`
399
+ * link, which keeps an eligibility flip from opening a stale-read enforcement
400
+ * path. O(1) negative fast path off {@link rowTimeBySource} so a source table
401
+ * with no row-time covering MV pays a single map lookup and stays on the
402
+ * synchronous index/scan path.
1154
403
  *
1155
404
  * **Collation eligibility gate.** A covering MV generates its conflict candidates
1156
405
  * by re-comparing each backing row under the SOURCE column's DECLARED collation
@@ -1249,5 +498,4 @@ export declare class MaterializedViewManager {
1249
498
  */
1250
499
  private tryBuildCoveringPrefix;
1251
500
  }
1252
- export {};
1253
501
  //# sourceMappingURL=database-materialized-views.d.ts.map