@quereus/quereus 4.5.0 → 4.7.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 (818) hide show
  1. package/README.md +5 -4
  2. package/dist/src/common/errors.d.ts +17 -0
  3. package/dist/src/common/errors.d.ts.map +1 -1
  4. package/dist/src/common/errors.js +21 -0
  5. package/dist/src/common/errors.js.map +1 -1
  6. package/dist/src/core/database-assertions.d.ts +4 -3
  7. package/dist/src/core/database-assertions.d.ts.map +1 -1
  8. package/dist/src/core/database-assertions.js +44 -14
  9. package/dist/src/core/database-assertions.js.map +1 -1
  10. package/dist/src/core/database-events.d.ts +161 -1
  11. package/dist/src/core/database-events.d.ts.map +1 -1
  12. package/dist/src/core/database-events.js +307 -5
  13. package/dist/src/core/database-events.js.map +1 -1
  14. package/dist/src/core/database-internal.d.ts +5 -2
  15. package/dist/src/core/database-internal.d.ts.map +1 -1
  16. package/dist/src/core/database-materialized-views-plan-builders.d.ts.map +1 -1
  17. package/dist/src/core/database-materialized-views-plan-builders.js +33 -4
  18. package/dist/src/core/database-materialized-views-plan-builders.js.map +1 -1
  19. package/dist/src/core/database-materialized-views-plans.d.ts +12 -2
  20. package/dist/src/core/database-materialized-views-plans.d.ts.map +1 -1
  21. package/dist/src/core/database-materialized-views.d.ts +46 -0
  22. package/dist/src/core/database-materialized-views.d.ts.map +1 -1
  23. package/dist/src/core/database-materialized-views.js +75 -4
  24. package/dist/src/core/database-materialized-views.js.map +1 -1
  25. package/dist/src/core/database-transaction.d.ts +9 -0
  26. package/dist/src/core/database-transaction.d.ts.map +1 -1
  27. package/dist/src/core/database-transaction.js +9 -0
  28. package/dist/src/core/database-transaction.js.map +1 -1
  29. package/dist/src/core/database.d.ts +16 -2
  30. package/dist/src/core/database.d.ts.map +1 -1
  31. package/dist/src/core/database.js +56 -15
  32. package/dist/src/core/database.js.map +1 -1
  33. package/dist/src/core/derived-row-validator.d.ts.map +1 -1
  34. package/dist/src/core/derived-row-validator.js +7 -1
  35. package/dist/src/core/derived-row-validator.js.map +1 -1
  36. package/dist/src/core/statement.d.ts.map +1 -1
  37. package/dist/src/core/statement.js +15 -5
  38. package/dist/src/core/statement.js.map +1 -1
  39. package/dist/src/emit/ast-stringify.d.ts +18 -2
  40. package/dist/src/emit/ast-stringify.d.ts.map +1 -1
  41. package/dist/src/emit/ast-stringify.js +22 -4
  42. package/dist/src/emit/ast-stringify.js.map +1 -1
  43. package/dist/src/func/builtins/aggregate.js +11 -11
  44. package/dist/src/func/builtins/aggregate.js.map +1 -1
  45. package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
  46. package/dist/src/func/builtins/builtin-window-functions.js +15 -85
  47. package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
  48. package/dist/src/func/builtins/conversion.d.ts.map +1 -1
  49. package/dist/src/func/builtins/conversion.js +10 -9
  50. package/dist/src/func/builtins/conversion.js.map +1 -1
  51. package/dist/src/func/builtins/datetime.d.ts.map +1 -1
  52. package/dist/src/func/builtins/datetime.js +28 -10
  53. package/dist/src/func/builtins/datetime.js.map +1 -1
  54. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  55. package/dist/src/func/builtins/explain.js +19 -5
  56. package/dist/src/func/builtins/explain.js.map +1 -1
  57. package/dist/src/func/builtins/json.d.ts.map +1 -1
  58. package/dist/src/func/builtins/json.js +23 -17
  59. package/dist/src/func/builtins/json.js.map +1 -1
  60. package/dist/src/func/builtins/mutation.js +2 -2
  61. package/dist/src/func/builtins/mutation.js.map +1 -1
  62. package/dist/src/func/builtins/return-types.d.ts +327 -0
  63. package/dist/src/func/builtins/return-types.d.ts.map +1 -0
  64. package/dist/src/func/builtins/return-types.js +43 -0
  65. package/dist/src/func/builtins/return-types.js.map +1 -0
  66. package/dist/src/func/builtins/scalar.d.ts.map +1 -1
  67. package/dist/src/func/builtins/scalar.js +150 -79
  68. package/dist/src/func/builtins/scalar.js.map +1 -1
  69. package/dist/src/func/builtins/schema.d.ts.map +1 -1
  70. package/dist/src/func/builtins/schema.js +43 -8
  71. package/dist/src/func/builtins/schema.js.map +1 -1
  72. package/dist/src/func/builtins/string.d.ts.map +1 -1
  73. package/dist/src/func/builtins/string.js +4 -2
  74. package/dist/src/func/builtins/string.js.map +1 -1
  75. package/dist/src/func/builtins/timespan.d.ts +3 -0
  76. package/dist/src/func/builtins/timespan.d.ts.map +1 -1
  77. package/dist/src/func/builtins/timespan.js +15 -11
  78. package/dist/src/func/builtins/timespan.js.map +1 -1
  79. package/dist/src/func/registration.d.ts +35 -1
  80. package/dist/src/func/registration.d.ts.map +1 -1
  81. package/dist/src/func/registration.js +235 -41
  82. package/dist/src/func/registration.js.map +1 -1
  83. package/dist/src/index.d.ts +14 -7
  84. package/dist/src/index.d.ts.map +1 -1
  85. package/dist/src/index.js +15 -6
  86. package/dist/src/index.js.map +1 -1
  87. package/dist/src/parser/ast.d.ts +58 -1
  88. package/dist/src/parser/ast.d.ts.map +1 -1
  89. package/dist/src/parser/parser.d.ts +46 -0
  90. package/dist/src/parser/parser.d.ts.map +1 -1
  91. package/dist/src/parser/parser.js +161 -45
  92. package/dist/src/parser/parser.js.map +1 -1
  93. package/dist/src/parser/utils.d.ts +13 -1
  94. package/dist/src/parser/utils.d.ts.map +1 -1
  95. package/dist/src/parser/utils.js +14 -0
  96. package/dist/src/parser/utils.js.map +1 -1
  97. package/dist/src/planner/analysis/assertion-classifier.d.ts.map +1 -1
  98. package/dist/src/planner/analysis/assertion-classifier.js +7 -2
  99. package/dist/src/planner/analysis/assertion-classifier.js.map +1 -1
  100. package/dist/src/planner/analysis/assertion-hoist-cache.d.ts.map +1 -1
  101. package/dist/src/planner/analysis/assertion-hoist-cache.js +5 -0
  102. package/dist/src/planner/analysis/assertion-hoist-cache.js.map +1 -1
  103. package/dist/src/planner/analysis/change-scope.d.ts +11 -3
  104. package/dist/src/planner/analysis/change-scope.d.ts.map +1 -1
  105. package/dist/src/planner/analysis/change-scope.js +5 -4
  106. package/dist/src/planner/analysis/change-scope.js.map +1 -1
  107. package/dist/src/planner/analysis/check-extraction.d.ts.map +1 -1
  108. package/dist/src/planner/analysis/check-extraction.js +37 -4
  109. package/dist/src/planner/analysis/check-extraction.js.map +1 -1
  110. package/dist/src/planner/analysis/comparison-collation.d.ts +20 -22
  111. package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -1
  112. package/dist/src/planner/analysis/comparison-collation.js +29 -26
  113. package/dist/src/planner/analysis/comparison-collation.js.map +1 -1
  114. package/dist/src/planner/analysis/constraint-extractor.d.ts +0 -7
  115. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
  116. package/dist/src/planner/analysis/constraint-extractor.js +59 -59
  117. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
  118. package/dist/src/planner/analysis/coverage-prover.d.ts.map +1 -1
  119. package/dist/src/planner/analysis/coverage-prover.js +13 -5
  120. package/dist/src/planner/analysis/coverage-prover.js.map +1 -1
  121. package/dist/src/planner/analysis/equi-correlation.d.ts +6 -1
  122. package/dist/src/planner/analysis/equi-correlation.d.ts.map +1 -1
  123. package/dist/src/planner/analysis/equi-correlation.js +8 -1
  124. package/dist/src/planner/analysis/equi-correlation.js.map +1 -1
  125. package/dist/src/planner/analysis/predicate-dependencies.d.ts +34 -0
  126. package/dist/src/planner/analysis/predicate-dependencies.d.ts.map +1 -0
  127. package/dist/src/planner/analysis/predicate-dependencies.js +60 -0
  128. package/dist/src/planner/analysis/predicate-dependencies.js.map +1 -0
  129. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts +1 -1
  130. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts.map +1 -1
  131. package/dist/src/planner/analysis/query-rewrite-matcher.js +0 -26
  132. package/dist/src/planner/analysis/query-rewrite-matcher.js.map +1 -1
  133. package/dist/src/planner/building/alter-table.d.ts.map +1 -1
  134. package/dist/src/planner/building/alter-table.js +117 -43
  135. package/dist/src/planner/building/alter-table.js.map +1 -1
  136. package/dist/src/planner/building/coercion.d.ts +21 -45
  137. package/dist/src/planner/building/coercion.d.ts.map +1 -1
  138. package/dist/src/planner/building/coercion.js +42 -91
  139. package/dist/src/planner/building/coercion.js.map +1 -1
  140. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
  141. package/dist/src/planner/building/constraint-builder.js +9 -5
  142. package/dist/src/planner/building/constraint-builder.js.map +1 -1
  143. package/dist/src/planner/building/create-assertion.d.ts.map +1 -1
  144. package/dist/src/planner/building/create-assertion.js +72 -1
  145. package/dist/src/planner/building/create-assertion.js.map +1 -1
  146. package/dist/src/planner/building/create-view.d.ts +6 -1
  147. package/dist/src/planner/building/create-view.d.ts.map +1 -1
  148. package/dist/src/planner/building/create-view.js +12 -3
  149. package/dist/src/planner/building/create-view.js.map +1 -1
  150. package/dist/src/planner/building/ddl.d.ts.map +1 -1
  151. package/dist/src/planner/building/ddl.js +6 -2
  152. package/dist/src/planner/building/ddl.js.map +1 -1
  153. package/dist/src/planner/building/delete.d.ts.map +1 -1
  154. package/dist/src/planner/building/delete.js +23 -10
  155. package/dist/src/planner/building/delete.js.map +1 -1
  156. package/dist/src/planner/building/dml-target.d.ts.map +1 -1
  157. package/dist/src/planner/building/dml-target.js +4 -0
  158. package/dist/src/planner/building/dml-target.js.map +1 -1
  159. package/dist/src/planner/building/drop-assertion.d.ts.map +1 -1
  160. package/dist/src/planner/building/drop-assertion.js +3 -1
  161. package/dist/src/planner/building/drop-assertion.js.map +1 -1
  162. package/dist/src/planner/building/expression.d.ts +17 -0
  163. package/dist/src/planner/building/expression.d.ts.map +1 -1
  164. package/dist/src/planner/building/expression.js +28 -17
  165. package/dist/src/planner/building/expression.js.map +1 -1
  166. package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -1
  167. package/dist/src/planner/building/foreign-key-builder.js +7 -5
  168. package/dist/src/planner/building/foreign-key-builder.js.map +1 -1
  169. package/dist/src/planner/building/function-call.d.ts +35 -0
  170. package/dist/src/planner/building/function-call.d.ts.map +1 -1
  171. package/dist/src/planner/building/function-call.js +60 -42
  172. package/dist/src/planner/building/function-call.js.map +1 -1
  173. package/dist/src/planner/building/insert.d.ts.map +1 -1
  174. package/dist/src/planner/building/insert.js +185 -48
  175. package/dist/src/planner/building/insert.js.map +1 -1
  176. package/dist/src/planner/building/materialized-view.d.ts.map +1 -1
  177. package/dist/src/planner/building/materialized-view.js +3 -1
  178. package/dist/src/planner/building/materialized-view.js.map +1 -1
  179. package/dist/src/planner/building/schema-authored-context.d.ts +69 -0
  180. package/dist/src/planner/building/schema-authored-context.d.ts.map +1 -0
  181. package/dist/src/planner/building/schema-authored-context.js +75 -0
  182. package/dist/src/planner/building/schema-authored-context.js.map +1 -0
  183. package/dist/src/planner/building/schema-resolution.d.ts.map +1 -1
  184. package/dist/src/planner/building/schema-resolution.js +7 -4
  185. package/dist/src/planner/building/schema-resolution.js.map +1 -1
  186. package/dist/src/planner/building/select-aggregates.d.ts +188 -3
  187. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  188. package/dist/src/planner/building/select-aggregates.js +449 -65
  189. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  190. package/dist/src/planner/building/select-compound.js +2 -2
  191. package/dist/src/planner/building/select-compound.js.map +1 -1
  192. package/dist/src/planner/building/select-context.d.ts +98 -0
  193. package/dist/src/planner/building/select-context.d.ts.map +1 -1
  194. package/dist/src/planner/building/select-context.js +120 -37
  195. package/dist/src/planner/building/select-context.js.map +1 -1
  196. package/dist/src/planner/building/select-modifiers.d.ts +10 -3
  197. package/dist/src/planner/building/select-modifiers.d.ts.map +1 -1
  198. package/dist/src/planner/building/select-modifiers.js +29 -8
  199. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  200. package/dist/src/planner/building/select-ordinal.d.ts +64 -19
  201. package/dist/src/planner/building/select-ordinal.d.ts.map +1 -1
  202. package/dist/src/planner/building/select-ordinal.js +79 -30
  203. package/dist/src/planner/building/select-ordinal.js.map +1 -1
  204. package/dist/src/planner/building/select-projections.d.ts +1 -1
  205. package/dist/src/planner/building/select-projections.d.ts.map +1 -1
  206. package/dist/src/planner/building/select-projections.js +18 -11
  207. package/dist/src/planner/building/select-projections.js.map +1 -1
  208. package/dist/src/planner/building/select-window.d.ts +13 -3
  209. package/dist/src/planner/building/select-window.d.ts.map +1 -1
  210. package/dist/src/planner/building/select-window.js +142 -37
  211. package/dist/src/planner/building/select-window.js.map +1 -1
  212. package/dist/src/planner/building/select.d.ts +37 -1
  213. package/dist/src/planner/building/select.d.ts.map +1 -1
  214. package/dist/src/planner/building/select.js +240 -109
  215. package/dist/src/planner/building/select.js.map +1 -1
  216. package/dist/src/planner/building/update.d.ts.map +1 -1
  217. package/dist/src/planner/building/update.js +27 -13
  218. package/dist/src/planner/building/update.js.map +1 -1
  219. package/dist/src/planner/building/view-mutation-builder.d.ts +1 -1
  220. package/dist/src/planner/building/view-mutation-builder.d.ts.map +1 -1
  221. package/dist/src/planner/building/view-mutation-builder.js +102 -8
  222. package/dist/src/planner/building/view-mutation-builder.js.map +1 -1
  223. package/dist/src/planner/building/with.d.ts.map +1 -1
  224. package/dist/src/planner/building/with.js +34 -4
  225. package/dist/src/planner/building/with.js.map +1 -1
  226. package/dist/src/planner/cache/correlation-detector.d.ts +15 -0
  227. package/dist/src/planner/cache/correlation-detector.d.ts.map +1 -1
  228. package/dist/src/planner/cache/correlation-detector.js +26 -0
  229. package/dist/src/planner/cache/correlation-detector.js.map +1 -1
  230. package/dist/src/planner/cache/materialization-advisory.d.ts +7 -0
  231. package/dist/src/planner/cache/materialization-advisory.d.ts.map +1 -1
  232. package/dist/src/planner/cache/materialization-advisory.js +12 -3
  233. package/dist/src/planner/cache/materialization-advisory.js.map +1 -1
  234. package/dist/src/planner/cost/conjunct-cost.d.ts +40 -0
  235. package/dist/src/planner/cost/conjunct-cost.d.ts.map +1 -1
  236. package/dist/src/planner/cost/conjunct-cost.js +45 -0
  237. package/dist/src/planner/cost/conjunct-cost.js.map +1 -1
  238. package/dist/src/planner/cost/index.d.ts +10 -0
  239. package/dist/src/planner/cost/index.d.ts.map +1 -1
  240. package/dist/src/planner/cost/index.js +15 -0
  241. package/dist/src/planner/cost/index.js.map +1 -1
  242. package/dist/src/planner/framework/characteristics.d.ts +9 -0
  243. package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
  244. package/dist/src/planner/framework/characteristics.js.map +1 -1
  245. package/dist/src/planner/framework/pass.d.ts +2 -0
  246. package/dist/src/planner/framework/pass.d.ts.map +1 -1
  247. package/dist/src/planner/framework/pass.js +15 -0
  248. package/dist/src/planner/framework/pass.js.map +1 -1
  249. package/dist/src/planner/mutation/backward-body.d.ts.map +1 -1
  250. package/dist/src/planner/mutation/backward-body.js +4 -1
  251. package/dist/src/planner/mutation/backward-body.js.map +1 -1
  252. package/dist/src/planner/mutation/body-context.d.ts +23 -0
  253. package/dist/src/planner/mutation/body-context.d.ts.map +1 -0
  254. package/dist/src/planner/mutation/body-context.js +26 -0
  255. package/dist/src/planner/mutation/body-context.js.map +1 -0
  256. package/dist/src/planner/mutation/cte-flatten.js +15 -2
  257. package/dist/src/planner/mutation/cte-flatten.js.map +1 -1
  258. package/dist/src/planner/mutation/decomposition.d.ts +8 -0
  259. package/dist/src/planner/mutation/decomposition.d.ts.map +1 -1
  260. package/dist/src/planner/mutation/decomposition.js +8 -3
  261. package/dist/src/planner/mutation/decomposition.js.map +1 -1
  262. package/dist/src/planner/mutation/lens-enforcement.js +1 -1
  263. package/dist/src/planner/mutation/multi-source.d.ts +7 -0
  264. package/dist/src/planner/mutation/multi-source.d.ts.map +1 -1
  265. package/dist/src/planner/mutation/multi-source.js +5 -0
  266. package/dist/src/planner/mutation/multi-source.js.map +1 -1
  267. package/dist/src/planner/mutation/mutation-diagnostic.d.ts +1 -1
  268. package/dist/src/planner/mutation/mutation-diagnostic.d.ts.map +1 -1
  269. package/dist/src/planner/mutation/mutation-diagnostic.js.map +1 -1
  270. package/dist/src/planner/mutation/scope-transform.d.ts +32 -0
  271. package/dist/src/planner/mutation/scope-transform.d.ts.map +1 -1
  272. package/dist/src/planner/mutation/scope-transform.js +181 -33
  273. package/dist/src/planner/mutation/scope-transform.js.map +1 -1
  274. package/dist/src/planner/mutation/set-op.d.ts.map +1 -1
  275. package/dist/src/planner/mutation/set-op.js +66 -16
  276. package/dist/src/planner/mutation/set-op.js.map +1 -1
  277. package/dist/src/planner/mutation/single-source.d.ts.map +1 -1
  278. package/dist/src/planner/mutation/single-source.js +100 -24
  279. package/dist/src/planner/mutation/single-source.js.map +1 -1
  280. package/dist/src/planner/nodes/add-constraint-node.d.ts +15 -1
  281. package/dist/src/planner/nodes/add-constraint-node.d.ts.map +1 -1
  282. package/dist/src/planner/nodes/add-constraint-node.js +10 -1
  283. package/dist/src/planner/nodes/add-constraint-node.js.map +1 -1
  284. package/dist/src/planner/nodes/aggregate-node.d.ts +15 -0
  285. package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
  286. package/dist/src/planner/nodes/aggregate-node.js +32 -17
  287. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  288. package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
  289. package/dist/src/planner/nodes/alias-node.js +2 -1
  290. package/dist/src/planner/nodes/alias-node.js.map +1 -1
  291. package/dist/src/planner/nodes/alter-table-node.d.ts +51 -10
  292. package/dist/src/planner/nodes/alter-table-node.d.ts.map +1 -1
  293. package/dist/src/planner/nodes/alter-table-node.js +49 -2
  294. package/dist/src/planner/nodes/alter-table-node.js.map +1 -1
  295. package/dist/src/planner/nodes/asof-scan-node.d.ts.map +1 -1
  296. package/dist/src/planner/nodes/asof-scan-node.js +4 -1
  297. package/dist/src/planner/nodes/asof-scan-node.js.map +1 -1
  298. package/dist/src/planner/nodes/asserted-keys-node.d.ts.map +1 -1
  299. package/dist/src/planner/nodes/asserted-keys-node.js +2 -1
  300. package/dist/src/planner/nodes/asserted-keys-node.js.map +1 -1
  301. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
  302. package/dist/src/planner/nodes/bloom-join-node.js +8 -3
  303. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
  304. package/dist/src/planner/nodes/cache-node.d.ts.map +1 -1
  305. package/dist/src/planner/nodes/cache-node.js +2 -1
  306. package/dist/src/planner/nodes/cache-node.js.map +1 -1
  307. package/dist/src/planner/nodes/constraint-check-node.d.ts.map +1 -1
  308. package/dist/src/planner/nodes/constraint-check-node.js +17 -19
  309. package/dist/src/planner/nodes/constraint-check-node.js.map +1 -1
  310. package/dist/src/planner/nodes/create-assertion-node.d.ts +2 -1
  311. package/dist/src/planner/nodes/create-assertion-node.d.ts.map +1 -1
  312. package/dist/src/planner/nodes/create-assertion-node.js +5 -2
  313. package/dist/src/planner/nodes/create-assertion-node.js.map +1 -1
  314. package/dist/src/planner/nodes/cte-node.d.ts +19 -9
  315. package/dist/src/planner/nodes/cte-node.d.ts.map +1 -1
  316. package/dist/src/planner/nodes/cte-node.js +25 -9
  317. package/dist/src/planner/nodes/cte-node.js.map +1 -1
  318. package/dist/src/planner/nodes/delete-node.d.ts +20 -2
  319. package/dist/src/planner/nodes/delete-node.d.ts.map +1 -1
  320. package/dist/src/planner/nodes/delete-node.js +11 -2
  321. package/dist/src/planner/nodes/delete-node.js.map +1 -1
  322. package/dist/src/planner/nodes/distinct-node.d.ts +6 -0
  323. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
  324. package/dist/src/planner/nodes/distinct-node.js +10 -2
  325. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  326. package/dist/src/planner/nodes/dml-executor-node.d.ts +58 -1
  327. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  328. package/dist/src/planner/nodes/dml-executor-node.js +107 -15
  329. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  330. package/dist/src/planner/nodes/drop-assertion-node.d.ts +2 -1
  331. package/dist/src/planner/nodes/drop-assertion-node.d.ts.map +1 -1
  332. package/dist/src/planner/nodes/drop-assertion-node.js +5 -2
  333. package/dist/src/planner/nodes/drop-assertion-node.js.map +1 -1
  334. package/dist/src/planner/nodes/eager-prefetch-node.d.ts.map +1 -1
  335. package/dist/src/planner/nodes/eager-prefetch-node.js +2 -1
  336. package/dist/src/planner/nodes/eager-prefetch-node.js.map +1 -1
  337. package/dist/src/planner/nodes/fanout-lookup-join-node.d.ts +5 -0
  338. package/dist/src/planner/nodes/fanout-lookup-join-node.d.ts.map +1 -1
  339. package/dist/src/planner/nodes/fanout-lookup-join-node.js +13 -6
  340. package/dist/src/planner/nodes/fanout-lookup-join-node.js.map +1 -1
  341. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  342. package/dist/src/planner/nodes/filter.js +18 -5
  343. package/dist/src/planner/nodes/filter.js.map +1 -1
  344. package/dist/src/planner/nodes/hash-aggregate.d.ts +1 -0
  345. package/dist/src/planner/nodes/hash-aggregate.d.ts.map +1 -1
  346. package/dist/src/planner/nodes/hash-aggregate.js +21 -16
  347. package/dist/src/planner/nodes/hash-aggregate.js.map +1 -1
  348. package/dist/src/planner/nodes/insert-node.d.ts +19 -2
  349. package/dist/src/planner/nodes/insert-node.d.ts.map +1 -1
  350. package/dist/src/planner/nodes/insert-node.js +10 -2
  351. package/dist/src/planner/nodes/insert-node.js.map +1 -1
  352. package/dist/src/planner/nodes/join-node.d.ts +20 -1
  353. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  354. package/dist/src/planner/nodes/join-node.js +30 -9
  355. package/dist/src/planner/nodes/join-node.js.map +1 -1
  356. package/dist/src/planner/nodes/join-utils.d.ts +21 -0
  357. package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
  358. package/dist/src/planner/nodes/join-utils.js +26 -0
  359. package/dist/src/planner/nodes/join-utils.js.map +1 -1
  360. package/dist/src/planner/nodes/key-set-semi-join-node.d.ts +42 -10
  361. package/dist/src/planner/nodes/key-set-semi-join-node.d.ts.map +1 -1
  362. package/dist/src/planner/nodes/key-set-semi-join-node.js +90 -17
  363. package/dist/src/planner/nodes/key-set-semi-join-node.js.map +1 -1
  364. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts +5 -0
  365. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts.map +1 -1
  366. package/dist/src/planner/nodes/lens-auxiliary-access-node.js +2 -1
  367. package/dist/src/planner/nodes/lens-auxiliary-access-node.js.map +1 -1
  368. package/dist/src/planner/nodes/limit-offset.d.ts +6 -0
  369. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  370. package/dist/src/planner/nodes/limit-offset.js +10 -2
  371. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  372. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
  373. package/dist/src/planner/nodes/merge-join-node.js +8 -3
  374. package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
  375. package/dist/src/planner/nodes/ordinal-slice-node.d.ts +5 -0
  376. package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
  377. package/dist/src/planner/nodes/ordinal-slice-node.js +9 -2
  378. package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
  379. package/dist/src/planner/nodes/plan-node.d.ts +29 -0
  380. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  381. package/dist/src/planner/nodes/plan-node.js +12 -0
  382. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  383. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  384. package/dist/src/planner/nodes/project-node.js +18 -36
  385. package/dist/src/planner/nodes/project-node.js.map +1 -1
  386. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  387. package/dist/src/planner/nodes/reference.js +3 -2
  388. package/dist/src/planner/nodes/reference.js.map +1 -1
  389. package/dist/src/planner/nodes/retrieve-node.d.ts +16 -2
  390. package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -1
  391. package/dist/src/planner/nodes/retrieve-node.js +10 -2
  392. package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
  393. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  394. package/dist/src/planner/nodes/returning-node.js +13 -32
  395. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  396. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  397. package/dist/src/planner/nodes/scalar.js +5 -18
  398. package/dist/src/planner/nodes/scalar.js.map +1 -1
  399. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  400. package/dist/src/planner/nodes/sort.js +3 -1
  401. package/dist/src/planner/nodes/sort.js.map +1 -1
  402. package/dist/src/planner/nodes/stream-aggregate.d.ts +1 -0
  403. package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
  404. package/dist/src/planner/nodes/stream-aggregate.js +22 -20
  405. package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
  406. package/dist/src/planner/nodes/table-access-nodes.d.ts +89 -1
  407. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
  408. package/dist/src/planner/nodes/table-access-nodes.js +69 -2
  409. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  410. package/dist/src/planner/nodes/update-node.d.ts +19 -2
  411. package/dist/src/planner/nodes/update-node.d.ts.map +1 -1
  412. package/dist/src/planner/nodes/update-node.js +10 -2
  413. package/dist/src/planner/nodes/update-node.js.map +1 -1
  414. package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
  415. package/dist/src/planner/nodes/window-function.js +8 -0
  416. package/dist/src/planner/nodes/window-function.js.map +1 -1
  417. package/dist/src/planner/nodes/window-node.d.ts +1 -1
  418. package/dist/src/planner/nodes/window-node.d.ts.map +1 -1
  419. package/dist/src/planner/nodes/window-node.js +3 -1
  420. package/dist/src/planner/nodes/window-node.js.map +1 -1
  421. package/dist/src/planner/optimizer.d.ts +27 -1
  422. package/dist/src/planner/optimizer.d.ts.map +1 -1
  423. package/dist/src/planner/optimizer.js +130 -10
  424. package/dist/src/planner/optimizer.js.map +1 -1
  425. package/dist/src/planner/planning-context.d.ts +24 -0
  426. package/dist/src/planner/planning-context.d.ts.map +1 -1
  427. package/dist/src/planner/planning-context.js.map +1 -1
  428. package/dist/src/planner/rules/access/rule-key-set-seek.d.ts +78 -20
  429. package/dist/src/planner/rules/access/rule-key-set-seek.d.ts.map +1 -1
  430. package/dist/src/planner/rules/access/rule-key-set-seek.js +296 -135
  431. package/dist/src/planner/rules/access/rule-key-set-seek.js.map +1 -1
  432. package/dist/src/planner/rules/access/rule-monotonic-range-access.d.ts.map +1 -1
  433. package/dist/src/planner/rules/access/rule-monotonic-range-access.js +2 -2
  434. package/dist/src/planner/rules/access/rule-monotonic-range-access.js.map +1 -1
  435. package/dist/src/planner/rules/access/rule-select-access-path.d.ts +30 -1
  436. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  437. package/dist/src/planner/rules/access/rule-select-access-path.js +70 -5
  438. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  439. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts +7 -4
  440. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts.map +1 -1
  441. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js +39 -5
  442. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js.map +1 -1
  443. package/dist/src/planner/rules/cache/rule-cte-optimization.d.ts.map +1 -1
  444. package/dist/src/planner/rules/cache/rule-cte-optimization.js +15 -2
  445. package/dist/src/planner/rules/cache/rule-cte-optimization.js.map +1 -1
  446. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js +10 -3
  447. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js.map +1 -1
  448. package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.d.ts.map +1 -1
  449. package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.js +6 -4
  450. package/dist/src/planner/rules/cache/rule-nested-loop-right-cache.js.map +1 -1
  451. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts +5 -31
  452. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts.map +1 -1
  453. package/dist/src/planner/rules/join/equi-pair-extractor.js +4 -44
  454. package/dist/src/planner/rules/join/equi-pair-extractor.js.map +1 -1
  455. package/dist/src/planner/rules/join/index-nested-loop.d.ts +49 -0
  456. package/dist/src/planner/rules/join/index-nested-loop.d.ts.map +1 -0
  457. package/dist/src/planner/rules/join/index-nested-loop.js +291 -0
  458. package/dist/src/planner/rules/join/index-nested-loop.js.map +1 -0
  459. package/dist/src/planner/rules/join/rule-fanout-batched-outer.js +8 -8
  460. package/dist/src/planner/rules/join/rule-fanout-lookup-join.d.ts +4 -0
  461. package/dist/src/planner/rules/join/rule-fanout-lookup-join.d.ts.map +1 -1
  462. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js +50 -15
  463. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js.map +1 -1
  464. package/dist/src/planner/rules/join/rule-join-elimination.d.ts +6 -0
  465. package/dist/src/planner/rules/join/rule-join-elimination.d.ts.map +1 -1
  466. package/dist/src/planner/rules/join/rule-join-elimination.js +25 -9
  467. package/dist/src/planner/rules/join/rule-join-elimination.js.map +1 -1
  468. package/dist/src/planner/rules/join/rule-join-key-inference.d.ts +7 -0
  469. package/dist/src/planner/rules/join/rule-join-key-inference.d.ts.map +1 -1
  470. package/dist/src/planner/rules/join/rule-join-key-inference.js +23 -11
  471. package/dist/src/planner/rules/join/rule-join-key-inference.js.map +1 -1
  472. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts +10 -4
  473. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -1
  474. package/dist/src/planner/rules/join/rule-join-physical-selection.js +115 -29
  475. package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -1
  476. package/dist/src/planner/rules/join/rule-monotonic-merge-join.d.ts +2 -0
  477. package/dist/src/planner/rules/join/rule-monotonic-merge-join.d.ts.map +1 -1
  478. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js +18 -4
  479. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js.map +1 -1
  480. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts +2 -2
  481. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts.map +1 -1
  482. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js +19 -22
  483. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js.map +1 -1
  484. package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.d.ts +21 -8
  485. package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.d.ts.map +1 -1
  486. package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.js +70 -14
  487. package/dist/src/planner/rules/predicate/rule-filter-conjunct-ordering.js.map +1 -1
  488. package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts +56 -17
  489. package/dist/src/planner/rules/predicate/rule-filter-selectivity.d.ts.map +1 -1
  490. package/dist/src/planner/rules/predicate/rule-filter-selectivity.js +103 -154
  491. package/dist/src/planner/rules/predicate/rule-filter-selectivity.js.map +1 -1
  492. package/dist/src/planner/rules/predicate/rule-join-predicate-pushdown.d.ts +76 -0
  493. package/dist/src/planner/rules/predicate/rule-join-predicate-pushdown.d.ts.map +1 -0
  494. package/dist/src/planner/rules/predicate/rule-join-predicate-pushdown.js +208 -0
  495. package/dist/src/planner/rules/predicate/rule-join-predicate-pushdown.js.map +1 -0
  496. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts +14 -11
  497. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts.map +1 -1
  498. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +21 -85
  499. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -1
  500. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts +7 -1
  501. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.d.ts.map +1 -1
  502. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js +18 -22
  503. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -1
  504. package/dist/src/planner/rules/shared/access-leaf.d.ts +52 -0
  505. package/dist/src/planner/rules/shared/access-leaf.d.ts.map +1 -0
  506. package/dist/src/planner/rules/shared/access-leaf.js +95 -0
  507. package/dist/src/planner/rules/shared/access-leaf.js.map +1 -0
  508. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts.map +1 -1
  509. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js +17 -7
  510. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js.map +1 -1
  511. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts +3 -1
  512. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts.map +1 -1
  513. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js +26 -9
  514. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js.map +1 -1
  515. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
  516. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +69 -11
  517. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
  518. package/dist/src/planner/rules/window/rule-monotonic-window.d.ts +17 -7
  519. package/dist/src/planner/rules/window/rule-monotonic-window.d.ts.map +1 -1
  520. package/dist/src/planner/rules/window/rule-monotonic-window.js +124 -87
  521. package/dist/src/planner/rules/window/rule-monotonic-window.js.map +1 -1
  522. package/dist/src/planner/scopes/aliased.d.ts.map +1 -1
  523. package/dist/src/planner/scopes/aliased.js +6 -0
  524. package/dist/src/planner/scopes/aliased.js.map +1 -1
  525. package/dist/src/planner/stats/catalog-stats.d.ts +44 -13
  526. package/dist/src/planner/stats/catalog-stats.d.ts.map +1 -1
  527. package/dist/src/planner/stats/catalog-stats.js +137 -61
  528. package/dist/src/planner/stats/catalog-stats.js.map +1 -1
  529. package/dist/src/planner/stats/conjunct-selectivity.d.ts +48 -0
  530. package/dist/src/planner/stats/conjunct-selectivity.d.ts.map +1 -0
  531. package/dist/src/planner/stats/conjunct-selectivity.js +168 -0
  532. package/dist/src/planner/stats/conjunct-selectivity.js.map +1 -0
  533. package/dist/src/planner/stats/index.d.ts +22 -3
  534. package/dist/src/planner/stats/index.d.ts.map +1 -1
  535. package/dist/src/planner/stats/index.js.map +1 -1
  536. package/dist/src/planner/stats/table-cardinality.d.ts +28 -0
  537. package/dist/src/planner/stats/table-cardinality.d.ts.map +1 -0
  538. package/dist/src/planner/stats/table-cardinality.js +29 -0
  539. package/dist/src/planner/stats/table-cardinality.js.map +1 -0
  540. package/dist/src/planner/stored-body-context.d.ts +57 -0
  541. package/dist/src/planner/stored-body-context.d.ts.map +1 -0
  542. package/dist/src/planner/stored-body-context.js +64 -0
  543. package/dist/src/planner/stored-body-context.js.map +1 -0
  544. package/dist/src/planner/util/column-origins.d.ts +29 -8
  545. package/dist/src/planner/util/column-origins.d.ts.map +1 -1
  546. package/dist/src/planner/util/column-origins.js +74 -14
  547. package/dist/src/planner/util/column-origins.js.map +1 -1
  548. package/dist/src/planner/util/fd-utils.d.ts +32 -8
  549. package/dist/src/planner/util/fd-utils.d.ts.map +1 -1
  550. package/dist/src/planner/util/fd-utils.js +46 -9
  551. package/dist/src/planner/util/fd-utils.js.map +1 -1
  552. package/dist/src/planner/util/ind-utils.d.ts +66 -19
  553. package/dist/src/planner/util/ind-utils.d.ts.map +1 -1
  554. package/dist/src/planner/util/ind-utils.js +91 -21
  555. package/dist/src/planner/util/ind-utils.js.map +1 -1
  556. package/dist/src/planner/util/key-utils.d.ts +36 -3
  557. package/dist/src/planner/util/key-utils.d.ts.map +1 -1
  558. package/dist/src/planner/util/key-utils.js +57 -7
  559. package/dist/src/planner/util/key-utils.js.map +1 -1
  560. package/dist/src/planner/util/output-names.d.ts +12 -0
  561. package/dist/src/planner/util/output-names.d.ts.map +1 -0
  562. package/dist/src/planner/util/output-names.js +20 -0
  563. package/dist/src/planner/util/output-names.js.map +1 -0
  564. package/dist/src/planner/util/row-estimates.d.ts +39 -0
  565. package/dist/src/planner/util/row-estimates.d.ts.map +1 -0
  566. package/dist/src/planner/util/row-estimates.js +68 -0
  567. package/dist/src/planner/util/row-estimates.js.map +1 -0
  568. package/dist/src/planner/util/row-population.d.ts +42 -0
  569. package/dist/src/planner/util/row-population.d.ts.map +1 -0
  570. package/dist/src/planner/util/row-population.js +71 -0
  571. package/dist/src/planner/util/row-population.js.map +1 -0
  572. package/dist/src/runtime/deferred-constraint-queue.d.ts.map +1 -1
  573. package/dist/src/runtime/deferred-constraint-queue.js +3 -2
  574. package/dist/src/runtime/deferred-constraint-queue.js.map +1 -1
  575. package/dist/src/runtime/emit/add-constraint.d.ts.map +1 -1
  576. package/dist/src/runtime/emit/add-constraint.js +60 -6
  577. package/dist/src/runtime/emit/add-constraint.js.map +1 -1
  578. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  579. package/dist/src/runtime/emit/aggregate.js +4 -4
  580. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  581. package/dist/src/runtime/emit/alter-schema-event.d.ts +97 -0
  582. package/dist/src/runtime/emit/alter-schema-event.d.ts.map +1 -0
  583. package/dist/src/runtime/emit/alter-schema-event.js +87 -0
  584. package/dist/src/runtime/emit/alter-schema-event.js.map +1 -0
  585. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  586. package/dist/src/runtime/emit/alter-table.js +582 -236
  587. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  588. package/dist/src/runtime/emit/analyze.d.ts.map +1 -1
  589. package/dist/src/runtime/emit/analyze.js +50 -7
  590. package/dist/src/runtime/emit/analyze.js.map +1 -1
  591. package/dist/src/runtime/emit/assertion-drop-guard.d.ts +37 -0
  592. package/dist/src/runtime/emit/assertion-drop-guard.d.ts.map +1 -0
  593. package/dist/src/runtime/emit/assertion-drop-guard.js +59 -0
  594. package/dist/src/runtime/emit/assertion-drop-guard.js.map +1 -0
  595. package/dist/src/runtime/emit/assertion-rename-helpers.d.ts +33 -0
  596. package/dist/src/runtime/emit/assertion-rename-helpers.d.ts.map +1 -0
  597. package/dist/src/runtime/emit/assertion-rename-helpers.js +124 -0
  598. package/dist/src/runtime/emit/assertion-rename-helpers.js.map +1 -0
  599. package/dist/src/runtime/emit/cast.d.ts.map +1 -1
  600. package/dist/src/runtime/emit/cast.js +4 -19
  601. package/dist/src/runtime/emit/cast.js.map +1 -1
  602. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  603. package/dist/src/runtime/emit/constraint-check.js +10 -227
  604. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  605. package/dist/src/runtime/emit/create-assertion.d.ts.map +1 -1
  606. package/dist/src/runtime/emit/create-assertion.js +31 -14
  607. package/dist/src/runtime/emit/create-assertion.js.map +1 -1
  608. package/dist/src/runtime/emit/cte.d.ts.map +1 -1
  609. package/dist/src/runtime/emit/cte.js +11 -6
  610. package/dist/src/runtime/emit/cte.js.map +1 -1
  611. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  612. package/dist/src/runtime/emit/dml-executor.js +233 -28
  613. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  614. package/dist/src/runtime/emit/drop-assertion.js +8 -8
  615. package/dist/src/runtime/emit/drop-assertion.js.map +1 -1
  616. package/dist/src/runtime/emit/drop-column-guards.d.ts +151 -0
  617. package/dist/src/runtime/emit/drop-column-guards.d.ts.map +1 -0
  618. package/dist/src/runtime/emit/drop-column-guards.js +230 -0
  619. package/dist/src/runtime/emit/drop-column-guards.js.map +1 -0
  620. package/dist/src/runtime/emit/drop-index.d.ts.map +1 -1
  621. package/dist/src/runtime/emit/drop-index.js +4 -3
  622. package/dist/src/runtime/emit/drop-index.js.map +1 -1
  623. package/dist/src/runtime/emit/drop-table.d.ts.map +1 -1
  624. package/dist/src/runtime/emit/drop-table.js +6 -0
  625. package/dist/src/runtime/emit/drop-table.js.map +1 -1
  626. package/dist/src/runtime/emit/drop-view.d.ts.map +1 -1
  627. package/dist/src/runtime/emit/drop-view.js +4 -0
  628. package/dist/src/runtime/emit/drop-view.js.map +1 -1
  629. package/dist/src/runtime/emit/hash-aggregate.d.ts.map +1 -1
  630. package/dist/src/runtime/emit/hash-aggregate.js +2 -2
  631. package/dist/src/runtime/emit/hash-aggregate.js.map +1 -1
  632. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  633. package/dist/src/runtime/emit/join.js +8 -67
  634. package/dist/src/runtime/emit/join.js.map +1 -1
  635. package/dist/src/runtime/emit/key-set-semi-join.d.ts.map +1 -1
  636. package/dist/src/runtime/emit/key-set-semi-join.js +11 -3
  637. package/dist/src/runtime/emit/key-set-semi-join.js.map +1 -1
  638. package/dist/src/runtime/emit/materialized-view-helpers.d.ts +4 -4
  639. package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -1
  640. package/dist/src/runtime/emit/materialized-view-helpers.js +34 -22
  641. package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -1
  642. package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -1
  643. package/dist/src/runtime/emit/materialized-view.js +7 -2
  644. package/dist/src/runtime/emit/materialized-view.js.map +1 -1
  645. package/dist/src/runtime/emit/operand-comparator.d.ts +30 -0
  646. package/dist/src/runtime/emit/operand-comparator.d.ts.map +1 -1
  647. package/dist/src/runtime/emit/operand-comparator.js +34 -0
  648. package/dist/src/runtime/emit/operand-comparator.js.map +1 -1
  649. package/dist/src/runtime/emit/recursive-cte.d.ts.map +1 -1
  650. package/dist/src/runtime/emit/recursive-cte.js +4 -5
  651. package/dist/src/runtime/emit/recursive-cte.js.map +1 -1
  652. package/dist/src/runtime/emit/schema-declarative.d.ts.map +1 -1
  653. package/dist/src/runtime/emit/schema-declarative.js +30 -0
  654. package/dist/src/runtime/emit/schema-declarative.js.map +1 -1
  655. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  656. package/dist/src/runtime/emit/subquery.js +153 -52
  657. package/dist/src/runtime/emit/subquery.js.map +1 -1
  658. package/dist/src/runtime/emit/update.d.ts.map +1 -1
  659. package/dist/src/runtime/emit/update.js +18 -6
  660. package/dist/src/runtime/emit/update.js.map +1 -1
  661. package/dist/src/runtime/emit/window.js +36 -23
  662. package/dist/src/runtime/emit/window.js.map +1 -1
  663. package/dist/src/runtime/row-constraints.d.ts +85 -0
  664. package/dist/src/runtime/row-constraints.d.ts.map +1 -0
  665. package/dist/src/runtime/row-constraints.js +239 -0
  666. package/dist/src/runtime/row-constraints.js.map +1 -0
  667. package/dist/src/runtime/types.d.ts +8 -11
  668. package/dist/src/runtime/types.d.ts.map +1 -1
  669. package/dist/src/runtime/types.js.map +1 -1
  670. package/dist/src/schema/assertion.d.ts +14 -1
  671. package/dist/src/schema/assertion.d.ts.map +1 -1
  672. package/dist/src/schema/assertion.js +14 -1
  673. package/dist/src/schema/assertion.js.map +1 -1
  674. package/dist/src/schema/catalog-persistability.d.ts +19 -16
  675. package/dist/src/schema/catalog-persistability.d.ts.map +1 -1
  676. package/dist/src/schema/catalog-persistability.js +92 -20
  677. package/dist/src/schema/catalog-persistability.js.map +1 -1
  678. package/dist/src/schema/catalog.d.ts +73 -2
  679. package/dist/src/schema/catalog.d.ts.map +1 -1
  680. package/dist/src/schema/catalog.js +220 -39
  681. package/dist/src/schema/catalog.js.map +1 -1
  682. package/dist/src/schema/column-source-resolver.d.ts +18 -0
  683. package/dist/src/schema/column-source-resolver.d.ts.map +1 -0
  684. package/dist/src/schema/column-source-resolver.js +22 -0
  685. package/dist/src/schema/column-source-resolver.js.map +1 -0
  686. package/dist/src/schema/column.d.ts +26 -3
  687. package/dist/src/schema/column.d.ts.map +1 -1
  688. package/dist/src/schema/column.js.map +1 -1
  689. package/dist/src/schema/constraint-builder.d.ts.map +1 -1
  690. package/dist/src/schema/constraint-builder.js +7 -1
  691. package/dist/src/schema/constraint-builder.js.map +1 -1
  692. package/dist/src/schema/ddl-generator.d.ts.map +1 -1
  693. package/dist/src/schema/ddl-generator.js +27 -6
  694. package/dist/src/schema/ddl-generator.js.map +1 -1
  695. package/dist/src/schema/function.d.ts +32 -1
  696. package/dist/src/schema/function.d.ts.map +1 -1
  697. package/dist/src/schema/function.js +10 -2
  698. package/dist/src/schema/function.js.map +1 -1
  699. package/dist/src/schema/lens-compiler.d.ts.map +1 -1
  700. package/dist/src/schema/lens-compiler.js +203 -51
  701. package/dist/src/schema/lens-compiler.js.map +1 -1
  702. package/dist/src/schema/lens-prover.d.ts +2 -3
  703. package/dist/src/schema/lens-prover.d.ts.map +1 -1
  704. package/dist/src/schema/lens-prover.js +19 -11
  705. package/dist/src/schema/lens-prover.js.map +1 -1
  706. package/dist/src/schema/manager.d.ts +115 -20
  707. package/dist/src/schema/manager.d.ts.map +1 -1
  708. package/dist/src/schema/manager.js +202 -70
  709. package/dist/src/schema/manager.js.map +1 -1
  710. package/dist/src/schema/rename-rewriter.d.ts +142 -0
  711. package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
  712. package/dist/src/schema/rename-rewriter.js +254 -9
  713. package/dist/src/schema/rename-rewriter.js.map +1 -1
  714. package/dist/src/schema/reserved-tags.d.ts +1 -1
  715. package/dist/src/schema/reserved-tags.d.ts.map +1 -1
  716. package/dist/src/schema/reserved-tags.js +4 -3
  717. package/dist/src/schema/reserved-tags.js.map +1 -1
  718. package/dist/src/schema/schema-differ.d.ts +16 -0
  719. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  720. package/dist/src/schema/schema-differ.js +225 -38
  721. package/dist/src/schema/schema-differ.js.map +1 -1
  722. package/dist/src/schema/table.d.ts +149 -1
  723. package/dist/src/schema/table.d.ts.map +1 -1
  724. package/dist/src/schema/table.js +248 -1
  725. package/dist/src/schema/table.js.map +1 -1
  726. package/dist/src/schema/unique-enforcement.d.ts +5 -3
  727. package/dist/src/schema/unique-enforcement.d.ts.map +1 -1
  728. package/dist/src/schema/unique-enforcement.js +5 -3
  729. package/dist/src/schema/unique-enforcement.js.map +1 -1
  730. package/dist/src/schema/view.d.ts +11 -0
  731. package/dist/src/schema/view.d.ts.map +1 -1
  732. package/dist/src/schema/view.js +12 -0
  733. package/dist/src/schema/view.js.map +1 -1
  734. package/dist/src/types/builtin-types.d.ts +54 -0
  735. package/dist/src/types/builtin-types.d.ts.map +1 -1
  736. package/dist/src/types/builtin-types.js +123 -34
  737. package/dist/src/types/builtin-types.js.map +1 -1
  738. package/dist/src/types/cast-semantics.d.ts +42 -0
  739. package/dist/src/types/cast-semantics.d.ts.map +1 -1
  740. package/dist/src/types/cast-semantics.js +64 -0
  741. package/dist/src/types/cast-semantics.js.map +1 -1
  742. package/dist/src/types/comparison-coercion.d.ts +101 -0
  743. package/dist/src/types/comparison-coercion.d.ts.map +1 -0
  744. package/dist/src/types/comparison-coercion.js +162 -0
  745. package/dist/src/types/comparison-coercion.js.map +1 -0
  746. package/dist/src/types/index.d.ts +2 -2
  747. package/dist/src/types/index.d.ts.map +1 -1
  748. package/dist/src/types/index.js +2 -2
  749. package/dist/src/types/index.js.map +1 -1
  750. package/dist/src/types/logical-type.d.ts +7 -0
  751. package/dist/src/types/logical-type.d.ts.map +1 -1
  752. package/dist/src/types/logical-type.js.map +1 -1
  753. package/dist/src/types/validation.d.ts +56 -0
  754. package/dist/src/types/validation.d.ts.map +1 -1
  755. package/dist/src/types/validation.js +68 -0
  756. package/dist/src/types/validation.js.map +1 -1
  757. package/dist/src/util/{working-table-iterable.d.ts → array-row-iterable.d.ts} +6 -6
  758. package/dist/src/util/array-row-iterable.d.ts.map +1 -0
  759. package/dist/src/util/{working-table-iterable.js → array-row-iterable.js} +6 -6
  760. package/dist/src/util/array-row-iterable.js.map +1 -0
  761. package/dist/src/util/coercion.d.ts +8 -0
  762. package/dist/src/util/coercion.d.ts.map +1 -1
  763. package/dist/src/util/coercion.js +8 -0
  764. package/dist/src/util/coercion.js.map +1 -1
  765. package/dist/src/util/comparison.d.ts +16 -3
  766. package/dist/src/util/comparison.d.ts.map +1 -1
  767. package/dist/src/util/comparison.js +21 -5
  768. package/dist/src/util/comparison.js.map +1 -1
  769. package/dist/src/util/key-serializer.d.ts +46 -0
  770. package/dist/src/util/key-serializer.d.ts.map +1 -1
  771. package/dist/src/util/key-serializer.js +47 -0
  772. package/dist/src/util/key-serializer.js.map +1 -1
  773. package/dist/src/util/value-set.d.ts +21 -0
  774. package/dist/src/util/value-set.d.ts.map +1 -0
  775. package/dist/src/util/value-set.js +22 -0
  776. package/dist/src/util/value-set.js.map +1 -0
  777. package/dist/src/vtab/capabilities.d.ts +1 -1
  778. package/dist/src/vtab/events.d.ts +8 -1
  779. package/dist/src/vtab/events.d.ts.map +1 -1
  780. package/dist/src/vtab/events.js.map +1 -1
  781. package/dist/src/vtab/manifest.d.ts +15 -0
  782. package/dist/src/vtab/manifest.d.ts.map +1 -1
  783. package/dist/src/vtab/memory/layer/alter-column.d.ts +147 -0
  784. package/dist/src/vtab/memory/layer/alter-column.d.ts.map +1 -0
  785. package/dist/src/vtab/memory/layer/alter-column.js +214 -0
  786. package/dist/src/vtab/memory/layer/alter-column.js.map +1 -0
  787. package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
  788. package/dist/src/vtab/memory/layer/base.js +4 -3
  789. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  790. package/dist/src/vtab/memory/layer/interface.d.ts +2 -2
  791. package/dist/src/vtab/memory/layer/interface.d.ts.map +1 -1
  792. package/dist/src/vtab/memory/layer/manager.d.ts +176 -25
  793. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  794. package/dist/src/vtab/memory/layer/manager.js +569 -558
  795. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  796. package/dist/src/vtab/memory/layer/scan-layer.d.ts.map +1 -1
  797. package/dist/src/vtab/memory/layer/scan-layer.js +32 -5
  798. package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
  799. package/dist/src/vtab/memory/layer/transaction.d.ts +101 -15
  800. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  801. package/dist/src/vtab/memory/layer/transaction.js +133 -45
  802. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  803. package/dist/src/vtab/memory/module.d.ts +16 -1
  804. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  805. package/dist/src/vtab/memory/module.js +64 -3
  806. package/dist/src/vtab/memory/module.js.map +1 -1
  807. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  808. package/dist/src/vtab/memory/table.js +11 -6
  809. package/dist/src/vtab/memory/table.js.map +1 -1
  810. package/dist/src/vtab/module.d.ts +77 -23
  811. package/dist/src/vtab/module.d.ts.map +1 -1
  812. package/dist/src/vtab/table.d.ts +9 -2
  813. package/dist/src/vtab/table.d.ts.map +1 -1
  814. package/dist/src/vtab/table.js +1 -1
  815. package/dist/src/vtab/table.js.map +1 -1
  816. package/package.json +3 -3
  817. package/dist/src/util/working-table-iterable.d.ts.map +0 -1
  818. package/dist/src/util/working-table-iterable.js.map +0 -1
