@quereus/quereus 3.3.0 → 4.1.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 (900) hide show
  1. package/README.md +7 -0
  2. package/dist/src/common/datatype.d.ts +12 -0
  3. package/dist/src/common/datatype.d.ts.map +1 -1
  4. package/dist/src/common/datatype.js.map +1 -1
  5. package/dist/src/common/types.d.ts +24 -0
  6. package/dist/src/common/types.d.ts.map +1 -1
  7. package/dist/src/common/types.js.map +1 -1
  8. package/dist/src/core/database-assertions.d.ts +37 -9
  9. package/dist/src/core/database-assertions.d.ts.map +1 -1
  10. package/dist/src/core/database-assertions.js +62 -110
  11. package/dist/src/core/database-assertions.js.map +1 -1
  12. package/dist/src/core/database-events.d.ts +163 -0
  13. package/dist/src/core/database-events.d.ts.map +1 -1
  14. package/dist/src/core/database-events.js +235 -21
  15. package/dist/src/core/database-events.js.map +1 -1
  16. package/dist/src/core/database-external-changes.d.ts +28 -0
  17. package/dist/src/core/database-external-changes.d.ts.map +1 -0
  18. package/dist/src/core/database-external-changes.js +242 -0
  19. package/dist/src/core/database-external-changes.js.map +1 -0
  20. package/dist/src/core/database-internal.d.ts +50 -1
  21. package/dist/src/core/database-internal.d.ts.map +1 -1
  22. package/dist/src/core/database-materialized-views.d.ts +1253 -0
  23. package/dist/src/core/database-materialized-views.d.ts.map +1 -0
  24. package/dist/src/core/database-materialized-views.js +3064 -0
  25. package/dist/src/core/database-materialized-views.js.map +1 -0
  26. package/dist/src/core/database-options.d.ts +4 -0
  27. package/dist/src/core/database-options.d.ts.map +1 -1
  28. package/dist/src/core/database-options.js +10 -0
  29. package/dist/src/core/database-options.js.map +1 -1
  30. package/dist/src/core/database-transaction.d.ts +19 -3
  31. package/dist/src/core/database-transaction.d.ts.map +1 -1
  32. package/dist/src/core/database-transaction.js +30 -3
  33. package/dist/src/core/database-transaction.js.map +1 -1
  34. package/dist/src/core/database-watchers.d.ts +19 -0
  35. package/dist/src/core/database-watchers.d.ts.map +1 -1
  36. package/dist/src/core/database-watchers.js +63 -3
  37. package/dist/src/core/database-watchers.js.map +1 -1
  38. package/dist/src/core/database.d.ts +204 -11
  39. package/dist/src/core/database.d.ts.map +1 -1
  40. package/dist/src/core/database.js +493 -29
  41. package/dist/src/core/database.js.map +1 -1
  42. package/dist/src/core/derived-row-validator.d.ts +137 -0
  43. package/dist/src/core/derived-row-validator.d.ts.map +1 -0
  44. package/dist/src/core/derived-row-validator.js +314 -0
  45. package/dist/src/core/derived-row-validator.js.map +1 -0
  46. package/dist/src/core/statement.d.ts.map +1 -1
  47. package/dist/src/core/statement.js +30 -9
  48. package/dist/src/core/statement.js.map +1 -1
  49. package/dist/src/emit/ast-stringify.d.ts +135 -1
  50. package/dist/src/emit/ast-stringify.d.ts.map +1 -1
  51. package/dist/src/emit/ast-stringify.js +793 -118
  52. package/dist/src/emit/ast-stringify.js.map +1 -1
  53. package/dist/src/func/builtins/aggregate.d.ts.map +1 -1
  54. package/dist/src/func/builtins/aggregate.js +11 -10
  55. package/dist/src/func/builtins/aggregate.js.map +1 -1
  56. package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
  57. package/dist/src/func/builtins/builtin-window-functions.js +32 -0
  58. package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
  59. package/dist/src/func/builtins/explain.d.ts +3 -0
  60. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  61. package/dist/src/func/builtins/explain.js +229 -0
  62. package/dist/src/func/builtins/explain.js.map +1 -1
  63. package/dist/src/func/builtins/index.d.ts.map +1 -1
  64. package/dist/src/func/builtins/index.js +10 -2
  65. package/dist/src/func/builtins/index.js.map +1 -1
  66. package/dist/src/func/builtins/json.d.ts.map +1 -1
  67. package/dist/src/func/builtins/json.js +3 -2
  68. package/dist/src/func/builtins/json.js.map +1 -1
  69. package/dist/src/func/builtins/mutation.d.ts +2 -0
  70. package/dist/src/func/builtins/mutation.d.ts.map +1 -0
  71. package/dist/src/func/builtins/mutation.js +53 -0
  72. package/dist/src/func/builtins/mutation.js.map +1 -0
  73. package/dist/src/func/builtins/schema.d.ts +2 -0
  74. package/dist/src/func/builtins/schema.d.ts.map +1 -1
  75. package/dist/src/func/builtins/schema.js +716 -27
  76. package/dist/src/func/builtins/schema.js.map +1 -1
  77. package/dist/src/func/builtins/string.js +1 -1
  78. package/dist/src/func/builtins/string.js.map +1 -1
  79. package/dist/src/func/registration.d.ts +13 -0
  80. package/dist/src/func/registration.d.ts.map +1 -1
  81. package/dist/src/func/registration.js +5 -0
  82. package/dist/src/func/registration.js.map +1 -1
  83. package/dist/src/index.d.ts +25 -6
  84. package/dist/src/index.d.ts.map +1 -1
  85. package/dist/src/index.js +27 -3
  86. package/dist/src/index.js.map +1 -1
  87. package/dist/src/parser/ast.d.ts +353 -21
  88. package/dist/src/parser/ast.d.ts.map +1 -1
  89. package/dist/src/parser/index.d.ts +14 -1
  90. package/dist/src/parser/index.d.ts.map +1 -1
  91. package/dist/src/parser/index.js +19 -0
  92. package/dist/src/parser/index.js.map +1 -1
  93. package/dist/src/parser/lexer.d.ts +9 -0
  94. package/dist/src/parser/lexer.d.ts.map +1 -1
  95. package/dist/src/parser/lexer.js +9 -0
  96. package/dist/src/parser/lexer.js.map +1 -1
  97. package/dist/src/parser/parser.d.ts +276 -7
  98. package/dist/src/parser/parser.d.ts.map +1 -1
  99. package/dist/src/parser/parser.js +1387 -469
  100. package/dist/src/parser/parser.js.map +1 -1
  101. package/dist/src/parser/visitor.d.ts.map +1 -1
  102. package/dist/src/parser/visitor.js +12 -8
  103. package/dist/src/parser/visitor.js.map +1 -1
  104. package/dist/src/planner/analysis/assertion-classifier.d.ts.map +1 -1
  105. package/dist/src/planner/analysis/assertion-classifier.js +4 -0
  106. package/dist/src/planner/analysis/assertion-classifier.js.map +1 -1
  107. package/dist/src/planner/analysis/assertion-hoist-cache.d.ts.map +1 -1
  108. package/dist/src/planner/analysis/assertion-hoist-cache.js +8 -4
  109. package/dist/src/planner/analysis/assertion-hoist-cache.js.map +1 -1
  110. package/dist/src/planner/analysis/authored-inverse.d.ts +22 -0
  111. package/dist/src/planner/analysis/authored-inverse.d.ts.map +1 -0
  112. package/dist/src/planner/analysis/authored-inverse.js +267 -0
  113. package/dist/src/planner/analysis/authored-inverse.js.map +1 -0
  114. package/dist/src/planner/analysis/change-scope.d.ts +34 -4
  115. package/dist/src/planner/analysis/change-scope.d.ts.map +1 -1
  116. package/dist/src/planner/analysis/change-scope.js +108 -7
  117. package/dist/src/planner/analysis/change-scope.js.map +1 -1
  118. package/dist/src/planner/analysis/check-extraction.d.ts +36 -2
  119. package/dist/src/planner/analysis/check-extraction.d.ts.map +1 -1
  120. package/dist/src/planner/analysis/check-extraction.js +174 -46
  121. package/dist/src/planner/analysis/check-extraction.js.map +1 -1
  122. package/dist/src/planner/analysis/coarsened-key.d.ts +109 -0
  123. package/dist/src/planner/analysis/coarsened-key.d.ts.map +1 -0
  124. package/dist/src/planner/analysis/coarsened-key.js +228 -0
  125. package/dist/src/planner/analysis/coarsened-key.js.map +1 -0
  126. package/dist/src/planner/analysis/comparison-collation.d.ts +216 -0
  127. package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -0
  128. package/dist/src/planner/analysis/comparison-collation.js +341 -0
  129. package/dist/src/planner/analysis/comparison-collation.js.map +1 -0
  130. package/dist/src/planner/analysis/constraint-extractor.d.ts +3 -1
  131. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
  132. package/dist/src/planner/analysis/constraint-extractor.js +192 -9
  133. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
  134. package/dist/src/planner/analysis/coverage-prover.d.ts +321 -0
  135. package/dist/src/planner/analysis/coverage-prover.d.ts.map +1 -0
  136. package/dist/src/planner/analysis/coverage-prover.js +1038 -0
  137. package/dist/src/planner/analysis/coverage-prover.js.map +1 -0
  138. package/dist/src/planner/analysis/key-filter.d.ts +22 -0
  139. package/dist/src/planner/analysis/key-filter.d.ts.map +1 -0
  140. package/dist/src/planner/analysis/key-filter.js +105 -0
  141. package/dist/src/planner/analysis/key-filter.js.map +1 -0
  142. package/dist/src/planner/analysis/partial-unique-extraction.d.ts +36 -1
  143. package/dist/src/planner/analysis/partial-unique-extraction.d.ts.map +1 -1
  144. package/dist/src/planner/analysis/partial-unique-extraction.js +148 -22
  145. package/dist/src/planner/analysis/partial-unique-extraction.js.map +1 -1
  146. package/dist/src/planner/analysis/predicate-normalizer.d.ts.map +1 -1
  147. package/dist/src/planner/analysis/predicate-normalizer.js +30 -1
  148. package/dist/src/planner/analysis/predicate-normalizer.js.map +1 -1
  149. package/dist/src/planner/analysis/predicate-shape.d.ts +36 -1
  150. package/dist/src/planner/analysis/predicate-shape.d.ts.map +1 -1
  151. package/dist/src/planner/analysis/predicate-shape.js +51 -13
  152. package/dist/src/planner/analysis/predicate-shape.js.map +1 -1
  153. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts +314 -0
  154. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts.map +1 -0
  155. package/dist/src/planner/analysis/query-rewrite-matcher.js +1081 -0
  156. package/dist/src/planner/analysis/query-rewrite-matcher.js.map +1 -0
  157. package/dist/src/planner/analysis/scalar-invertibility.d.ts +92 -0
  158. package/dist/src/planner/analysis/scalar-invertibility.d.ts.map +1 -0
  159. package/dist/src/planner/analysis/scalar-invertibility.js +129 -0
  160. package/dist/src/planner/analysis/scalar-invertibility.js.map +1 -0
  161. package/dist/src/planner/analysis/update-lineage.d.ts +196 -0
  162. package/dist/src/planner/analysis/update-lineage.d.ts.map +1 -0
  163. package/dist/src/planner/analysis/update-lineage.js +322 -0
  164. package/dist/src/planner/analysis/update-lineage.js.map +1 -0
  165. package/dist/src/planner/analysis/view-complement.d.ts +42 -0
  166. package/dist/src/planner/analysis/view-complement.d.ts.map +1 -0
  167. package/dist/src/planner/analysis/view-complement.js +54 -0
  168. package/dist/src/planner/analysis/view-complement.js.map +1 -0
  169. package/dist/src/planner/building/alter-table.d.ts +1 -1
  170. package/dist/src/planner/building/alter-table.d.ts.map +1 -1
  171. package/dist/src/planner/building/alter-table.js +211 -2
  172. package/dist/src/planner/building/alter-table.js.map +1 -1
  173. package/dist/src/planner/building/block.d.ts.map +1 -1
  174. package/dist/src/planner/building/block.js +18 -1
  175. package/dist/src/planner/building/block.js.map +1 -1
  176. package/dist/src/planner/building/constraint-builder.d.ts +33 -5
  177. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
  178. package/dist/src/planner/building/constraint-builder.js +63 -28
  179. package/dist/src/planner/building/constraint-builder.js.map +1 -1
  180. package/dist/src/planner/building/create-view.d.ts +9 -0
  181. package/dist/src/planner/building/create-view.d.ts.map +1 -1
  182. package/dist/src/planner/building/create-view.js +41 -12
  183. package/dist/src/planner/building/create-view.js.map +1 -1
  184. package/dist/src/planner/building/ddl.d.ts.map +1 -1
  185. package/dist/src/planner/building/ddl.js +94 -0
  186. package/dist/src/planner/building/ddl.js.map +1 -1
  187. package/dist/src/planner/building/declare-schema.d.ts +1 -0
  188. package/dist/src/planner/building/declare-schema.d.ts.map +1 -1
  189. package/dist/src/planner/building/declare-schema.js +4 -1
  190. package/dist/src/planner/building/declare-schema.js.map +1 -1
  191. package/dist/src/planner/building/default-scope.d.ts +26 -0
  192. package/dist/src/planner/building/default-scope.d.ts.map +1 -0
  193. package/dist/src/planner/building/default-scope.js +41 -0
  194. package/dist/src/planner/building/default-scope.js.map +1 -0
  195. package/dist/src/planner/building/delete.d.ts +19 -1
  196. package/dist/src/planner/building/delete.d.ts.map +1 -1
  197. package/dist/src/planner/building/delete.js +109 -30
  198. package/dist/src/planner/building/delete.js.map +1 -1
  199. package/dist/src/planner/building/dml-target.d.ts +118 -0
  200. package/dist/src/planner/building/dml-target.d.ts.map +1 -0
  201. package/dist/src/planner/building/dml-target.js +282 -0
  202. package/dist/src/planner/building/dml-target.js.map +1 -0
  203. package/dist/src/planner/building/drop-index.d.ts.map +1 -1
  204. package/dist/src/planner/building/drop-index.js +4 -1
  205. package/dist/src/planner/building/drop-index.js.map +1 -1
  206. package/dist/src/planner/building/drop-view.d.ts.map +1 -1
  207. package/dist/src/planner/building/drop-view.js +4 -2
  208. package/dist/src/planner/building/drop-view.js.map +1 -1
  209. package/dist/src/planner/building/expression.d.ts.map +1 -1
  210. package/dist/src/planner/building/expression.js +60 -21
  211. package/dist/src/planner/building/expression.js.map +1 -1
  212. package/dist/src/planner/building/foreign-key-builder.d.ts +30 -0
  213. package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -1
  214. package/dist/src/planner/building/foreign-key-builder.js +160 -129
  215. package/dist/src/planner/building/foreign-key-builder.js.map +1 -1
  216. package/dist/src/planner/building/insert.d.ts +45 -2
  217. package/dist/src/planner/building/insert.d.ts.map +1 -1
  218. package/dist/src/planner/building/insert.js +257 -88
  219. package/dist/src/planner/building/insert.js.map +1 -1
  220. package/dist/src/planner/building/lens-auxiliary-access.d.ts +22 -0
  221. package/dist/src/planner/building/lens-auxiliary-access.d.ts.map +1 -0
  222. package/dist/src/planner/building/lens-auxiliary-access.js +132 -0
  223. package/dist/src/planner/building/lens-auxiliary-access.js.map +1 -0
  224. package/dist/src/planner/building/materialized-view.d.ts +16 -0
  225. package/dist/src/planner/building/materialized-view.d.ts.map +1 -0
  226. package/dist/src/planner/building/materialized-view.js +57 -0
  227. package/dist/src/planner/building/materialized-view.js.map +1 -0
  228. package/dist/src/planner/building/returning-star.d.ts +32 -0
  229. package/dist/src/planner/building/returning-star.d.ts.map +1 -0
  230. package/dist/src/planner/building/returning-star.js +45 -0
  231. package/dist/src/planner/building/returning-star.js.map +1 -0
  232. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  233. package/dist/src/planner/building/select-aggregates.js +47 -0
  234. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  235. package/dist/src/planner/building/select-compound.d.ts.map +1 -1
  236. package/dist/src/planner/building/select-compound.js +84 -11
  237. package/dist/src/planner/building/select-compound.js.map +1 -1
  238. package/dist/src/planner/building/select-context.d.ts +10 -2
  239. package/dist/src/planner/building/select-context.d.ts.map +1 -1
  240. package/dist/src/planner/building/select-context.js +7 -1
  241. package/dist/src/planner/building/select-context.js.map +1 -1
  242. package/dist/src/planner/building/select-modifiers.js +6 -0
  243. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  244. package/dist/src/planner/building/select-ordinal.d.ts +18 -0
  245. package/dist/src/planner/building/select-ordinal.d.ts.map +1 -1
  246. package/dist/src/planner/building/select-ordinal.js +30 -0
  247. package/dist/src/planner/building/select-ordinal.js.map +1 -1
  248. package/dist/src/planner/building/select-projections.d.ts +8 -2
  249. package/dist/src/planner/building/select-projections.d.ts.map +1 -1
  250. package/dist/src/planner/building/select-projections.js +26 -4
  251. package/dist/src/planner/building/select-projections.js.map +1 -1
  252. package/dist/src/planner/building/select-window.d.ts.map +1 -1
  253. package/dist/src/planner/building/select-window.js +8 -5
  254. package/dist/src/planner/building/select-window.js.map +1 -1
  255. package/dist/src/planner/building/select.d.ts.map +1 -1
  256. package/dist/src/planner/building/select.js +164 -59
  257. package/dist/src/planner/building/select.js.map +1 -1
  258. package/dist/src/planner/building/set-object-tags.d.ts +7 -0
  259. package/dist/src/planner/building/set-object-tags.d.ts.map +1 -0
  260. package/dist/src/planner/building/set-object-tags.js +38 -0
  261. package/dist/src/planner/building/set-object-tags.js.map +1 -0
  262. package/dist/src/planner/building/tag-diagnostics.d.ts +27 -0
  263. package/dist/src/planner/building/tag-diagnostics.d.ts.map +1 -0
  264. package/dist/src/planner/building/tag-diagnostics.js +37 -0
  265. package/dist/src/planner/building/tag-diagnostics.js.map +1 -0
  266. package/dist/src/planner/building/update.d.ts +18 -1
  267. package/dist/src/planner/building/update.d.ts.map +1 -1
  268. package/dist/src/planner/building/update.js +134 -58
  269. package/dist/src/planner/building/update.js.map +1 -1
  270. package/dist/src/planner/building/view-mutation-builder.d.ts +15 -0
  271. package/dist/src/planner/building/view-mutation-builder.d.ts.map +1 -0
  272. package/dist/src/planner/building/view-mutation-builder.js +1158 -0
  273. package/dist/src/planner/building/view-mutation-builder.js.map +1 -0
  274. package/dist/src/planner/building/with.d.ts +11 -0
  275. package/dist/src/planner/building/with.d.ts.map +1 -1
  276. package/dist/src/planner/building/with.js +48 -10
  277. package/dist/src/planner/building/with.js.map +1 -1
  278. package/dist/src/planner/cost/index.d.ts +83 -0
  279. package/dist/src/planner/cost/index.d.ts.map +1 -1
  280. package/dist/src/planner/cost/index.js +114 -0
  281. package/dist/src/planner/cost/index.js.map +1 -1
  282. package/dist/src/planner/framework/characteristics.d.ts +38 -4
  283. package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
  284. package/dist/src/planner/framework/characteristics.js +50 -6
  285. package/dist/src/planner/framework/characteristics.js.map +1 -1
  286. package/dist/src/planner/framework/pass.d.ts.map +1 -1
  287. package/dist/src/planner/framework/pass.js +2 -1
  288. package/dist/src/planner/framework/pass.js.map +1 -1
  289. package/dist/src/planner/framework/registry.d.ts +39 -1
  290. package/dist/src/planner/framework/registry.d.ts.map +1 -1
  291. package/dist/src/planner/framework/registry.js +18 -2
  292. package/dist/src/planner/framework/registry.js.map +1 -1
  293. package/dist/src/planner/mutation/backward-body.d.ts +131 -0
  294. package/dist/src/planner/mutation/backward-body.d.ts.map +1 -0
  295. package/dist/src/planner/mutation/backward-body.js +135 -0
  296. package/dist/src/planner/mutation/backward-body.js.map +1 -0
  297. package/dist/src/planner/mutation/cte-flatten.d.ts +17 -0
  298. package/dist/src/planner/mutation/cte-flatten.d.ts.map +1 -0
  299. package/dist/src/planner/mutation/cte-flatten.js +364 -0
  300. package/dist/src/planner/mutation/cte-flatten.js.map +1 -0
  301. package/dist/src/planner/mutation/decomposition.d.ts +273 -0
  302. package/dist/src/planner/mutation/decomposition.d.ts.map +1 -0
  303. package/dist/src/planner/mutation/decomposition.js +1719 -0
  304. package/dist/src/planner/mutation/decomposition.js.map +1 -0
  305. package/dist/src/planner/mutation/lens-enforcement.d.ts +165 -0
  306. package/dist/src/planner/mutation/lens-enforcement.d.ts.map +1 -0
  307. package/dist/src/planner/mutation/lens-enforcement.js +745 -0
  308. package/dist/src/planner/mutation/lens-enforcement.js.map +1 -0
  309. package/dist/src/planner/mutation/multi-source.d.ts +568 -0
  310. package/dist/src/planner/mutation/multi-source.d.ts.map +1 -0
  311. package/dist/src/planner/mutation/multi-source.js +2915 -0
  312. package/dist/src/planner/mutation/multi-source.js.map +1 -0
  313. package/dist/src/planner/mutation/mutation-diagnostic.d.ts +37 -0
  314. package/dist/src/planner/mutation/mutation-diagnostic.d.ts.map +1 -0
  315. package/dist/src/planner/mutation/mutation-diagnostic.js +24 -0
  316. package/dist/src/planner/mutation/mutation-diagnostic.js.map +1 -0
  317. package/dist/src/planner/mutation/mutation-tags.d.ts +33 -0
  318. package/dist/src/planner/mutation/mutation-tags.d.ts.map +1 -0
  319. package/dist/src/planner/mutation/mutation-tags.js +31 -0
  320. package/dist/src/planner/mutation/mutation-tags.js.map +1 -0
  321. package/dist/src/planner/mutation/propagate.d.ts +97 -0
  322. package/dist/src/planner/mutation/propagate.d.ts.map +1 -0
  323. package/dist/src/planner/mutation/propagate.js +220 -0
  324. package/dist/src/planner/mutation/propagate.js.map +1 -0
  325. package/dist/src/planner/mutation/scope-transform.d.ts +181 -0
  326. package/dist/src/planner/mutation/scope-transform.d.ts.map +1 -0
  327. package/dist/src/planner/mutation/scope-transform.js +574 -0
  328. package/dist/src/planner/mutation/scope-transform.js.map +1 -0
  329. package/dist/src/planner/mutation/set-op.d.ts +242 -0
  330. package/dist/src/planner/mutation/set-op.d.ts.map +1 -0
  331. package/dist/src/planner/mutation/set-op.js +1687 -0
  332. package/dist/src/planner/mutation/set-op.js.map +1 -0
  333. package/dist/src/planner/mutation/single-source.d.ts +261 -0
  334. package/dist/src/planner/mutation/single-source.d.ts.map +1 -0
  335. package/dist/src/planner/mutation/single-source.js +1096 -0
  336. package/dist/src/planner/mutation/single-source.js.map +1 -0
  337. package/dist/src/planner/nodes/aggregate-node.js +3 -3
  338. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  339. package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
  340. package/dist/src/planner/nodes/alias-node.js +5 -1
  341. package/dist/src/planner/nodes/alias-node.js.map +1 -1
  342. package/dist/src/planner/nodes/alter-table-node.d.ts +124 -1
  343. package/dist/src/planner/nodes/alter-table-node.d.ts.map +1 -1
  344. package/dist/src/planner/nodes/alter-table-node.js +27 -0
  345. package/dist/src/planner/nodes/alter-table-node.js.map +1 -1
  346. package/dist/src/planner/nodes/analyze-node.d.ts +2 -1
  347. package/dist/src/planner/nodes/analyze-node.d.ts.map +1 -1
  348. package/dist/src/planner/nodes/analyze-node.js +18 -1
  349. package/dist/src/planner/nodes/analyze-node.js.map +1 -1
  350. package/dist/src/planner/nodes/asserted-keys-node.d.ts +43 -0
  351. package/dist/src/planner/nodes/asserted-keys-node.d.ts.map +1 -0
  352. package/dist/src/planner/nodes/asserted-keys-node.js +99 -0
  353. package/dist/src/planner/nodes/asserted-keys-node.js.map +1 -0
  354. package/dist/src/planner/nodes/async-gather-node.d.ts.map +1 -1
  355. package/dist/src/planner/nodes/async-gather-node.js +33 -8
  356. package/dist/src/planner/nodes/async-gather-node.js.map +1 -1
  357. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
  358. package/dist/src/planner/nodes/bloom-join-node.js +2 -1
  359. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
  360. package/dist/src/planner/nodes/create-view-node.d.ts +7 -2
  361. package/dist/src/planner/nodes/create-view-node.d.ts.map +1 -1
  362. package/dist/src/planner/nodes/create-view-node.js +4 -1
  363. package/dist/src/planner/nodes/create-view-node.js.map +1 -1
  364. package/dist/src/planner/nodes/declarative-schema.d.ts +13 -1
  365. package/dist/src/planner/nodes/declarative-schema.d.ts.map +1 -1
  366. package/dist/src/planner/nodes/declarative-schema.js +32 -0
  367. package/dist/src/planner/nodes/declarative-schema.js.map +1 -1
  368. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
  369. package/dist/src/planner/nodes/distinct-node.js +2 -0
  370. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  371. package/dist/src/planner/nodes/dml-executor-node.d.ts +29 -1
  372. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  373. package/dist/src/planner/nodes/dml-executor-node.js +27 -3
  374. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  375. package/dist/src/planner/nodes/eager-prefetch-node.d.ts.map +1 -1
  376. package/dist/src/planner/nodes/eager-prefetch-node.js +2 -0
  377. package/dist/src/planner/nodes/eager-prefetch-node.js.map +1 -1
  378. package/dist/src/planner/nodes/envelope-scan-node.d.ts +42 -0
  379. package/dist/src/planner/nodes/envelope-scan-node.d.ts.map +1 -0
  380. package/dist/src/planner/nodes/envelope-scan-node.js +62 -0
  381. package/dist/src/planner/nodes/envelope-scan-node.js.map +1 -0
  382. package/dist/src/planner/nodes/fanout-lookup-join-node.d.ts.map +1 -1
  383. package/dist/src/planner/nodes/fanout-lookup-join-node.js +11 -1
  384. package/dist/src/planner/nodes/fanout-lookup-join-node.js.map +1 -1
  385. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  386. package/dist/src/planner/nodes/filter.js +63 -13
  387. package/dist/src/planner/nodes/filter.js.map +1 -1
  388. package/dist/src/planner/nodes/join-node.d.ts +41 -1
  389. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  390. package/dist/src/planner/nodes/join-node.js +78 -8
  391. package/dist/src/planner/nodes/join-node.js.map +1 -1
  392. package/dist/src/planner/nodes/join-utils.d.ts +33 -6
  393. package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
  394. package/dist/src/planner/nodes/join-utils.js +124 -9
  395. package/dist/src/planner/nodes/join-utils.js.map +1 -1
  396. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts +104 -0
  397. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts.map +1 -0
  398. package/dist/src/planner/nodes/lens-auxiliary-access-node.js +91 -0
  399. package/dist/src/planner/nodes/lens-auxiliary-access-node.js.map +1 -0
  400. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  401. package/dist/src/planner/nodes/limit-offset.js +4 -5
  402. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  403. package/dist/src/planner/nodes/materialized-view-nodes.d.ts +69 -0
  404. package/dist/src/planner/nodes/materialized-view-nodes.d.ts.map +1 -0
  405. package/dist/src/planner/nodes/materialized-view-nodes.js +111 -0
  406. package/dist/src/planner/nodes/materialized-view-nodes.js.map +1 -0
  407. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
  408. package/dist/src/planner/nodes/merge-join-node.js +2 -1
  409. package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
  410. package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
  411. package/dist/src/planner/nodes/ordinal-slice-node.js +2 -0
  412. package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
  413. package/dist/src/planner/nodes/plan-node-type.d.ts +9 -0
  414. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  415. package/dist/src/planner/nodes/plan-node-type.js +9 -0
  416. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  417. package/dist/src/planner/nodes/plan-node.d.ts +265 -5
  418. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  419. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  420. package/dist/src/planner/nodes/pragma.d.ts +2 -1
  421. package/dist/src/planner/nodes/pragma.d.ts.map +1 -1
  422. package/dist/src/planner/nodes/pragma.js +12 -0
  423. package/dist/src/planner/nodes/pragma.js.map +1 -1
  424. package/dist/src/planner/nodes/project-node.d.ts +14 -1
  425. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  426. package/dist/src/planner/nodes/project-node.js +85 -11
  427. package/dist/src/planner/nodes/project-node.js.map +1 -1
  428. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  429. package/dist/src/planner/nodes/reference.js +62 -27
  430. package/dist/src/planner/nodes/reference.js.map +1 -1
  431. package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -1
  432. package/dist/src/planner/nodes/retrieve-node.js +7 -0
  433. package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
  434. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  435. package/dist/src/planner/nodes/returning-node.js +10 -3
  436. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  437. package/dist/src/planner/nodes/scalar.d.ts +20 -0
  438. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  439. package/dist/src/planner/nodes/scalar.js +71 -14
  440. package/dist/src/planner/nodes/scalar.js.map +1 -1
  441. package/dist/src/planner/nodes/set-object-tags-node.d.ts +39 -0
  442. package/dist/src/planner/nodes/set-object-tags-node.d.ts.map +1 -0
  443. package/dist/src/planner/nodes/set-object-tags-node.js +41 -0
  444. package/dist/src/planner/nodes/set-object-tags-node.js.map +1 -0
  445. package/dist/src/planner/nodes/set-operation-node.d.ts +123 -1
  446. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  447. package/dist/src/planner/nodes/set-operation-node.js +291 -18
  448. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  449. package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
  450. package/dist/src/planner/nodes/single-row.js +3 -0
  451. package/dist/src/planner/nodes/single-row.js.map +1 -1
  452. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  453. package/dist/src/planner/nodes/sort.js +7 -6
  454. package/dist/src/planner/nodes/sort.js.map +1 -1
  455. package/dist/src/planner/nodes/subquery.d.ts +2 -0
  456. package/dist/src/planner/nodes/subquery.d.ts.map +1 -1
  457. package/dist/src/planner/nodes/subquery.js +18 -2
  458. package/dist/src/planner/nodes/subquery.js.map +1 -1
  459. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
  460. package/dist/src/planner/nodes/table-access-nodes.js +23 -3
  461. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  462. package/dist/src/planner/nodes/table-function-call.js +6 -0
  463. package/dist/src/planner/nodes/table-function-call.js.map +1 -1
  464. package/dist/src/planner/nodes/values-node.d.ts +1 -0
  465. package/dist/src/planner/nodes/values-node.d.ts.map +1 -1
  466. package/dist/src/planner/nodes/values-node.js +16 -6
  467. package/dist/src/planner/nodes/values-node.js.map +1 -1
  468. package/dist/src/planner/nodes/view-mutation-node.d.ts +259 -0
  469. package/dist/src/planner/nodes/view-mutation-node.d.ts.map +1 -0
  470. package/dist/src/planner/nodes/view-mutation-node.js +273 -0
  471. package/dist/src/planner/nodes/view-mutation-node.js.map +1 -0
  472. package/dist/src/planner/nodes/window-function.d.ts +17 -1
  473. package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
  474. package/dist/src/planner/nodes/window-function.js +15 -1
  475. package/dist/src/planner/nodes/window-function.js.map +1 -1
  476. package/dist/src/planner/nodes/window-node.js +2 -2
  477. package/dist/src/planner/nodes/window-node.js.map +1 -1
  478. package/dist/src/planner/optimizer.d.ts.map +1 -1
  479. package/dist/src/planner/optimizer.js +372 -39
  480. package/dist/src/planner/optimizer.js.map +1 -1
  481. package/dist/src/planner/planning-context.d.ts +1 -1
  482. package/dist/src/planner/planning-context.d.ts.map +1 -1
  483. package/dist/src/planner/rules/access/lens-access-form-matcher.d.ts +70 -0
  484. package/dist/src/planner/rules/access/lens-access-form-matcher.d.ts.map +1 -0
  485. package/dist/src/planner/rules/access/lens-access-form-matcher.js +156 -0
  486. package/dist/src/planner/rules/access/lens-access-form-matcher.js.map +1 -0
  487. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.d.ts +31 -0
  488. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.d.ts.map +1 -0
  489. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.js +176 -0
  490. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.js.map +1 -0
  491. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  492. package/dist/src/planner/rules/access/rule-select-access-path.js +435 -37
  493. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  494. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts.map +1 -1
  495. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js +9 -0
  496. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js.map +1 -1
  497. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts +39 -0
  498. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts.map +1 -0
  499. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js +616 -0
  500. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js.map +1 -0
  501. package/dist/src/planner/rules/cache/rule-scalar-cse.d.ts.map +1 -1
  502. package/dist/src/planner/rules/cache/rule-scalar-cse.js +8 -1
  503. package/dist/src/planner/rules/cache/rule-scalar-cse.js.map +1 -1
  504. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts +36 -0
  505. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts.map +1 -1
  506. package/dist/src/planner/rules/join/equi-pair-extractor.js +38 -1
  507. package/dist/src/planner/rules/join/equi-pair-extractor.js.map +1 -1
  508. package/dist/src/planner/rules/join/rule-fanout-batched-outer.d.ts.map +1 -1
  509. package/dist/src/planner/rules/join/rule-fanout-batched-outer.js +10 -0
  510. package/dist/src/planner/rules/join/rule-fanout-batched-outer.js.map +1 -1
  511. package/dist/src/planner/rules/join/rule-fanout-lookup-join.d.ts.map +1 -1
  512. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js +19 -1
  513. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js.map +1 -1
  514. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts +130 -0
  515. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts.map +1 -0
  516. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js +206 -0
  517. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js.map +1 -0
  518. package/dist/src/planner/rules/join/rule-join-elimination.d.ts +67 -14
  519. package/dist/src/planner/rules/join/rule-join-elimination.d.ts.map +1 -1
  520. package/dist/src/planner/rules/join/rule-join-elimination.js +81 -25
  521. package/dist/src/planner/rules/join/rule-join-elimination.js.map +1 -1
  522. package/dist/src/planner/rules/join/rule-join-existence-pruning.d.ts +84 -0
  523. package/dist/src/planner/rules/join/rule-join-existence-pruning.d.ts.map +1 -0
  524. package/dist/src/planner/rules/join/rule-join-existence-pruning.js +138 -0
  525. package/dist/src/planner/rules/join/rule-join-existence-pruning.js.map +1 -0
  526. package/dist/src/planner/rules/join/rule-join-greedy-commute.d.ts.map +1 -1
  527. package/dist/src/planner/rules/join/rule-join-greedy-commute.js +9 -1
  528. package/dist/src/planner/rules/join/rule-join-greedy-commute.js.map +1 -1
  529. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -1
  530. package/dist/src/planner/rules/join/rule-join-physical-selection.js +12 -1
  531. package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -1
  532. package/dist/src/planner/rules/join/rule-lateral-top1-asof.d.ts.map +1 -1
  533. package/dist/src/planner/rules/join/rule-lateral-top1-asof.js +4 -0
  534. package/dist/src/planner/rules/join/rule-lateral-top1-asof.js.map +1 -1
  535. package/dist/src/planner/rules/join/rule-monotonic-merge-join.d.ts.map +1 -1
  536. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js +4 -0
  537. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js.map +1 -1
  538. package/dist/src/planner/rules/join/rule-quickpick-enumeration.d.ts.map +1 -1
  539. package/dist/src/planner/rules/join/rule-quickpick-enumeration.js +10 -0
  540. package/dist/src/planner/rules/join/rule-quickpick-enumeration.js.map +1 -1
  541. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.d.ts +286 -0
  542. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.d.ts.map +1 -0
  543. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.js +548 -0
  544. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.js.map +1 -0
  545. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.d.ts.map +1 -1
  546. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.js +9 -1
  547. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.js.map +1 -1
  548. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.d.ts.map +1 -1
  549. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js +7 -0
  550. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js.map +1 -1
  551. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.d.ts.map +1 -1
  552. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.js +10 -1
  553. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.js.map +1 -1
  554. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts.map +1 -1
  555. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js +9 -0
  556. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js.map +1 -1
  557. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts.map +1 -1
  558. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +18 -0
  559. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js.map +1 -1
  560. package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts.map +1 -1
  561. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js +7 -0
  562. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js.map +1 -1
  563. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts.map +1 -1
  564. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +9 -0
  565. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -1
  566. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js +13 -3
  567. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -1
  568. package/dist/src/planner/rules/retrieve/rule-projection-pruning.d.ts.map +1 -1
  569. package/dist/src/planner/rules/retrieve/rule-projection-pruning.js +14 -0
  570. package/dist/src/planner/rules/retrieve/rule-projection-pruning.js.map +1 -1
  571. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts +1 -1
  572. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js +4 -4
  573. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js.map +1 -1
  574. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts.map +1 -1
  575. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js +8 -0
  576. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js.map +1 -1
  577. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts.map +1 -1
  578. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js +7 -0
  579. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js.map +1 -1
  580. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
  581. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +12 -0
  582. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
  583. package/dist/src/planner/type-utils.d.ts +14 -0
  584. package/dist/src/planner/type-utils.d.ts.map +1 -1
  585. package/dist/src/planner/type-utils.js +66 -21
  586. package/dist/src/planner/type-utils.js.map +1 -1
  587. package/dist/src/planner/util/fd-utils.d.ts +177 -43
  588. package/dist/src/planner/util/fd-utils.d.ts.map +1 -1
  589. package/dist/src/planner/util/fd-utils.js +396 -101
  590. package/dist/src/planner/util/fd-utils.js.map +1 -1
  591. package/dist/src/planner/util/ind-utils.d.ts +27 -1
  592. package/dist/src/planner/util/ind-utils.d.ts.map +1 -1
  593. package/dist/src/planner/util/ind-utils.js +80 -6
  594. package/dist/src/planner/util/ind-utils.js.map +1 -1
  595. package/dist/src/planner/util/key-utils.d.ts.map +1 -1
  596. package/dist/src/planner/util/key-utils.js +81 -12
  597. package/dist/src/planner/util/key-utils.js.map +1 -1
  598. package/dist/src/planner/util/set-op-wrapper.d.ts +37 -0
  599. package/dist/src/planner/util/set-op-wrapper.d.ts.map +1 -0
  600. package/dist/src/planner/util/set-op-wrapper.js +82 -0
  601. package/dist/src/planner/util/set-op-wrapper.js.map +1 -0
  602. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  603. package/dist/src/planner/validation/plan-validator.js +1 -0
  604. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  605. package/dist/src/runtime/context-helpers.d.ts +13 -1
  606. package/dist/src/runtime/context-helpers.d.ts.map +1 -1
  607. package/dist/src/runtime/context-helpers.js +7 -1
  608. package/dist/src/runtime/context-helpers.js.map +1 -1
  609. package/dist/src/runtime/delta-executor.d.ts +30 -1
  610. package/dist/src/runtime/delta-executor.d.ts.map +1 -1
  611. package/dist/src/runtime/delta-executor.js +29 -4
  612. package/dist/src/runtime/delta-executor.js.map +1 -1
  613. package/dist/src/runtime/emit/add-constraint.d.ts.map +1 -1
  614. package/dist/src/runtime/emit/add-constraint.js +38 -5
  615. package/dist/src/runtime/emit/add-constraint.js.map +1 -1
  616. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  617. package/dist/src/runtime/emit/aggregate.js +10 -8
  618. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  619. package/dist/src/runtime/emit/alter-table.d.ts +1 -1
  620. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  621. package/dist/src/runtime/emit/alter-table.js +664 -108
  622. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  623. package/dist/src/runtime/emit/analyze.d.ts.map +1 -1
  624. package/dist/src/runtime/emit/analyze.js +2 -1
  625. package/dist/src/runtime/emit/analyze.js.map +1 -1
  626. package/dist/src/runtime/emit/asof-scan.d.ts.map +1 -1
  627. package/dist/src/runtime/emit/asof-scan.js +18 -5
  628. package/dist/src/runtime/emit/asof-scan.js.map +1 -1
  629. package/dist/src/runtime/emit/asserted-keys.d.ts +13 -0
  630. package/dist/src/runtime/emit/asserted-keys.d.ts.map +1 -0
  631. package/dist/src/runtime/emit/asserted-keys.js +13 -0
  632. package/dist/src/runtime/emit/asserted-keys.js.map +1 -0
  633. package/dist/src/runtime/emit/between.d.ts.map +1 -1
  634. package/dist/src/runtime/emit/between.js +24 -19
  635. package/dist/src/runtime/emit/between.js.map +1 -1
  636. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  637. package/dist/src/runtime/emit/binary.js +5 -9
  638. package/dist/src/runtime/emit/binary.js.map +1 -1
  639. package/dist/src/runtime/emit/block.d.ts.map +1 -1
  640. package/dist/src/runtime/emit/block.js +11 -2
  641. package/dist/src/runtime/emit/block.js.map +1 -1
  642. package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -1
  643. package/dist/src/runtime/emit/bloom-join.js +8 -2
  644. package/dist/src/runtime/emit/bloom-join.js.map +1 -1
  645. package/dist/src/runtime/emit/constraint-check.js +15 -0
  646. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  647. package/dist/src/runtime/emit/create-table.d.ts.map +1 -1
  648. package/dist/src/runtime/emit/create-table.js +8 -0
  649. package/dist/src/runtime/emit/create-table.js.map +1 -1
  650. package/dist/src/runtime/emit/create-view.d.ts.map +1 -1
  651. package/dist/src/runtime/emit/create-view.js +16 -1
  652. package/dist/src/runtime/emit/create-view.js.map +1 -1
  653. package/dist/src/runtime/emit/dml-executor.d.ts +27 -0
  654. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  655. package/dist/src/runtime/emit/dml-executor.js +413 -193
  656. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  657. package/dist/src/runtime/emit/drop-table.d.ts.map +1 -1
  658. package/dist/src/runtime/emit/drop-table.js +10 -0
  659. package/dist/src/runtime/emit/drop-table.js.map +1 -1
  660. package/dist/src/runtime/emit/drop-view.d.ts.map +1 -1
  661. package/dist/src/runtime/emit/drop-view.js +17 -0
  662. package/dist/src/runtime/emit/drop-view.js.map +1 -1
  663. package/dist/src/runtime/emit/envelope-scan.d.ts +13 -0
  664. package/dist/src/runtime/emit/envelope-scan.d.ts.map +1 -0
  665. package/dist/src/runtime/emit/envelope-scan.js +22 -0
  666. package/dist/src/runtime/emit/envelope-scan.js.map +1 -0
  667. package/dist/src/runtime/emit/join.d.ts +10 -2
  668. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  669. package/dist/src/runtime/emit/join.js +128 -38
  670. package/dist/src/runtime/emit/join.js.map +1 -1
  671. package/dist/src/runtime/emit/lens-auxiliary-access.d.ts +16 -0
  672. package/dist/src/runtime/emit/lens-auxiliary-access.d.ts.map +1 -0
  673. package/dist/src/runtime/emit/lens-auxiliary-access.js +16 -0
  674. package/dist/src/runtime/emit/lens-auxiliary-access.js.map +1 -0
  675. package/dist/src/runtime/emit/materialized-view-helpers.d.ts +640 -0
  676. package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -0
  677. package/dist/src/runtime/emit/materialized-view-helpers.js +2576 -0
  678. package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -0
  679. package/dist/src/runtime/emit/materialized-view.d.ts +31 -0
  680. package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -0
  681. package/dist/src/runtime/emit/materialized-view.js +187 -0
  682. package/dist/src/runtime/emit/materialized-view.js.map +1 -0
  683. package/dist/src/runtime/emit/merge-join.d.ts.map +1 -1
  684. package/dist/src/runtime/emit/merge-join.js +15 -3
  685. package/dist/src/runtime/emit/merge-join.js.map +1 -1
  686. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  687. package/dist/src/runtime/emit/project.js +10 -5
  688. package/dist/src/runtime/emit/project.js.map +1 -1
  689. package/dist/src/runtime/emit/schema-declarative.d.ts +1 -0
  690. package/dist/src/runtime/emit/schema-declarative.d.ts.map +1 -1
  691. package/dist/src/runtime/emit/schema-declarative.js +101 -5
  692. package/dist/src/runtime/emit/schema-declarative.js.map +1 -1
  693. package/dist/src/runtime/emit/set-object-tags.d.ts +16 -0
  694. package/dist/src/runtime/emit/set-object-tags.d.ts.map +1 -0
  695. package/dist/src/runtime/emit/set-object-tags.js +57 -0
  696. package/dist/src/runtime/emit/set-object-tags.js.map +1 -0
  697. package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
  698. package/dist/src/runtime/emit/set-operation.js +140 -24
  699. package/dist/src/runtime/emit/set-operation.js.map +1 -1
  700. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  701. package/dist/src/runtime/emit/subquery.js +110 -5
  702. package/dist/src/runtime/emit/subquery.js.map +1 -1
  703. package/dist/src/runtime/emit/unary.d.ts.map +1 -1
  704. package/dist/src/runtime/emit/unary.js +34 -6
  705. package/dist/src/runtime/emit/unary.js.map +1 -1
  706. package/dist/src/runtime/emit/view-mutation.d.ts +70 -0
  707. package/dist/src/runtime/emit/view-mutation.d.ts.map +1 -0
  708. package/dist/src/runtime/emit/view-mutation.js +299 -0
  709. package/dist/src/runtime/emit/view-mutation.js.map +1 -0
  710. package/dist/src/runtime/emit/window.js +29 -5
  711. package/dist/src/runtime/emit/window.js.map +1 -1
  712. package/dist/src/runtime/foreign-key-actions.d.ts +66 -3
  713. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
  714. package/dist/src/runtime/foreign-key-actions.js +580 -172
  715. package/dist/src/runtime/foreign-key-actions.js.map +1 -1
  716. package/dist/src/runtime/parallel-driver.d.ts +4 -1
  717. package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
  718. package/dist/src/runtime/parallel-driver.js +5 -1
  719. package/dist/src/runtime/parallel-driver.js.map +1 -1
  720. package/dist/src/runtime/register.d.ts.map +1 -1
  721. package/dist/src/runtime/register.js +17 -1
  722. package/dist/src/runtime/register.js.map +1 -1
  723. package/dist/src/runtime/types.d.ts +10 -0
  724. package/dist/src/runtime/types.d.ts.map +1 -1
  725. package/dist/src/runtime/types.js.map +1 -1
  726. package/dist/src/schema/basis-backfill.d.ts +63 -0
  727. package/dist/src/schema/basis-backfill.d.ts.map +1 -0
  728. package/dist/src/schema/basis-backfill.js +161 -0
  729. package/dist/src/schema/basis-backfill.js.map +1 -0
  730. package/dist/src/schema/catalog.d.ts +115 -1
  731. package/dist/src/schema/catalog.d.ts.map +1 -1
  732. package/dist/src/schema/catalog.js +249 -22
  733. package/dist/src/schema/catalog.js.map +1 -1
  734. package/dist/src/schema/change-events.d.ts +42 -1
  735. package/dist/src/schema/change-events.d.ts.map +1 -1
  736. package/dist/src/schema/change-events.js.map +1 -1
  737. package/dist/src/schema/column.d.ts +16 -0
  738. package/dist/src/schema/column.d.ts.map +1 -1
  739. package/dist/src/schema/column.js.map +1 -1
  740. package/dist/src/schema/constraint-builder.d.ts +182 -0
  741. package/dist/src/schema/constraint-builder.d.ts.map +1 -0
  742. package/dist/src/schema/constraint-builder.js +424 -0
  743. package/dist/src/schema/constraint-builder.js.map +1 -0
  744. package/dist/src/schema/ddl-generator.d.ts +86 -1
  745. package/dist/src/schema/ddl-generator.d.ts.map +1 -1
  746. package/dist/src/schema/ddl-generator.js +316 -20
  747. package/dist/src/schema/ddl-generator.js.map +1 -1
  748. package/dist/src/schema/declared-schema-manager.d.ts +51 -0
  749. package/dist/src/schema/declared-schema-manager.d.ts.map +1 -1
  750. package/dist/src/schema/declared-schema-manager.js +61 -0
  751. package/dist/src/schema/declared-schema-manager.js.map +1 -1
  752. package/dist/src/schema/derivation.d.ts +106 -0
  753. package/dist/src/schema/derivation.d.ts.map +1 -0
  754. package/dist/src/schema/derivation.js +25 -0
  755. package/dist/src/schema/derivation.js.map +1 -0
  756. package/dist/src/schema/function.d.ts +20 -0
  757. package/dist/src/schema/function.d.ts.map +1 -1
  758. package/dist/src/schema/function.js.map +1 -1
  759. package/dist/src/schema/lens-ack.d.ts +90 -0
  760. package/dist/src/schema/lens-ack.d.ts.map +1 -0
  761. package/dist/src/schema/lens-ack.js +361 -0
  762. package/dist/src/schema/lens-ack.js.map +1 -0
  763. package/dist/src/schema/lens-compiler.d.ts +62 -0
  764. package/dist/src/schema/lens-compiler.d.ts.map +1 -0
  765. package/dist/src/schema/lens-compiler.js +1594 -0
  766. package/dist/src/schema/lens-compiler.js.map +1 -0
  767. package/dist/src/schema/lens-fk-discovery.d.ts +175 -0
  768. package/dist/src/schema/lens-fk-discovery.d.ts.map +1 -0
  769. package/dist/src/schema/lens-fk-discovery.js +336 -0
  770. package/dist/src/schema/lens-fk-discovery.js.map +1 -0
  771. package/dist/src/schema/lens-prover.d.ts +336 -0
  772. package/dist/src/schema/lens-prover.d.ts.map +1 -0
  773. package/dist/src/schema/lens-prover.js +1988 -0
  774. package/dist/src/schema/lens-prover.js.map +1 -0
  775. package/dist/src/schema/lens.d.ts +254 -0
  776. package/dist/src/schema/lens.d.ts.map +1 -0
  777. package/dist/src/schema/lens.js +21 -0
  778. package/dist/src/schema/lens.js.map +1 -0
  779. package/dist/src/schema/manager.d.ts +676 -18
  780. package/dist/src/schema/manager.d.ts.map +1 -1
  781. package/dist/src/schema/manager.js +1573 -238
  782. package/dist/src/schema/manager.js.map +1 -1
  783. package/dist/src/schema/mapping-advertisement-tags.d.ts +39 -0
  784. package/dist/src/schema/mapping-advertisement-tags.d.ts.map +1 -0
  785. package/dist/src/schema/mapping-advertisement-tags.js +216 -0
  786. package/dist/src/schema/mapping-advertisement-tags.js.map +1 -0
  787. package/dist/src/schema/rename-rewriter.d.ts +45 -4
  788. package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
  789. package/dist/src/schema/rename-rewriter.js +412 -19
  790. package/dist/src/schema/rename-rewriter.js.map +1 -1
  791. package/dist/src/schema/reserved-tags-policy.d.ts +32 -0
  792. package/dist/src/schema/reserved-tags-policy.d.ts.map +1 -0
  793. package/dist/src/schema/reserved-tags-policy.js +34 -0
  794. package/dist/src/schema/reserved-tags-policy.js.map +1 -0
  795. package/dist/src/schema/reserved-tags.d.ts +170 -0
  796. package/dist/src/schema/reserved-tags.d.ts.map +1 -0
  797. package/dist/src/schema/reserved-tags.js +507 -0
  798. package/dist/src/schema/reserved-tags.js.map +1 -0
  799. package/dist/src/schema/schema-differ.d.ts +158 -2
  800. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  801. package/dist/src/schema/schema-differ.js +1460 -78
  802. package/dist/src/schema/schema-differ.js.map +1 -1
  803. package/dist/src/schema/schema-hasher.d.ts +8 -3
  804. package/dist/src/schema/schema-hasher.d.ts.map +1 -1
  805. package/dist/src/schema/schema-hasher.js +22 -2
  806. package/dist/src/schema/schema-hasher.js.map +1 -1
  807. package/dist/src/schema/schema.d.ts +25 -1
  808. package/dist/src/schema/schema.d.ts.map +1 -1
  809. package/dist/src/schema/schema.js +36 -2
  810. package/dist/src/schema/schema.js.map +1 -1
  811. package/dist/src/schema/table.d.ts +259 -10
  812. package/dist/src/schema/table.d.ts.map +1 -1
  813. package/dist/src/schema/table.js +309 -26
  814. package/dist/src/schema/table.js.map +1 -1
  815. package/dist/src/schema/unique-enforcement.d.ts +78 -0
  816. package/dist/src/schema/unique-enforcement.d.ts.map +1 -0
  817. package/dist/src/schema/unique-enforcement.js +93 -0
  818. package/dist/src/schema/unique-enforcement.js.map +1 -0
  819. package/dist/src/schema/view.d.ts +83 -2
  820. package/dist/src/schema/view.d.ts.map +1 -1
  821. package/dist/src/schema/view.js +67 -1
  822. package/dist/src/schema/view.js.map +1 -1
  823. package/dist/src/schema/window-function.d.ts +9 -1
  824. package/dist/src/schema/window-function.d.ts.map +1 -1
  825. package/dist/src/schema/window-function.js.map +1 -1
  826. package/dist/src/util/comparison.d.ts +24 -0
  827. package/dist/src/util/comparison.d.ts.map +1 -1
  828. package/dist/src/util/comparison.js +34 -0
  829. package/dist/src/util/comparison.js.map +1 -1
  830. package/dist/src/util/mutation-statement.d.ts.map +1 -1
  831. package/dist/src/util/mutation-statement.js +4 -1
  832. package/dist/src/util/mutation-statement.js.map +1 -1
  833. package/dist/src/util/serialization.d.ts +9 -0
  834. package/dist/src/util/serialization.d.ts.map +1 -1
  835. package/dist/src/util/serialization.js +26 -0
  836. package/dist/src/util/serialization.js.map +1 -1
  837. package/dist/src/vtab/backing-host.d.ts +286 -0
  838. package/dist/src/vtab/backing-host.d.ts.map +1 -0
  839. package/dist/src/vtab/backing-host.js +118 -0
  840. package/dist/src/vtab/backing-host.js.map +1 -0
  841. package/dist/src/vtab/best-access-plan.d.ts +21 -0
  842. package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
  843. package/dist/src/vtab/best-access-plan.js.map +1 -1
  844. package/dist/src/vtab/capabilities.d.ts +5 -5
  845. package/dist/src/vtab/capabilities.d.ts.map +1 -1
  846. package/dist/src/vtab/mapping-advertisement.d.ts +163 -0
  847. package/dist/src/vtab/mapping-advertisement.d.ts.map +1 -0
  848. package/dist/src/vtab/mapping-advertisement.js +2 -0
  849. package/dist/src/vtab/mapping-advertisement.js.map +1 -0
  850. package/dist/src/vtab/memory/index.d.ts +64 -4
  851. package/dist/src/vtab/memory/index.d.ts.map +1 -1
  852. package/dist/src/vtab/memory/index.js +119 -12
  853. package/dist/src/vtab/memory/index.js.map +1 -1
  854. package/dist/src/vtab/memory/layer/base.d.ts +38 -1
  855. package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
  856. package/dist/src/vtab/memory/layer/base.js +112 -24
  857. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  858. package/dist/src/vtab/memory/layer/manager.d.ts +291 -4
  859. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  860. package/dist/src/vtab/memory/layer/manager.js +1050 -91
  861. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  862. package/dist/src/vtab/memory/layer/plan-filter.d.ts.map +1 -1
  863. package/dist/src/vtab/memory/layer/plan-filter.js +35 -6
  864. package/dist/src/vtab/memory/layer/plan-filter.js.map +1 -1
  865. package/dist/src/vtab/memory/layer/scan-layer.d.ts.map +1 -1
  866. package/dist/src/vtab/memory/layer/scan-layer.js +66 -14
  867. package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
  868. package/dist/src/vtab/memory/layer/scan-plan.d.ts +14 -0
  869. package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
  870. package/dist/src/vtab/memory/layer/scan-plan.js +27 -4
  871. package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
  872. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  873. package/dist/src/vtab/memory/layer/transaction.js +5 -1
  874. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  875. package/dist/src/vtab/memory/module.d.ts +17 -0
  876. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  877. package/dist/src/vtab/memory/module.js +82 -3
  878. package/dist/src/vtab/memory/module.js.map +1 -1
  879. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  880. package/dist/src/vtab/memory/table.js +15 -5
  881. package/dist/src/vtab/memory/table.js.map +1 -1
  882. package/dist/src/vtab/memory/types.d.ts +20 -2
  883. package/dist/src/vtab/memory/types.d.ts.map +1 -1
  884. package/dist/src/vtab/memory/utils/predicate.d.ts.map +1 -1
  885. package/dist/src/vtab/memory/utils/predicate.js +46 -24
  886. package/dist/src/vtab/memory/utils/predicate.js.map +1 -1
  887. package/dist/src/vtab/memory/utils/primary-key-encode.d.ts +31 -0
  888. package/dist/src/vtab/memory/utils/primary-key-encode.d.ts.map +1 -0
  889. package/dist/src/vtab/memory/utils/primary-key-encode.js +101 -0
  890. package/dist/src/vtab/memory/utils/primary-key-encode.js.map +1 -0
  891. package/dist/src/vtab/memory/utils/primary-key.d.ts +8 -0
  892. package/dist/src/vtab/memory/utils/primary-key.d.ts.map +1 -1
  893. package/dist/src/vtab/memory/utils/primary-key.js +12 -5
  894. package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
  895. package/dist/src/vtab/module.d.ts +203 -4
  896. package/dist/src/vtab/module.d.ts.map +1 -1
  897. package/dist/src/vtab/table.d.ts +9 -0
  898. package/dist/src/vtab/table.d.ts.map +1 -1
  899. package/dist/src/vtab/table.js.map +1 -1
  900. package/package.json +17 -16