@@ -1,23 +1,27 @@
1
1
  import { asRun } from '../types.js';
2
2
  import { emitCallFromPlan } from '../emitters.js';
3
3
  import { createRowSlot } from '../context-helpers.js';
4
- import { QuereusError } from '../../common/errors.js';
4
+ import { QuereusError, RelationNotFoundError } from '../../common/errors.js';
5
5
  import { StatusCode } from '../../common/types.js';
6
6
  import { createLogger } from '../../common/logger.js';
7
- import { buildColumnIndexMap, withGeneratedColumnGraph, requireVtabModule, resolveNamedConstraintClass, validateCollationForType } from '../../schema/table.js';
7
+ import { buildColumnIndexMap, withGeneratedColumnGraph, requireVtabModule, resolveNamedConstraintClass, namedConstraintExists, assertConstraintNameFree, validateCollationForType, columnDefToSchema } from '../../schema/table.js';
8
8
  import { validateForeignKeyCollations, buildForeignKeyConstraintSchema, extractColumnLevelCheckConstraints, extractColumnLevelForeignKeys, extractColumnLevelUniqueConstraints } from '../../schema/constraint-builder.js';
9
- import { MemoryTableModule } from '../../vtab/memory/module.js';
10
9
  import { quoteIdentifier, expressionToString, astToString } from '../../emit/ast-stringify.js';