@@ -1,11 +1,16 @@
1
+ import { emitCallFromPlan } from '../emitters.js';
2
+ import { createRowSlot } from '../context-helpers.js';
1
3
  import { QuereusError } from '../../common/errors.js';
2
4
  import { StatusCode } from '../../common/types.js';
3
5
  import { createLogger } from '../../common/logger.js';
4
- import { buildColumnIndexMap, opsToMask, withGeneratedColumnGraph } from '../../schema/table.js';
6
+ import { buildColumnIndexMap, withGeneratedColumnGraph, requireVtabModule, resolveNamedConstraintClass, validateCollationForType } from '../../schema/table.js';
7
+ import { validateForeignKeyOverExistingRows, validateForeignKeyCollations, extractColumnLevelCheckConstraints, extractColumnLevelForeignKeys, extractColumnLevelUniqueConstraints } from '../../schema/constraint-builder.js';
5
8
  import { MemoryTableModule } from '../../vtab/memory/module.js';
6
- import { quoteIdentifier, expressionToString, selectToString } from '../../emit/ast-stringify.js';
9
+ import { quoteIdentifier, expressionToString, astToString } from '../../emit/ast-stringify.js';
7
10
  import { renameTableInAst, renameColumnInAst, renameColumnInCheckExpression } from '../../schema/rename-rewriter.js';