11
- import { renameTableInAst, renameColumnInAst, renameColumnInCheckExpression } from '../../schema/rename-rewriter.js';
10
+ import { renameTableInAst, renameColumnInAst, renameColumnInCheckExpression, renameColumnInColumnExpressions, renameTableInColumnExpressions } from '../../schema/rename-rewriter.js';
12
11
  import { assertCatalogObjectPersistable, assertRenameDependentsPersistable } from '../../schema/catalog-persistability.js';
13
- import { tryFoldLiteral } from '../../parser/utils.js';
12
+ import { assertUniqueConstraintIndexNameFree, assertUniqueConstraintNotDuplicated, uniqueConstraintColumnSetKey } from '../../schema/catalog.js';
14
13
  import { isTruthy } from '../../util/comparison.js';
15
- import { assertDdlTransactionPolicy } from './ddl-transaction-policy.js';
16
- import { validateAndParse } from '../../types/validation.js';
14
+ import { assertDdlTransactionPolicy, isExplicitTransactionOpen } from './ddl-transaction-policy.js';
15
+ import { buildColumnSourceResolver } from '../../schema/column-source-resolver.js';
16
+ import { assertNoColumnDefaultNamesColumn, assertNoCheckConstraintNamesColumn, assertNoAssertionNamesColumn, assertNoForeignKeyReferencesColumn } from './drop-column-guards.js';
17
+ import { emitAlterSchemaEvent, withStatementScopedSchemaEvents } from './alter-schema-event.js';
18
+ import { foldDefaultToType, validateAndParse } from '../../types/validation.js';
17
19
  import { snapshotStaleMaterializedViews, propagateTableRenameToMaterializedViews, propagateColumnRenameToMaterializedViews, restoreUnaffectedMaterializedViews, attachMaintainedDerivation, detachMaintainedDerivation, } from './materialized-view-helpers.js';
20
+ import { propagateTableRenameToAssertions, propagateColumnRenameToAssertions, } from './assertion-rename-helpers.js';
18
21
  import { isMaintainedTable } from '../../schema/derivation.js';
19
22
  import { inferType } from '../../types/registry.js';
20
23
  const log = createLogger('runtime:emit:alter-table');
24
+ const warnLog = log.extend('warn');
21
25
  /** A scheduled sub-program resolved to a callback the emitter invokes per row. */
22
26
  function qualifyTableName(schemaName, tableName) {
23
27
  const prefix = (schemaName && schemaName.toLowerCase() !== 'main')
@@ -28,12 +32,15 @@ function qualifyTableName(schemaName, tableName) {
28
32
  export function emitAlterTable(plan, ctx) {
29
33
  const tableSchema = plan.table.tableSchema;
30
34
  const action = plan.action;
31
- // An ADD COLUMN with a non-foldable DEFAULT carries a backfill scalar; emit it as a
32
- // scheduled sub-program so the scheduler resolves it into a callback the run() body
33
- // evaluates per existing row (via a row slot over the default's row descriptor). When the
34
- // new column also carries a CHECK, its predicates ride alongside as further callbacks,
35
- // evaluated per backfilled row against `[...existingRow, backfilledValue]`. Slot order is
36
- // fixed: backfill first (present whenever checks are), then the checks in order.
35
+ // An ADD COLUMN with a per-row value source — a non-foldable DEFAULT, or a GENERATED
36
+ // ALWAYS AS expression — carries a backfill scalar; emit it as a scheduled sub-program
37
+ // so the scheduler resolves it into a callback the run() body evaluates per existing row
38
+ // (via a row slot over the backfill's row descriptor). When the new column also carries a
39
+ // CHECK, its predicates ride alongside as further callbacks, evaluated per backfilled row
40
+ // against `[...existingRow, backfilledValue]`. Slot order is fixed: backfill first
41
+ // (present whenever checks are), then the checks in order — this MUST match
42
+ // `AlterTableNode.addColumnExpressions()` (planner/nodes/alter-table-node.ts), which is
43
+ // the order the optimizer rewrites these children in via getChildren/withChildren.
37
44
  const backfill = action.type === 'addColumn' ? action.backfill : undefined;
38
45
  const checks = action.type === 'addColumn' ? action.checks : undefined;
39
46
  const params = [
@@ -66,58 +73,66 @@ export function emitAlterTable(plan, ctx) {
66
73
  ? `cannot ALTER TABLE '${tableSchema.name}': it is a materialized view — use ALTER MATERIALIZED VIEW for tags`
67
74
  : `cannot ALTER '${tableSchema.name}': it is a materialized view — its shape is defined by the view body (drop and recreate to change it)`, StatusCode.ERROR);
68
75
  }
69
- switch (action.type) {
70
- case 'renameTable':
71
- return runRenameTable(rctx, tableSchema, schema, action.newName);
72
- case 'renameColumn':
73
- return runRenameColumn(rctx, tableSchema, schema, action.oldName, action.newName);
74
- case 'addColumn': {
75
- // Slot order set in `params`: backfill callback first (if any), then check callbacks.
76
- const backfillCb = backfill ? args[0] : undefined;
77
- const checkCbs = args.slice(backfill ? 1 : 0);
78
- return runAddColumn(rctx, tableSchema, schema, action.column, backfill, backfillCb, checks, checkCbs);
79
- }
80
- case 'dropColumn':
81
- return runDropColumn(rctx, tableSchema, schema, action.name);
82
- case 'dropConstraint':
83
- return runDropConstraint(rctx, tableSchema, schema, action.name);
84
- case 'renameConstraint':
85
- return runRenameConstraint(rctx, tableSchema, schema, action.oldName, action.newName);
86
- case 'alterPrimaryKey':
87
- return runAlterPrimaryKey(rctx, tableSchema, schema, action.columns);
88
- case 'alterColumn':
89
- return runAlterColumn(rctx, tableSchema, schema, action);
90
- case 'setTags': {
91
- const target = action.target;
92
- if (action.mode === 'merge') {
93
- // ADD TAGS — per-key merge onto the live tag set.
76
+ // Every arm runs under the statement-scoped schema-event scope: an arm that fails
77
+ // after the module call has already let an emitter-backed module announce the
78
+ // statement (it emits from inside `module.alterTable`, not at the statement's end),
79
+ // so the failure path must retract that announcement. See
80
+ // {@link withStatementScopedSchemaEvents} for why this sits at the statement
81
+ // boundary rather than inside any one arm's revert.
82
+ return withStatementScopedSchemaEvents(rctx, async () => {
83
+ switch (action.type) {
84
+ case 'renameTable':
85
+ return runRenameTable(rctx, tableSchema, schema, action.newName, plan.sql);
86
+ case 'renameColumn':
87
+ return runRenameColumn(rctx, tableSchema, schema, action.oldName, action.newName, plan.sql);
88
+ case 'addColumn': {
89
+ // Slot order set in `params`: backfill callback first (if any), then check callbacks.
90
+ const backfillCb = backfill ? args[0] : undefined;
91
+ const checkCbs = args.slice(backfill ? 1 : 0);
92
+ return runAddColumn(rctx, tableSchema, schema, action.column, plan.sql, backfill, backfillCb, checks, checkCbs);
93
+ }
94
+ case 'dropColumn':
95
+ return runDropColumn(rctx, tableSchema, schema, action.name, plan.sql);
96
+ case 'dropConstraint':
97
+ return runDropConstraint(rctx, tableSchema, schema, action.name, plan.sql);
98
+ case 'renameConstraint':
99
+ return runRenameConstraint(rctx, tableSchema, schema, action.oldName, action.newName, plan.sql);
100
+ case 'alterPrimaryKey':
101
+ return runAlterPrimaryKey(rctx, tableSchema, schema, action.columns, plan.sql);
102
+ case 'alterColumn':
103
+ return runAlterColumn(rctx, tableSchema, schema, action, plan.sql);
104
+ case 'setTags': {
105
+ const target = action.target;
106
+ if (action.mode === 'merge') {
107
+ // ADD TAGS — per-key merge onto the live tag set.
108
+ if (target.kind === 'column')
109
+ return runMergeColumnTags(rctx, tableSchema, target.columnName, action.tags);
110
+ if (target.kind === 'constraint')
111
+ return runMergeConstraintTags(rctx, tableSchema, target.constraintName, action.tags);
112
+ return runMergeTableTags(rctx, tableSchema, action.tags);
113
+ }
114
+ // SET TAGS — whole-set replace.
94
115
  if (target.kind === 'column')
95
- return runMergeColumnTags(rctx, tableSchema, target.columnName, action.tags);
116
+ return runSetColumnTags(rctx, tableSchema, target.columnName, action.tags);
96
117
  if (target.kind === 'constraint')
97
- return runMergeConstraintTags(rctx, tableSchema, target.constraintName, action.tags);
98
- return runMergeTableTags(rctx, tableSchema, action.tags);
118
+ return runSetConstraintTags(rctx, tableSchema, target.constraintName, action.tags);
119
+ return runSetTableTags(rctx, tableSchema, action.tags);
99
120
  }
100
- // SET TAGS — whole-set replace.
101
- if (target.kind === 'column')
102
- return runSetColumnTags(rctx, tableSchema, target.columnName, action.tags);
103
- if (target.kind === 'constraint')
104
- return runSetConstraintTags(rctx, tableSchema, target.constraintName, action.tags);
105
- return runSetTableTags(rctx, tableSchema, action.tags);
106
- }
107
- case 'dropTags': {
108
- // DROP TAGS — per-key delete (atomic NOTFOUND if any key absent).
109
- const target = action.target;
110
- if (target.kind === 'column')
111
- return runDropColumnTags(rctx, tableSchema, target.columnName, action.keys);
112
- if (target.kind === 'constraint')
113
- return runDropConstraintTags(rctx, tableSchema, target.constraintName, action.keys);
114
- return runDropTableTags(rctx, tableSchema, action.keys);
121
+ case 'dropTags': {
122
+ // DROP TAGS — per-key delete (atomic NOTFOUND if any key absent).
123
+ const target = action.target;
124
+ if (target.kind === 'column')
125
+ return runDropColumnTags(rctx, tableSchema, target.columnName, action.keys);
126
+ if (target.kind === 'constraint')
127
+ return runDropConstraintTags(rctx, tableSchema, target.constraintName, action.keys);
128
+ return runDropTableTags(rctx, tableSchema, action.keys);
129
+ }
130
+ case 'setMaintained':
131
+ return runSetMaintained(rctx, tableSchema, schema, action.columns, action.select);
132
+ case 'dropMaintained':
133
+ return runDropMaintained(rctx, tableSchema, schema);
115
134
  }
116
- case 'setMaintained':
117
- return runSetMaintained(rctx, tableSchema, schema, action.columns, action.select);
118
- case 'dropMaintained':
119
- return runDropMaintained(rctx, tableSchema, schema);
120
- }
135
+ });
121
136
  }
122
137
  const note = (() => {
123
138
  switch (action.type) {
@@ -153,7 +168,7 @@ export function emitAlterTable(plan, ctx) {
153
168
  note,
154
169
  };
155
170
  }
156
- async function runRenameTable(rctx, tableSchema, schema, newName) {
171
+ async function runRenameTable(rctx, tableSchema, schema, newName, sql) {
157
172
  const oldName = tableSchema.name;
158
173
  // Check for name conflict
159
174
  if (schema.getTable(newName)) {
@@ -172,7 +187,7 @@ async function runRenameTable(rctx, tableSchema, schema, newName) {
172
187
  // substitutes `newName`, which is already under test as the record's own name.
173
188
  assertCatalogObjectPersistable(rctx.db, 'materializedView', { ...tableSchema, name: newName });
174
189
  }
175
- assertRenameDependentsPersistable(rctx.db, schema, ast => renameTableInAst(ast, oldName, newName, tableSchema.schemaName));
190
+ assertRenameDependentsPersistable(rctx.db, schema, ast => renameTableInAst(ast, oldName, newName, tableSchema.schemaName), t => rewriteTableForTableRename(t, tableSchema.schemaName.toLowerCase(), oldName, newName));
176
191
  // Clone schema with new name
177
192
  const updatedTableSchema = {
178
193
  ...tableSchema,
@@ -184,7 +199,9 @@ async function runRenameTable(rctx, tableSchema, schema, newName) {
184
199
  // omit the hook.
185
200
  const module = requireVtabModule(tableSchema);
186
201
  if (module.renameTable) {
187
- await module.renameTable(rctx.db, tableSchema.schemaName, oldName, newName);
202
+ // `sql` marks this call as the statement's own action: an emitter-backed module
203
+ // emits its schema-change event iff it is present (see VirtualTableModule.renameTable).
204
+ await module.renameTable(rctx.db, tableSchema.schemaName, oldName, newName, sql);
188
205
  }
189
206
  // Events this transaction already recorded still carry the OLD name; relabel them so
190
207
  // the commit delivers every event under the name the table has at delivery. AFTER the
@@ -194,9 +211,11 @@ async function runRenameTable(rctx, tableSchema, schema, newName) {
194
211
  // matching where the other ALTER arms call `remapBatchedDataEvents`.
195
212
  //
196
213
  // NOTE: batched SCHEMA events are deliberately out of scope here. A schema event
197
- // records a DDL operation, not current state — relabelling `objectName` without
198
- // rewriting its `ddl` text would produce an incoherent instruction. How a rename
199
- // crosses the wire to a peer is `fix/sync-schema-migrations-replicate-empty-ddl`.
214
+ // records a DDL operation, not current state — each now carries the statement's own
215
+ // canonical `ddl` text (and, for a rename, `oldObjectName`), so relabelling
216
+ // `objectName` without rewriting that text would produce an incoherent instruction.
217
+ // A consumer replays the schema events in order; the rename is one of them, carrying
218
+ // this very statement's SQL, so earlier events legitimately name the old table.
200
219
  rctx.db._getEventEmitter().renameBatchedEvents(tableSchema.schemaName, oldName, newName);
201
220
  // Deferred constraint checks this transaction already parked carry evaluators compiled
202
221
  // against the OLD name — their scan leaves would connect to a table that no longer
@@ -261,10 +280,20 @@ async function runRenameTable(rctx, tableSchema, schema, newName) {
261
280
  // names a vanished table. A module whose `renameTable` already did all its work (or
262
281
  // that keeps no per-name catalog) simply omits the hook.
263
282
  await module.finalizeRename?.(rctx.db, tableSchema.schemaName, oldName, newName);
283
+ // The public schema-change event, for a module with no emitter of its own — see
284
+ // {@link emitAlterSchemaEvent} for why every arm emits at its tail rather than
285
+ // alongside the module call. `objectName` is the NEW table; `oldObjectName` says
286
+ // what it renamed FROM, so a receiver can tell which of its tables the event is about.
287
+ emitAlterSchemaEvent(rctx, tableSchema, {
288
+ type: 'alter', objectType: 'table',
289
+ objectName: newName,
290
+ oldObjectName: oldName,
291
+ ddl: sql,
292
+ });
264
293
  log('Renamed table %s.%s to %s', tableSchema.schemaName, oldName, newName);
265
294
  return null;
266
295
  }
267
- async function runRenameColumn(rctx, tableSchema, schema, oldName, newName) {
296
+ async function runRenameColumn(rctx, tableSchema, schema, oldName, newName, sql) {
268
297
  const colIndex = tableSchema.columnIndexMap.get(oldName.toLowerCase());
269
298
  if (colIndex === undefined) {
270
299
  throw new QuereusError(`Column '${oldName}' not found in table '${tableSchema.name}'`, StatusCode.ERROR);
@@ -274,15 +303,18 @@ async function runRenameColumn(rctx, tableSchema, schema, oldName, newName) {
274
303
  throw new QuereusError(`Column '${newName}' already exists in table '${tableSchema.name}'`, StatusCode.ERROR);
275
304
  }
276
305
  // Pre-flight, BEFORE the first side effect (`module.alterTable`): the rewritten
277
- // body of every dependent view / materialized view must still be persistable —
306
+ // body of every dependent view / materialized view — and the rewritten record of
307
+ // every dependent table (its CHECK expressions, the referenced-column list of an FK
308
+ // pointing here, its partial-index predicates) — must still be persistable, on the
278
309
  // same unfailable-propagation reasoning as the table-rename arm above. Shares one
279
310
  // resolver with `propagateColumnRename` so the two passes cannot drift apart in
280
311
  // code; what makes them agree at RUNTIME (the resolver reads the LIVE catalog, and
281
312
  // this probe runs pre-mutation while the propagation runs post-) is that
282
313
  // `isTableInUnaliasedScope` skips the renamed table itself and probes only OTHER
283
314
  // sources, whose column sets this rename does not touch.
284
- const resolveColumnInSource = buildColumnSourceResolver(rctx.db);
285
- assertRenameDependentsPersistable(rctx.db, schema, ast => renameColumnInAst(ast, tableSchema.name, oldName, newName, tableSchema.schemaName, resolveColumnInSource));
315
+ const resolveColumnInSource = buildColumnSourceResolver(rctx.db.schemaManager);
316
+ assertRenameDependentsPersistable(rctx.db, schema, ast => renameColumnInAst(ast, tableSchema.name, oldName, newName, tableSchema.schemaName, resolveColumnInSource), t => rewriteTableForColumnRename(t, tableSchema.schemaName.toLowerCase(), tableSchema.name, oldName, newName, resolveColumnInSource));
317
+ assertRenamedColumnBackingNamesFree(tableSchema, colIndex, oldName, newName);
286
318
  const existingCol = tableSchema.columns[colIndex];
287
319
  // Build a ColumnDef AST for the renamed column (preserving type info)
288
320
  const newColumnDef = {
@@ -299,6 +331,7 @@ async function runRenameColumn(rctx, tableSchema, schema, oldName, newName) {
299
331
  oldName,
300
332
  newName,
301
333
  newColumnDefAst: newColumnDef,
334
+ ddl: sql,
302
335
  });
303
336
  }
304
337
  else {
@@ -333,10 +366,88 @@ async function runRenameColumn(rctx, tableSchema, schema, oldName, newName) {
333
366
  // Propagate the rename into dependent objects (CHECK / FK / partial-index
334
367
  // predicates in this and other tables, view and materialized-view bodies).
335
368
  await propagateColumnRename(rctx, tableSchema.schemaName, tableSchema.name, oldName, newName, preStaleMvs, resolveColumnInSource);
369
+ emitAlterSchemaEvent(rctx, tableSchema, {
370
+ type: 'alter', objectType: 'column',
371
+ objectName: tableSchema.name,
372
+ columnName: newName,
373
+ oldColumnName: oldName,
374
+ ddl: sql,
375
+ });
336
376
  log('Renamed column %s.%s.%s to %s', tableSchema.schemaName, tableSchema.name, oldName, newName);
337
377
  return null;
338
378
  }
339
- async function runAddColumn(rctx, tableSchema, schema, columnDef, backfill, backfillCb, checks, checkCbs) {
379
+ /**
380
+ * Refuses a RENAME COLUMN that would move an unnamed UNIQUE constraint's backing
381
+ * structure onto a name an index on the same table already holds.
382
+ *
383
+ * An unnamed UNIQUE is enforced by a structure named `_uc_<covered column names>`,
384
+ * derived from the LIVE column names and never recorded — so renaming a covered
385
+ * column moves that name. This is the same collision the four declaration paths
386
+ * already refuse (ADD CONSTRAINT, ADD COLUMN … unique, RENAME CONSTRAINT, and
387
+ * `SchemaManager.createIndex` from the index side), reached through a rename instead
388
+ * of a declaration. Left unguarded the user's index is silently reclassified as a
389
+ * hidden backing structure: it vanishes from `schema()` / `index_info()`, `DROP INDEX`
390
+ * answers `no such index`, and store-backed its `CREATE INDEX` line is dropped from
391
+ * the persisted catalog entry — after which the constraint's entries are built into
392
+ * that index's store and, on reopen, it stops rejecting duplicates.
393
+ *
394
+ * Placed before `module.alterTable` for the same reason those paths are: the store's
395
+ * `alterTable` persists, so a later throw would leave the damage on disk.
396
+ *
397
+ * Skips a case-only rename entirely: the derived name folds to the constraint's OWN
398
+ * pre-rename structure, which the memory backend materializes as a real index entry
399
+ * and the name-only guard would otherwise read as a collision (the same reason
400
+ * `runRenameConstraint` gates its check on `oldLower !== newLower`).
401
+ *
402
+ * Named and `derivedFromIndex` constraints are unaffected — neither takes a derived
403
+ * name. Two DIFFERENT unnamed constraints deriving one post-rename name is only
404
+ * reachable through duplicate unnamed UNIQUEs and is not this guard's problem.
405
+ *
406
+ * NOTE: name-only, like the declaration guards, so it also refuses the rename when the
407
+ * constraint is realized by a REUSED same-column-set index and therefore has no
408
+ * `_uc_*` structure to move — a legal rename turned away over a name nothing would
409
+ * have claimed. Deliberate: both backends decide reuse internally and at different
410
+ * times, so a reuse-aware check would make them disagree on which renames are legal.
411
+ * The refusal names both objects and is escapable by renaming the index first. If the
412
+ * false refusal ever bites, gate the check on the constraint actually holding a
413
+ * `_uc_*` structure — which means asking the module, not just `tableSchema.indexes`.
414
+ */
415
+ function assertRenamedColumnBackingNamesFree(tableSchema, colIndex, oldName, newName) {
416
+ if (oldName.toLowerCase() === newName.toLowerCase())
417
+ return;
418
+ for (const uc of tableSchema.uniqueConstraints ?? []) {
419
+ if (uc.name !== undefined || uc.derivedFromIndex !== undefined)
420
+ continue;
421
+ if (!uc.columns.includes(colIndex))
422
+ continue;
423
+ const postRenameColumns = uc.columns.map(i => i === colIndex ? newName : (tableSchema.columns[i]?.name ?? String(i)));
424
+ assertUniqueConstraintIndexNameFree(tableSchema, undefined, postRenameColumns, `rename column '${oldName}' to '${newName}' on table '${tableSchema.name}'`);
425
+ }
426
+ }
427
+ /**
428
+ * Refuses an inline constraint on a new column whose *user-written* name is already taken —
429
+ * by a constraint on the table, or by an earlier inline constraint in the same ADD COLUMN
430
+ * (neither is on `tableSchema` yet). Same within-table rule ADD CONSTRAINT and RENAME
431
+ * CONSTRAINT enforce; see {@link assertConstraintNameFree} for the ordering constraints.
432
+ *
433
+ * Reads the RAW declaration rather than the extracted table constraints: the extractors
434
+ * auto-name an unnamed CHECK `_check_<column>`, and that synthesized name is not user
435
+ * identity — comparing it would refuse two unnamed CHECKs on one new column, which is
436
+ * legal. Only the three classes that occupy a named-constraint array are compared (a name
437
+ * on an inline NOT NULL / DEFAULT / PRIMARY KEY is not stored, so it cannot collide).
438
+ */
439
+ function assertInlineConstraintNamesFree(tableSchema, columnDef) {
440
+ const seen = new Set();
441
+ for (const declared of columnDef.constraints) {
442
+ if (!declared.name)
443
+ continue;
444
+ if (declared.type !== 'check' && declared.type !== 'unique' && declared.type !== 'foreignKey')
445
+ continue;
446
+ assertConstraintNameFree(tableSchema, declared.name, seen);
447
+ seen.add(declared.name.toLowerCase());
448
+ }
449
+ }
450
+ async function runAddColumn(rctx, tableSchema, schema, columnDef, sql, backfill, backfillCb, checks, checkCbs) {
340
451
  // Validate column doesn't already exist
341
452
  if (tableSchema.columnIndexMap.has(columnDef.name.toLowerCase())) {
342
453
  throw new QuereusError(`Column '${columnDef.name}' already exists in table '${tableSchema.name}'`, StatusCode.ERROR);
@@ -349,21 +460,37 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef, backfill, back
349
460
  // (bind params / bare columns / non-determinism rejected; `new.<column>` accepted)
350
461
  // and, when it does not fold to a literal, compiled into `backfill` — the default
351
462
  // evaluated against the existing row, so `new.<column>` reads that row's sibling.
463
+ // A GENERATED ALWAYS AS expression takes the same `backfill` route (always, since a
464
+ // generated column has no `defaultValue` any module could bulk-write), validated at
465
+ // plan-build with the generated-flavoured determinism check.
352
466
  const defaultConstraint = columnDef.constraints?.find(c => c.type === 'default');
353
- // Folded literal default; undefined when there is no default or it does not fold
354
- // (the latter carries `backfill` instead). Used by the NOT NULL gate below and by
355
- // the batched-event remap's backfill value.
356
- const foldedDefault = defaultConstraint?.expr ? tryFoldLiteral(defaultConstraint.expr) : undefined;
467
+ // Folded literal default, converted to the new column's declared type — the value a
468
+ // fresh INSERT under the same DEFAULT would store, and the same value each module
469
+ // folds for its own rows. Undefined when there is no default (a generated column
470
+ // included) or it does not fold — those carry `backfill` instead. Used by the NOT NULL
471
+ // gate below and by the batched-event remap's backfill value. An unconvertible literal
472
+ // (`integer default 'abc'`) throws MISMATCH here, before anything is mutated.
473
+ const foldedDefault = foldDefaultToType(defaultConstraint?.expr, inferType(columnDef.dataType), columnDef.name);
357
474
  // Call module.alterTable for data + schema update
358
475
  const module = requireVtabModule(tableSchema);
359
476
  if (!module.alterTable) {
360
477
  throw new QuereusError(`Module for table '${tableSchema.name}' does not support ALTER TABLE ADD COLUMN`, StatusCode.UNSUPPORTED);
361
478
  }
362
- // NOT NULL without a usable DEFAULT cannot backfill existing rows. A DEFAULT whose
363
- // folded value is NULL is equivalent to "no DEFAULT" for this purpose. A non-foldable
364
- // expression default (carried in `backfill`) IS usable — its NOT NULL enforcement is
365
- // deferred to the post-backfill scan — so it is not rejected here. If the table is
366
- // non-empty and the default is nullish, reject before mutating any schema or data.
479
+ // NOT NULL without a usable value source cannot backfill existing rows. A DEFAULT whose
480
+ // folded value is NULL is equivalent to "no DEFAULT" for this purpose. A per-row source
481
+ // (carried in `backfill` — a non-foldable expression default or a GENERATED ALWAYS AS
482
+ // expression) IS usable: its NOT NULL enforcement is deferred to the module's per-row
483
+ // backfill, which rejects the ALTER if any row evaluates to NULL. If the table is
484
+ // non-empty and there is no usable source, reject before mutating any schema or data.
485
+ //
486
+ // Mandatoriness is RESOLVED, not read off the statement text: a column is NOT NULL
487
+ // either by an explicit `not null` or by the session `default_column_nullability`
488
+ // (which ships as `not_null`), so `add column x text default null` is a mandatory
489
+ // column with no value for the existing rows and must be refused. `columnDefToSchema`
490
+ // is the same resolver the memory module, the store module and the isolation layer's
491
+ // `deriveAddColumnBackfill` use, so a fourth spelling of the rule cannot drift. It
492
+ // also validates an explicit COLLATE and rejects DEFAULT + GENERATED ALWAYS AS on one
493
+ // column — both previously raised by the module mid-work, now pre-mutation.
367
494
  //
368
495
  // A module may opt out of this engine-generic rejection via the
369
496
  // `delegatesNotNullBackfill` capability (structurally-total modules that
@@ -371,8 +498,9 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef, backfill, back
371
498
  // it declares the capability, the decision is left entirely to its
372
499
  // `alterTable`. Native modules leave it off, so this still fires for them.
373
500
  const delegatesBackfill = module.getCapabilities?.().delegatesNotNullBackfill === true;
374
- const hasNotNull = columnDef.constraints?.some(c => c.type === 'notNull') ?? false;
375
- if (hasNotNull && !delegatesBackfill && !backfill) {
501
+ const defaultNotNull = rctx.db.options.getStringOption('default_column_nullability') === 'not_null';
502
+ const resolvedNotNull = columnDefToSchema(columnDef, defaultNotNull, rctx.db.options.getStringOption('default_collation'), (n) => rctx.db.isCollationRegistered(n)).notNull;
503
+ if (resolvedNotNull && !delegatesBackfill && !backfill) {
376
504
  const defaultIsNullish = !defaultConstraint?.expr || foldedDefault === null;
377
505
  if (defaultIsNullish) {
378
506
  await validateNotNullBackfill(rctx, tableSchema, columnDef.name);
@@ -395,9 +523,37 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef, backfill, back
395
523
  ...inlineChecks,
396
524
  ...extractColumnLevelForeignKeys(columnDef),
397
525
  ];
398
- // A non-foldable default backfills each existing row from its own value. Install a row
399
- // slot over the default's row descriptor; the evaluator the module calls per existing
400
- // row sets the slot to that row, so the default's `new.<col>` refs resolve to it.
526
+ // Refused before the column is materialized, so a duplicate name leaves the table
527
+ // completely untouched rather than relying on the revert path.
528
+ assertInlineConstraintNamesFree(tableSchema, columnDef);
529
+ // An inline `unique` builds an implicit backing structure named after the constraint
530
+ // — or `_uc_<column>` when unnamed — so reject before the column is materialized when
531
+ // that name is already an index on this table, or when the declaration merely repeats
532
+ // a UNIQUE the table already carries. The column does not exist yet, so both tests run
533
+ // off the column definition's own name (which is exactly what
534
+ // `extractColumnLevelUniqueConstraints` put in `columns`). Placed here, ahead of
535
+ // `module.alterTable`, so a refused statement leaves the table completely untouched
536
+ // rather than relying on the revert path.
537
+ //
538
+ // Duplicate-first, index-name-second — see the ordering rationale in
539
+ // `runAddConstraintViaModule`. `declaredColumnSets` carries the unnamed sets claimed by
540
+ // earlier inline constraints in THIS statement (`add column c … unique unique`); none
541
+ // of them is on `tableSchema` yet, so the guard cannot see them any other way.
542
+ const declaredColumnSets = new Set();
543
+ for (const constraint of inlineConstraints) {
544
+ if (constraint.type !== 'unique')
545
+ continue;
546
+ const columnNames = (constraint.columns ?? []).map(c => c.name);
547
+ const operation = `add ${constraint.name ? `constraint '${constraint.name}'` : 'UNIQUE'} column '${columnDef.name}' to table '${tableSchema.name}'`;
548
+ assertUniqueConstraintNotDuplicated(tableSchema, constraint.name, columnNames, operation, declaredColumnSets);
549
+ assertUniqueConstraintIndexNameFree(tableSchema, constraint.name, columnNames, operation);
550
+ if (constraint.name === undefined)
551
+ declaredColumnSets.add(uniqueConstraintColumnSetKey(columnNames));
552
+ }
553
+ // A per-row backfill derives each existing row's value from that row. Install a row slot
554
+ // over the backfill's row descriptor; the evaluator the module calls per existing row
555
+ // sets the slot to that row, so the expression's `new.<col>` refs (and the bare `<col>`
556
+ // refs a GENERATED ALWAYS AS expression uses) resolve to it.
401
557
  const rowSlot = backfill ? createRowSlot(rctx, backfill.rowDescriptor) : undefined;
402
558
  // When the new column carries a CHECK, install a second slot over the existing columns
403
559
  // plus the new column; we evaluate each predicate against `[...existingRow, value]` after
@@ -411,7 +567,15 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef, backfill, back
411
567
  ? async (row) => {
412
568
  rowSlot.set(row);
413
569
  const valueRaw = backfillCb(rctx);
414
- const value = (valueRaw instanceof Promise ? await valueRaw : valueRaw);
570
+ const evaluated = (valueRaw instanceof Promise ? await valueRaw : valueRaw);
571
+ // Convert to the new column's declared type BEFORE the CHECK predicates see it,
572
+ // matching the write path (`emitInsert` coerces at the top of the DML pipeline, so
573
+ // constraint checking and storage both see the declared form). `coerceTo` is unset
574
+ // when the expression's static type already IS the column's type — see
575
+ // `AddColumnBackfill.coerceTo` for why re-converting there would be destructive.
576
+ const value = backfill.coerceTo
577
+ ? validateAndParse(evaluated, backfill.coerceTo, columnDef.name)
578
+ : evaluated;
415
579
  if (checkSlot && checkPredicates.length > 0 && checkCbs) {
416
580
  checkSlot.set([...row, value]);
417
581
  for (let i = 0; i < checkPredicates.length; i++) {
@@ -438,10 +602,19 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef, backfill, back
438
602
  // the inverse event remap.
439
603
  let addedColIndex;
440
604
  try {
605
+ // `ddl` marks this call — and only this one — as the statement's own action: the
606
+ // inline-constraint installs below and any revert calls pass none, so an
607
+ // emitter-backed module announces exactly ONE event for the whole statement.
608
+ //
609
+ // That marker settles HOW MANY events a successful statement announces, not whether a
610
+ // failed one announces any: this call is not the end of the statement, so a failure in
611
+ // the inline-constraint installs below leaves this announcement already batched. The
612
+ // statement-scoped retraction wrapped around the whole arm dispatch is what removes it.
441
613
  updatedTableSchema = await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, {
442
614
  type: 'addColumn',
443
615
  columnDef,
444
616
  backfillEvaluator,
617
+ ddl: sql,
445
618
  });
446
619
  // Events this transaction already batched for the table still describe the
447
620
  // pre-ADD column set; insert the backfilled value at the new slot so a listener
@@ -513,9 +686,10 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef, backfill, back
513
686
  // folding against them is sound and preserves the optimizer's reach.
514
687
  schema.addTable(columnOnlySchema);
515
688
  // Validate the backfilled values against each inline CHECK, for the literal-default
516
- // path only. A per-row (evaluator) default already enforced its CHECKs inside the
517
- // backfill hook above — against the freshly-computed value rather than this scan's
518
- // stale pre-backfill snapshot — and the module enforces NOT NULL there too. Runs
689
+ // path only. A per-row (evaluator) backfill — non-foldable DEFAULT or GENERATED
690
+ // ALWAYS AS — already enforced its CHECKs inside the backfill hook above, against the
691
+ // freshly-computed value rather than this scan's stale pre-backfill snapshot, and the
692
+ // module enforces NOT NULL there too. Runs
519
693
  // before the whole install loop below, so on a column declaring several kinds a
520
694
  // CHECK violation is reported ahead of a UNIQUE or FK one.
521
695
  if (!backfill && inlineChecks.length > 0) {
@@ -554,6 +728,9 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef, backfill, back
554
728
  // orphans) and — store-backed — persists. Thread the returned schema forward so
555
729
  // each constraint layers on the last. The module's answer carries no
556
730
  // generated-column bookkeeping of its own, so re-derive it each round.
731
+ // Deliberately NO `ddl`: this is an engine-internal sub-step of the ADD COLUMN
732
+ // statement, so an emitter-backed module must announce nothing for it — the
733
+ // statement's one event rode the `addColumn` call above.
557
734
  const withConstraint = await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, {
558
735
  type: 'addConstraint',
559
736
  constraint,
@@ -577,6 +754,17 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef, backfill, back
577
754
  oldObject: tableSchema,
578
755
  newObject: finalTableSchema,
579
756
  });
757
+ // ONE event for the whole statement, even when the column declared inline constraints.
758
+ // The install loop above makes a second `module.alterTable(addConstraint)` round-trip per
759
+ // inline constraint; an emitter-backed module now agrees on one event too, because only
760
+ // the `addColumn` call carried `ddl` and a module emits iff it is set. Do not "fix"
761
+ // this into per-constraint events on either path.
762
+ emitAlterSchemaEvent(rctx, tableSchema, {
763
+ type: 'alter', objectType: 'column',
764
+ objectName: tableSchema.name,
765
+ columnName: columnDef.name,
766
+ ddl: sql,
767
+ });
580
768
  log('Added column %s to table %s.%s', columnDef.name, tableSchema.schemaName, tableSchema.name);
581
769
  return null;
582
770
  }
@@ -594,6 +782,14 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef, backfill, back
594
782
  * mask the original violation. Restoring the catalog entry is a no-op when the ALTER failed
595
783
  * before registering anything (the original schema is still the live one).
596
784
  *
785
+ * Every module call here passes no `ddl`, deliberately: an emitter-backed module emits only
786
+ * for a call carrying `ddl`, so the unwinding itself announces nothing. That is the SECOND
787
+ * line of defence, not the only one — the failed statement's own `addColumn` call DID carry
788
+ * `ddl`, and an emitter-backed module already batched an event for it before we got here.
789
+ * What actually keeps a failed ADD COLUMN silent is the statement-scoped retraction the whole
790
+ * arm dispatch runs under (`withStatementScopedSchemaEvents` in `emitAlterTable`'s `run()`),
791
+ * which drops that event as the error propagates.
792
+ *
597
793
  * NOTE: the hand-back is by NAME, so it assumes a name resolves to the constraint this
598
794
  * ALTER installed. A pre-existing constraint can legitimately share an auto-name (nothing
599
795
  * rejects `constraint _check_w check (…)` on a table that later gets `add column w …
@@ -656,6 +852,12 @@ async function validateBackfillAgainstChecks(rctx, columnOnlySchema, newCheckCon
656
852
  const checkSql = expressionToString(cc.expr);
657
853
  const sql = `select 1 from ${qualifiedTable} where not (${checkSql}) limit 1`;
658
854
  const stmt = rctx.db.prepare(sql);
855
+ // The CHECK is SCHEMA-AUTHORED: it belongs to the altered table's own DDL, so a
856
+ // bare relation name inside it means the ALTERED table's schema — not the session
857
+ // path this freshly-prepared validation statement would otherwise inherit. Owning
858
+ // schema ONLY, matching `schemaAuthoredContext` (planner/building/schema-authored-context.ts),
859
+ // which decides the same thing for every CHECK the DML builders compile.
860
+ stmt._schemaPathOverride = [columnOnlySchema.schemaName];
659
861
  try {
660
862
  let violated = false;
661
863
  for await (const _row of stmt._iterateRowsRaw()) {
@@ -672,9 +874,10 @@ async function validateBackfillAgainstChecks(rctx, columnOnlySchema, newCheckCon
672
874
  }
673
875
  }
674
876
  /**
675
- * Rejects ADD COLUMN ... NOT NULL when no usable DEFAULT is supplied and the
676
- * table already has rows. The pre-mutation form means no rollback is needed —
677
- * the schema and module state are still untouched at this point.
877
+ * Rejects ADD COLUMN ... NOT NULL when no usable value source is supplied (no DEFAULT,
878
+ * a DEFAULT folding to NULL, and no per-row backfill) and the table already has rows.
879
+ * The pre-mutation form means no rollback is needed — the schema and module state are
880
+ * still untouched at this point.
678
881
  */
679
882
  async function validateNotNullBackfill(rctx, tableSchema, newColumnName) {
680
883
  const qualifiedTable = qualifyTableName(tableSchema.schemaName, tableSchema.name);
@@ -731,7 +934,7 @@ function predicateReferencesColumn(expr, columnName) {
731
934
  visit(expr);
732
935
  return found;
733
936
  }
734
- async function runDropColumn(rctx, tableSchema, schema, columnName) {
937
+ async function runDropColumn(rctx, tableSchema, schema, columnName, sql) {
735
938
  const colIndex = tableSchema.columnIndexMap.get(columnName.toLowerCase());
736
939
  if (colIndex === undefined) {
737
940
  throw new QuereusError(`Column '${columnName}' not found in table '${tableSchema.name}'`, StatusCode.ERROR);
@@ -764,6 +967,16 @@ async function runDropColumn(rctx, tableSchema, schema, columnName) {
764
967
  throw new QuereusError(`Cannot drop column '${columnName}' from '${tableSchema.name}': it is referenced by the WHERE clause of partial index '${idx.name}'`, StatusCode.CONSTRAINT);
765
968
  }
766
969
  }
970
+ // Validate: the remaining dependents `module.alterTable` cannot narrow — a sibling
971
+ // column's DEFAULT, a CHECK on this table, a foreign key in another table pointing AT
972
+ // the column, and an assertion body. All four run before `requireVtabModule` /
973
+ // `module.alterTable`, so a refused drop persists nothing. Ordered by widening blast
974
+ // radius (a column of this table → this table → another table → the whole database), so
975
+ // the most locally-explainable violation is the one reported.
976
+ assertNoColumnDefaultNamesColumn(rctx.db, tableSchema, columnName);
977
+ assertNoCheckConstraintNamesColumn(rctx.db, tableSchema, columnName);
978
+ assertNoForeignKeyReferencesColumn(rctx.db, tableSchema, columnName);
979
+ assertNoAssertionNamesColumn(rctx.db, tableSchema, columnName);
767
980
  // Call module.alterTable for data + schema update
768
981
  const module = requireVtabModule(tableSchema);
769
982
  if (!module.alterTable) {
@@ -772,6 +985,7 @@ async function runDropColumn(rctx, tableSchema, schema, columnName) {
772
985
  const updatedTableSchema = await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, {
773
986
  type: 'dropColumn',
774
987
  columnName,
988
+ ddl: sql,
775
989
  });
776
990
  // Events this transaction already batched for the table still carry the pre-drop
777
991
  // arity; drop the slot so a listener at commit pairs value i with column i of the
@@ -792,6 +1006,14 @@ async function runDropColumn(rctx, tableSchema, schema, columnName) {
792
1006
  oldObject: tableSchema,
793
1007
  newObject: finalSchema,
794
1008
  });
1009
+ // `drop`, not `alter` — the arm removes an object. Matches what an emitter-backed module
1010
+ // reports for the same statement.
1011
+ emitAlterSchemaEvent(rctx, tableSchema, {
1012
+ type: 'drop', objectType: 'column',
1013
+ objectName: tableSchema.name,
1014
+ columnName,
1015
+ ddl: sql,
1016
+ });
795
1017
  log('Dropped column %s from table %s.%s', columnName, tableSchema.schemaName, tableSchema.name);
796
1018
  return null;
797
1019
  }
@@ -805,7 +1027,7 @@ async function runDropColumn(rctx, tableSchema, schema, columnName) {
805
1027
  * module owns the actual array rewrite and, for a UNIQUE, tearing down the
806
1028
  * implicit covering index that backs it.
807
1029
  */
808
- async function runDropConstraint(rctx, tableSchema, schema, constraintName) {
1030
+ async function runDropConstraint(rctx, tableSchema, schema, constraintName, sql) {
809
1031
  const constraintClass = resolveNamedConstraintClass(tableSchema, constraintName);
810
1032
  if (constraintClass === 'unique') {
811
1033
  rejectDerivedFromIndex(tableSchema, constraintName, 'DROP');
@@ -817,6 +1039,7 @@ async function runDropConstraint(rctx, tableSchema, schema, constraintName) {
817
1039
  const updatedTableSchema = await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, {
818
1040
  type: 'dropConstraint',
819
1041
  constraintName,
1042
+ ddl: sql,
820
1043
  });
821
1044
  schema.addTable(updatedTableSchema);
822
1045
  rctx.db.schemaManager.getChangeNotifier().notifyChange({
@@ -826,6 +1049,11 @@ async function runDropConstraint(rctx, tableSchema, schema, constraintName) {
826
1049
  oldObject: tableSchema,
827
1050
  newObject: updatedTableSchema,
828
1051
  });
1052
+ emitAlterSchemaEvent(rctx, tableSchema, {
1053
+ type: 'alter', objectType: 'table',
1054
+ objectName: tableSchema.name,
1055
+ ddl: sql,
1056
+ });
829
1057
  log('Dropped constraint %s from table %s.%s', constraintName, tableSchema.schemaName, tableSchema.name);
830
1058
  return null;
831
1059
  }
@@ -835,7 +1063,7 @@ async function runDropConstraint(rctx, tableSchema, schema, constraintName) {
835
1063
  * name must not already address a constraint), and rejects renaming a UNIQUE
836
1064
  * derived from an explicit index. Routed through `module.alterTable`.
837
1065
  */
838
- async function runRenameConstraint(rctx, tableSchema, schema, oldName, newName) {
1066
+ async function runRenameConstraint(rctx, tableSchema, schema, oldName, newName, sql) {
839
1067
  const constraintClass = resolveNamedConstraintClass(tableSchema, oldName);
840
1068
  if (constraintClass === 'unique') {
841
1069
  rejectDerivedFromIndex(tableSchema, oldName, 'RENAME');
@@ -847,6 +1075,17 @@ async function runRenameConstraint(rctx, tableSchema, schema, oldName, newName)
847
1075
  if (oldLower !== newLower && namedConstraintExists(tableSchema, newName)) {
848
1076
  throw new QuereusError(`Cannot rename constraint to '${newName}': a constraint with that name already exists in table '${tableSchema.name}'`, StatusCode.CONSTRAINT);
849
1077
  }
1078
+ // A UNIQUE constraint's implicit backing structure is named after the constraint, so
1079
+ // the rename renames that structure too — reject when the new name is already an
1080
+ // index on this table (the mirror of `SchemaManager.createIndex`'s refusal). Gated on
1081
+ // `oldLower !== newLower` for the same reason the collision check above is: on the
1082
+ // memory backend the constraint's OWN backing structure is a materialized index under
1083
+ // the old name, which a case-only rename would otherwise match.
1084
+ if (constraintClass === 'unique' && oldLower !== newLower) {
1085
+ // No columns to pass: the renamed-to name is always a name, so the `_uc_<cols>`
1086
+ // auto-name branch is unreachable from here.
1087
+ assertUniqueConstraintIndexNameFree(tableSchema, newName, [], `rename constraint '${oldName}' to '${newName}' on table '${tableSchema.name}'`);
1088
+ }
850
1089
  const module = requireVtabModule(tableSchema);
851
1090
  if (!module.alterTable) {
852
1091
  throw new QuereusError(`Module for table '${tableSchema.name}' does not support ALTER TABLE RENAME CONSTRAINT`, StatusCode.UNSUPPORTED);
@@ -855,6 +1094,7 @@ async function runRenameConstraint(rctx, tableSchema, schema, oldName, newName)
855
1094
  type: 'renameConstraint',
856
1095
  oldName,
857
1096
  newName,
1097
+ ddl: sql,
858
1098
  });
859
1099
  schema.addTable(updatedTableSchema);
860
1100
  rctx.db.schemaManager.getChangeNotifier().notifyChange({
@@ -864,16 +1104,16 @@ async function runRenameConstraint(rctx, tableSchema, schema, oldName, newName)
864
1104
  oldObject: tableSchema,
865
1105
  newObject: updatedTableSchema,
866
1106
  });
1107
+ // A named constraint is not an `objectType` of its own, so the arm reports the TABLE it
1108
+ // reshaped — same as an emitter-backed module does.
1109
+ emitAlterSchemaEvent(rctx, tableSchema, {
1110
+ type: 'alter', objectType: 'table',
1111
+ objectName: tableSchema.name,
1112
+ ddl: sql,
1113
+ });
867
1114
  log('Renamed constraint %s.%s.%s to %s', tableSchema.schemaName, tableSchema.name, oldName, newName);
868
1115
  return null;
869
1116
  }
870
- /** True when `name` addresses any named CHECK / UNIQUE / FOREIGN KEY constraint. */
871
- function namedConstraintExists(tableSchema, name) {
872
- const lower = name.toLowerCase();
873
- return (tableSchema.checkConstraints ?? []).some(c => c.name?.toLowerCase() === lower)
874
- || (tableSchema.uniqueConstraints ?? []).some(c => c.name?.toLowerCase() === lower)
875
- || (tableSchema.foreignKeys ?? []).some(c => c.name?.toLowerCase() === lower);
876
- }
877
1117
  /**
878
1118
  * Rejects DROP/RENAME of a UNIQUE constraint that was synthesized from an explicit
879
1119
  * `CREATE UNIQUE INDEX` (`derivedFromIndex` set). That constraint is the index's
@@ -887,7 +1127,7 @@ function rejectDerivedFromIndex(tableSchema, constraintName, op) {
887
1127
  throw new QuereusError(`Cannot ${op} CONSTRAINT '${constraintName}' on '${tableSchema.name}': it is backed by index '${uc.derivedFromIndex}' (created via CREATE UNIQUE INDEX). Use DROP INDEX '${uc.derivedFromIndex}' instead.`, StatusCode.CONSTRAINT);
888
1128
  }
889
1129
  }
890
- async function runAlterColumn(rctx, tableSchema, schema, action) {
1130
+ async function runAlterColumn(rctx, tableSchema, schema, action, sql) {
891
1131
  const colIndex = tableSchema.columnIndexMap.get(action.columnName.toLowerCase());
892
1132
  if (colIndex === undefined) {
893
1133
  throw new QuereusError(`Column '${action.columnName}' not found in table '${tableSchema.name}'`, StatusCode.ERROR);
@@ -944,6 +1184,7 @@ async function runAlterColumn(rctx, tableSchema, schema, action) {
944
1184
  setDataType: action.setDataType,
945
1185
  setDefault: action.setDefault,
946
1186
  setCollation: action.setCollation,
1187
+ ddl: sql,
947
1188
  });
948
1189
  // Events this transaction already batched still carry the PRE-conversion value at
949
1190
  // the altered column (`SET DATA TYPE`'s normalization, `SET NOT NULL`'s null →
@@ -965,6 +1206,15 @@ async function runAlterColumn(rctx, tableSchema, schema, action) {
965
1206
  oldObject: tableSchema,
966
1207
  newObject: updatedTableSchema,
967
1208
  });
1209
+ // All four attribute forms (SET/DROP NOT NULL, SET DATA TYPE, SET/DROP DEFAULT,
1210
+ // SET COLLATE) report the same `alter`/`column` shape — the event says which column
1211
+ // changed, not which attribute; `ddl` says which attribute, exactly.
1212
+ emitAlterSchemaEvent(rctx, tableSchema, {
1213
+ type: 'alter', objectType: 'column',
1214
+ objectName: tableSchema.name,
1215
+ columnName: action.columnName,
1216
+ ddl: sql,
1217
+ });
968
1218
  log('Altered column %s.%s.%s', tableSchema.schemaName, tableSchema.name, action.columnName);
969
1219
  return null;
970
1220
  }
@@ -1002,11 +1252,17 @@ function alterColumnEventValueRemap(tableSchema, colIndex, action) {
1002
1252
  };
1003
1253
  }
1004
1254
  if (action.setNotNull === true) {
1005
- // SET NOT NULL backfill: null → the folded literal DEFAULT, the same map the
1006
- // module applies. No usable literal default means the module either found no
1007
- // NULLs (nothing to remap) or rejected the ALTER before reaching here.
1008
- const defaultExpr = tableSchema.columns[colIndex].defaultValue;
1009
- const folded = defaultExpr ? tryFoldLiteral(defaultExpr) : undefined;
1255
+ // SET NOT NULL backfill: null → the folded-and-CONVERTED literal DEFAULT, the same
1256
+ // map the module applies to its rows. No usable literal default means the module
1257
+ // either found no NULLs (nothing to remap) or rejected the ALTER before reaching here.
1258
+ //
1259
+ // NOTE: `foldDefaultToType` throws MISMATCH on an unconvertible literal, and this
1260
+ // runs AFTER the module mutated. Unreachable today — every module folds the same
1261
+ // DEFAULT through the same helper up front and rejects the ALTER there, so a literal
1262
+ // that fails here would already have failed. If a module ever stops folding eagerly,
1263
+ // catch here and return undefined rather than aborting a completed ALTER.
1264
+ const col = tableSchema.columns[colIndex];
1265
+ const folded = foldDefaultToType(col.defaultValue, col.logicalType, col.name);
1010
1266
  if (folded === undefined || folded === null)
1011
1267
  return undefined;
1012
1268
  return (v) => (v === null ? folded : v);
@@ -1080,7 +1336,7 @@ function runDropConstraintTags(rctx, tableSchema, constraintName, keys) {
1080
1336
  log('Dropped tags on constraint %s.%s.%s', tableSchema.schemaName, tableSchema.name, constraintName);
1081
1337
  return null;
1082
1338
  }
1083
- async function runAlterPrimaryKey(rctx, tableSchema, schema, columns) {
1339
+ async function runAlterPrimaryKey(rctx, tableSchema, schema, columns, sql) {
1084
1340
  const newPkDef = columns.map(col => {
1085
1341
  const idx = tableSchema.columnIndexMap.get(col.name.toLowerCase());
1086
1342
  if (idx === undefined) {
@@ -1100,12 +1356,33 @@ async function runAlterPrimaryKey(rctx, tableSchema, schema, columns) {
1100
1356
  }
1101
1357
  seen.add(pk.index);
1102
1358
  }
1359
+ // Column indices of the key being retired and the one replacing it. Both index the
1360
+ // CURRENT column layout — ALTER PRIMARY KEY adds and drops no column — so they are
1361
+ // also indices into the batched events' row images, which any earlier ALTER in this
1362
+ // transaction has already remapped to that layout.
1363
+ const oldPkIndices = tableSchema.primaryKeyDefinition.map(pk => pk.index);
1364
+ const newPkIndices = newPkDef.map(pk => pk.index);
1103
1365
  // Try native module re-key first
1104
1366
  const module = requireVtabModule(tableSchema);
1105
1367
  if (module.alterTable) {
1106
1368
  try {
1107
1369
  const schemaChangePk = newPkDef.map(pk => ({ index: pk.index, desc: pk.desc ?? false }));
1108
- const updatedTableSchema = await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, { type: 'alterPrimaryKey', newPkColumns: schemaChangePk });
1370
+ const updatedTableSchema = await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, { type: 'alterPrimaryKey', newPkColumns: schemaChangePk, ddl: sql });
1371
+ // Events this transaction already recorded identify their rows by the RETIRED
1372
+ // key; re-derive each from its own row image so the commit delivers every event
1373
+ // under the key the table has at delivery. AFTER the module call (a module
1374
+ // failure must leave the batch as untouched as the catalog, and the store's
1375
+ // `ddlCommitPendingOps` flushes its queued events into our batch DURING that
1376
+ // call — those must be in the batch before we walk it), BEFORE the catalog swap,
1377
+ // matching where the other ALTER arms call `remapBatchedDataEvents`.
1378
+ //
1379
+ // NOTE: this sits inside the try whose catch falls through to the rebuild, so an
1380
+ // UNSUPPORTED raised BELOW it (only reachable via a `table_modified` listener, as
1381
+ // `schema.addTable` raises no UNSUPPORTED) would re-key twice. The second pass is
1382
+ // idempotent for every event except a PK-moving update, whose image tie-break no
1383
+ // longer recognizes the already-rewritten key. If anything below this line gains
1384
+ // a real UNSUPPORTED path, narrow the try to the `module.alterTable` call.
1385
+ rctx.db._getEventEmitter().rekeyBatchedDataEvents(tableSchema.schemaName, tableSchema.name, oldPkIndices, newPkIndices);
1109
1386
  schema.addTable(updatedTableSchema);
1110
1387
  rctx.db.schemaManager.getChangeNotifier().notifyChange({
1111
1388
  type: 'table_modified',
@@ -1114,39 +1391,98 @@ async function runAlterPrimaryKey(rctx, tableSchema, schema, columns) {
1114
1391
  oldObject: tableSchema,
1115
1392
  newObject: updatedTableSchema,
1116
1393
  });
1394
+ // NOTE: inside the try whose catch falls through to the rebuild — same caveat as
1395
+ // the re-key above. The emit raises no UNSUPPORTED (the gate either emits or
1396
+ // does not), so it cannot itself trigger the fallback.
1397
+ emitAlterSchemaEvent(rctx, tableSchema, {
1398
+ type: 'alter', objectType: 'table',
1399
+ objectName: tableSchema.name,
1400
+ ddl: sql,
1401
+ });
1117
1402
  log('Altered primary key of %s.%s (native)', tableSchema.schemaName, tableSchema.name);
1118
1403
  return null;
1119
1404
  }
1120
1405
  catch (e) {
1121
1406
  if (e instanceof QuereusError && e.code === StatusCode.UNSUPPORTED) {
1122
- // Fall through to rebuild
1407
+ // Fall through to rebuild. The swallow is the documented protocol
1408
+ // (docs/module-authoring.md § `alterPrimaryKey`), but a swallowed error must
1409
+ // still leave a trace — this is the only record that the native re-key was
1410
+ // attempted and declined.
1411
+ warnLog('Module %s declined an in-place re-key of %s.%s (UNSUPPORTED: %s); falling back to a shadow-table rebuild', tableSchema.vtabModuleName ?? '<unknown>', tableSchema.schemaName, tableSchema.name, e.message);
1123
1412
  }
1124
1413
  else {
1125
1414
  throw e;
1126
1415
  }
1127
1416
  }
1128
1417
  }
1129
- // Rebuild fallback
1418
+ // Rebuild fallback. Two preconditions, both refusals rather than repairs — see
1419
+ // `rebuildViaShadowTable` for why neither has a correct outcome. Checked here, after the
1420
+ // native attempt, so both entry paths into the rebuild (no `alterTable` hook at all; the
1421
+ // hook raised UNSUPPORTED) are covered by one check each; a module that raised
1422
+ // UNSUPPORTED has by contract mutated nothing, so a refusal here leaves the catalog, the
1423
+ // table and the enclosing transaction untouched. Capability first: it is unconditional,
1424
+ // so it is the more informative answer when both apply.
1425
+ if (!module.renameTable) {
1426
+ throw new QuereusError(`Module '${tableSchema.vtabModuleName ?? '<unknown>'}' does not support ALTER PRIMARY KEY on table `
1427
+ + `'${tableSchema.name}': it cannot re-key in place (it implements no 'alterTable' hook, or the `
1428
+ + `hook declined), and the engine's fallback rebuild finishes by renaming a shadow table over `
1429
+ + `this one — without 'renameTable' the module would keep the rows under the shadow name and `
1430
+ + `the rebuilt table could not be opened.`, StatusCode.UNSUPPORTED);
1431
+ }
1432
+ // NOTE: refused on every `DdlTransactionality` tier, including a module declaring
1433
+ // 'transactional'. None does today; if one appears its DROP + RENAME would roll back
1434
+ // together with the row copy, making this refusal over-broad — exempt that tier then, the
1435
+ // way `assertDdlTransactionPolicy` already does.
1436
+ if (isExplicitTransactionOpen(rctx.db)) {
1437
+ throw new QuereusError(`ALTER PRIMARY KEY on table '${tableSchema.name}' is not allowed inside an explicit transaction: `
1438
+ + `module '${tableSchema.vtabModuleName ?? '<unknown>'}' cannot re-key in place, so the statement `
1439
+ + `would fall back to a shadow-table rebuild whose DROP + RENAME survives ROLLBACK while its row `
1440
+ + `copy does not — a rollback would leave an empty table and destroy rows committed before this `
1441
+ + `transaction began. COMMIT or ROLLBACK first, then re-issue in autocommit mode.`, StatusCode.ERROR);
1442
+ }
1130
1443
  await rebuildTableWithNewShape(rctx, tableSchema, schema, tableSchema.columns.map(c => c.name), newPkDef);
1444
+ // A DEFENSIVE NO-OP on this path today, not the working re-key the native arm above does.
1445
+ // Nothing can be in the batch for this table by now: the rebuild's own events are
1446
+ // suppressed (see `rebuildViaShadowTable`), the ALTER statement writes no rows of its own,
1447
+ // and the explicit-transaction refusal above rules out earlier same-transaction writes.
1448
+ // Kept anyway — it costs one walk of an empty batch, and it is the correct call the moment
1449
+ // that transaction guard is loosened; deleting it would quietly make this arm's
1450
+ // as-of-delivery `key` guarantee depend on the guard staying exactly as it is. Every column
1451
+ // survives the rebuild in order (`survivingColumns` above is the full list), so the indices
1452
+ // would still line up with the event images.
1453
+ rctx.db._getEventEmitter().rekeyBatchedDataEvents(tableSchema.schemaName, tableSchema.name, oldPkIndices, newPkIndices);
1454
+ // The rebuild's own four statements are silent (`rebuildViaShadowTable` runs them inside
1455
+ // `withPublicEventsSuppressed`, which also swallows the inner RENAME TO arm's event). This
1456
+ // emit is OUTSIDE that scope, so the re-key itself reports exactly one `alter`/`table` —
1457
+ // the same shape the native branch above reports.
1458
+ //
1459
+ // NOTE: this arm is the one place where a module WITH its own emitter can end up reporting
1460
+ // nothing — it raised UNSUPPORTED instead of emitting, and the gate below then suppresses
1461
+ // the engine's fallback because the module registration advertises native support. No such
1462
+ // module exists today (memory re-keys in place, the store handles `alterPrimaryKey`
1463
+ // natively), so the path is unreachable. If an emitter-backed module ever declines the
1464
+ // re-key, teach the gate that a rebuild fallback owns the event regardless of the module's
1465
+ // emitter.
1466
+ emitAlterSchemaEvent(rctx, tableSchema, {
1467
+ type: 'alter', objectType: 'table',
1468
+ objectName: tableSchema.name,
1469
+ ddl: sql,
1470
+ });
1131
1471
  log('Altered primary key of %s.%s (rebuild)', tableSchema.schemaName, tableSchema.name);
1132
1472
  return null;
1133
1473
  }
1134
1474
  /**
1135
- * Rebuilds a table with a new column projection and/or primary key.
1136
- * For MemoryTable: builds a new table via the module API and copies rows directly,
1137
- * bypassing SQL execution to avoid transaction-layer isolation issues.
1138
- * For other modules: uses shadow-table SQL approach with DROP+RENAME.
1475
+ * Rebuilds a table with a new column projection and/or primary key, via the
1476
+ * shadow-table SQL approach with DROP+RENAME. This is the fallback for a module
1477
+ * whose `alterTable` throws `UNSUPPORTED` for `alterPrimaryKey` (or omits the
1478
+ * hook); the built-in memory and store modules both re-key in place and never
1479
+ * reach it. See `rebuildViaShadowTable` for the two preconditions
1480
+ * `runAlterPrimaryKey` checks before calling this.
1139
1481
  */
1140
1482
  async function rebuildTableWithNewShape(rctx, tableSchema, schema, survivingColumns, newPkDef) {
1141
1483
  const tableName = tableSchema.name;
1142
1484
  const schemaName = tableSchema.schemaName;
1143
- const module = requireVtabModule(tableSchema);
1144
- if (module instanceof MemoryTableModule) {
1145
- await rebuildMemoryTable(rctx, tableSchema, schema, module, survivingColumns, newPkDef);
1146
- }
1147
- else {
1148
- await rebuildViaShadowTable(rctx, tableSchema, schema, survivingColumns, newPkDef);
1149
- }
1485
+ await rebuildViaShadowTable(rctx, tableSchema, schema, survivingColumns, newPkDef);
1150
1486
  const finalSchema = schema.getTable(tableName);
1151
1487
  if (finalSchema) {
1152
1488
  rctx.db.schemaManager.getChangeNotifier().notifyChange({
@@ -1158,87 +1494,6 @@ async function rebuildTableWithNewShape(rctx, tableSchema, schema, survivingColu
1158
1494
  });
1159
1495
  }
1160
1496
  }
1161
- /**
1162
- * MemoryTable rebuild: builds a new table via module.create() and copies rows
1163
- * directly from the old manager, then swaps in the module and catalog.
1164
- */
1165
- async function rebuildMemoryTable(rctx, tableSchema, schema, module, survivingColumns, newPkDef) {
1166
- const tableName = tableSchema.name;
1167
- const schemaName = tableSchema.schemaName;
1168
- const oldKey = `${schemaName}.${tableName}`.toLowerCase();
1169
- const oldMgr = module.tables.get(oldKey);
1170
- if (!oldMgr) {
1171
- throw new QuereusError(`Table '${tableName}' not found in module`, StatusCode.INTERNAL);
1172
- }
1173
- // Build column index mapping: old column index → new column index
1174
- const survivingIndices = [];
1175
- const newColumns = [];
1176
- for (const colName of survivingColumns) {
1177
- const oldIdx = tableSchema.columnIndexMap.get(colName.toLowerCase());
1178
- if (oldIdx === undefined)
1179
- continue;
1180
- survivingIndices.push(oldIdx);
1181
- newColumns.push(tableSchema.columns[oldIdx]);
1182
- }
1183
- // Remap PK indices from old schema to new column order
1184
- const remappedPk = newPkDef.map(pk => {
1185
- const newIdx = survivingIndices.indexOf(pk.index);
1186
- if (newIdx === -1) {
1187
- throw new QuereusError(`PK column index ${pk.index} not in surviving columns`, StatusCode.INTERNAL);
1188
- }
1189
- return { ...pk, index: newIdx };
1190
- });
1191
- // Build new schema
1192
- const newSchema = Object.freeze({
1193
- ...tableSchema,
1194
- columns: Object.freeze(newColumns),
1195
- columnIndexMap: buildColumnIndexMap(newColumns),
1196
- primaryKeyDefinition: Object.freeze(remappedPk),
1197
- indexes: Object.freeze([]),
1198
- });
1199
- // Create the new table via the module API (goes directly to base layer)
1200
- const shadowName = `${tableName}__rekey_${Date.now()}`;
1201
- const shadowSchema = Object.freeze({ ...newSchema, name: shadowName });
1202
- await module.create(rctx.db, shadowSchema);
1203
- const shadowMgr = module.tables.get(`${schemaName}.${shadowName}`.toLowerCase());
1204
- if (!shadowMgr) {
1205
- throw new QuereusError(`Shadow table manager not found after create`, StatusCode.INTERNAL);
1206
- }
1207
- try {
1208
- // Copy rows from old table to new, projecting surviving columns
1209
- const rows = oldMgr.scanAllRows();
1210
- for (const oldRow of rows) {
1211
- const newRow = survivingIndices.map(i => oldRow[i]);
1212
- shadowMgr.insertRow(newRow);
1213
- }
1214
- // Swap: remove old, remove shadow, re-register shadow under old name
1215
- module.tables.delete(oldKey);
1216
- module.tables.delete(`${schemaName}.${shadowName}`.toLowerCase());
1217
- shadowMgr.renameTable(tableName);
1218
- module.tables.set(oldKey, shadowMgr);
1219
- // Update catalog
1220
- schema.removeTable(tableName);
1221
- schema.addTable(shadowMgr.tableSchema);
1222
- // The old manager is now orphaned. Any active VirtualTableConnection bound
1223
- // to it (e.g. from a prior insert in this session) is stale and must not be
1224
- // reused against the rebuilt table — a reused-stale + fresh connection pair
1225
- // leaves two candidates registered for the same table name, which trips
1226
- // DeferredConstraintQueue.findConnection at the next commit. Mirror the
1227
- // drop-table path's cleanup (schema/manager.ts dropTable). The orphaned
1228
- // manager and its pending layer are discarded with the old manager, so no
1229
- // rollback is needed; this intentionally bypasses implicit-transaction
1230
- // deferral, exactly as drop table relies on.
1231
- rctx.db.removeConnectionsForTable(schemaName, tableName);
1232
- }
1233
- catch (e) {
1234
- // Clean up shadow on failure
1235
- try {
1236
- module.tables.delete(`${schemaName}.${shadowName}`.toLowerCase());
1237
- }
1238
- catch { /* ignore */ }
1239
- throw e;
1240
- }
1241
- }
1242
1497
  /**
1243
1498
  * Build the shadow-table CREATE TABLE DDL used by the non-memory rebuild path.
1244
1499
  *
@@ -1310,7 +1565,7 @@ export function buildShadowTableDdl(tableSchema, shadowName, survivingColumns, n
1310
1565
  async function runSetMaintained(rctx, tableSchema, schema, columns, select) {
1311
1566
  const live = schema.getTable(tableSchema.name);
1312
1567
  if (!live) {
1313
- throw new QuereusError(`no such table: ${tableSchema.name}`, StatusCode.ERROR);
1568
+ throw new RelationNotFoundError(`no such table: ${tableSchema.name}`);
1314
1569
  }
1315
1570
  const explicit = columns !== undefined && columns.length > 0;
1316
1571
  // Any omitted-insert defaults ride inside `select` (→ derivation.selectAst).
@@ -1345,9 +1600,29 @@ async function runDropMaintained(rctx, tableSchema, schema) {
1345
1600
  return null;
1346
1601
  }
1347
1602
  /**
1348
- * Generic rebuild via shadow table SQL for non-memory modules.
1603
+ * Generic rebuild via shadow table SQL, for a module without a native
1604
+ * `alterPrimaryKey`.
1605
+ *
1606
+ * Two preconditions the caller (`runAlterPrimaryKey`) enforces, because this rebuild has no
1607
+ * correct outcome without them:
1608
+ *
1609
+ * - **The module must implement `renameTable`.** The last step renames the shadow table over
1610
+ * the original; a module that files its rows under the table's name and never hears about
1611
+ * the rename keeps them under the shadow name while the catalog says otherwise, and the
1612
+ * rebuilt table cannot be connected at all.
1613
+ * - **No explicit transaction may be open.** The two halves have different transactional
1614
+ * lifetimes: the schema half (DROP + RENAME) escapes ROLLBACK on every
1615
+ * `DdlTransactionality` tier a built-in module reaches, while the row copy is staged in the
1616
+ * transaction and IS undone. A ROLLBACK would therefore keep the new empty table and
1617
+ * discard the copy of the rows it replaced — destroying data committed before the
1618
+ * transaction began. Making the schema half roll back needs transactional DDL no module
1619
+ * offers; making the data half survive would commit part of the user's transaction behind
1620
+ * their back.
1621
+ *
1622
+ * The four statements are engine scaffolding, not statements the application issued, so the
1623
+ * whole rebuild runs with the PUBLIC event channels suppressed — see the scope inside.
1349
1624
  */
1350
- async function rebuildViaShadowTable(rctx, tableSchema, schema, survivingColumns, newPkDef) {
1625
+ async function rebuildViaShadowTable(rctx, tableSchema, _schema, survivingColumns, newPkDef) {
1351
1626
  const tableName = tableSchema.name;
1352
1627
  const schemaName = tableSchema.schemaName;
1353
1628
  const shadowName = `${tableName}__rekey_${Date.now()}`;
@@ -1355,19 +1630,40 @@ async function rebuildViaShadowTable(rctx, tableSchema, schema, survivingColumns
1355
1630
  const qualifiedTable = qualifyTableName(schemaName, tableName);
1356
1631
  const createDdl = buildShadowTableDdl(tableSchema, shadowName, survivingColumns, newPkDef);
1357
1632
  const projection = survivingColumns.map(c => quoteIdentifier(c)).join(', ');
1358
- try {
1359
- await rctx.db._execWithinTransaction(createDdl);
1360
- await rctx.db._execWithinTransaction(`insert into ${qualifiedShadow} (${projection}) select ${projection} from ${qualifiedTable}`);
1361
- await rctx.db._execWithinTransaction(`drop table ${qualifiedTable}`);
1362
- await rctx.db._execWithinTransaction(`alter table ${qualifiedShadow} rename to ${quoteIdentifier(tableName)}`);
1363
- }
1364
- catch (e) {
1633
+ // The rebuild's statements are ordinary SQL, so without this scope they would raise
1634
+ // ordinary notifications describing the scaffolding rather than what the user asked for:
1635
+ // the copy announces every existing row as a fresh `insert` (relabelled onto the real
1636
+ // table by the trailing rename), and the create/drop pair announces a timestamped table
1637
+ // created and the real one dropped. A re-key changes no row and replaces no table, so all
1638
+ // of that is wrong. Covers the failure cleanup below too — a shadow table nobody was told
1639
+ // about must not announce its own drop.
1640
+ //
1641
+ // Only the PUBLIC channels are suppressed. The internal catalog change notifier keeps
1642
+ // firing throughout (it is what invalidates the optimizer's and the write path's cached
1643
+ // schemas), which is why the rebuilt table is immediately plannable under its new key.
1644
+ //
1645
+ // NOTE: a module whose own emitter defers delivery to its own commit — rather than
1646
+ // emitting during the write — can still leak the copy's inserts, because its events
1647
+ // arrive after this scope has closed. Conditional, not a live defect: no module that
1648
+ // reaches this rebuild behaves that way (memory and the store both re-key in place and
1649
+ // never enter it). If one ever does, suppression has to become name-keyed (covering the
1650
+ // shadow name as well as the real one) or the events have to be dropped out of the batch
1651
+ // after the fact.
1652
+ await rctx.db._getEventEmitter().withPublicEventsSuppressed(async () => {
1365
1653
  try {
1366
- await rctx.db._execWithinTransaction(`drop table if exists ${qualifiedShadow}`);
1654
+ await rctx.db._execWithinTransaction(createDdl);
1655
+ await rctx.db._execWithinTransaction(`insert into ${qualifiedShadow} (${projection}) select ${projection} from ${qualifiedTable}`);
1656
+ await rctx.db._execWithinTransaction(`drop table ${qualifiedTable}`);
1657
+ await rctx.db._execWithinTransaction(`alter table ${qualifiedShadow} rename to ${quoteIdentifier(tableName)}`);
1367
1658
  }
1368
- catch { /* ignore */ }
1369
- throw e;
1370
- }
1659
+ catch (e) {
1660
+ try {
1661
+ await rctx.db._execWithinTransaction(`drop table if exists ${qualifiedShadow}`);
1662
+ }
1663
+ catch { /* ignore */ }
1664
+ throw e;
1665
+ }
1666
+ });
1371
1667
  }
1372
1668
  /**
1373
1669
  * Propagates a table rename into every dependent schema object the catalog
@@ -1428,6 +1724,11 @@ async function propagateTableRenameInSchema(db, schema, renamedSchemaName, oldNa
1428
1724
  });
1429
1725
  }
1430
1726
  }
1727
+ // Assertions: same in-place body rewrite as plain views, plus a regenerated
1728
+ // `violationSql` (the text the commit-time evaluator re-parses). Assertions
1729
+ // feed no materialized view, so order against the MV pass is free; sitting
1730
+ // next to the view loop keeps the plain schema-level objects together.
1731
+ propagateTableRenameToAssertions(db, schema, renamedSchemaName, oldName, newName);
1431
1732
  // Materialized views: same in-place body rewrite as plain views ("MV ≡
1432
1733
  // faster view"), plus the derived-field re-key, row-time re-registration,
1433
1734
  // and staleness discipline the MV record needs. Runs AFTER the view loop
@@ -1465,6 +1766,20 @@ function rewriteTableForTableRename(table, renamedSchemaLower, oldName, newName)
1465
1766
  changed = true;
1466
1767
  return { ...idx };
1467
1768
  });
1769
+ // Column-level expressions — a DEFAULT (`w integer default ((select min(v) from u))`)
1770
+ // and a generated column's body. Unlike the column verb's arm, no seeded/unseeded
1771
+ // split: `renameTableInAst` resolves nothing against an implicit owning table, so one
1772
+ // entry point covers the renamed table's own self-referencing default and every other
1773
+ // table's alike.
1774
+ //
1775
+ // Also unlike the collections above, no per-item shallow copy: the rewrite is in place
1776
+ // and a `ColumnSchema`'s own fields are untouched, so a fresh column object would only
1777
+ // make the catalog's array stop being identical to the one the module's rename hook
1778
+ // just handed back. Flipping `changed` is what re-registers the table and fires
1779
+ // `table_modified`, which is all the copies above achieve either.
1780
+ const columnsRewritten = renameTableInColumnExpressions(table.columns, oldName, newName, renamedSchemaLower);
1781
+ if (columnsRewritten)
1782
+ changed = true;
1468
1783
  if (!changed)
1469
1784
  return table;
1470
1785
  return Object.freeze({
@@ -1474,21 +1789,6 @@ function rewriteTableForTableRename(table, renamedSchemaLower, oldName, newName)
1474
1789
  indexes: table.indexes ? Object.freeze(newIndexes) : table.indexes,
1475
1790
  });
1476
1791
  }
1477
- /**
1478
- * The catalog-backed {@link ResolveColumnInSource} the column-rename rewriters consult
1479
- * to keep their unqualified-reference walk scope-aware. Built once per statement and
1480
- * shared by the pre-flight probe in {@link runRenameColumn} and the real propagation
1481
- * below, so the two cannot drift apart. Note it resolves against the LIVE catalog on
1482
- * every call, so sharing it does not by itself freeze the answer between the two passes
1483
- * — see the pre-flight's comment for why they agree anyway.
1484
- */
1485
- function buildColumnSourceResolver(db) {
1486
- return (s, t, col) => {
1487
- const targetSchema = db.schemaManager.getSchema(s);
1488
- const targetTable = targetSchema?.getTable(t);
1489
- return targetTable?.columnIndexMap.has(col.toLowerCase()) ?? false;
1490
- };
1491
- }
1492
1792
  async function propagateColumnRename(rctx, renamedSchemaName, tableName, oldCol, newCol, preStaleMvs, resolveColumnInSource) {
1493
1793
  const schemaManager = rctx.db.schemaManager;
1494
1794
  for (const schema of schemaManager._getAllSchemas()) {
@@ -1543,6 +1843,10 @@ async function propagateColumnRenameInSchema(db, schema, renamedSchemaName, tabl
1543
1843
  });
1544
1844
  }
1545
1845
  }
1846
+ // Assertions: same in-place body rewrite as plain views (unseeded walker —
1847
+ // an assertion body owns its own FROM scopes), plus a regenerated
1848
+ // `violationSql`.
1849
+ propagateColumnRenameToAssertions(db, schema, renamedSchemaName, tableName, oldCol, newCol, resolveColumnInSource);
1546
1850
  // Materialized views: same in-place body rewrite as plain views, then the
1547
1851
  // MV-specific tail — backing-column rename for a shifted output name,
1548
1852
  // row-time re-registration, staleness discipline (the listener marked every
@@ -1560,7 +1864,7 @@ function rewriteTableForColumnRename(table, renamedSchemaLower, tableName, oldCo
1560
1864
  const newChecks = table.checkConstraints.map(cc => {
1561
1865
  const rewrote = isRenamedTable
1562
1866
  ? renameColumnInCheckExpression(cc.expr, tableName, oldCol, newCol, renamedSchemaLower, resolveColumnInSource)
1563
- : renameColumnInAst(cc.expr, tableName, oldCol, newCol, renamedSchemaLower);
1867
+ : renameColumnInAst(cc.expr, tableName, oldCol, newCol, renamedSchemaLower, resolveColumnInSource);
1564
1868
  if (!rewrote)
1565
1869
  return cc;
1566
1870
  changed = true;
@@ -1606,12 +1910,29 @@ function rewriteTableForColumnRename(table, renamedSchemaLower, tableName, oldCo
1606
1910
  const newIndexes = (table.indexes ?? []).map(idx => {
1607
1911
  const rewrote = isRenamedTable
1608
1912
  ? renameColumnInCheckExpression(idx.predicate, tableName, oldCol, newCol, renamedSchemaLower, resolveColumnInSource)
1609
- : renameColumnInAst(idx.predicate, tableName, oldCol, newCol, renamedSchemaLower);
1913
+ : renameColumnInAst(idx.predicate, tableName, oldCol, newCol, renamedSchemaLower, resolveColumnInSource);
1610
1914
  if (!rewrote)
1611
1915
  return idx;
1612
1916
  changed = true;
1613
1917
  return { ...idx };
1614
1918
  });
1919
+ // Column-level expressions — a DEFAULT (`b integer default (new.a + 1)`) and a
1920
+ // generated column's body (`g integer generated always as (a + 1)`). Same branch split
1921
+ // the checks and predicates use above: the renamed table's own columns take the seeded
1922
+ // walk (a generated body's bare `a` binds to the owning table; a default's `new.a`
1923
+ // names its row image), any other table's take the unseeded one (it can reach here only
1924
+ // through a subquery, whose FROM must bind the ref).
1925
+ //
1926
+ // Unlike the collections above, no per-item shallow copy: the rewrite is in place and a
1927
+ // `ColumnSchema`'s own fields are untouched, so a fresh column object would only make
1928
+ // the catalog's array stop being identical to the one the module's rename hook just
1929
+ // built and handed back. Flipping `changed` is what re-registers the table and fires
1930
+ // `table_modified`, which is all the copies above achieve either.
1931
+ const columnsRewritten = isRenamedTable
1932
+ ? renameColumnInColumnExpressions(table.columns, tableName, oldCol, newCol, renamedSchemaLower, resolveColumnInSource)
1933
+ : rewriteOtherTableColumnExpressions(table.columns, tableName, oldCol, newCol, renamedSchemaLower, resolveColumnInSource);
1934
+ if (columnsRewritten)
1935
+ changed = true;
1615
1936
  if (!changed)
1616
1937
  return table;
1617
1938
  return Object.freeze({
@@ -1621,6 +1942,31 @@ function rewriteTableForColumnRename(table, renamedSchemaLower, tableName, oldCo
1621
1942
  indexes: table.indexes ? Object.freeze(newIndexes) : table.indexes,
1622
1943
  });
1623
1944
  }
1945
+ /**
1946
+ * The unseeded arm of the column-expression rewrite above, for a table that is NOT the
1947
+ * renamed one. `renameColumnInColumnExpressions` is deliberately seeded-only (that is the
1948
+ * whole reason it exists), so the other branch walks the two fields directly with
1949
+ * {@link renameColumnInAst} — the same entry point the checks and predicates arms use for
1950
+ * a foreign table, and for the same reason: an unqualified ref in someone else's default
1951
+ * must bind inside its own subquery's FROM, never to this table.
1952
+ *
1953
+ * `resolveColumnInSource` is as load-bearing here as on the seeded arm, and for the mirror
1954
+ * reason: without it the walk cannot tell that an inner FROM source exposes the old name,
1955
+ * so a nested `(select (select max(a) from other) from t)` rewrites the INNER `a` — which
1956
+ * binds to `other` — and the default silently starts reading a different column. It also
1957
+ * keeps this pass in step with the pre-flight persistability probe, which runs the same
1958
+ * rewriter with the resolver supplied.
1959
+ */
1960
+ function rewriteOtherTableColumnExpressions(columns, tableName, oldCol, newCol, renamedSchemaLower, resolveColumnInSource) {
1961
+ let changed = false;
1962
+ for (const col of columns) {
1963
+ for (const expr of [col.defaultValue, col.generatedExpr]) {
1964
+ if (expr && renameColumnInAst(expr, tableName, oldCol, newCol, renamedSchemaLower, resolveColumnInSource))
1965
+ changed = true;
1966
+ }
1967
+ }
1968
+ return changed;
1969
+ }
1624
1970
  /**
1625
1971
  * Build a minimal constraints array from an existing ColumnSchema
1626
1972
  * so that the ColumnDef AST accurately represents the column.