8
11
  import { tryFoldLiteral } from '../../parser/utils.js';
12
+ import { snapshotStaleMaterializedViews, propagateTableRenameToMaterializedViews, propagateColumnRenameToMaterializedViews, restoreUnaffectedMaterializedViews, attachMaintainedDerivation, detachMaintainedDerivation, } from './materialized-view-helpers.js';
13
+ import { isMaintainedTable } from '../../schema/derivation.js';
9
14
  const log = createLogger('runtime:emit:alter-table');
10
15
  function qualifyTableName(schemaName, tableName) {
11
16
  const prefix = (schemaName && schemaName.toLowerCase() !== 'main')
@@ -13,27 +18,92 @@ function qualifyTableName(schemaName, tableName) {
13
18
  : '';
14
19
  return `${prefix}${quoteIdentifier(tableName)}`;
15
20
  }
16
- export function emitAlterTable(plan, _ctx) {
21
+ export function emitAlterTable(plan, ctx) {
17
22
  const tableSchema = plan.table.tableSchema;
18
23
  const action = plan.action;
19
- async function run(rctx) {
24
+ // An ADD COLUMN with a non-foldable DEFAULT carries a backfill scalar; emit it as a
25
+ // scheduled sub-program so the scheduler resolves it into a callback the run() body
26
+ // evaluates per existing row (via a row slot over the default's row descriptor). When the
27
+ // new column also carries a CHECK, its predicates ride alongside as further callbacks,
28
+ // evaluated per backfilled row against `[...existingRow, backfilledValue]`. Slot order is
29
+ // fixed: backfill first (present whenever checks are), then the checks in order.
30
+ const backfill = action.type === 'addColumn' ? action.backfill : undefined;
31
+ const checks = action.type === 'addColumn' ? action.checks : undefined;
32
+ const params = [
33
+ ...(backfill ? [emitCallFromPlan(backfill.node, ctx)] : []),
34
+ ...(checks?.predicates ?? []).map(p => emitCallFromPlan(p.node, ctx)),
35
+ ];
36
+ async function run(rctx, ...args) {
20
37
  // Ensure we're in a transaction before DDL (lazy/JIT transaction start)
21
38
  await rctx.db._ensureTransaction();
22
39
  const schemaManager = rctx.db.schemaManager;
23
40
  const schema = schemaManager.getSchemaOrFail(tableSchema.schemaName);
41
+ // A maintained table's shape is DEFINED by its derivation body — structural
42
+ // ALTERs would desynchronize (and, mechanically, drop the derivation when the
43
+ // module returns a fresh schema). Only rename and the derivation lifecycle
44
+ // verbs (SET MAINTAINED = re-attach, DROP MAINTAINED = detach) remain
45
+ // allowed. Tag actions must go through ALTER MATERIALIZED VIEW: the TABLE
46
+ // verb fires `table_modified`, not `materialized_view_modified`, so the tag
47
+ // edit would never reach the persisted maintained-table catalog entry.
48
+ if (isMaintainedTable(tableSchema)
49
+ && action.type !== 'renameTable'
50
+ && action.type !== 'setMaintained'
51
+ && action.type !== 'dropMaintained') {
52
+ throw new QuereusError(action.type === 'setTags' || action.type === 'dropTags'
53
+ ? `cannot ALTER TABLE '${tableSchema.name}': it is a materialized view — use ALTER MATERIALIZED VIEW for tags`
54
+ : `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);
55
+ }
24
56
  switch (action.type) {
25
57
  case 'renameTable':
26
58
  return runRenameTable(rctx, tableSchema, schema, action.newName);
27
59
  case 'renameColumn':
28
60
  return runRenameColumn(rctx, tableSchema, schema, action.oldName, action.newName);
29
- case 'addColumn':
30
- return runAddColumn(rctx, tableSchema, schema, action.column);
61
+ case 'addColumn': {
62
+ // Slot order set in `params`: backfill callback first (if any), then check callbacks.
63
+ const backfillCb = backfill ? args[0] : undefined;
64
+ const checkCbs = args.slice(backfill ? 1 : 0);
65
+ return runAddColumn(rctx, tableSchema, schema, action.column, backfill, backfillCb, checks, checkCbs);
66
+ }
31
67
  case 'dropColumn':
32
68
  return runDropColumn(rctx, tableSchema, schema, action.name);
69
+ case 'dropConstraint':
70
+ return runDropConstraint(rctx, tableSchema, schema, action.name);
71
+ case 'renameConstraint':
72
+ return runRenameConstraint(rctx, tableSchema, schema, action.oldName, action.newName);
33
73
  case 'alterPrimaryKey':
34
74
  return runAlterPrimaryKey(rctx, tableSchema, schema, action.columns);
35
75
  case 'alterColumn':
36
76
  return runAlterColumn(rctx, tableSchema, schema, action);
77
+ case 'setTags': {
78
+ const target = action.target;
79
+ if (action.mode === 'merge') {
80
+ // ADD TAGS — per-key merge onto the live tag set.
81
+ if (target.kind === 'column')
82
+ return runMergeColumnTags(rctx, tableSchema, target.columnName, action.tags);
83
+ if (target.kind === 'constraint')
84
+ return runMergeConstraintTags(rctx, tableSchema, target.constraintName, action.tags);
85
+ return runMergeTableTags(rctx, tableSchema, action.tags);
86
+ }
87
+ // SET TAGS — whole-set replace.
88
+ if (target.kind === 'column')
89
+ return runSetColumnTags(rctx, tableSchema, target.columnName, action.tags);
90
+ if (target.kind === 'constraint')
91
+ return runSetConstraintTags(rctx, tableSchema, target.constraintName, action.tags);
92
+ return runSetTableTags(rctx, tableSchema, action.tags);
93
+ }
94
+ case 'dropTags': {
95
+ // DROP TAGS — per-key delete (atomic NOTFOUND if any key absent).
96
+ const target = action.target;
97
+ if (target.kind === 'column')
98
+ return runDropColumnTags(rctx, tableSchema, target.columnName, action.keys);
99
+ if (target.kind === 'constraint')
100
+ return runDropConstraintTags(rctx, tableSchema, target.constraintName, action.keys);
101
+ return runDropTableTags(rctx, tableSchema, action.keys);
102
+ }
103
+ case 'setMaintained':
104
+ return runSetMaintained(rctx, tableSchema, schema, action.columns, action.select);
105
+ case 'dropMaintained':
106
+ return runDropMaintained(rctx, tableSchema, schema);
37
107
  }
38
108
  }
39
109
  const note = (() => {
@@ -42,12 +112,30 @@ export function emitAlterTable(plan, _ctx) {
42
112
  case 'renameColumn': return `renameColumn(${tableSchema.name}.${action.oldName} -> ${action.newName})`;
43
113
  case 'addColumn': return `addColumn(${tableSchema.name}.${action.column.name})`;
44
114
  case 'dropColumn': return `dropColumn(${tableSchema.name}.${action.name})`;
115
+ case 'dropConstraint': return `dropConstraint(${tableSchema.name}.${action.name})`;
116
+ case 'renameConstraint': return `renameConstraint(${tableSchema.name}.${action.oldName} -> ${action.newName})`;
45
117
  case 'alterPrimaryKey': return `alterPrimaryKey(${tableSchema.name} -> [${action.columns.map(c => c.name).join(', ')}])`;
46
118
  case 'alterColumn': return `alterColumn(${tableSchema.name}.${action.columnName})`;
119
+ case 'setTags': {
120
+ const t = action.target;
121
+ const where = t.kind === 'column' ? `${tableSchema.name}.${t.columnName}`
122
+ : t.kind === 'constraint' ? `${tableSchema.name}.constraint ${t.constraintName}`
123
+ : tableSchema.name;
124
+ return action.mode === 'merge' ? `mergeTags(${where})` : `setTags(${where})`;
125
+ }
126
+ case 'dropTags': {
127
+ const t = action.target;
128
+ const where = t.kind === 'column' ? `${tableSchema.name}.${t.columnName}`
129
+ : t.kind === 'constraint' ? `${tableSchema.name}.constraint ${t.constraintName}`
130
+ : tableSchema.name;
131
+ return `dropTags(${where})`;
132
+ }
133
+ case 'setMaintained': return `setMaintained(${tableSchema.name})`;
134
+ case 'dropMaintained': return `dropMaintained(${tableSchema.name})`;
47
135
  }
48
136
  })();
49
137
  return {
50
- params: [],
138
+ params,
51
139
  run: run,
52
140
  note,
53
141
  };
@@ -67,13 +155,18 @@ async function runRenameTable(rctx, tableSchema, schema, newName) {
67
155
  // BEFORE we mutate the in-memory catalog, so a module failure leaves the
68
156
  // catalog untouched. Modules that don't persist by table name can simply
69
157
  // omit the hook.
70
- const module = tableSchema.vtabModule;
158
+ const module = requireVtabModule(tableSchema);
71
159
  if (module.renameTable) {
72
160
  await module.renameTable(rctx.db, tableSchema.schemaName, oldName, newName);
73
161
  }
74
162
  // Remove old, add new in the catalog
75
163
  schema.removeTable(oldName);
76
164
  schema.addTable(updatedTableSchema);
165
+ // Snapshot which MVs are stale BEFORE this statement's first schema-change
166
+ // notify: the MV propagation below restores staleness set by this very
167
+ // statement's events, but must never clear a pre-existing flag (the backing
168
+ // may already be behind; only REFRESH can safely clear that).
169
+ const preStaleMvs = snapshotStaleMaterializedViews(rctx.db);
77
170
  // Notify schema change
78
171
  rctx.db.schemaManager.getChangeNotifier().notifyChange({
79
172
  type: 'table_modified',
@@ -82,10 +175,32 @@ async function runRenameTable(rctx, tableSchema, schema, newName) {
82
175
  oldObject: tableSchema,
83
176
  newObject: updatedTableSchema,
84
177
  });
85
- // Propagate the rename into dependent objects (CHECK / FK in this and other
86
- // tables, view bodies). Best-effort AST rewrite there is no global
87
- // dependency tracker yet, so we walk the catalog and patch in-place.
88
- propagateTableRename(rctx, tableSchema.schemaName, oldName, newName);
178
+ // Propagate the rename into dependent objects (CHECK / FK / partial-index
179
+ // predicates in this and other tables, view and materialized-view bodies).
180
+ // Best-effort AST rewrite — there is no global dependency tracker yet, so we
181
+ // walk the catalog and patch in-place.
182
+ await propagateTableRename(rctx, tableSchema.schemaName, oldName, newName, preStaleMvs);
183
+ // Renaming a MAINTAINED table is an ordinary table rename plus a maintenance
184
+ // re-key: the row-time plan is keyed by `schema.name`, so release the old key
185
+ // and re-register under the new one, then move the persisted MV catalog entry
186
+ // (`materialized_view_removed` old name → `materialized_view_added` new name).
187
+ if (isMaintainedTable(updatedTableSchema)) {
188
+ rctx.db.unregisterMaterializedView(tableSchema.schemaName, oldName);
189
+ rctx.db.registerMaterializedView(updatedTableSchema);
190
+ const notifier = rctx.db.schemaManager.getChangeNotifier();
191
+ notifier.notifyChange({
192
+ type: 'materialized_view_removed',
193
+ schemaName: tableSchema.schemaName,
194
+ objectName: oldName,
195
+ oldObject: tableSchema,
196
+ });
197
+ notifier.notifyChange({
198
+ type: 'materialized_view_added',
199
+ schemaName: tableSchema.schemaName,
200
+ objectName: newName,
201
+ newObject: updatedTableSchema,
202
+ });
203
+ }
89
204
  log('Renamed table %s.%s to %s', tableSchema.schemaName, oldName, newName);
90
205
  return null;
91
206
  }
@@ -106,7 +221,7 @@ async function runRenameColumn(rctx, tableSchema, schema, oldName, newName) {
106
221
  constraints: buildConstraintsFromColumn(existingCol),
107
222
  };
108
223
  // Call module.alterTable if available (handles data-level changes)
109
- const module = tableSchema.vtabModule;
224
+ const module = requireVtabModule(tableSchema);
110
225
  let updatedTableSchema;
111
226
  if (module.alterTable) {
112
227
  updatedTableSchema = await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, {
@@ -127,6 +242,11 @@ async function runRenameColumn(rctx, tableSchema, schema, oldName, newName) {
127
242
  }
128
243
  // Update the schema catalog
129
244
  schema.addTable(updatedTableSchema);
245
+ // Snapshot pre-statement MV staleness BEFORE the notify below: the notify's
246
+ // listener marks every dependent MV stale, and the propagation must be able to
247
+ // tell that statement-local staleness (restorable after a successful rewrite)
248
+ // apart from a pre-existing flag (never cleared — only REFRESH may).
249
+ const preStaleMvs = snapshotStaleMaterializedViews(rctx.db);
130
250
  rctx.db.schemaManager.getChangeNotifier().notifyChange({
131
251
  type: 'table_modified',
132
252
  schemaName: tableSchema.schemaName,
@@ -134,13 +254,13 @@ async function runRenameColumn(rctx, tableSchema, schema, oldName, newName) {
134
254
  oldObject: tableSchema,
135
255
  newObject: updatedTableSchema,
136
256
  });
137
- // Propagate the rename into dependent objects (CHECK / FK in this and other
138
- // tables, view bodies).
139
- propagateColumnRename(rctx, tableSchema.schemaName, tableSchema.name, oldName, newName);
257
+ // Propagate the rename into dependent objects (CHECK / FK / partial-index
258
+ // predicates in this and other tables, view and materialized-view bodies).
259
+ await propagateColumnRename(rctx, tableSchema.schemaName, tableSchema.name, oldName, newName, preStaleMvs);
140
260
  log('Renamed column %s.%s.%s to %s', tableSchema.schemaName, tableSchema.name, oldName, newName);
141
261
  return null;
142
262
  }
143
- async function runAddColumn(rctx, tableSchema, schema, columnDef) {
263
+ async function runAddColumn(rctx, tableSchema, schema, columnDef, backfill, backfillCb, checks, checkCbs) {
144
264
  // Validate column doesn't already exist
145
265
  if (tableSchema.columnIndexMap.has(columnDef.name.toLowerCase())) {
146
266
  throw new QuereusError(`Column '${columnDef.name}' already exists in table '${tableSchema.name}'`, StatusCode.ERROR);
@@ -149,23 +269,21 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef) {
149
269
  if (columnDef.constraints?.some(c => c.type === 'primaryKey')) {
150
270
  throw new QuereusError(`Cannot add a PRIMARY KEY column via ALTER TABLE`, StatusCode.ERROR);
151
271
  }
152
- // Reject non-foldable DEFAULT expressions at DDL time. ADD COLUMN backfills
153
- // existing rows with the DEFAULT value, so the expression must evaluate to a
154
- // concrete literal at ALTER time. Column references, bind parameters, and
155
- // non-deterministic function calls don't fold and are rejected per the
156
- // determinism rule (consistent with CREATE TABLE's DEFAULT validation).
272
+ // The DEFAULT was validated at plan-build time through the shared DDL validator
273
+ // (bind params / bare columns / non-determinism rejected; `new.<column>` accepted)
274
+ // and, when it does not fold to a literal, compiled into `backfill` — the default
275
+ // evaluated against the existing row, so `new.<column>` reads that row's sibling.
157
276
  const defaultConstraint = columnDef.constraints?.find(c => c.type === 'default');
158
- if (defaultConstraint && defaultConstraint.expr && tryFoldLiteral(defaultConstraint.expr) === undefined) {
159
- throw new QuereusError(`ALTER TABLE ADD COLUMN DEFAULT for '${columnDef.name}' must fold to a literal — column references, bind parameters, and non-deterministic expressions are not allowed`, StatusCode.ERROR);
160
- }
161
277
  // Call module.alterTable for data + schema update
162
- const module = tableSchema.vtabModule;
278
+ const module = requireVtabModule(tableSchema);
163
279
  if (!module.alterTable) {
164
280
  throw new QuereusError(`Module for table '${tableSchema.name}' does not support ALTER TABLE ADD COLUMN`, StatusCode.UNSUPPORTED);
165
281
  }
166
282
  // NOT NULL without a usable DEFAULT cannot backfill existing rows. A DEFAULT whose
167
- // folded value is NULL is equivalent to "no DEFAULT" for this purpose. If the table
168
- // is non-empty, reject before mutating any schema or data.
283
+ // folded value is NULL is equivalent to "no DEFAULT" for this purpose. A non-foldable
284
+ // expression default (carried in `backfill`) IS usable its NOT NULL enforcement is
285
+ // deferred to the post-backfill scan — so it is not rejected here. If the table is
286
+ // non-empty and the default is nullish, reject before mutating any schema or data.
169
287
  //
170
288
  // A module may opt out of this engine-generic rejection via the
171
289
  // `delegatesNotNullBackfill` capability (structurally-total modules that
@@ -174,21 +292,107 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef) {
174
292
  // `alterTable`. Native modules leave it off, so this still fires for them.
175
293
  const delegatesBackfill = module.getCapabilities?.().delegatesNotNullBackfill === true;
176
294
  const hasNotNull = columnDef.constraints?.some(c => c.type === 'notNull') ?? false;
177
- if (hasNotNull && !delegatesBackfill) {
295
+ if (hasNotNull && !delegatesBackfill && !backfill) {
178
296
  const folded = defaultConstraint?.expr ? tryFoldLiteral(defaultConstraint.expr) : undefined;
179
- const defaultIsNullish = !defaultConstraint || folded === undefined || folded === null;
297
+ const defaultIsNullish = !defaultConstraint?.expr || folded === null;
180
298
  if (defaultIsNullish) {
181
299
  await validateNotNullBackfill(rctx, tableSchema, columnDef.name);
182
300
  }
183
301
  }
184
- // Extract column-level CHECK / FK constraints. Column-level UNIQUE is not enforced via
185
- // table-level constraints; the existing rejection path in the manager handles it.
302
+ // Extract column-level CHECK / FK constraints to merge into the engine-side schema below.
303
+ // Column-level UNIQUE is handled separately, right after the column is materialized (see
304
+ // the inline-UNIQUE block below): it routes through the module's `addConstraint` UNIQUE
305
+ // path — the same path `ALTER TABLE ADD CONSTRAINT … UNIQUE` uses — so it is materialized,
306
+ // enforced, and (for store-backed modules) persisted, symmetric with CREATE TABLE.
186
307
  const newCheckConstraints = extractColumnLevelCheckConstraints(columnDef);
187
308
  const newForeignKeys = extractColumnLevelForeignKeys(columnDef, tableSchema.schemaName);
188
- const updatedTableSchema = await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, {
189
- type: 'addColumn',
190
- columnDef,
191
- });
309
+ // A non-foldable default backfills each existing row from its own value. Install a row
310
+ // slot over the default's row descriptor; the evaluator the module calls per existing
311
+ // row sets the slot to that row, so the default's `new.<col>` refs resolve to it.
312
+ const rowSlot = backfill ? createRowSlot(rctx, backfill.rowDescriptor) : undefined;
313
+ // When the new column carries a CHECK, install a second slot over the existing columns
314
+ // plus the new column; we evaluate each predicate against `[...existingRow, value]` after
315
+ // computing the backfilled value and throw on a violation, so a CHECK-violating row aborts
316
+ // the ALTER inside the per-row hook — before any tree/batch swap — and the catalog is never
317
+ // mutated (mirrors the NOT NULL per-row path). This supersedes the post-backfill scan,
318
+ // which reads a stale pre-backfill snapshot for the evaluator path.
319
+ const checkSlot = backfill && checks ? createRowSlot(rctx, checks.rowDescriptor) : undefined;
320
+ const checkPredicates = checks?.predicates ?? [];
321
+ const backfillEvaluator = backfill && backfillCb && rowSlot
322
+ ? async (row) => {
323
+ rowSlot.set(row);
324
+ const valueRaw = backfillCb(rctx);
325
+ const value = (valueRaw instanceof Promise ? await valueRaw : valueRaw);
326
+ if (checkSlot && checkPredicates.length > 0 && checkCbs) {
327
+ checkSlot.set([...row, value]);
328
+ for (let i = 0; i < checkPredicates.length; i++) {
329
+ const resultRaw = checkCbs[i](rctx);
330
+ const result = (resultRaw instanceof Promise ? await resultRaw : resultRaw);
331
+ // CHECK passes on truthy / NULL; fails on false / 0 (matches write-time semantics).
332
+ if (result === false || result === 0) {
333
+ const pred = checkPredicates[i];
334
+ const hint = pred.exprText ? ` (${pred.exprText})` : '';
335
+ throw new QuereusError(`CHECK constraint failed: ${pred.name ?? `_check_${columnDef.name}`}${hint}`, StatusCode.CONSTRAINT);
336
+ }
337
+ }
338
+ }
339
+ return value;
340
+ }
341
+ : undefined;
342
+ // The slots are only needed while the module is appending the column (it calls the
343
+ // evaluator per existing row); close them as soon as that returns — before the CHECK
344
+ // scan below re-reads the table — so the backfill's context does not shadow the
345
+ // scan's own row context.
346
+ let updatedTableSchema;
347
+ try {
348
+ updatedTableSchema = await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, {
349
+ type: 'addColumn',
350
+ columnDef,
351
+ backfillEvaluator,
352
+ });
353
+ }
354
+ finally {
355
+ rowSlot?.close();
356
+ checkSlot?.close();
357
+ }
358
+ // Materialize + enforce any inline column-level UNIQUE(s) on the new column. CREATE TABLE
359
+ // routes inline UNIQUE through `extractUniqueConstraints`; `ALTER TABLE ADD CONSTRAINT …
360
+ // UNIQUE` routes it through `module.alterTable({ addConstraint })`. The imperative ADD
361
+ // COLUMN path reaches neither, so without this an inline UNIQUE would be silently dropped —
362
+ // never materialized, enforced, or rejected. Convert each into the equivalent table-level
363
+ // constraint over the just-added column and feed it to the same addConstraint path, so the
364
+ // module builds/reuses its covering structure, validates the existing rows (throwing
365
+ // CONSTRAINT on the first duplicate), and (store) persists. Each call returns a schema
366
+ // carrying the new column + the unique constraint (+ memory covering index); thread the
367
+ // latest forward so the CHECK/FK merge below layers naturally on top.
368
+ //
369
+ // Ordering: the column is already materialized (so it resolves in `columnIndexMap`), and the
370
+ // engine catalog is untouched until the first `schema.addTable` below. So on a UNIQUE failure
371
+ // (e.g. a literal DEFAULT that backfills the same value to ≥2 existing rows → immediate
372
+ // duplicate) we only drop the just-added column from the module and rethrow — no catalog
373
+ // restore. The module's own addConstraint already rolled back its half-built covering
374
+ // structure before throwing.
375
+ const inlineUniqueConstraints = extractColumnLevelUniqueConstraints(columnDef);
376
+ for (const uniqueConstraint of inlineUniqueConstraints) {
377
+ try {
378
+ updatedTableSchema = await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, {
379
+ type: 'addConstraint',
380
+ constraint: uniqueConstraint,
381
+ });
382
+ }
383
+ catch (err) {
384
+ try {
385
+ await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, {
386
+ type: 'dropColumn',
387
+ columnName: columnDef.name,
388
+ });
389
+ }
390
+ catch (revertErr) {
391
+ log('Failed to revert ADD COLUMN after inline UNIQUE violation: %s', revertErr.message);
392
+ }
393
+ throw err;
394
+ }
395
+ }
192
396
  // Resolve the new child column index in the freshly returned schema for any FK constraints.
193
397
  const newColIdx = updatedTableSchema.columnIndexMap.get(columnDef.name.toLowerCase());
194
398
  const resolvedForeignKeys = newColIdx !== undefined
@@ -212,12 +416,73 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef) {
212
416
  // generated-column edges form a cycle, this throws before we register the
213
417
  // new schema in the catalog.
214
418
  const enhancedTableSchema = withGeneratedColumnGraph(enhancedBase);
215
- // Register the enhanced schema BEFORE backfill validation so that SQL bound
216
- // during validation can resolve the new column.
217
- schema.addTable(enhancedTableSchema);
218
- if (newCheckConstraints.length > 0) {
419
+ // The optimizer trusts a DECLARED constraint as a proven invariant, which makes
420
+ // the existing-row validators below fold away their own work if the new constraint
421
+ // is already live:
422
+ // - A new FK seeds an inclusion dependency `child.fk parent.pk`; the FK
423
+ // validator's `not exists` anti-join folds to EmptyRelation under
424
+ // `ruleAntiJoinFkEmpty` (+ the INDs seeded at TableReferenceNode).
425
+ // - A new CHECK `<p>` seeds a domain constraint on the scan; the CHECK post-scan's
426
+ // own `where not (<p>)` folds to EmptyRelation under `ruleFilterContradiction`
427
+ // (the domain `<p>` and the predicate `not <p>` are jointly unsatisfiable).
428
+ // Either fold makes validation trust the very invariant it is checking and silently
429
+ // admit a violating row. So register the new COLUMN with only the PRE-EXISTING
430
+ // (already-proven) constraints for the validation pass, then register the full schema
431
+ // — with the new FK(s) and CHECK(s) — only once validation passes. This mirrors the
432
+ // ADD CONSTRAINT path, which validates before swapping the constraint into the live
433
+ // schema. Pre-existing constraints are kept: they held before this ALTER, so folding
434
+ // against them is sound and preserves the optimizer's reach.
435
+ const hasNewForeignKeys = resolvedForeignKeys.length > 0;
436
+ const hasNewChecks = newCheckConstraints.length > 0;
437
+ const usesIntermediateSchema = hasNewForeignKeys || hasNewChecks;
438
+ const validationSchema = usesIntermediateSchema
439
+ ? withGeneratedColumnGraph({
440
+ ...enhancedBase,
441
+ checkConstraints: updatedTableSchema.checkConstraints,
442
+ foreignKeys: updatedTableSchema.foreignKeys,
443
+ })
444
+ : enhancedTableSchema;
445
+ schema.addTable(validationSchema);
446
+ // Validate new CHECK constraints against the (already-backfilled) rows AND validate
447
+ // existing rows against any new column-level FK, reverting (drop the column + restore
448
+ // the original catalog entry) on a violation. Both run inside a single try/revert
449
+ // region so that when both a new CHECK and a new FK exist and either fails, the same
450
+ // revert path fires.
451
+ //
452
+ // CHECK is gated on `!backfill`: NOT NULL of a per-row default is enforced by the module
453
+ // during backfill (it has the values in-hand and throws before the column is committed),
454
+ // and the per-row (evaluator) default path already enforced each CHECK inside the backfill
455
+ // hook above (against the freshly-computed value, not a stale snapshot). The CHECK post-scan
456
+ // is therefore only correct for the literal-default path, whose values were bulk-written by
457
+ // the module without a per-row hook.
458
+ //
459
+ // FK runs for ALL default kinds. It is a cross-table existence check, not a per-row
460
+ // predicate, so it must be a post-`alterTable` scan: the scan sees both the bulk-written
461
+ // (literal) and per-row-evaluated backfilled values, and for a self-referential FK it reads
462
+ // a consistent post-alter table (a per-row hook would have to query the very table being
463
+ // rebuilt). It reuses `validateForeignKeyOverExistingRows` — the same MATCH-SIMPLE,
464
+ // pragma-gated validator the ADD CONSTRAINT path calls — so the two paths can never drift.
465
+ const runCheckScan = !backfill && newCheckConstraints.length > 0;
466
+ if (runCheckScan || hasNewForeignKeys) {
219
467
  try {
220
- await validateBackfillAgainstChecks(rctx, enhancedTableSchema, newCheckConstraints);
468
+ // Reject any new FK whose child/parent column collations declare a same-rank
469
+ // conflict (the conflict enforcement would raise at first DML). Pure schema
470
+ // check — no row scan, pragma-independent — but kept inside this try/revert
471
+ // region so a conflict drops the just-materialized column and restores the
472
+ // original catalog, leaving the table untouched. `enhancedTableSchema` carries
473
+ // the new column so the child FK column resolves.
474
+ for (const fk of resolvedForeignKeys) {
475
+ validateForeignKeyCollations(rctx.db, enhancedTableSchema, fk);
476
+ }
477
+ if (runCheckScan) {
478
+ await validateBackfillAgainstChecks(rctx, validationSchema, newCheckConstraints);
479
+ }
480
+ for (const fk of resolvedForeignKeys) {
481
+ // `enhancedTableSchema` supplies only column-name resolution here; the LIVE
482
+ // schema the planner reads is `validationSchema`, which omits the new FK(s)
483
+ // and CHECK(s), so the anti-join is not folded.
484
+ await validateForeignKeyOverExistingRows(rctx.db, enhancedTableSchema, fk);
485
+ }
221
486
  }
222
487
  catch (err) {
223
488
  // Revert: drop the column and restore the original catalog entry.
@@ -228,12 +493,18 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef) {
228
493
  });
229
494
  }
230
495
  catch (revertErr) {
231
- log('Failed to revert ADD COLUMN after CHECK violation: %s', revertErr.message);
496
+ log('Failed to revert ADD COLUMN after constraint violation: %s', revertErr.message);
232
497
  }
233
498
  schema.addTable(tableSchema);
234
499
  throw err;
235
500
  }
236
501
  }
502
+ // Validation passed — commit the full schema (with the new FK(s)/CHECK(s)) into the
503
+ // catalog. Skipped when no intermediate schema was used, in which case
504
+ // `validationSchema === enhancedTableSchema` is already registered.
505
+ if (usesIntermediateSchema) {
506
+ schema.addTable(enhancedTableSchema);
507
+ }
237
508
  rctx.db.schemaManager.getChangeNotifier().notifyChange({
238
509
  type: 'table_modified',
239
510
  schemaName: tableSchema.schemaName,
@@ -244,46 +515,6 @@ async function runAddColumn(rctx, tableSchema, schema, columnDef) {
244
515
  log('Added column %s to table %s.%s', columnDef.name, tableSchema.schemaName, tableSchema.name);
245
516
  return null;
246
517
  }
247
- function extractColumnLevelCheckConstraints(columnDef) {
248
- const result = [];
249
- for (const con of columnDef.constraints ?? []) {
250
- if (con.type !== 'check' || !con.expr)
251
- continue;
252
- result.push({
253
- name: con.name ?? `_check_${columnDef.name}`,
254
- expr: con.expr,
255
- operations: opsToMask(con.operations),
256
- tags: con.tags && Object.keys(con.tags).length > 0 ? Object.freeze({ ...con.tags }) : undefined,
257
- });
258
- }
259
- return result;
260
- }
261
- function extractColumnLevelForeignKeys(columnDef, defaultSchemaName) {
262
- const result = [];
263
- for (const con of columnDef.constraints ?? []) {
264
- if (con.type !== 'foreignKey' || !con.foreignKey)
265
- continue;
266
- const fk = con.foreignKey;
267
- // child column index gets resolved by caller after module.alterTable returns
268
- // the updated schema with the new column appended.
269
- if (fk.columns && fk.columns.length !== 1) {
270
- throw new QuereusError(`FK constraint '${con.name ?? `_fk_${columnDef.name}`}' on ADD COLUMN '${columnDef.name}': child column count (1) does not match parent column count (${fk.columns.length})`, StatusCode.ERROR);
271
- }
272
- result.push({
273
- name: con.name ?? `_fk_${columnDef.name}`,
274
- columns: Object.freeze([]),
275
- referencedTable: fk.table,
276
- referencedSchema: defaultSchemaName,
277
- referencedColumns: Object.freeze([]),
278
- referencedColumnNames: fk.columns,
279
- onDelete: fk.onDelete ?? 'restrict',
280
- onUpdate: fk.onUpdate ?? 'restrict',
281
- deferred: fk.initiallyDeferred ?? false,
282
- tags: con.tags && Object.keys(con.tags).length > 0 ? Object.freeze({ ...con.tags }) : undefined,
283
- });
284
- }
285
- return result;
286
- }
287
518
  /**
288
519
  * Runs each new CHECK against existing rows. We rely on the just-registered
289
520
  * enhanced schema so SQL can resolve the new column. Any row matching
@@ -352,7 +583,7 @@ async function runDropColumn(rctx, tableSchema, schema, columnName) {
352
583
  }
353
584
  }
354
585
  // Call module.alterTable for data + schema update
355
- const module = tableSchema.vtabModule;
586
+ const module = requireVtabModule(tableSchema);
356
587
  if (!module.alterTable) {
357
588
  throw new QuereusError(`Module for table '${tableSchema.name}' does not support ALTER TABLE DROP COLUMN`, StatusCode.UNSUPPORTED);
358
589
  }
@@ -375,18 +606,112 @@ async function runDropColumn(rctx, tableSchema, schema, columnName) {
375
606
  log('Dropped column %s from table %s.%s', columnName, tableSchema.schemaName, tableSchema.name);
376
607
  return null;
377
608
  }
609
+ /**
610
+ * DROP CONSTRAINT <name> — removes a named table-level constraint (CHECK / UNIQUE
611
+ * / FOREIGN KEY). Resolves the class up front (NOTFOUND / ambiguous surfaced here
612
+ * with a clear error before any module call), rejects dropping a UNIQUE constraint
613
+ * that is the synthesized side of an explicit `CREATE UNIQUE INDEX` (the index is
614
+ * the user's — `DROP INDEX` is the correct primitive), then routes the rewrite
615
+ * through `module.alterTable` so persistent modules re-persist their DDL. The
616
+ * module owns the actual array rewrite and, for a UNIQUE, tearing down the
617
+ * implicit covering index that backs it.
618
+ */
619
+ async function runDropConstraint(rctx, tableSchema, schema, constraintName) {
620
+ const constraintClass = resolveNamedConstraintClass(tableSchema, constraintName);
621
+ if (constraintClass === 'unique') {
622
+ rejectDerivedFromIndex(tableSchema, constraintName, 'DROP');
623
+ }
624
+ const module = requireVtabModule(tableSchema);
625
+ if (!module.alterTable) {
626
+ throw new QuereusError(`Module for table '${tableSchema.name}' does not support ALTER TABLE DROP CONSTRAINT`, StatusCode.UNSUPPORTED);
627
+ }
628
+ const updatedTableSchema = await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, {
629
+ type: 'dropConstraint',
630
+ constraintName,
631
+ });
632
+ schema.addTable(updatedTableSchema);
633
+ rctx.db.schemaManager.getChangeNotifier().notifyChange({
634
+ type: 'table_modified',
635
+ schemaName: tableSchema.schemaName,
636
+ objectName: tableSchema.name,
637
+ oldObject: tableSchema,
638
+ newObject: updatedTableSchema,
639
+ });
640
+ log('Dropped constraint %s from table %s.%s', constraintName, tableSchema.schemaName, tableSchema.name);
641
+ return null;
642
+ }
643
+ /**
644
+ * RENAME CONSTRAINT <old> TO <new> — name-level rename of a named table-level
645
+ * constraint. Resolves the class up front, rejects a no-op / collision (the new
646
+ * name must not already address a constraint), and rejects renaming a UNIQUE
647
+ * derived from an explicit index. Routed through `module.alterTable`.
648
+ */
649
+ async function runRenameConstraint(rctx, tableSchema, schema, oldName, newName) {
650
+ const constraintClass = resolveNamedConstraintClass(tableSchema, oldName);
651
+ if (constraintClass === 'unique') {
652
+ rejectDerivedFromIndex(tableSchema, oldName, 'RENAME');
653
+ }
654
+ // Collision: the new name must not already address an existing named constraint
655
+ // (unless it's a case-only change of the same constraint).
656
+ const oldLower = oldName.toLowerCase();
657
+ const newLower = newName.toLowerCase();
658
+ if (oldLower !== newLower && namedConstraintExists(tableSchema, newName)) {
659
+ throw new QuereusError(`Cannot rename constraint to '${newName}': a constraint with that name already exists in table '${tableSchema.name}'`, StatusCode.CONSTRAINT);
660
+ }
661
+ const module = requireVtabModule(tableSchema);
662
+ if (!module.alterTable) {
663
+ throw new QuereusError(`Module for table '${tableSchema.name}' does not support ALTER TABLE RENAME CONSTRAINT`, StatusCode.UNSUPPORTED);
664
+ }
665
+ const updatedTableSchema = await module.alterTable(rctx.db, tableSchema.schemaName, tableSchema.name, {
666
+ type: 'renameConstraint',
667
+ oldName,
668
+ newName,
669
+ });
670
+ schema.addTable(updatedTableSchema);
671
+ rctx.db.schemaManager.getChangeNotifier().notifyChange({
672
+ type: 'table_modified',
673
+ schemaName: tableSchema.schemaName,
674
+ objectName: tableSchema.name,
675
+ oldObject: tableSchema,
676
+ newObject: updatedTableSchema,
677
+ });
678
+ log('Renamed constraint %s.%s.%s to %s', tableSchema.schemaName, tableSchema.name, oldName, newName);
679
+ return null;
680
+ }
681
+ /** True when `name` addresses any named CHECK / UNIQUE / FOREIGN KEY constraint. */
682
+ function namedConstraintExists(tableSchema, name) {
683
+ const lower = name.toLowerCase();
684
+ return (tableSchema.checkConstraints ?? []).some(c => c.name?.toLowerCase() === lower)
685
+ || (tableSchema.uniqueConstraints ?? []).some(c => c.name?.toLowerCase() === lower)
686
+ || (tableSchema.foreignKeys ?? []).some(c => c.name?.toLowerCase() === lower);
687
+ }
688
+ /**
689
+ * Rejects DROP/RENAME of a UNIQUE constraint that was synthesized from an explicit
690
+ * `CREATE UNIQUE INDEX` (`derivedFromIndex` set). That constraint is the index's
691
+ * shadow — dropping/renaming it alone would strand the index, so the user must
692
+ * operate on the index (`DROP INDEX`) instead.
693
+ */
694
+ function rejectDerivedFromIndex(tableSchema, constraintName, op) {
695
+ const lower = constraintName.toLowerCase();
696
+ const uc = (tableSchema.uniqueConstraints ?? []).find(c => c.name?.toLowerCase() === lower);
697
+ if (uc?.derivedFromIndex) {
698
+ 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);
699
+ }
700
+ }
378
701
  async function runAlterColumn(rctx, tableSchema, schema, action) {
379
702
  const colIndex = tableSchema.columnIndexMap.get(action.columnName.toLowerCase());
380
703
  if (colIndex === undefined) {
381
704
  throw new QuereusError(`Column '${action.columnName}' not found in table '${tableSchema.name}'`, StatusCode.ERROR);
382
705
  }
383
- // Guard: at most one of the three attribute changes per statement.
384
- const populated = [action.setNotNull !== undefined, action.setDataType !== undefined, action.setDefault !== undefined];
706
+ // Guard: at most one of the four attribute changes per statement.
707
+ const populated = [action.setNotNull !== undefined, action.setDataType !== undefined, action.setDefault !== undefined, action.setCollation !== undefined];
385
708
  const populatedCount = populated.filter(Boolean).length;
386
709
  if (populatedCount !== 1) {
387
- throw new QuereusError(`ALTER COLUMN requires exactly one of SET/DROP NOT NULL, SET DATA TYPE, SET/DROP DEFAULT (got ${populatedCount})`, StatusCode.INTERNAL);
710
+ throw new QuereusError(`ALTER COLUMN requires exactly one of SET/DROP NOT NULL, SET DATA TYPE, SET/DROP DEFAULT, SET COLLATE (got ${populatedCount})`, StatusCode.INTERNAL);
388
711
  }
389
- // Cannot alter a PRIMARY KEY column's nullability or data type.
712
+ // Cannot alter a PRIMARY KEY column's nullability or data type. (SET COLLATE on
713
+ // a PK column IS permitted — the module re-keys the primary structure under the
714
+ // new collation; see runAlterColumn module contract.)
390
715
  if (tableSchema.primaryKeyDefinition.some(def => def.index === colIndex)) {
391
716
  if (action.setNotNull === false) {
392
717
  throw new QuereusError(`Cannot DROP NOT NULL on PRIMARY KEY column '${action.columnName}'`, StatusCode.CONSTRAINT);
@@ -395,7 +720,21 @@ async function runAlterColumn(rctx, tableSchema, schema, action) {
395
720
  throw new QuereusError(`Cannot SET DATA TYPE on PRIMARY KEY column '${action.columnName}'`, StatusCode.CONSTRAINT);
396
721
  }
397
722
  }
398
- const module = tableSchema.vtabModule;
723
+ // SET COLLATE: validate the collation against the column's logical type up front
724
+ // (same error shape as CREATE TABLE), so an unknown collation is rejected before
725
+ // any module round-trip / re-sort. The module re-normalizes and applies it.
726
+ if (action.setCollation !== undefined) {
727
+ validateCollationForType(action.setCollation, tableSchema.columns[colIndex].logicalType, action.columnName);
728
+ }
729
+ // Route a SET DEFAULT through the same DDL validator CREATE TABLE uses, so the
730
+ // stored default is consistent with what INSERT will accept: bind params / bare
731
+ // columns / non-determinism rejected, `new.<column>` accepted (deferred to INSERT
732
+ // time). DROP DEFAULT (`setDefault === null`) needs no validation.
733
+ if (action.setDefault !== undefined && action.setDefault !== null) {
734
+ const hasMutationContext = !!tableSchema.mutationContext && tableSchema.mutationContext.length > 0;
735
+ rctx.db.schemaManager.validateAlterColumnDefault(action.setDefault, action.columnName, tableSchema.name, hasMutationContext);
736
+ }
737
+ const module = requireVtabModule(tableSchema);
399
738
  if (!module.alterTable) {
400
739
  throw new QuereusError(`Module for table '${tableSchema.name}' does not support ALTER COLUMN`, StatusCode.UNSUPPORTED);
401
740
  }
@@ -405,6 +744,7 @@ async function runAlterColumn(rctx, tableSchema, schema, action) {
405
744
  setNotNull: action.setNotNull,
406
745
  setDataType: action.setDataType,
407
746
  setDefault: action.setDefault,
747
+ setCollation: action.setCollation,
408
748
  });
409
749
  schema.addTable(updatedTableSchema);
410
750
  rctx.db.schemaManager.getChangeNotifier().notifyChange({
@@ -417,6 +757,73 @@ async function runAlterColumn(rctx, tableSchema, schema, action) {
417
757
  log('Altered column %s.%s.%s', tableSchema.schemaName, tableSchema.name, action.columnName);
418
758
  return null;
419
759
  }
760
+ /**
761
+ * Catalog-only metadata-tag mutations. Tags touch no stored row and no physical
762
+ * layout, so these never call `module.alterTable` — they delegate to the
763
+ * SchemaManager setters, which swap the in-memory schema and fire `table_modified`
764
+ * (so optimizer caches invalidate). This makes SET TAGS succeed even on modules
765
+ * without an `alterTable` hook.
766
+ *
767
+ * NOTE: store-backed modules persist DDL from their own `alterTable`, which this
768
+ * path deliberately bypasses. The generic store module recovers the tag change by
769
+ * subscribing to these `table_modified` events and re-writing its catalog DDL, so
770
+ * table / column / named-constraint tag swaps now survive reconnect for store
771
+ * tables (index and view/MV tag persistence is still pending — see backlog tickets
772
+ * `store-secondary-index-persistence` / `store-view-mv-persistence`).
773
+ */
774
+ function runSetTableTags(rctx, tableSchema, tags) {
775
+ rctx.db.schemaManager.setTableTags(tableSchema.name, tags, tableSchema.schemaName);
776
+ log('Set tags on table %s.%s', tableSchema.schemaName, tableSchema.name);
777
+ return null;
778
+ }
779
+ function runSetColumnTags(rctx, tableSchema, columnName, tags) {
780
+ rctx.db.schemaManager.setColumnTags(tableSchema.name, columnName, tags, tableSchema.schemaName);
781
+ log('Set tags on column %s.%s.%s', tableSchema.schemaName, tableSchema.name, columnName);
782
+ return null;
783
+ }
784
+ function runSetConstraintTags(rctx, tableSchema, constraintName, tags) {
785
+ rctx.db.schemaManager.setConstraintTags(tableSchema.name, constraintName, tags, tableSchema.schemaName);
786
+ log('Set tags on constraint %s.%s.%s', tableSchema.schemaName, tableSchema.name, constraintName);
787
+ return null;
788
+ }
789
+ // ── ADD TAGS (per-key merge) ──
790
+ // Each delegates to the matching SchemaManager merge setter, which reads the
791
+ // table's *live* tags at execution time (not the plan-time snapshot), so a
792
+ // prepared/reused ADD TAGS or back-to-back ALTERs compose onto the prior result.
793
+ function runMergeTableTags(rctx, tableSchema, tags) {
794
+ rctx.db.schemaManager.mergeTableTags(tableSchema.name, tags, tableSchema.schemaName);
795
+ log('Merged tags on table %s.%s', tableSchema.schemaName, tableSchema.name);
796
+ return null;
797
+ }
798
+ function runMergeColumnTags(rctx, tableSchema, columnName, tags) {
799
+ rctx.db.schemaManager.mergeColumnTags(tableSchema.name, columnName, tags, tableSchema.schemaName);
800
+ log('Merged tags on column %s.%s.%s', tableSchema.schemaName, tableSchema.name, columnName);
801
+ return null;
802
+ }
803
+ function runMergeConstraintTags(rctx, tableSchema, constraintName, tags) {
804
+ rctx.db.schemaManager.mergeConstraintTags(tableSchema.name, constraintName, tags, tableSchema.schemaName);
805
+ log('Merged tags on constraint %s.%s.%s', tableSchema.schemaName, tableSchema.name, constraintName);
806
+ return null;
807
+ }
808
+ // ── DROP TAGS (per-key delete) ──
809
+ // Each delegates to the matching SchemaManager drop setter, which validates that
810
+ // every listed key is present (atomic NOTFOUND) before mutating, again against the
811
+ // live tags at execution time.
812
+ function runDropTableTags(rctx, tableSchema, keys) {
813
+ rctx.db.schemaManager.dropTableTags(tableSchema.name, keys, tableSchema.schemaName);
814
+ log('Dropped tags on table %s.%s', tableSchema.schemaName, tableSchema.name);
815
+ return null;
816
+ }
817
+ function runDropColumnTags(rctx, tableSchema, columnName, keys) {
818
+ rctx.db.schemaManager.dropColumnTags(tableSchema.name, columnName, keys, tableSchema.schemaName);
819
+ log('Dropped tags on column %s.%s.%s', tableSchema.schemaName, tableSchema.name, columnName);
820
+ return null;
821
+ }
822
+ function runDropConstraintTags(rctx, tableSchema, constraintName, keys) {
823
+ rctx.db.schemaManager.dropConstraintTags(tableSchema.name, constraintName, keys, tableSchema.schemaName);
824
+ log('Dropped tags on constraint %s.%s.%s', tableSchema.schemaName, tableSchema.name, constraintName);
825
+ return null;
826
+ }
420
827
  async function runAlterPrimaryKey(rctx, tableSchema, schema, columns) {
421
828
  const newPkDef = columns.map(col => {
422
829
  const idx = tableSchema.columnIndexMap.get(col.name.toLowerCase());
@@ -438,7 +845,7 @@ async function runAlterPrimaryKey(rctx, tableSchema, schema, columns) {
438
845
  seen.add(pk.index);
439
846
  }
440
847
  // Try native module re-key first
441
- const module = tableSchema.vtabModule;
848
+ const module = requireVtabModule(tableSchema);
442
849
  if (module.alterTable) {
443
850
  try {
444
851
  const schemaChangePk = newPkDef.map(pk => ({ index: pk.index, desc: pk.desc ?? false }));
@@ -477,7 +884,7 @@ async function runAlterPrimaryKey(rctx, tableSchema, schema, columns) {
477
884
  async function rebuildTableWithNewShape(rctx, tableSchema, schema, survivingColumns, newPkDef) {
478
885
  const tableName = tableSchema.name;
479
886
  const schemaName = tableSchema.schemaName;
480
- const module = tableSchema.vtabModule;
887
+ const module = requireVtabModule(tableSchema);
481
888
  if (module instanceof MemoryTableModule) {
482
889
  await rebuildMemoryTable(rctx, tableSchema, schema, module, survivingColumns, newPkDef);
483
890
  }
@@ -556,6 +963,16 @@ async function rebuildMemoryTable(rctx, tableSchema, schema, module, survivingCo
556
963
  // Update catalog
557
964
  schema.removeTable(tableName);
558
965
  schema.addTable(shadowMgr.tableSchema);
966
+ // The old manager is now orphaned. Any active VirtualTableConnection bound
967
+ // to it (e.g. from a prior insert in this session) is stale and must not be
968
+ // reused against the rebuilt table — a reused-stale + fresh connection pair
969
+ // leaves two candidates registered for the same table name, which trips
970
+ // DeferredConstraintQueue.findConnection at the next commit. Mirror the
971
+ // drop-table path's cleanup (schema/manager.ts dropTable). The orphaned
972
+ // manager and its pending layer are discarded with the old manager, so no
973
+ // rollback is needed; this intentionally bypasses implicit-transaction
974
+ // deferral, exactly as drop table relies on.
975
+ rctx.db.removeConnectionsForTable(schemaName, tableName);
559
976
  }
560
977
  catch (e) {
561
978
  // Clean up shadow on failure
@@ -613,6 +1030,64 @@ export function buildShadowTableDdl(tableSchema, shadowName, survivingColumns, n
613
1030
  }
614
1031
  return createDdl;
615
1032
  }
1033
+ /**
1034
+ * SET MAINTAINED [(cols)] AS <body> — attach a derivation to a plain table, or
1035
+ * atomically replace an already-maintained table's derivation (the differ's
1036
+ * body-change primitive). All gates, the verify-by-diff reconcile, the
1037
+ * catalog/registration flip, the consumer cascade, and the lifecycle event
1038
+ * (`materialized_view_added` on fresh attach, `materialized_view_modified` on
1039
+ * re-attach) live in the shared {@link attachMaintainedDerivation} core.
1040
+ * Resolved against the LIVE table (the build-time schema may be a cached
1041
+ * statement's snapshot).
1042
+ *
1043
+ * The optional `columns` rename list selects the attach mode:
1044
+ * - present ⇒ EXPLICIT: the body outputs are renamed positionally to it, the
1045
+ * list is recorded as `derivation.columns`, and a same-arity name drift
1046
+ * reshapes (renames) the backing in place to the listed names — the differ's
1047
+ * lossless re-attach of an MV-sugar `(a, c)` rename;
1048
+ * - absent ⇒ IMPLICIT: the body's natural names are recorded (undefined), and a
1049
+ * differing derived shape reshapes the backing to follow the body — now also
1050
+ * over a prior-explicit record (the deliberate "go implicit" re-attach).
1051
+ * Both pass `allowReshape` (the verb is the reshape-permitting path; create stays
1052
+ * strict).
1053
+ */
1054
+ async function runSetMaintained(rctx, tableSchema, schema, columns, select) {
1055
+ const live = schema.getTable(tableSchema.name);
1056
+ if (!live) {
1057
+ throw new QuereusError(`no such table: ${tableSchema.name}`, StatusCode.ERROR);
1058
+ }
1059
+ const explicit = columns !== undefined && columns.length > 0;
1060
+ // Any omitted-insert defaults ride inside `select` (→ derivation.selectAst).
1061
+ await attachMaintainedDerivation(rctx.db, live, select,
1062
+ /*recordedColumns*/ explicit ? columns : undefined,
1063
+ /*positionalRename*/ explicit, /*allowReshape*/ true,
1064
+ /*discardBackingOnFailure*/ true);
1065
+ log('Attached derivation to table %s.%s', live.schemaName, live.name);
1066
+ return null;
1067
+ }
1068
+ /**
1069
+ * DROP MAINTAINED — detach the table's derivation (see
1070
+ * {@link detachMaintainedDerivation}: catalog-only, rows intact, maintenance
1071
+ * stops, the table becomes ordinary and user-writable). Allowed on a STALE
1072
+ * maintained table too — the flag leaves with the derivation. Resolved against
1073
+ * the LIVE table.
1074
+ */
1075
+ async function runDropMaintained(rctx, tableSchema, schema) {
1076
+ const live = schema.getTable(tableSchema.name);
1077
+ if (!live || !isMaintainedTable(live)) {
1078
+ throw new QuereusError(`cannot drop maintained on '${tableSchema.name}': it is not a maintained table`, StatusCode.ERROR);
1079
+ }
1080
+ const plain = detachMaintainedDerivation(rctx.db, live);
1081
+ // Retire the durable backing store the attach materialized, migrating its
1082
+ // rows back into ordinary storage so the detached table stays readable and
1083
+ // user-writable. `detachMaintainedDerivation` stays SYNC (catalog-only); the
1084
+ // async store retirement rides here, in its sole caller. A no-op for modules
1085
+ // that omit the hook (memory detaches catalog-only — one physical storage).
1086
+ const module = requireVtabModule(live);
1087
+ await module.retireBackingForAttach?.(rctx.db, plain.schemaName, plain.name, plain);
1088
+ log('Detached derivation from table %s.%s', live.schemaName, live.name);
1089
+ return null;
1090
+ }
616
1091
  /**
617
1092
  * Generic rebuild via shadow table SQL for non-memory modules.
618
1093
  */
@@ -640,18 +1115,23 @@ async function rebuildViaShadowTable(rctx, tableSchema, schema, survivingColumns
640
1115
  }
641
1116
  /**
642
1117
  * Propagates a table rename into every dependent schema object the catalog
643
- * knows about: CHECK expressions, FK references, and view bodies. Walks every
644
- * schema (not just the renamed table's home schema) so cross-schema FK
645
- * references are picked up. View `selectAst` is mutated in place because the
646
- * planner re-walks it on every reference.
1118
+ * knows about: CHECK expressions, FK references, partial-index predicates,
1119
+ * view bodies, and materialized-view bodies. Walks every schema (not just the
1120
+ * renamed table's home schema) so cross-schema FK references are picked up.
1121
+ * View `selectAst` is mutated in place because the planner re-walks it on
1122
+ * every reference.
647
1123
  */
648
- function propagateTableRename(rctx, renamedSchemaName, oldName, newName) {
649
- const notifier = rctx.db.schemaManager.getChangeNotifier();
1124
+ async function propagateTableRename(rctx, renamedSchemaName, oldName, newName, preStaleMvs) {
650
1125
  for (const schema of rctx.db.schemaManager._getAllSchemas()) {
651
- propagateTableRenameInSchema(schema, renamedSchemaName, oldName, newName, notifier);
1126
+ await propagateTableRenameInSchema(rctx.db, schema, renamedSchemaName, oldName, newName, preStaleMvs);
652
1127
  }
1128
+ // After all per-schema rewrites and their cascade events: restore any MV this
1129
+ // statement's events marked stale that the rename provably did not affect
1130
+ // (e.g. a dependent of another source whose only change was an FK rewrite).
1131
+ await restoreUnaffectedMaterializedViews(rctx.db, preStaleMvs);
653
1132
  }
654
- function propagateTableRenameInSchema(schema, renamedSchemaName, oldName, newName, notifier) {
1133
+ async function propagateTableRenameInSchema(db, schema, renamedSchemaName, oldName, newName, preStaleMvs) {
1134
+ const notifier = db.schemaManager.getChangeNotifier();
655
1135
  const renamedSchemaLower = renamedSchemaName.toLowerCase();
656
1136
  for (const table of Array.from(schema.getAllTables())) {
657
1137
  // Skip the just-renamed table when iterating the home schema; the FK
@@ -671,12 +1151,33 @@ function propagateTableRenameInSchema(schema, renamedSchemaName, oldName, newNam
671
1151
  }
672
1152
  if (schema.name.toLowerCase() === renamedSchemaLower) {
673
1153
  for (const view of Array.from(schema.getAllViews())) {
674
- const changed = renameTableInAst(view.selectAst, oldName, newName, renamedSchemaName);
675
- if (changed) {
676
- const updatedView = { ...view, sql: selectToString(view.selectAst) };
1154
+ // The body walk also descends the trailing `with defaults (…)` clause
1155
+ // (now stored on `selectAst.defaults`), so a clause-only rewrite — a
1156
+ // defaults-expr subquery referencing the renamed table even when the body
1157
+ // never names it — flips `bodyChanged` and fires the (single) view_modified.
1158
+ const bodyChanged = renameTableInAst(view.selectAst, oldName, newName, renamedSchemaName);
1159
+ if (bodyChanged) {
1160
+ const updatedView = { ...view, sql: astToString(view.selectAst) };
677
1161
  schema.addView(updatedView);
1162
+ // The rewriter mutated `view.selectAst` (including its defaults clause) in
1163
+ // place, so `oldObject` shares the rewritten AST (only `newObject.sql`
1164
+ // differs). No consumer reads `oldObject.selectAst`; mirrors the table
1165
+ // loop above (no clone).
1166
+ notifier.notifyChange({
1167
+ type: 'view_modified',
1168
+ schemaName: schema.name,
1169
+ objectName: updatedView.name,
1170
+ oldObject: view,
1171
+ newObject: updatedView,
1172
+ });
678
1173
  }
679
1174
  }
1175
+ // Materialized views: same in-place body rewrite as plain views ("MV ≡
1176
+ // faster view"), plus the derived-field re-key, row-time re-registration,
1177
+ // and staleness discipline the MV record needs. Runs AFTER the view loop
1178
+ // so a body reading the renamed table through a view re-plans against the
1179
+ // already-rewritten view.
1180
+ await propagateTableRenameToMaterializedViews(db, schema, renamedSchemaName, oldName, newName, preStaleMvs);
680
1181
  }
681
1182
  }
682
1183
  function rewriteTableForTableRename(table, renamedSchemaLower, oldName, newName) {
@@ -698,27 +1199,43 @@ function rewriteTableForTableRename(table, renamedSchemaLower, oldName, newName)
698
1199
  changed = true;
699
1200
  return { ...fk, referencedTable: newName };
700
1201
  });
1202
+ // Partial-index predicates: the AST is mutated in place, so the derived
1203
+ // UNIQUE constraint of a unique partial index (which shares the predicate
1204
+ // by reference — see appendIndexToTableSchema) is rewritten with it.
1205
+ const newIndexes = (table.indexes ?? []).map(idx => {
1206
+ const rewrote = renameTableInAst(idx.predicate, oldName, newName, renamedSchemaLower);
1207
+ if (!rewrote)
1208
+ return idx;
1209
+ changed = true;
1210
+ return { ...idx };
1211
+ });
701
1212
  if (!changed)
702
1213
  return table;
703
1214
  return Object.freeze({
704
1215
  ...table,
705
1216
  checkConstraints: Object.freeze(newChecks),
706
1217
  foreignKeys: table.foreignKeys ? Object.freeze(newFks) : table.foreignKeys,
1218
+ indexes: table.indexes ? Object.freeze(newIndexes) : table.indexes,
707
1219
  });
708
1220
  }
709
- function propagateColumnRename(rctx, renamedSchemaName, tableName, oldCol, newCol) {
1221
+ async function propagateColumnRename(rctx, renamedSchemaName, tableName, oldCol, newCol, preStaleMvs) {
710
1222
  const schemaManager = rctx.db.schemaManager;
711
- const notifier = schemaManager.getChangeNotifier();
712
1223
  const resolveColumnInSource = (s, t, col) => {
713
1224
  const targetSchema = schemaManager.getSchema(s);
714
1225
  const targetTable = targetSchema?.getTable(t);
715
1226
  return targetTable?.columnIndexMap.has(col.toLowerCase()) ?? false;
716
1227
  };
717
1228
  for (const schema of schemaManager._getAllSchemas()) {
718
- propagateColumnRenameInSchema(schema, renamedSchemaName, tableName, oldCol, newCol, notifier, resolveColumnInSource);
1229
+ await propagateColumnRenameInSchema(rctx.db, schema, renamedSchemaName, tableName, oldCol, newCol, resolveColumnInSource, preStaleMvs);
719
1230
  }
1231
+ // After all per-schema rewrites and their cascade events: restore any MV this
1232
+ // statement's events marked stale that the rename provably did not affect — a
1233
+ // body that never names the renamed column, or a `select *` body whose output
1234
+ // is a pure name shift (carried onto the live backing by the pass).
1235
+ await restoreUnaffectedMaterializedViews(rctx.db, preStaleMvs);
720
1236
  }
721
- function propagateColumnRenameInSchema(schema, renamedSchemaName, tableName, oldCol, newCol, notifier, resolveColumnInSource) {
1237
+ async function propagateColumnRenameInSchema(db, schema, renamedSchemaName, tableName, oldCol, newCol, resolveColumnInSource, preStaleMvs) {
1238
+ const notifier = db.schemaManager.getChangeNotifier();
722
1239
  const renamedSchemaLower = renamedSchemaName.toLowerCase();
723
1240
  for (const table of Array.from(schema.getAllTables())) {
724
1241
  const updated = rewriteTableForColumnRename(table, renamedSchemaLower, tableName, oldCol, newCol, resolveColumnInSource);
@@ -735,12 +1252,37 @@ function propagateColumnRenameInSchema(schema, renamedSchemaName, tableName, old
735
1252
  }
736
1253
  if (schema.name.toLowerCase() === renamedSchemaLower) {
737
1254
  for (const view of Array.from(schema.getAllViews())) {
738
- const changed = renameColumnInAst(view.selectAst, tableName, oldCol, newCol, renamedSchemaName);
739
- if (changed) {
740
- const updatedView = { ...view, sql: selectToString(view.selectAst) };
1255
+ // The body walk also descends the trailing `with defaults (…)` clause (now
1256
+ // on `selectAst.defaults`): the entry `column` (a base column of the view's
1257
+ // FROM table, usually projected away) rewrites via the same scope-aware
1258
+ // synthetic probe as a `with inverse` target, and the entry exprs rewrite in
1259
+ // the FROM frame — so a clause-only change flips `bodyChanged`. The live
1260
+ // `resolveColumnInSource` keeps the walk scope-aware so an unqualified ref
1261
+ // inside a defaults-expr subquery that binds a like-named column on its own
1262
+ // FROM is not false-captured (the differ's inverse reconcile passes the
1263
+ // declared-side resolver for parity).
1264
+ const bodyChanged = renameColumnInAst(view.selectAst, tableName, oldCol, newCol, renamedSchemaName, resolveColumnInSource);
1265
+ if (bodyChanged) {
1266
+ const updatedView = { ...view, sql: astToString(view.selectAst) };
741
1267
  schema.addView(updatedView);
1268
+ // The rewriter mutated `view.selectAst` (including its defaults clause) in
1269
+ // place, so `oldObject` shares the rewritten AST (only `sql` differs). No
1270
+ // consumer reads `oldObject.selectAst`; mirrors the table loop above (no clone).
1271
+ notifier.notifyChange({
1272
+ type: 'view_modified',
1273
+ schemaName: schema.name,
1274
+ objectName: updatedView.name,
1275
+ oldObject: view,
1276
+ newObject: updatedView,
1277
+ });
742
1278
  }
743
1279
  }
1280
+ // Materialized views: same in-place body rewrite as plain views, then the
1281
+ // MV-specific tail — backing-column rename for a shifted output name,
1282
+ // row-time re-registration, staleness discipline (the listener marked every
1283
+ // dependent MV stale during the rename's notify; only statement-local
1284
+ // staleness is cleared, per the pre-statement snapshot).
1285
+ await propagateColumnRenameToMaterializedViews(db, schema, renamedSchemaName, tableName, oldCol, newCol, preStaleMvs, resolveColumnInSource);
744
1286
  }
745
1287
  }
746
1288
  function rewriteTableForColumnRename(table, renamedSchemaLower, tableName, oldCol, newCol, resolveColumnInSource) {
@@ -779,12 +1321,26 @@ function rewriteTableForColumnRename(table, renamedSchemaLower, tableName, oldCo
779
1321
  changed = true;
780
1322
  return { ...fk, referencedColumnNames: Object.freeze(newRefNames) };
781
1323
  });
1324
+ // Partial-index predicates resolve unqualified refs against the indexed
1325
+ // table, the same implicit seed CHECK expressions use. As with checks, the
1326
+ // AST is mutated in place, so the derived UNIQUE constraint of a unique
1327
+ // partial index (sharing the predicate by reference) is rewritten with it.
1328
+ const newIndexes = (table.indexes ?? []).map(idx => {
1329
+ const rewrote = isRenamedTable
1330
+ ? renameColumnInCheckExpression(idx.predicate, tableName, oldCol, newCol, renamedSchemaLower, resolveColumnInSource)
1331
+ : renameColumnInAst(idx.predicate, tableName, oldCol, newCol, renamedSchemaLower);
1332
+ if (!rewrote)
1333
+ return idx;
1334
+ changed = true;
1335
+ return { ...idx };
1336
+ });
782
1337
  if (!changed)
783
1338
  return table;
784
1339
  return Object.freeze({
785
1340
  ...table,
786
1341
  checkConstraints: Object.freeze(newChecks),
787
1342
  foreignKeys: table.foreignKeys ? Object.freeze(newFks) : table.foreignKeys,
1343
+ indexes: table.indexes ? Object.freeze(newIndexes) : table.indexes,
788
1344
  });
789
1345
  }
790
1346
  /**