@quereus/quereus 3.2.1 → 4.0.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 (935) 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 -106
  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 +203 -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 +795 -120
  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 +713 -26
  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 +9 -0
  80. package/dist/src/func/registration.d.ts.map +1 -1
  81. package/dist/src/func/registration.js +4 -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 +277 -8
  98. package/dist/src/parser/parser.d.ts.map +1 -1
  99. package/dist/src/parser/parser.js +1393 -471
  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/binding-extractor.d.ts.map +1 -1
  115. package/dist/src/planner/analysis/binding-extractor.js +9 -6
  116. package/dist/src/planner/analysis/binding-extractor.js.map +1 -1
  117. package/dist/src/planner/analysis/change-scope.d.ts +34 -4
  118. package/dist/src/planner/analysis/change-scope.d.ts.map +1 -1
  119. package/dist/src/planner/analysis/change-scope.js +115 -7
  120. package/dist/src/planner/analysis/change-scope.js.map +1 -1
  121. package/dist/src/planner/analysis/check-extraction.d.ts +36 -2
  122. package/dist/src/planner/analysis/check-extraction.d.ts.map +1 -1
  123. package/dist/src/planner/analysis/check-extraction.js +174 -46
  124. package/dist/src/planner/analysis/check-extraction.js.map +1 -1
  125. package/dist/src/planner/analysis/coarsened-key.d.ts +109 -0
  126. package/dist/src/planner/analysis/coarsened-key.d.ts.map +1 -0
  127. package/dist/src/planner/analysis/coarsened-key.js +228 -0
  128. package/dist/src/planner/analysis/coarsened-key.js.map +1 -0
  129. package/dist/src/planner/analysis/comparison-collation.d.ts +216 -0
  130. package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -0
  131. package/dist/src/planner/analysis/comparison-collation.js +341 -0
  132. package/dist/src/planner/analysis/comparison-collation.js.map +1 -0
  133. package/dist/src/planner/analysis/constraint-extractor.d.ts +13 -1
  134. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
  135. package/dist/src/planner/analysis/constraint-extractor.js +220 -21
  136. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
  137. package/dist/src/planner/analysis/coverage-prover.d.ts +321 -0
  138. package/dist/src/planner/analysis/coverage-prover.d.ts.map +1 -0
  139. package/dist/src/planner/analysis/coverage-prover.js +1038 -0
  140. package/dist/src/planner/analysis/coverage-prover.js.map +1 -0
  141. package/dist/src/planner/analysis/key-filter.d.ts +22 -0
  142. package/dist/src/planner/analysis/key-filter.d.ts.map +1 -0
  143. package/dist/src/planner/analysis/key-filter.js +105 -0
  144. package/dist/src/planner/analysis/key-filter.js.map +1 -0
  145. package/dist/src/planner/analysis/partial-unique-extraction.d.ts +36 -1
  146. package/dist/src/planner/analysis/partial-unique-extraction.d.ts.map +1 -1
  147. package/dist/src/planner/analysis/partial-unique-extraction.js +148 -22
  148. package/dist/src/planner/analysis/partial-unique-extraction.js.map +1 -1
  149. package/dist/src/planner/analysis/predicate-normalizer.d.ts.map +1 -1
  150. package/dist/src/planner/analysis/predicate-normalizer.js +30 -1
  151. package/dist/src/planner/analysis/predicate-normalizer.js.map +1 -1
  152. package/dist/src/planner/analysis/predicate-shape.d.ts +36 -1
  153. package/dist/src/planner/analysis/predicate-shape.d.ts.map +1 -1
  154. package/dist/src/planner/analysis/predicate-shape.js +51 -13
  155. package/dist/src/planner/analysis/predicate-shape.js.map +1 -1
  156. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts +314 -0
  157. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts.map +1 -0
  158. package/dist/src/planner/analysis/query-rewrite-matcher.js +1081 -0
  159. package/dist/src/planner/analysis/query-rewrite-matcher.js.map +1 -0
  160. package/dist/src/planner/analysis/scalar-invertibility.d.ts +92 -0
  161. package/dist/src/planner/analysis/scalar-invertibility.d.ts.map +1 -0
  162. package/dist/src/planner/analysis/scalar-invertibility.js +129 -0
  163. package/dist/src/planner/analysis/scalar-invertibility.js.map +1 -0
  164. package/dist/src/planner/analysis/update-lineage.d.ts +196 -0
  165. package/dist/src/planner/analysis/update-lineage.d.ts.map +1 -0
  166. package/dist/src/planner/analysis/update-lineage.js +322 -0
  167. package/dist/src/planner/analysis/update-lineage.js.map +1 -0
  168. package/dist/src/planner/analysis/view-complement.d.ts +42 -0
  169. package/dist/src/planner/analysis/view-complement.d.ts.map +1 -0
  170. package/dist/src/planner/analysis/view-complement.js +54 -0
  171. package/dist/src/planner/analysis/view-complement.js.map +1 -0
  172. package/dist/src/planner/building/alter-table.d.ts +1 -1
  173. package/dist/src/planner/building/alter-table.d.ts.map +1 -1
  174. package/dist/src/planner/building/alter-table.js +211 -2
  175. package/dist/src/planner/building/alter-table.js.map +1 -1
  176. package/dist/src/planner/building/block.d.ts.map +1 -1
  177. package/dist/src/planner/building/block.js +18 -1
  178. package/dist/src/planner/building/block.js.map +1 -1
  179. package/dist/src/planner/building/constraint-builder.d.ts +33 -5
  180. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
  181. package/dist/src/planner/building/constraint-builder.js +63 -28
  182. package/dist/src/planner/building/constraint-builder.js.map +1 -1
  183. package/dist/src/planner/building/create-view.d.ts +9 -0
  184. package/dist/src/planner/building/create-view.d.ts.map +1 -1
  185. package/dist/src/planner/building/create-view.js +41 -12
  186. package/dist/src/planner/building/create-view.js.map +1 -1
  187. package/dist/src/planner/building/ddl.d.ts.map +1 -1
  188. package/dist/src/planner/building/ddl.js +94 -0
  189. package/dist/src/planner/building/ddl.js.map +1 -1
  190. package/dist/src/planner/building/declare-schema.d.ts +1 -0
  191. package/dist/src/planner/building/declare-schema.d.ts.map +1 -1
  192. package/dist/src/planner/building/declare-schema.js +4 -1
  193. package/dist/src/planner/building/declare-schema.js.map +1 -1
  194. package/dist/src/planner/building/default-scope.d.ts +26 -0
  195. package/dist/src/planner/building/default-scope.d.ts.map +1 -0
  196. package/dist/src/planner/building/default-scope.js +41 -0
  197. package/dist/src/planner/building/default-scope.js.map +1 -0
  198. package/dist/src/planner/building/delete.d.ts +19 -1
  199. package/dist/src/planner/building/delete.d.ts.map +1 -1
  200. package/dist/src/planner/building/delete.js +116 -34
  201. package/dist/src/planner/building/delete.js.map +1 -1
  202. package/dist/src/planner/building/dml-target.d.ts +118 -0
  203. package/dist/src/planner/building/dml-target.d.ts.map +1 -0
  204. package/dist/src/planner/building/dml-target.js +282 -0
  205. package/dist/src/planner/building/dml-target.js.map +1 -0
  206. package/dist/src/planner/building/drop-index.d.ts.map +1 -1
  207. package/dist/src/planner/building/drop-index.js +4 -1
  208. package/dist/src/planner/building/drop-index.js.map +1 -1
  209. package/dist/src/planner/building/drop-view.d.ts.map +1 -1
  210. package/dist/src/planner/building/drop-view.js +4 -2
  211. package/dist/src/planner/building/drop-view.js.map +1 -1
  212. package/dist/src/planner/building/expression.d.ts.map +1 -1
  213. package/dist/src/planner/building/expression.js +60 -21
  214. package/dist/src/planner/building/expression.js.map +1 -1
  215. package/dist/src/planner/building/foreign-key-builder.d.ts +30 -0
  216. package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -1
  217. package/dist/src/planner/building/foreign-key-builder.js +160 -129
  218. package/dist/src/planner/building/foreign-key-builder.js.map +1 -1
  219. package/dist/src/planner/building/insert.d.ts +45 -2
  220. package/dist/src/planner/building/insert.d.ts.map +1 -1
  221. package/dist/src/planner/building/insert.js +257 -88
  222. package/dist/src/planner/building/insert.js.map +1 -1
  223. package/dist/src/planner/building/lens-auxiliary-access.d.ts +22 -0
  224. package/dist/src/planner/building/lens-auxiliary-access.d.ts.map +1 -0
  225. package/dist/src/planner/building/lens-auxiliary-access.js +132 -0
  226. package/dist/src/planner/building/lens-auxiliary-access.js.map +1 -0
  227. package/dist/src/planner/building/materialized-view.d.ts +16 -0
  228. package/dist/src/planner/building/materialized-view.d.ts.map +1 -0
  229. package/dist/src/planner/building/materialized-view.js +57 -0
  230. package/dist/src/planner/building/materialized-view.js.map +1 -0
  231. package/dist/src/planner/building/returning-star.d.ts +32 -0
  232. package/dist/src/planner/building/returning-star.d.ts.map +1 -0
  233. package/dist/src/planner/building/returning-star.js +45 -0
  234. package/dist/src/planner/building/returning-star.js.map +1 -0
  235. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  236. package/dist/src/planner/building/select-aggregates.js +51 -13
  237. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  238. package/dist/src/planner/building/select-compound.d.ts.map +1 -1
  239. package/dist/src/planner/building/select-compound.js +84 -11
  240. package/dist/src/planner/building/select-compound.js.map +1 -1
  241. package/dist/src/planner/building/select-context.d.ts +10 -2
  242. package/dist/src/planner/building/select-context.d.ts.map +1 -1
  243. package/dist/src/planner/building/select-context.js +7 -1
  244. package/dist/src/planner/building/select-context.js.map +1 -1
  245. package/dist/src/planner/building/select-modifiers.js +6 -0
  246. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  247. package/dist/src/planner/building/select-ordinal.d.ts +18 -0
  248. package/dist/src/planner/building/select-ordinal.d.ts.map +1 -1
  249. package/dist/src/planner/building/select-ordinal.js +30 -0
  250. package/dist/src/planner/building/select-ordinal.js.map +1 -1
  251. package/dist/src/planner/building/select-projections.d.ts +8 -2
  252. package/dist/src/planner/building/select-projections.d.ts.map +1 -1
  253. package/dist/src/planner/building/select-projections.js +26 -4
  254. package/dist/src/planner/building/select-projections.js.map +1 -1
  255. package/dist/src/planner/building/select-window.d.ts.map +1 -1
  256. package/dist/src/planner/building/select-window.js +8 -5
  257. package/dist/src/planner/building/select-window.js.map +1 -1
  258. package/dist/src/planner/building/select.d.ts.map +1 -1
  259. package/dist/src/planner/building/select.js +164 -59
  260. package/dist/src/planner/building/select.js.map +1 -1
  261. package/dist/src/planner/building/set-object-tags.d.ts +7 -0
  262. package/dist/src/planner/building/set-object-tags.d.ts.map +1 -0
  263. package/dist/src/planner/building/set-object-tags.js +38 -0
  264. package/dist/src/planner/building/set-object-tags.js.map +1 -0
  265. package/dist/src/planner/building/tag-diagnostics.d.ts +27 -0
  266. package/dist/src/planner/building/tag-diagnostics.d.ts.map +1 -0
  267. package/dist/src/planner/building/tag-diagnostics.js +37 -0
  268. package/dist/src/planner/building/tag-diagnostics.js.map +1 -0
  269. package/dist/src/planner/building/update.d.ts +18 -1
  270. package/dist/src/planner/building/update.d.ts.map +1 -1
  271. package/dist/src/planner/building/update.js +134 -58
  272. package/dist/src/planner/building/update.js.map +1 -1
  273. package/dist/src/planner/building/view-mutation-builder.d.ts +15 -0
  274. package/dist/src/planner/building/view-mutation-builder.d.ts.map +1 -0
  275. package/dist/src/planner/building/view-mutation-builder.js +1158 -0
  276. package/dist/src/planner/building/view-mutation-builder.js.map +1 -0
  277. package/dist/src/planner/building/with.d.ts +11 -0
  278. package/dist/src/planner/building/with.d.ts.map +1 -1
  279. package/dist/src/planner/building/with.js +48 -10
  280. package/dist/src/planner/building/with.js.map +1 -1
  281. package/dist/src/planner/cost/index.d.ts +83 -0
  282. package/dist/src/planner/cost/index.d.ts.map +1 -1
  283. package/dist/src/planner/cost/index.js +114 -0
  284. package/dist/src/planner/cost/index.js.map +1 -1
  285. package/dist/src/planner/framework/characteristics.d.ts +38 -4
  286. package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
  287. package/dist/src/planner/framework/characteristics.js +50 -6
  288. package/dist/src/planner/framework/characteristics.js.map +1 -1
  289. package/dist/src/planner/framework/pass.d.ts.map +1 -1
  290. package/dist/src/planner/framework/pass.js +2 -1
  291. package/dist/src/planner/framework/pass.js.map +1 -1
  292. package/dist/src/planner/framework/physical-utils.d.ts.map +1 -1
  293. package/dist/src/planner/framework/physical-utils.js +7 -1
  294. package/dist/src/planner/framework/physical-utils.js.map +1 -1
  295. package/dist/src/planner/framework/registry.d.ts +39 -1
  296. package/dist/src/planner/framework/registry.d.ts.map +1 -1
  297. package/dist/src/planner/framework/registry.js +18 -2
  298. package/dist/src/planner/framework/registry.js.map +1 -1
  299. package/dist/src/planner/mutation/backward-body.d.ts +131 -0
  300. package/dist/src/planner/mutation/backward-body.d.ts.map +1 -0
  301. package/dist/src/planner/mutation/backward-body.js +135 -0
  302. package/dist/src/planner/mutation/backward-body.js.map +1 -0
  303. package/dist/src/planner/mutation/cte-flatten.d.ts +17 -0
  304. package/dist/src/planner/mutation/cte-flatten.d.ts.map +1 -0
  305. package/dist/src/planner/mutation/cte-flatten.js +364 -0
  306. package/dist/src/planner/mutation/cte-flatten.js.map +1 -0
  307. package/dist/src/planner/mutation/decomposition.d.ts +273 -0
  308. package/dist/src/planner/mutation/decomposition.d.ts.map +1 -0
  309. package/dist/src/planner/mutation/decomposition.js +1719 -0
  310. package/dist/src/planner/mutation/decomposition.js.map +1 -0
  311. package/dist/src/planner/mutation/lens-enforcement.d.ts +165 -0
  312. package/dist/src/planner/mutation/lens-enforcement.d.ts.map +1 -0
  313. package/dist/src/planner/mutation/lens-enforcement.js +745 -0
  314. package/dist/src/planner/mutation/lens-enforcement.js.map +1 -0
  315. package/dist/src/planner/mutation/multi-source.d.ts +568 -0
  316. package/dist/src/planner/mutation/multi-source.d.ts.map +1 -0
  317. package/dist/src/planner/mutation/multi-source.js +2915 -0
  318. package/dist/src/planner/mutation/multi-source.js.map +1 -0
  319. package/dist/src/planner/mutation/mutation-diagnostic.d.ts +37 -0
  320. package/dist/src/planner/mutation/mutation-diagnostic.d.ts.map +1 -0
  321. package/dist/src/planner/mutation/mutation-diagnostic.js +24 -0
  322. package/dist/src/planner/mutation/mutation-diagnostic.js.map +1 -0
  323. package/dist/src/planner/mutation/mutation-tags.d.ts +33 -0
  324. package/dist/src/planner/mutation/mutation-tags.d.ts.map +1 -0
  325. package/dist/src/planner/mutation/mutation-tags.js +31 -0
  326. package/dist/src/planner/mutation/mutation-tags.js.map +1 -0
  327. package/dist/src/planner/mutation/propagate.d.ts +97 -0
  328. package/dist/src/planner/mutation/propagate.d.ts.map +1 -0
  329. package/dist/src/planner/mutation/propagate.js +220 -0
  330. package/dist/src/planner/mutation/propagate.js.map +1 -0
  331. package/dist/src/planner/mutation/scope-transform.d.ts +181 -0
  332. package/dist/src/planner/mutation/scope-transform.d.ts.map +1 -0
  333. package/dist/src/planner/mutation/scope-transform.js +574 -0
  334. package/dist/src/planner/mutation/scope-transform.js.map +1 -0
  335. package/dist/src/planner/mutation/set-op.d.ts +242 -0
  336. package/dist/src/planner/mutation/set-op.d.ts.map +1 -0
  337. package/dist/src/planner/mutation/set-op.js +1687 -0
  338. package/dist/src/planner/mutation/set-op.js.map +1 -0
  339. package/dist/src/planner/mutation/single-source.d.ts +261 -0
  340. package/dist/src/planner/mutation/single-source.d.ts.map +1 -0
  341. package/dist/src/planner/mutation/single-source.js +1096 -0
  342. package/dist/src/planner/mutation/single-source.js.map +1 -0
  343. package/dist/src/planner/nodes/aggregate-node.d.ts +6 -4
  344. package/dist/src/planner/nodes/aggregate-node.d.ts.map +1 -1
  345. package/dist/src/planner/nodes/aggregate-node.js +11 -9
  346. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  347. package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
  348. package/dist/src/planner/nodes/alias-node.js +5 -1
  349. package/dist/src/planner/nodes/alias-node.js.map +1 -1
  350. package/dist/src/planner/nodes/alter-table-node.d.ts +124 -1
  351. package/dist/src/planner/nodes/alter-table-node.d.ts.map +1 -1
  352. package/dist/src/planner/nodes/alter-table-node.js +27 -0
  353. package/dist/src/planner/nodes/alter-table-node.js.map +1 -1
  354. package/dist/src/planner/nodes/analyze-node.d.ts +2 -1
  355. package/dist/src/planner/nodes/analyze-node.d.ts.map +1 -1
  356. package/dist/src/planner/nodes/analyze-node.js +21 -1
  357. package/dist/src/planner/nodes/analyze-node.js.map +1 -1
  358. package/dist/src/planner/nodes/asserted-keys-node.d.ts +43 -0
  359. package/dist/src/planner/nodes/asserted-keys-node.d.ts.map +1 -0
  360. package/dist/src/planner/nodes/asserted-keys-node.js +99 -0
  361. package/dist/src/planner/nodes/asserted-keys-node.js.map +1 -0
  362. package/dist/src/planner/nodes/async-gather-node.d.ts.map +1 -1
  363. package/dist/src/planner/nodes/async-gather-node.js +33 -8
  364. package/dist/src/planner/nodes/async-gather-node.js.map +1 -1
  365. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
  366. package/dist/src/planner/nodes/bloom-join-node.js +2 -1
  367. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
  368. package/dist/src/planner/nodes/create-view-node.d.ts +7 -2
  369. package/dist/src/planner/nodes/create-view-node.d.ts.map +1 -1
  370. package/dist/src/planner/nodes/create-view-node.js +4 -1
  371. package/dist/src/planner/nodes/create-view-node.js.map +1 -1
  372. package/dist/src/planner/nodes/declarative-schema.d.ts +13 -1
  373. package/dist/src/planner/nodes/declarative-schema.d.ts.map +1 -1
  374. package/dist/src/planner/nodes/declarative-schema.js +32 -0
  375. package/dist/src/planner/nodes/declarative-schema.js.map +1 -1
  376. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
  377. package/dist/src/planner/nodes/distinct-node.js +2 -0
  378. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  379. package/dist/src/planner/nodes/dml-executor-node.d.ts +29 -1
  380. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  381. package/dist/src/planner/nodes/dml-executor-node.js +27 -3
  382. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  383. package/dist/src/planner/nodes/eager-prefetch-node.d.ts.map +1 -1
  384. package/dist/src/planner/nodes/eager-prefetch-node.js +2 -0
  385. package/dist/src/planner/nodes/eager-prefetch-node.js.map +1 -1
  386. package/dist/src/planner/nodes/envelope-scan-node.d.ts +42 -0
  387. package/dist/src/planner/nodes/envelope-scan-node.d.ts.map +1 -0
  388. package/dist/src/planner/nodes/envelope-scan-node.js +62 -0
  389. package/dist/src/planner/nodes/envelope-scan-node.js.map +1 -0
  390. package/dist/src/planner/nodes/fanout-lookup-join-node.d.ts.map +1 -1
  391. package/dist/src/planner/nodes/fanout-lookup-join-node.js +11 -1
  392. package/dist/src/planner/nodes/fanout-lookup-join-node.js.map +1 -1
  393. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  394. package/dist/src/planner/nodes/filter.js +63 -13
  395. package/dist/src/planner/nodes/filter.js.map +1 -1
  396. package/dist/src/planner/nodes/hash-aggregate.d.ts.map +1 -1
  397. package/dist/src/planner/nodes/hash-aggregate.js +6 -16
  398. package/dist/src/planner/nodes/hash-aggregate.js.map +1 -1
  399. package/dist/src/planner/nodes/join-node.d.ts +41 -1
  400. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  401. package/dist/src/planner/nodes/join-node.js +78 -8
  402. package/dist/src/planner/nodes/join-node.js.map +1 -1
  403. package/dist/src/planner/nodes/join-utils.d.ts +33 -6
  404. package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
  405. package/dist/src/planner/nodes/join-utils.js +131 -10
  406. package/dist/src/planner/nodes/join-utils.js.map +1 -1
  407. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts +104 -0
  408. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts.map +1 -0
  409. package/dist/src/planner/nodes/lens-auxiliary-access-node.js +91 -0
  410. package/dist/src/planner/nodes/lens-auxiliary-access-node.js.map +1 -0
  411. package/dist/src/planner/nodes/limit-offset.d.ts +12 -0
  412. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  413. package/dist/src/planner/nodes/limit-offset.js +52 -3
  414. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  415. package/dist/src/planner/nodes/materialized-view-nodes.d.ts +69 -0
  416. package/dist/src/planner/nodes/materialized-view-nodes.d.ts.map +1 -0
  417. package/dist/src/planner/nodes/materialized-view-nodes.js +111 -0
  418. package/dist/src/planner/nodes/materialized-view-nodes.js.map +1 -0
  419. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
  420. package/dist/src/planner/nodes/merge-join-node.js +2 -1
  421. package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
  422. package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
  423. package/dist/src/planner/nodes/ordinal-slice-node.js +2 -0
  424. package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
  425. package/dist/src/planner/nodes/plan-node-type.d.ts +9 -0
  426. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  427. package/dist/src/planner/nodes/plan-node-type.js +9 -0
  428. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  429. package/dist/src/planner/nodes/plan-node.d.ts +265 -5
  430. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  431. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  432. package/dist/src/planner/nodes/pragma.d.ts +2 -1
  433. package/dist/src/planner/nodes/pragma.d.ts.map +1 -1
  434. package/dist/src/planner/nodes/pragma.js +12 -0
  435. package/dist/src/planner/nodes/pragma.js.map +1 -1
  436. package/dist/src/planner/nodes/project-node.d.ts +14 -1
  437. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  438. package/dist/src/planner/nodes/project-node.js +103 -16
  439. package/dist/src/planner/nodes/project-node.js.map +1 -1
  440. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  441. package/dist/src/planner/nodes/reference.js +63 -30
  442. package/dist/src/planner/nodes/reference.js.map +1 -1
  443. package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -1
  444. package/dist/src/planner/nodes/retrieve-node.js +7 -0
  445. package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
  446. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  447. package/dist/src/planner/nodes/returning-node.js +10 -3
  448. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  449. package/dist/src/planner/nodes/scalar.d.ts +20 -0
  450. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  451. package/dist/src/planner/nodes/scalar.js +71 -14
  452. package/dist/src/planner/nodes/scalar.js.map +1 -1
  453. package/dist/src/planner/nodes/set-object-tags-node.d.ts +39 -0
  454. package/dist/src/planner/nodes/set-object-tags-node.d.ts.map +1 -0
  455. package/dist/src/planner/nodes/set-object-tags-node.js +41 -0
  456. package/dist/src/planner/nodes/set-object-tags-node.js.map +1 -0
  457. package/dist/src/planner/nodes/set-operation-node.d.ts +123 -1
  458. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  459. package/dist/src/planner/nodes/set-operation-node.js +302 -18
  460. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  461. package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
  462. package/dist/src/planner/nodes/single-row.js +3 -0
  463. package/dist/src/planner/nodes/single-row.js.map +1 -1
  464. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  465. package/dist/src/planner/nodes/sort.js +8 -7
  466. package/dist/src/planner/nodes/sort.js.map +1 -1
  467. package/dist/src/planner/nodes/stream-aggregate.d.ts.map +1 -1
  468. package/dist/src/planner/nodes/stream-aggregate.js +8 -23
  469. package/dist/src/planner/nodes/stream-aggregate.js.map +1 -1
  470. package/dist/src/planner/nodes/subquery.d.ts +2 -0
  471. package/dist/src/planner/nodes/subquery.d.ts.map +1 -1
  472. package/dist/src/planner/nodes/subquery.js +18 -2
  473. package/dist/src/planner/nodes/subquery.js.map +1 -1
  474. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
  475. package/dist/src/planner/nodes/table-access-nodes.js +23 -3
  476. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  477. package/dist/src/planner/nodes/table-function-call.js +6 -0
  478. package/dist/src/planner/nodes/table-function-call.js.map +1 -1
  479. package/dist/src/planner/nodes/values-node.d.ts +3 -1
  480. package/dist/src/planner/nodes/values-node.d.ts.map +1 -1
  481. package/dist/src/planner/nodes/values-node.js +26 -0
  482. package/dist/src/planner/nodes/values-node.js.map +1 -1
  483. package/dist/src/planner/nodes/view-mutation-node.d.ts +259 -0
  484. package/dist/src/planner/nodes/view-mutation-node.d.ts.map +1 -0
  485. package/dist/src/planner/nodes/view-mutation-node.js +273 -0
  486. package/dist/src/planner/nodes/view-mutation-node.js.map +1 -0
  487. package/dist/src/planner/nodes/window-function.d.ts +17 -1
  488. package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
  489. package/dist/src/planner/nodes/window-function.js +15 -1
  490. package/dist/src/planner/nodes/window-function.js.map +1 -1
  491. package/dist/src/planner/nodes/window-node.js +3 -3
  492. package/dist/src/planner/nodes/window-node.js.map +1 -1
  493. package/dist/src/planner/optimizer.d.ts.map +1 -1
  494. package/dist/src/planner/optimizer.js +372 -39
  495. package/dist/src/planner/optimizer.js.map +1 -1
  496. package/dist/src/planner/planning-context.d.ts +1 -1
  497. package/dist/src/planner/planning-context.d.ts.map +1 -1
  498. package/dist/src/planner/rules/access/lens-access-form-matcher.d.ts +70 -0
  499. package/dist/src/planner/rules/access/lens-access-form-matcher.d.ts.map +1 -0
  500. package/dist/src/planner/rules/access/lens-access-form-matcher.js +156 -0
  501. package/dist/src/planner/rules/access/lens-access-form-matcher.js.map +1 -0
  502. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.d.ts +31 -0
  503. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.d.ts.map +1 -0
  504. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.js +176 -0
  505. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.js.map +1 -0
  506. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  507. package/dist/src/planner/rules/access/rule-select-access-path.js +435 -37
  508. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  509. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.d.ts.map +1 -1
  510. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js +8 -27
  511. package/dist/src/planner/rules/aggregate/rule-aggregate-streaming.js.map +1 -1
  512. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts +9 -3
  513. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts.map +1 -1
  514. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js +56 -5
  515. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js.map +1 -1
  516. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts +39 -0
  517. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts.map +1 -0
  518. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js +616 -0
  519. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js.map +1 -0
  520. package/dist/src/planner/rules/cache/rule-scalar-cse.d.ts.map +1 -1
  521. package/dist/src/planner/rules/cache/rule-scalar-cse.js +8 -1
  522. package/dist/src/planner/rules/cache/rule-scalar-cse.js.map +1 -1
  523. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts +8 -7
  524. package/dist/src/planner/rules/distinct/rule-distinct-elimination.d.ts.map +1 -1
  525. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js +14 -21
  526. package/dist/src/planner/rules/distinct/rule-distinct-elimination.js.map +1 -1
  527. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts +36 -0
  528. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts.map +1 -1
  529. package/dist/src/planner/rules/join/equi-pair-extractor.js +42 -5
  530. package/dist/src/planner/rules/join/equi-pair-extractor.js.map +1 -1
  531. package/dist/src/planner/rules/join/rule-fanout-batched-outer.d.ts.map +1 -1
  532. package/dist/src/planner/rules/join/rule-fanout-batched-outer.js +10 -0
  533. package/dist/src/planner/rules/join/rule-fanout-batched-outer.js.map +1 -1
  534. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js +25 -9
  535. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js.map +1 -1
  536. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts +130 -0
  537. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts.map +1 -0
  538. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js +206 -0
  539. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js.map +1 -0
  540. package/dist/src/planner/rules/join/rule-join-elimination.d.ts +67 -14
  541. package/dist/src/planner/rules/join/rule-join-elimination.d.ts.map +1 -1
  542. package/dist/src/planner/rules/join/rule-join-elimination.js +81 -25
  543. package/dist/src/planner/rules/join/rule-join-elimination.js.map +1 -1
  544. package/dist/src/planner/rules/join/rule-join-existence-pruning.d.ts +84 -0
  545. package/dist/src/planner/rules/join/rule-join-existence-pruning.d.ts.map +1 -0
  546. package/dist/src/planner/rules/join/rule-join-existence-pruning.js +138 -0
  547. package/dist/src/planner/rules/join/rule-join-existence-pruning.js.map +1 -0
  548. package/dist/src/planner/rules/join/rule-join-greedy-commute.d.ts.map +1 -1
  549. package/dist/src/planner/rules/join/rule-join-greedy-commute.js +19 -1
  550. package/dist/src/planner/rules/join/rule-join-greedy-commute.js.map +1 -1
  551. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -1
  552. package/dist/src/planner/rules/join/rule-join-physical-selection.js +14 -2
  553. package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -1
  554. package/dist/src/planner/rules/join/rule-lateral-top1-asof.d.ts.map +1 -1
  555. package/dist/src/planner/rules/join/rule-lateral-top1-asof.js +5 -2
  556. package/dist/src/planner/rules/join/rule-lateral-top1-asof.js.map +1 -1
  557. package/dist/src/planner/rules/join/rule-monotonic-merge-join.d.ts.map +1 -1
  558. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js +4 -0
  559. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js.map +1 -1
  560. package/dist/src/planner/rules/join/rule-quickpick-enumeration.d.ts.map +1 -1
  561. package/dist/src/planner/rules/join/rule-quickpick-enumeration.js +10 -0
  562. package/dist/src/planner/rules/join/rule-quickpick-enumeration.js.map +1 -1
  563. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.d.ts +286 -0
  564. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.d.ts.map +1 -0
  565. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.js +548 -0
  566. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.js.map +1 -0
  567. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.d.ts.map +1 -1
  568. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.js +9 -1
  569. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.js.map +1 -1
  570. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.d.ts.map +1 -1
  571. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js +7 -0
  572. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js.map +1 -1
  573. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.d.ts.map +1 -1
  574. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.js +10 -1
  575. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.js.map +1 -1
  576. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts.map +1 -1
  577. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js +10 -1
  578. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js.map +1 -1
  579. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts.map +1 -1
  580. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +18 -0
  581. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js.map +1 -1
  582. package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts.map +1 -1
  583. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js +7 -0
  584. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js.map +1 -1
  585. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts.map +1 -1
  586. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +9 -0
  587. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -1
  588. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js +13 -3
  589. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -1
  590. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js +2 -2
  591. package/dist/src/planner/rules/retrieve/rule-grow-retrieve.js.map +1 -1
  592. package/dist/src/planner/rules/retrieve/rule-projection-pruning.d.ts.map +1 -1
  593. package/dist/src/planner/rules/retrieve/rule-projection-pruning.js +14 -0
  594. package/dist/src/planner/rules/retrieve/rule-projection-pruning.js.map +1 -1
  595. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts +16 -0
  596. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts.map +1 -1
  597. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js +47 -4
  598. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js.map +1 -1
  599. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts.map +1 -1
  600. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js +8 -0
  601. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js.map +1 -1
  602. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts.map +1 -1
  603. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js +7 -0
  604. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js.map +1 -1
  605. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
  606. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +12 -0
  607. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
  608. package/dist/src/planner/rules/window/rule-monotonic-window.js +1 -1
  609. package/dist/src/planner/rules/window/rule-monotonic-window.js.map +1 -1
  610. package/dist/src/planner/type-utils.d.ts +14 -0
  611. package/dist/src/planner/type-utils.d.ts.map +1 -1
  612. package/dist/src/planner/type-utils.js +66 -21
  613. package/dist/src/planner/type-utils.js.map +1 -1
  614. package/dist/src/planner/util/fd-utils.d.ts +228 -36
  615. package/dist/src/planner/util/fd-utils.d.ts.map +1 -1
  616. package/dist/src/planner/util/fd-utils.js +501 -84
  617. package/dist/src/planner/util/fd-utils.js.map +1 -1
  618. package/dist/src/planner/util/ind-utils.d.ts +27 -1
  619. package/dist/src/planner/util/ind-utils.d.ts.map +1 -1
  620. package/dist/src/planner/util/ind-utils.js +80 -6
  621. package/dist/src/planner/util/ind-utils.js.map +1 -1
  622. package/dist/src/planner/util/key-utils.d.ts +26 -3
  623. package/dist/src/planner/util/key-utils.d.ts.map +1 -1
  624. package/dist/src/planner/util/key-utils.js +182 -33
  625. package/dist/src/planner/util/key-utils.js.map +1 -1
  626. package/dist/src/planner/util/set-op-wrapper.d.ts +37 -0
  627. package/dist/src/planner/util/set-op-wrapper.d.ts.map +1 -0
  628. package/dist/src/planner/util/set-op-wrapper.js +82 -0
  629. package/dist/src/planner/util/set-op-wrapper.js.map +1 -0
  630. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  631. package/dist/src/planner/validation/plan-validator.js +1 -0
  632. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  633. package/dist/src/runtime/context-helpers.d.ts +13 -1
  634. package/dist/src/runtime/context-helpers.d.ts.map +1 -1
  635. package/dist/src/runtime/context-helpers.js +7 -1
  636. package/dist/src/runtime/context-helpers.js.map +1 -1
  637. package/dist/src/runtime/delta-executor.d.ts +30 -1
  638. package/dist/src/runtime/delta-executor.d.ts.map +1 -1
  639. package/dist/src/runtime/delta-executor.js +38 -4
  640. package/dist/src/runtime/delta-executor.js.map +1 -1
  641. package/dist/src/runtime/emit/add-constraint.d.ts.map +1 -1
  642. package/dist/src/runtime/emit/add-constraint.js +38 -5
  643. package/dist/src/runtime/emit/add-constraint.js.map +1 -1
  644. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  645. package/dist/src/runtime/emit/aggregate.js +10 -8
  646. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  647. package/dist/src/runtime/emit/alter-table.d.ts +1 -1
  648. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  649. package/dist/src/runtime/emit/alter-table.js +664 -108
  650. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  651. package/dist/src/runtime/emit/analyze.d.ts.map +1 -1
  652. package/dist/src/runtime/emit/analyze.js +2 -1
  653. package/dist/src/runtime/emit/analyze.js.map +1 -1
  654. package/dist/src/runtime/emit/asof-scan.d.ts.map +1 -1
  655. package/dist/src/runtime/emit/asof-scan.js +24 -9
  656. package/dist/src/runtime/emit/asof-scan.js.map +1 -1
  657. package/dist/src/runtime/emit/asserted-keys.d.ts +13 -0
  658. package/dist/src/runtime/emit/asserted-keys.d.ts.map +1 -0
  659. package/dist/src/runtime/emit/asserted-keys.js +13 -0
  660. package/dist/src/runtime/emit/asserted-keys.js.map +1 -0
  661. package/dist/src/runtime/emit/between.d.ts.map +1 -1
  662. package/dist/src/runtime/emit/between.js +24 -19
  663. package/dist/src/runtime/emit/between.js.map +1 -1
  664. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  665. package/dist/src/runtime/emit/binary.js +24 -36
  666. package/dist/src/runtime/emit/binary.js.map +1 -1
  667. package/dist/src/runtime/emit/block.d.ts.map +1 -1
  668. package/dist/src/runtime/emit/block.js +11 -2
  669. package/dist/src/runtime/emit/block.js.map +1 -1
  670. package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -1
  671. package/dist/src/runtime/emit/bloom-join.js +12 -4
  672. package/dist/src/runtime/emit/bloom-join.js.map +1 -1
  673. package/dist/src/runtime/emit/constraint-check.d.ts.map +1 -1
  674. package/dist/src/runtime/emit/constraint-check.js +50 -1
  675. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  676. package/dist/src/runtime/emit/create-table.d.ts.map +1 -1
  677. package/dist/src/runtime/emit/create-table.js +8 -0
  678. package/dist/src/runtime/emit/create-table.js.map +1 -1
  679. package/dist/src/runtime/emit/create-view.d.ts.map +1 -1
  680. package/dist/src/runtime/emit/create-view.js +16 -1
  681. package/dist/src/runtime/emit/create-view.js.map +1 -1
  682. package/dist/src/runtime/emit/delete.d.ts.map +1 -1
  683. package/dist/src/runtime/emit/delete.js +15 -5
  684. package/dist/src/runtime/emit/delete.js.map +1 -1
  685. package/dist/src/runtime/emit/dml-executor.d.ts +27 -0
  686. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  687. package/dist/src/runtime/emit/dml-executor.js +413 -193
  688. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  689. package/dist/src/runtime/emit/drop-table.d.ts.map +1 -1
  690. package/dist/src/runtime/emit/drop-table.js +10 -0
  691. package/dist/src/runtime/emit/drop-table.js.map +1 -1
  692. package/dist/src/runtime/emit/drop-view.d.ts.map +1 -1
  693. package/dist/src/runtime/emit/drop-view.js +17 -0
  694. package/dist/src/runtime/emit/drop-view.js.map +1 -1
  695. package/dist/src/runtime/emit/envelope-scan.d.ts +13 -0
  696. package/dist/src/runtime/emit/envelope-scan.d.ts.map +1 -0
  697. package/dist/src/runtime/emit/envelope-scan.js +22 -0
  698. package/dist/src/runtime/emit/envelope-scan.js.map +1 -0
  699. package/dist/src/runtime/emit/join.d.ts +10 -2
  700. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  701. package/dist/src/runtime/emit/join.js +128 -38
  702. package/dist/src/runtime/emit/join.js.map +1 -1
  703. package/dist/src/runtime/emit/lens-auxiliary-access.d.ts +16 -0
  704. package/dist/src/runtime/emit/lens-auxiliary-access.d.ts.map +1 -0
  705. package/dist/src/runtime/emit/lens-auxiliary-access.js +16 -0
  706. package/dist/src/runtime/emit/lens-auxiliary-access.js.map +1 -0
  707. package/dist/src/runtime/emit/materialized-view-helpers.d.ts +640 -0
  708. package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -0
  709. package/dist/src/runtime/emit/materialized-view-helpers.js +2576 -0
  710. package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -0
  711. package/dist/src/runtime/emit/materialized-view.d.ts +31 -0
  712. package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -0
  713. package/dist/src/runtime/emit/materialized-view.js +187 -0
  714. package/dist/src/runtime/emit/materialized-view.js.map +1 -0
  715. package/dist/src/runtime/emit/merge-join.d.ts.map +1 -1
  716. package/dist/src/runtime/emit/merge-join.js +19 -5
  717. package/dist/src/runtime/emit/merge-join.js.map +1 -1
  718. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  719. package/dist/src/runtime/emit/project.js +10 -5
  720. package/dist/src/runtime/emit/project.js.map +1 -1
  721. package/dist/src/runtime/emit/schema-declarative.d.ts +1 -0
  722. package/dist/src/runtime/emit/schema-declarative.d.ts.map +1 -1
  723. package/dist/src/runtime/emit/schema-declarative.js +101 -5
  724. package/dist/src/runtime/emit/schema-declarative.js.map +1 -1
  725. package/dist/src/runtime/emit/set-object-tags.d.ts +16 -0
  726. package/dist/src/runtime/emit/set-object-tags.d.ts.map +1 -0
  727. package/dist/src/runtime/emit/set-object-tags.js +57 -0
  728. package/dist/src/runtime/emit/set-object-tags.js.map +1 -0
  729. package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
  730. package/dist/src/runtime/emit/set-operation.js +140 -24
  731. package/dist/src/runtime/emit/set-operation.js.map +1 -1
  732. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  733. package/dist/src/runtime/emit/subquery.js +110 -5
  734. package/dist/src/runtime/emit/subquery.js.map +1 -1
  735. package/dist/src/runtime/emit/unary.d.ts.map +1 -1
  736. package/dist/src/runtime/emit/unary.js +34 -6
  737. package/dist/src/runtime/emit/unary.js.map +1 -1
  738. package/dist/src/runtime/emit/view-mutation.d.ts +70 -0
  739. package/dist/src/runtime/emit/view-mutation.d.ts.map +1 -0
  740. package/dist/src/runtime/emit/view-mutation.js +299 -0
  741. package/dist/src/runtime/emit/view-mutation.js.map +1 -0
  742. package/dist/src/runtime/emit/window.js +29 -5
  743. package/dist/src/runtime/emit/window.js.map +1 -1
  744. package/dist/src/runtime/foreign-key-actions.d.ts +66 -3
  745. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
  746. package/dist/src/runtime/foreign-key-actions.js +580 -172
  747. package/dist/src/runtime/foreign-key-actions.js.map +1 -1
  748. package/dist/src/runtime/parallel-driver.d.ts +4 -1
  749. package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
  750. package/dist/src/runtime/parallel-driver.js +5 -1
  751. package/dist/src/runtime/parallel-driver.js.map +1 -1
  752. package/dist/src/runtime/register.d.ts.map +1 -1
  753. package/dist/src/runtime/register.js +17 -1
  754. package/dist/src/runtime/register.js.map +1 -1
  755. package/dist/src/runtime/types.d.ts +10 -0
  756. package/dist/src/runtime/types.d.ts.map +1 -1
  757. package/dist/src/runtime/types.js.map +1 -1
  758. package/dist/src/schema/basis-backfill.d.ts +63 -0
  759. package/dist/src/schema/basis-backfill.d.ts.map +1 -0
  760. package/dist/src/schema/basis-backfill.js +161 -0
  761. package/dist/src/schema/basis-backfill.js.map +1 -0
  762. package/dist/src/schema/catalog.d.ts +115 -1
  763. package/dist/src/schema/catalog.d.ts.map +1 -1
  764. package/dist/src/schema/catalog.js +249 -22
  765. package/dist/src/schema/catalog.js.map +1 -1
  766. package/dist/src/schema/change-events.d.ts +42 -1
  767. package/dist/src/schema/change-events.d.ts.map +1 -1
  768. package/dist/src/schema/change-events.js.map +1 -1
  769. package/dist/src/schema/column.d.ts +16 -0
  770. package/dist/src/schema/column.d.ts.map +1 -1
  771. package/dist/src/schema/column.js.map +1 -1
  772. package/dist/src/schema/constraint-builder.d.ts +182 -0
  773. package/dist/src/schema/constraint-builder.d.ts.map +1 -0
  774. package/dist/src/schema/constraint-builder.js +424 -0
  775. package/dist/src/schema/constraint-builder.js.map +1 -0
  776. package/dist/src/schema/ddl-generator.d.ts +86 -1
  777. package/dist/src/schema/ddl-generator.d.ts.map +1 -1
  778. package/dist/src/schema/ddl-generator.js +316 -20
  779. package/dist/src/schema/ddl-generator.js.map +1 -1
  780. package/dist/src/schema/declared-schema-manager.d.ts +51 -0
  781. package/dist/src/schema/declared-schema-manager.d.ts.map +1 -1
  782. package/dist/src/schema/declared-schema-manager.js +61 -0
  783. package/dist/src/schema/declared-schema-manager.js.map +1 -1
  784. package/dist/src/schema/derivation.d.ts +106 -0
  785. package/dist/src/schema/derivation.d.ts.map +1 -0
  786. package/dist/src/schema/derivation.js +25 -0
  787. package/dist/src/schema/derivation.js.map +1 -0
  788. package/dist/src/schema/function.d.ts +13 -0
  789. package/dist/src/schema/function.d.ts.map +1 -1
  790. package/dist/src/schema/function.js.map +1 -1
  791. package/dist/src/schema/lens-ack.d.ts +90 -0
  792. package/dist/src/schema/lens-ack.d.ts.map +1 -0
  793. package/dist/src/schema/lens-ack.js +361 -0
  794. package/dist/src/schema/lens-ack.js.map +1 -0
  795. package/dist/src/schema/lens-compiler.d.ts +62 -0
  796. package/dist/src/schema/lens-compiler.d.ts.map +1 -0
  797. package/dist/src/schema/lens-compiler.js +1594 -0
  798. package/dist/src/schema/lens-compiler.js.map +1 -0
  799. package/dist/src/schema/lens-fk-discovery.d.ts +175 -0
  800. package/dist/src/schema/lens-fk-discovery.d.ts.map +1 -0
  801. package/dist/src/schema/lens-fk-discovery.js +336 -0
  802. package/dist/src/schema/lens-fk-discovery.js.map +1 -0
  803. package/dist/src/schema/lens-prover.d.ts +336 -0
  804. package/dist/src/schema/lens-prover.d.ts.map +1 -0
  805. package/dist/src/schema/lens-prover.js +1988 -0
  806. package/dist/src/schema/lens-prover.js.map +1 -0
  807. package/dist/src/schema/lens.d.ts +254 -0
  808. package/dist/src/schema/lens.d.ts.map +1 -0
  809. package/dist/src/schema/lens.js +21 -0
  810. package/dist/src/schema/lens.js.map +1 -0
  811. package/dist/src/schema/manager.d.ts +676 -18
  812. package/dist/src/schema/manager.d.ts.map +1 -1
  813. package/dist/src/schema/manager.js +1573 -238
  814. package/dist/src/schema/manager.js.map +1 -1
  815. package/dist/src/schema/mapping-advertisement-tags.d.ts +39 -0
  816. package/dist/src/schema/mapping-advertisement-tags.d.ts.map +1 -0
  817. package/dist/src/schema/mapping-advertisement-tags.js +216 -0
  818. package/dist/src/schema/mapping-advertisement-tags.js.map +1 -0
  819. package/dist/src/schema/rename-rewriter.d.ts +45 -4
  820. package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
  821. package/dist/src/schema/rename-rewriter.js +412 -19
  822. package/dist/src/schema/rename-rewriter.js.map +1 -1
  823. package/dist/src/schema/reserved-tags-policy.d.ts +32 -0
  824. package/dist/src/schema/reserved-tags-policy.d.ts.map +1 -0
  825. package/dist/src/schema/reserved-tags-policy.js +34 -0
  826. package/dist/src/schema/reserved-tags-policy.js.map +1 -0
  827. package/dist/src/schema/reserved-tags.d.ts +170 -0
  828. package/dist/src/schema/reserved-tags.d.ts.map +1 -0
  829. package/dist/src/schema/reserved-tags.js +507 -0
  830. package/dist/src/schema/reserved-tags.js.map +1 -0
  831. package/dist/src/schema/schema-differ.d.ts +158 -2
  832. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  833. package/dist/src/schema/schema-differ.js +1460 -78
  834. package/dist/src/schema/schema-differ.js.map +1 -1
  835. package/dist/src/schema/schema-hasher.d.ts +8 -3
  836. package/dist/src/schema/schema-hasher.d.ts.map +1 -1
  837. package/dist/src/schema/schema-hasher.js +22 -2
  838. package/dist/src/schema/schema-hasher.js.map +1 -1
  839. package/dist/src/schema/schema.d.ts +25 -1
  840. package/dist/src/schema/schema.d.ts.map +1 -1
  841. package/dist/src/schema/schema.js +36 -2
  842. package/dist/src/schema/schema.js.map +1 -1
  843. package/dist/src/schema/table.d.ts +259 -10
  844. package/dist/src/schema/table.d.ts.map +1 -1
  845. package/dist/src/schema/table.js +309 -26
  846. package/dist/src/schema/table.js.map +1 -1
  847. package/dist/src/schema/unique-enforcement.d.ts +78 -0
  848. package/dist/src/schema/unique-enforcement.d.ts.map +1 -0
  849. package/dist/src/schema/unique-enforcement.js +93 -0
  850. package/dist/src/schema/unique-enforcement.js.map +1 -0
  851. package/dist/src/schema/view.d.ts +83 -2
  852. package/dist/src/schema/view.d.ts.map +1 -1
  853. package/dist/src/schema/view.js +67 -1
  854. package/dist/src/schema/view.js.map +1 -1
  855. package/dist/src/schema/window-function.d.ts +9 -1
  856. package/dist/src/schema/window-function.d.ts.map +1 -1
  857. package/dist/src/schema/window-function.js.map +1 -1
  858. package/dist/src/types/temporal-types.d.ts.map +1 -1
  859. package/dist/src/types/temporal-types.js +71 -36
  860. package/dist/src/types/temporal-types.js.map +1 -1
  861. package/dist/src/util/comparison.d.ts +24 -0
  862. package/dist/src/util/comparison.d.ts.map +1 -1
  863. package/dist/src/util/comparison.js +34 -0
  864. package/dist/src/util/comparison.js.map +1 -1
  865. package/dist/src/util/mutation-statement.d.ts.map +1 -1
  866. package/dist/src/util/mutation-statement.js +4 -1
  867. package/dist/src/util/mutation-statement.js.map +1 -1
  868. package/dist/src/util/serialization.d.ts +9 -0
  869. package/dist/src/util/serialization.d.ts.map +1 -1
  870. package/dist/src/util/serialization.js +26 -0
  871. package/dist/src/util/serialization.js.map +1 -1
  872. package/dist/src/vtab/backing-host.d.ts +286 -0
  873. package/dist/src/vtab/backing-host.d.ts.map +1 -0
  874. package/dist/src/vtab/backing-host.js +118 -0
  875. package/dist/src/vtab/backing-host.js.map +1 -0
  876. package/dist/src/vtab/best-access-plan.d.ts +21 -0
  877. package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
  878. package/dist/src/vtab/best-access-plan.js.map +1 -1
  879. package/dist/src/vtab/capabilities.d.ts +5 -5
  880. package/dist/src/vtab/capabilities.d.ts.map +1 -1
  881. package/dist/src/vtab/mapping-advertisement.d.ts +163 -0
  882. package/dist/src/vtab/mapping-advertisement.d.ts.map +1 -0
  883. package/dist/src/vtab/mapping-advertisement.js +2 -0
  884. package/dist/src/vtab/mapping-advertisement.js.map +1 -0
  885. package/dist/src/vtab/memory/index.d.ts +64 -4
  886. package/dist/src/vtab/memory/index.d.ts.map +1 -1
  887. package/dist/src/vtab/memory/index.js +119 -12
  888. package/dist/src/vtab/memory/index.js.map +1 -1
  889. package/dist/src/vtab/memory/layer/base.d.ts +38 -1
  890. package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
  891. package/dist/src/vtab/memory/layer/base.js +112 -24
  892. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  893. package/dist/src/vtab/memory/layer/manager.d.ts +291 -4
  894. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  895. package/dist/src/vtab/memory/layer/manager.js +1050 -91
  896. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  897. package/dist/src/vtab/memory/layer/plan-filter.d.ts.map +1 -1
  898. package/dist/src/vtab/memory/layer/plan-filter.js +35 -6
  899. package/dist/src/vtab/memory/layer/plan-filter.js.map +1 -1
  900. package/dist/src/vtab/memory/layer/scan-layer.d.ts.map +1 -1
  901. package/dist/src/vtab/memory/layer/scan-layer.js +66 -14
  902. package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
  903. package/dist/src/vtab/memory/layer/scan-plan.d.ts +14 -0
  904. package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
  905. package/dist/src/vtab/memory/layer/scan-plan.js +27 -4
  906. package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
  907. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  908. package/dist/src/vtab/memory/layer/transaction.js +5 -1
  909. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  910. package/dist/src/vtab/memory/module.d.ts +17 -0
  911. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  912. package/dist/src/vtab/memory/module.js +82 -3
  913. package/dist/src/vtab/memory/module.js.map +1 -1
  914. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  915. package/dist/src/vtab/memory/table.js +15 -5
  916. package/dist/src/vtab/memory/table.js.map +1 -1
  917. package/dist/src/vtab/memory/types.d.ts +20 -2
  918. package/dist/src/vtab/memory/types.d.ts.map +1 -1
  919. package/dist/src/vtab/memory/utils/predicate.d.ts.map +1 -1
  920. package/dist/src/vtab/memory/utils/predicate.js +46 -24
  921. package/dist/src/vtab/memory/utils/predicate.js.map +1 -1
  922. package/dist/src/vtab/memory/utils/primary-key-encode.d.ts +31 -0
  923. package/dist/src/vtab/memory/utils/primary-key-encode.d.ts.map +1 -0
  924. package/dist/src/vtab/memory/utils/primary-key-encode.js +101 -0
  925. package/dist/src/vtab/memory/utils/primary-key-encode.js.map +1 -0
  926. package/dist/src/vtab/memory/utils/primary-key.d.ts +8 -0
  927. package/dist/src/vtab/memory/utils/primary-key.d.ts.map +1 -1
  928. package/dist/src/vtab/memory/utils/primary-key.js +12 -5
  929. package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
  930. package/dist/src/vtab/module.d.ts +203 -4
  931. package/dist/src/vtab/module.d.ts.map +1 -1
  932. package/dist/src/vtab/table.d.ts +9 -0
  933. package/dist/src/vtab/table.d.ts.map +1 -1
  934. package/dist/src/vtab/table.js.map +1 -1
  935. package/package.json +6 -5
@@ -0,0 +1,1096 @@
1
+ import { isRelationalNode } from '../nodes/plan-node.js';
2
+ import { StatusCode } from '../../common/types.js';
3
+ import { QuereusError } from '../../common/errors.js';
4
+ import { sqlValuesEqual } from '../../util/comparison.js';
5
+ import { buildSelectStmt } from '../building/select.js';
6
+ import { classifyViewBody } from './propagate.js';
7
+ import { raiseMutationDiagnostic } from './mutation-diagnostic.js';
8
+ import { deriveViewColumns, resolveBaseSite } from '../analysis/update-lineage.js';
9
+ import { ProjectNode } from '../nodes/project-node.js';
10
+ import { ColumnReferenceNode } from '../nodes/reference.js';
11
+ import { requireValidatedNewRefIndex } from '../analysis/authored-inverse.js';
12
+ import { expressionToString } from '../../emit/ast-stringify.js';
13
+ import { transformExpr, cloneExpr, substituteNewRefs, transformScopedExpr, transformScopedQuery } from './scope-transform.js';
14
+ import { isMaintainedTable } from '../../schema/derivation.js';
15
+ import { bodyDefaults } from '../../schema/view.js';
16
+ /**
17
+ * Reserved, collision-proof correlation name synthesised onto the lowered
18
+ * single-source UPDATE/DELETE target. The `__` internal-name convention (same family
19
+ * as `__vmupd_keys` / `__shared_key`) guarantees it cannot collide with any
20
+ * user-introduced FROM source, so a substituted subquery-descent base term qualified
21
+ * with it (`__vm_self.col`) always binds the outer target row — even when the user
22
+ * subquery FROM names the view's own base table. Lowered-target nesting cannot occur
23
+ * (view-over-view / MV-over-MV / view-over-MV are all rejected by `analyzeView`, and a
24
+ * user subquery is a plain SELECT that never re-lowers), so a single module-level
25
+ * constant suffices: two `__vm_self`-aliased targets can never be in scope at once.
26
+ *
27
+ * The **multi-source** per-side lowered UPDATE (`multi-source.ts`) reuses this same
28
+ * constant: each per-side op is a flat single-table base UPDATE, planned independently
29
+ * through this same base builder and never co-scoped or nested with another lowered
30
+ * target, so the same "at most one `__vm_self` in scope" invariant holds. The per-side
31
+ * UPDATE carries `alias: SELF_ALIAS`, and its capture read-back owning-PK operands and
32
+ * owning-side strip-to-bare refs are qualified with it, so a correlation reference
33
+ * emitted inside a user value subquery binds the target row rather than re-binding to a
34
+ * same-named column in the subquery's own FROM (the multi-source analog of the
35
+ * single-source qualification below).
36
+ */
37
+ export const SELF_ALIAS = '__vm_self';
38
+ function columnExpr(name) {
39
+ return { type: 'column', name };
40
+ }
41
+ function tableIdentifier(table) {
42
+ return { type: 'identifier', name: table.name, schema: table.schemaName };
43
+ }
44
+ /** Flatten a conjunction (`a AND b AND c`) into its conjuncts. */
45
+ export function flattenAnd(expr) {
46
+ if (expr.type === 'binary' && expr.operator === 'AND') {
47
+ return [...flattenAnd(expr.left), ...flattenAnd(expr.right)];
48
+ }
49
+ return [expr];
50
+ }
51
+ /** Conjoin two optional predicates with AND. */
52
+ export function combineAnd(a, b) {
53
+ if (a && b)
54
+ return { type: 'binary', operator: 'AND', left: a, right: b };
55
+ return a ?? b;
56
+ }
57
+ /**
58
+ * Rewrite base-term column references so they resolve against the single base
59
+ * table after the rewrite. The view body may qualify its base columns by the
60
+ * source's alias or the base table name (`x.col` / `pa.col`); the rewritten
61
+ * statement has exactly one source, so those qualifiers are dropped (an
62
+ * unqualified reference resolves unambiguously). This normalizes the **view
63
+ * body's own** projection / WHERE terms (already in base terms); it does not
64
+ * descend into subqueries, which is correct here — the body's own subqueries are
65
+ * conjoined / projected verbatim, not re-bound against view columns. The
66
+ * **user** predicate / assigned-value descent (where a nested reference can name
67
+ * a *view* column) is handled separately by {@link makeViewColumnDescend}.
68
+ */
69
+ function normalizeBaseRefs(expr, aliases) {
70
+ return transformExpr(expr, (col) => col.table && aliases.has(col.table.toLowerCase()) ? { type: 'column', name: col.name } : undefined);
71
+ }
72
+ /**
73
+ * Build the closure that correlation-qualifies a substituted base *term* emitted
74
+ * INSIDE a subquery operand of a single-source rewrite. An unqualified base term
75
+ * there would re-bind to a same-named source the subquery's own FROM introduces
76
+ * (innermost SQL scoping) instead of correlating to the outer UPDATE/DELETE target
77
+ * row. Qualifying it with `qualifierName` makes it correlate to the outer row
78
+ * regardless of what the subquery FROM defines. For UPDATE/DELETE the caller passes
79
+ * the lowered target's synthesised collision-proof alias ({@link SELF_ALIAS}), so the
80
+ * qualified term binds the outer row even when the subquery FROM names the view's own
81
+ * base table; INSERT leaves it at the base table name (no target-row scan to collide
82
+ * with). Default is the bare base table name.
83
+ *
84
+ * The qualification is **scope-aware and DEEP** (it rides the shared
85
+ * {@link transformScopedExpr} descent over {@link makeBaseQualifyScope}): it
86
+ * qualifies a base-table column at the replacement's top level, and descends into a
87
+ * nested scalar subquery WITHIN the replacement (a computed lineage term such as
88
+ * `(select x from oth where fk = id)`), qualifying only the lineage's own
89
+ * correlation refs — a base column not shadowed by the lineage subquery's own FROM
90
+ * — and leaving the lineage's genuinely-local columns alone. The multi-source
91
+ * spine has its own analog (`makeSideQualifyScope` in multi-source.ts), which
92
+ * qualifies a bare lineage leaf with its owning side's alias.
93
+ *
94
+ * Returns a fresh tree (does not mutate the shared `columnMap` entry).
95
+ */
96
+ function makeBaseQualifier(ctx, baseTable, qualifierName = baseTable.name) {
97
+ const scope = makeBaseQualifyScope(baseTable, qualifierName);
98
+ return (repl) => transformScopedExpr(ctx, scope, repl);
99
+ }
100
+ /**
101
+ * The {@link ScopeContext} for the base-term correlation-qualifier — the
102
+ * scope-aware DEEP qualify of a substituted base term. Its substitution qualifies
103
+ * an unqualified BASE-table column that is not shadowed with `qualifierName` — the
104
+ * lowered statement's correlation name (the synthesised {@link SELF_ALIAS} for
105
+ * UPDATE/DELETE, the bare base table name for INSERT / multi-source). An
106
+ * already-qualified ref, a non-base name (a lineage-local column such as the `x` /
107
+ * `fk` a nested subquery's own FROM introduces), or a shadowed name is left untouched.
108
+ * Restricting to base columns changes nothing for a `normalizeBaseRefs`-normalized
109
+ * lineage (whose top-level refs are all base columns) and is the principled gate: only
110
+ * the view's own base-term lineage is correlation-qualified, never a column a nested
111
+ * source owns.
112
+ *
113
+ * An unresolvable scope (`select *` / TVF / CTE) is **rejected** rather than
114
+ * tainted-and-deferred: shadowing cannot be proven, so the term could over- or
115
+ * under-qualify into a silent wrong write (`unresolvableScope: 'reject'`).
116
+ */
117
+ function makeBaseQualifyScope(baseTable, qualifierName = baseTable.name) {
118
+ const qualifier = qualifierName;
119
+ const baseCols = new Set(baseTable.columns.map(c => c.name.toLowerCase()));
120
+ return {
121
+ makeSubstitute: (shadowed) => (col) => {
122
+ if (col.table)
123
+ return undefined;
124
+ const name = col.name.toLowerCase();
125
+ if (shadowed.has(name) || !baseCols.has(name))
126
+ return undefined;
127
+ return { ...col, table: qualifier };
128
+ },
129
+ unresolvableScope: 'reject',
130
+ rejectUnresolvableScope: () => raiseMutationDiagnostic({
131
+ reason: 'unsupported-subquery-correlation',
132
+ message: `cannot write through view: a computed column's lineage contains a correlated subquery whose source columns are not statically resolvable (a 'select *' / table-valued function / unresolved source), so its correlation cannot be proven; restructure the view body`,
133
+ }),
134
+ rejectDmlSubquery: () => raiseMutationDiagnostic({
135
+ reason: 'unsupported-subquery-correlation',
136
+ message: `cannot correlation-qualify a view lineage term: a data-modifying subquery (INSERT/UPDATE/DELETE) within it cannot be analysed`,
137
+ }),
138
+ };
139
+ }
140
+ // --- view-column descent into subquery operands ---------------------------
141
+ //
142
+ // `transformExpr` rewrites a view-column reference at the top level of a user
143
+ // predicate / assigned value. A reference nested inside a `subquery` / `exists` /
144
+ // `in`-subquery operand resolves in the *lowered* base statement's scope, where
145
+ // it can silently re-bind to a same-named base column instead of the view
146
+ // column's true lineage. The descent below (the shared scope-transform over
147
+ // {@link makeViewScope}) rewrites such a nested reference to its base term — but
148
+ // scope-aware, so it neither mis-binds a reference a subquery-local source
149
+ // introduces (`in (select note from src)` where `src.note` exists) nor touches a
150
+ // base-alias-qualified reference. A reference it cannot prove correlated (an
151
+ // unresolvable subquery source) is rejected loudly rather than mis-bound silently.
152
+ // See `docs/view-updateability.md` § Selection.
153
+ /**
154
+ * The {@link ScopeContext} for the view-column → base-term descent. A reference is
155
+ * rewritten to its base-term lineage only when it is genuinely correlated to the
156
+ * outer view row:
157
+ *
158
+ * - **qualified by the view name** → an unambiguous view-output reference;
159
+ * substitute (when the name is a known view column).
160
+ * - **unqualified**, a known view column, and NOT shadowed by a source local to
161
+ * this (or an enclosing) subquery scope → correlated to the outer view row;
162
+ * substitute.
163
+ * - **qualified by any other (base-alias) name**, or a name some local source
164
+ * introduces → left untouched.
165
+ *
166
+ * In a **tainted** scope (one whose local column names could not be resolved
167
+ * statically) an unqualified view-column-named reference cannot be proven
168
+ * correlated, so it is rejected with `unsupported-subquery-correlation` rather than
169
+ * silently mis-bound — hence `unresolvableScope: 'taint'` (the substitution decides
170
+ * per-reference once tainted, instead of rejecting the whole scope up front).
171
+ *
172
+ * When a replacement is emitted inside a subquery operand, `baseQualify`
173
+ * correlation-qualifies its base terms (scope-aware and deep — see
174
+ * {@link makeBaseQualifier}) so they bind to the outer (UPDATE/DELETE target) row
175
+ * rather than re-binding to a same-named local source. The single-source rewriters
176
+ * pass it; the multi-source spine passes its side-alias qualifier
177
+ * (`makeSideQualifyScope`), which qualifies a bare lineage leaf with its owning
178
+ * side's alias. `resolve` returns a fresh tree, never the shared `columnMap`
179
+ * entry.
180
+ */
181
+ function makeViewScope(columnMap, viewName, view, baseQualify) {
182
+ const lcView = viewName.toLowerCase();
183
+ const resolve = (name) => {
184
+ const repl = columnMap.get(name);
185
+ if (!repl || !baseQualify)
186
+ return repl;
187
+ return baseQualify(repl);
188
+ };
189
+ return {
190
+ makeSubstitute: (shadowed, tainted, aliasShadowed) => (col) => {
191
+ const name = col.name.toLowerCase();
192
+ if (col.table) {
193
+ const lcQual = col.table.toLowerCase();
194
+ // A view-name-qualified ref (`t.id`) is normally an unambiguous outer
195
+ // view-output correlation, rewritten to its base-term lineage. BUT when the
196
+ // SAME name is a locally-shadowed FROM alias — the user-predicate self-read
197
+ // `select t.id from t` over the eager capture — `t.id` is the capture's own
198
+ // column, not an outer correlation; leave it local (innermost-scope SQL
199
+ // rules) so it binds to the captured snapshot rather than a de-correlated
200
+ // `__vm_self`-qualified base term (docs/view-updateability.md § Common Table
201
+ // Expressions — self-reference). Other ScopeContext implementers never reach
202
+ // this branch with an aliased self-read (no own-name to shadow).
203
+ if (aliasShadowed.has(lcQual))
204
+ return undefined;
205
+ return lcQual === lcView ? resolve(name) : undefined;
206
+ }
207
+ if (shadowed.has(name))
208
+ return undefined;
209
+ if (!columnMap.has(name))
210
+ return undefined;
211
+ if (tainted) {
212
+ raiseMutationDiagnostic({
213
+ reason: 'unsupported-subquery-correlation',
214
+ table: view.name,
215
+ column: col.name,
216
+ message: `cannot write through view '${view.name}': the reference '${col.name}' inside a subquery cannot be proven correlated to the view because the subquery's source columns are not statically resolvable (a 'select *' / table-valued function / unresolved source); qualify the reference with its base table or alias, or restructure the predicate`,
217
+ });
218
+ }
219
+ return resolve(name);
220
+ },
221
+ unresolvableScope: 'taint',
222
+ rejectDmlSubquery: () => raiseMutationDiagnostic({
223
+ reason: 'unsupported-subquery-correlation',
224
+ table: view.name,
225
+ message: `cannot write through view '${view.name}': a data-modifying subquery (INSERT/UPDATE/DELETE) in a predicate or assigned value cannot be analysed for view-column correlation`,
226
+ }),
227
+ };
228
+ }
229
+ /**
230
+ * Build the `descend` transformer threaded into the top-level {@link transformExpr}
231
+ * calls on a user predicate / assigned value, so a view-column reference nested in
232
+ * a `subquery` / `exists` / `in`-subquery operand is rewritten scope-aware to its
233
+ * base-term lineage. `columnMap` is the view-col (lowercase) → base-term map;
234
+ * `viewName` is the view's own name (so a `view.col` qualifier is recognised).
235
+ *
236
+ * `baseQualify` is the single-source lowered statement's correlation qualifier
237
+ * (built by {@link makeBaseQualifier} from the base table); the multi-source spine
238
+ * passes its side-alias qualifier (`makeSideQualifyScope`), which qualifies a bare
239
+ * lineage leaf with its owning side's alias. See {@link makeViewScope}.
240
+ */
241
+ export function makeViewColumnDescend(ctx, columnMap, viewName, view, baseQualify) {
242
+ const scope = makeViewScope(columnMap, viewName, view, baseQualify);
243
+ return (query) => transformScopedQuery(ctx, scope, query, new Set(), false);
244
+ }
245
+ /**
246
+ * Plan the view body, gate it for phase-1 mutability, and derive the
247
+ * view→base column model. Throws a structured diagnostic on any unsupported
248
+ * shape.
249
+ */
250
+ function analyzeView(ctx, view) {
251
+ // Lens read-only gate: a logical table whose primary key is not reconstructible
252
+ // at the lens boundary deploys read-only (the prover sets `LensSlot.readOnly`;
253
+ // docs/lens.md § Coverage checklist). Reads still resolve through the registered
254
+ // view; any mutation errors here with a precise diagnostic. The lookup only
255
+ // matches a logical schema's lens slot — a plain view / MV (physical schema) has
256
+ // none, so this never false-positives on ordinary view write-through.
257
+ const lensSlot = ctx.schemaManager.getSchema(view.schemaName)?.getLensSlot(view.name);
258
+ if (lensSlot?.readOnly) {
259
+ raiseMutationDiagnostic({
260
+ reason: 'lens-read-only',
261
+ table: view.name,
262
+ message: `cannot write through logical table '${view.schemaName}.${view.name}': its primary key is not reconstructible at the lens boundary, so it is read-only (deploy advisory lens.pk-not-reconstructible)`,
263
+ });
264
+ }
265
+ if (view.selectAst.type !== 'select') {
266
+ raiseMutationDiagnostic({
267
+ reason: 'no-base-lineage',
268
+ table: view.name,
269
+ message: `${view.noun ?? 'view'} '${view.name}' has a ${view.selectAst.type.toUpperCase()} body, which has no recoverable base operation`,
270
+ });
271
+ }
272
+ const sel = view.selectAst;
273
+ // Build the body plan and gate it (joins / aggregates / set-ops / recursive
274
+ // CTEs / VALUES bodies are rejected here).
275
+ const bodyPlan = buildSelectStmt(ctx, sel);
276
+ if (!isRelationalNode(bodyPlan)) {
277
+ raiseMutationDiagnostic({
278
+ reason: 'no-base-lineage',
279
+ table: view.name,
280
+ message: `${view.noun ?? 'view'} '${view.name}' body did not produce a relation`,
281
+ });
282
+ }
283
+ const classification = classifyViewBody(bodyPlan);
284
+ if (classification.kind === 'rejected') {
285
+ raiseMutationDiagnostic({
286
+ reason: classification.reason,
287
+ table: view.name,
288
+ // Name the target by its kind (`view.noun`) so a body-shape reject on a
289
+ // maintained table reads "materialized view 'm'", not the misleading
290
+ // plain-view framing. A maintained table reaches this and the sibling
291
+ // body-shape branches below — e.g. an aggregate-bodied MV here, or a
292
+ // subquery-in-FROM MV at the single-base-source branch — so every
293
+ // body-shape diagnostic in this function honours the noun.
294
+ message: `cannot write through ${view.noun ?? 'view'} '${view.name}': ${classification.detail}`,
295
+ });
296
+ }
297
+ const baseTable = classification.baseTable.tableSchema;
298
+ // Single-level base-table source only: a body that sources another view/CTE
299
+ // inlines to one table ref but its inner filters/projections live in the
300
+ // plan, not in this view's selectAst — driving the rewrite from selectAst
301
+ // would silently drop them. Reject (the inline-and-propagate generality is
302
+ // a later phase).
303
+ if (!sel.from || sel.from.length !== 1 || sel.from[0].type !== 'table') {
304
+ raiseMutationDiagnostic({
305
+ reason: 'nested-view',
306
+ table: view.name,
307
+ message: `cannot write through ${view.noun ?? 'view'} '${view.name}': only a single base-table source is supported in phase 1`,
308
+ });
309
+ }
310
+ const fromTable = sel.from[0];
311
+ if (ctx.schemaManager.getView(fromTable.table.schema ?? null, fromTable.table.name)) {
312
+ raiseMutationDiagnostic({
313
+ reason: 'nested-view',
314
+ table: view.name,
315
+ message: `cannot write through ${view.noun ?? 'view'} '${view.name}': its body references another view; nested-view mutation is not yet supported`,
316
+ });
317
+ }
318
+ // MV-over-MV (or a plain view over an MV): the body's single source is itself a
319
+ // maintained table, whose contents are derived — user DML may not write it
320
+ // directly. Write-through one level down (route to the inner MV's own
321
+ // write-through + the maintenance cascade) is deferred; reject cleanly. The
322
+ // source→backing maintenance cascade is unaffected — that is the read/maintain
323
+ // direction; this guards only the MV-name *write* direction.
324
+ // Checked both by name (current-schema default) and on the PLAN-resolved base
325
+ // table — the body's FROM resolves through the schema path, which can reach a
326
+ // maintained table the name lookup misses.
327
+ if (ctx.schemaManager.getMaintainedTable(fromTable.table.schema ?? null, fromTable.table.name)
328
+ || isMaintainedTable(baseTable)) {
329
+ raiseMutationDiagnostic({
330
+ reason: 'nested-view',
331
+ table: view.name,
332
+ message: `cannot write through '${view.name}': its body reads a materialized view; `
333
+ + `write-through to a materialized-view-over-materialized-view is not yet supported — write the base source instead`,
334
+ });
335
+ }
336
+ // LIMIT / OFFSET / DISTINCT are accepted by the plan-walk classifier as
337
+ // pass-through operators (so it can still reach the base table), but the
338
+ // predicate-conjoin rewrite cannot faithfully reproduce them: a row-count
339
+ // window or duplicate-collapse is not capturable as a WHERE predicate, so a
340
+ // mutation would affect base rows outside what the view exposes. Reject here
341
+ // rather than silently widening the write. (Phase 2 substrate territory.)
342
+ if (sel.limit || sel.offset) {
343
+ raiseMutationDiagnostic({
344
+ reason: 'unsupported-limit',
345
+ table: view.name,
346
+ message: `cannot write through ${view.noun ?? 'view'} '${view.name}': a LIMIT/OFFSET body is not decomposable in phase 1 (a mutation would escape the limited window)`,
347
+ });
348
+ }
349
+ if (sel.distinct) {
350
+ raiseMutationDiagnostic({
351
+ reason: 'unsupported-distinct',
352
+ table: view.name,
353
+ message: `cannot write through ${view.noun ?? 'view'} '${view.name}': a DISTINCT body has no 1:1 base-row lineage and is not updateable in phase 1`,
354
+ });
355
+ }
356
+ // Names that qualify the single base source inside the body — its alias (if
357
+ // any) and the table name as written. References so qualified are normalized
358
+ // to unqualified form when threaded into the rewritten single-source statement.
359
+ const baseAliases = new Set([fromTable.table.name.toLowerCase()]);
360
+ if (fromTable.alias)
361
+ baseAliases.add(fromTable.alias.toLowerCase());
362
+ // Build the view-column lineage model from the projection list (shared with
363
+ // the update-lineage analysis surface).
364
+ const viewColumns = deriveViewColumns(sel, baseTable, view.columns);
365
+ // Build the remap table: each view column → its base-term replacement
366
+ // (computed expressions are normalized so any alias-qualified base column
367
+ // resolves against the rewritten single-source statement).
368
+ const columnMap = new Map();
369
+ for (const vc of viewColumns) {
370
+ columnMap.set(vc.name.toLowerCase(), vc.lineage.kind === 'base' ? columnExpr(vc.lineage.baseColumnName) : normalizeBaseRefs(vc.lineage.expr, baseAliases));
371
+ }
372
+ const filterConstants = extractFilterConstants(sel.where, baseTable);
373
+ const filterPredicate = sel.where ? normalizeBaseRefs(sel.where, baseAliases) : undefined;
374
+ // Writable-base write sites (UPDATE SET + INSERT): read the threaded plan-node
375
+ // `updateLineage` off the already-planned body and, per view column, capture
376
+ // EVERY writable, non-null-extended base column (identity / passthrough /
377
+ // inverse) with its optional backward `inverse` closure. This is the
378
+ // single-source dual of what the multi-source spine consumes (whose
379
+ // `OutColumn.writable` is likewise the inverse-agnostic `base`-not-null-extended
380
+ // site). The identity-only AST readers (`deriveViewColumns` /
381
+ // `classifyProjectionExpr` / `viewColumnsFromUpdateLineage`) are deliberately NOT
382
+ // widened — their parity is pinned by `test/property.spec.ts` — so the richer
383
+ // `base` chain is read separately here via the shared `resolveBaseSite`. The UPDATE
384
+ // SET path routes any site (applying its `inverse` when present); INSERT
385
+ // (`rewriteViewInsert`) admits only the inverse-absent subset (identity + passthrough,
386
+ // stored verbatim). A passthrough (`collate` / no-op `cast`) or identity / rename
387
+ // column carries no `inverse`; an `inverse` column carries its closure (UPDATE-only —
388
+ // non-insertable); an `opaque` / null-extended column has no site, so a write to it
389
+ // still raises `no-inverse` via `requireBaseColumn`.
390
+ // `viewColumns[i]` ↔ `attrs[i]` holds because `deriveViewColumns` and the planned
391
+ // projection expand `select *` identically (the parity `viewColumnsFromUpdateLineage`
392
+ // relies on); a `*` column is pure identity, stored verbatim like any other.
393
+ const relBody = bodyPlan;
394
+ const attrs = relBody.getAttributes();
395
+ const lineage = relBody.physical.updateLineage;
396
+ const writableSites = new Map();
397
+ viewColumns.forEach((vc, i) => {
398
+ const site = resolveBaseSite(lineage?.get(attrs[i]?.id));
399
+ if (!site.writable || site.nullExtended)
400
+ return;
401
+ if (site.authored) {
402
+ // An authored (`with inverse`) site — writable and insertable through its
403
+ // put expressions. Single-source: every put target is a column of THE base
404
+ // table (the lineage routed each through the sole TableReferenceNode), so
405
+ // the table discriminator is dropped here.
406
+ writableSites.set(vc.name.toLowerCase(), {
407
+ kind: 'authored',
408
+ puts: site.authored.puts.map(p => ({ baseColumn: p.baseColumn, expr: p.expr })),
409
+ newRefIndex: site.authored.newRefIndex,
410
+ });
411
+ return;
412
+ }
413
+ if (site.baseColumn) {
414
+ writableSites.set(vc.name.toLowerCase(), {
415
+ kind: 'base',
416
+ baseColumn: site.baseColumn,
417
+ ...(site.inverse ? { inverse: site.inverse } : {}),
418
+ // No shipped invertibility profile produces a `domain` (`x ± k` is
419
+ // unrestricted over integers), so this is always absent today. Threaded
420
+ // for parity with multi-source (`multi-source.ts` decomposeUpdate), not
421
+ // yet conjoined into the identifying predicate — the documented deferral.
422
+ ...(site.domain ? { domain: site.domain } : {}),
423
+ });
424
+ }
425
+ });
426
+ return { baseTable, viewColumns, filterPredicate, filterConstants, columnMap, writableSites };
427
+ }
428
+ /**
429
+ * Build the eager **CTE self-read capture** for a CTE-name DML target whose user
430
+ * clauses self-read the target name (docs/view-updateability.md § Common Table
431
+ * Expressions — self-reference). The capture is the FULL body relation — every view
432
+ * column, **unfiltered** (the self-read `from t` is the whole relation, exactly a
433
+ * materialized CTE) — projected over the body planned under `ctx` (the **target-
434
+ * excluded** body context, so the body's own `from base` reaches the REAL base table,
435
+ * the load-bearing shadow case). It rides {@link import('../nodes/view-mutation-node.js').ViewMutationNode}'s
436
+ * `identityCapture`, which the emitter materializes ONCE before any base op runs — so
437
+ * the lowered base op's `from t` reads the pre-mutation snapshot, Halloween-safe by
438
+ * construction.
439
+ *
440
+ * Mirrors `set-op.ts`'s `buildSetOpCapture`, minus the user-WHERE filter (the whole
441
+ * relation, not just the affected rows — a self-read names the entire CTE). Returns a
442
+ * {@link MultiSourceKeyCapture} so the readers reuse `makeMultiSourceKeyRef` /
443
+ * `withCteCapture` and the existing `identityCapture` side-input substrate verbatim.
444
+ *
445
+ * Deliberately plans the body a SECOND time (alongside `analyzeView`'s own body plan,
446
+ * threaded through `rewriteViewUpdate`/`Delete`): a localization tradeoff the ticket
447
+ * accepts — the body is a cheap single-source projection-and-filter, and the capture's
448
+ * projection over a freshly-planned root keeps the descriptor self-contained.
449
+ */
450
+ export function buildCteSelfCapture(ctx, view) {
451
+ // Gate + derive the view-column model (names honour a `t(a,b)` rename via
452
+ // `deriveViewColumns`; an unsupported body shape rejects here just as the lowering's
453
+ // own `analyzeView` would).
454
+ const analysis = analyzeView(ctx, view);
455
+ const sel = view.selectAst; // analyzeView already proved a SELECT body
456
+ const bodyPlan = buildSelectStmt(ctx, sel);
457
+ const attrs = bodyPlan.getAttributes();
458
+ // One capture column per view column, positionally aligned to the body plan's
459
+ // attributes (the `viewColumns[i] ↔ attrs[i]` parity `analyzeView` relies on). The
460
+ // renamed name is the capture column name, so a self-read `from t` exposes the
461
+ // renamed columns; the type/id come from the planned attribute.
462
+ const projections = analysis.viewColumns.map((vc, i) => {
463
+ const attr = attrs[i];
464
+ const node = new ColumnReferenceNode(ctx.scope, { type: 'column', name: vc.name }, attr.type, attr.id, i);
465
+ return { node, alias: vc.name };
466
+ });
467
+ // preserveInputColumns=false → the materialized rows are exactly the view columns.
468
+ const source = new ProjectNode(ctx.scope, bodyPlan, projections, undefined, undefined, false);
469
+ const keyColumns = analysis.viewColumns.map((vc, i) => ({ name: vc.name, type: attrs[i].type }));
470
+ return { source, descriptor: {}, keyColumns };
471
+ }
472
+ /** Extract `baseColumn = literal` bindings from the view's selection predicate. */
473
+ function extractFilterConstants(where, baseTable) {
474
+ const out = [];
475
+ if (!where)
476
+ return out;
477
+ for (const conj of flattenAnd(where)) {
478
+ if (conj.type !== 'binary' || conj.operator !== '=')
479
+ continue;
480
+ const colSide = conj.left.type === 'column' ? conj.left : conj.right.type === 'column' ? conj.right : undefined;
481
+ const litSide = conj.left.type === 'literal' ? conj.left : conj.right.type === 'literal' ? conj.right : undefined;
482
+ if (!colSide || !litSide)
483
+ continue;
484
+ const baseCol = baseTable.columns.find(c => c.name.toLowerCase() === colSide.name.toLowerCase());
485
+ if (!baseCol)
486
+ continue;
487
+ const value = litSide.value instanceof Promise ? undefined : litSide.value;
488
+ out.push({ baseColumnName: baseCol.name, valueExpr: litSide, value });
489
+ }
490
+ return out;
491
+ }
492
+ function findViewColumn(analysis, name, view) {
493
+ const vc = analysis.viewColumns.find(c => c.name.toLowerCase() === name.toLowerCase());
494
+ if (!vc) {
495
+ // A `set` target / `insert` target column that is not a view column at all —
496
+ // the same encapsulation-leak guard the top-level `where` / `returning` scan
497
+ // applies (a base-only column must not be writable through the view). Computed
498
+ // view columns ARE found here and surface the `no-inverse` diagnostic instead.
499
+ raiseUnknownViewColumn(name, view, analysis.viewColumns.map(c => c.name));
500
+ }
501
+ return vc;
502
+ }
503
+ /**
504
+ * Visit every column reference at the TOP LEVEL of a scalar expression — i.e. NOT
505
+ * descending into a `subquery` / `exists` / `in`-subquery operand (those nested
506
+ * references resolve in the lowered base scope and are handled scope-aware by
507
+ * {@link makeViewColumnDescend}; the nested-rebind correctness ticket
508
+ * `view-mutation-single-source-subquery-base-term-local-rebind` owns them). The
509
+ * structure mirrors {@link transformExpr} exactly, minus the subquery descent.
510
+ */
511
+ function forEachTopLevelColumn(expr, visit) {
512
+ switch (expr.type) {
513
+ case 'column':
514
+ visit(expr);
515
+ return;
516
+ case 'binary':
517
+ forEachTopLevelColumn(expr.left, visit);
518
+ forEachTopLevelColumn(expr.right, visit);
519
+ return;
520
+ case 'unary':
521
+ case 'cast':
522
+ case 'collate':
523
+ forEachTopLevelColumn(expr.expr, visit);
524
+ return;
525
+ case 'function':
526
+ expr.args.forEach(a => forEachTopLevelColumn(a, visit));
527
+ return;
528
+ case 'between':
529
+ forEachTopLevelColumn(expr.expr, visit);
530
+ forEachTopLevelColumn(expr.lower, visit);
531
+ forEachTopLevelColumn(expr.upper, visit);
532
+ return;
533
+ case 'case':
534
+ if (expr.baseExpr)
535
+ forEachTopLevelColumn(expr.baseExpr, visit);
536
+ expr.whenThenClauses.forEach(w => { forEachTopLevelColumn(w.when, visit); forEachTopLevelColumn(w.then, visit); });
537
+ if (expr.elseExpr)
538
+ forEachTopLevelColumn(expr.elseExpr, visit);
539
+ return;
540
+ case 'in':
541
+ forEachTopLevelColumn(expr.expr, visit);
542
+ if (expr.values)
543
+ expr.values.forEach(v => forEachTopLevelColumn(v, visit));
544
+ // expr.subquery is a nested scope — intentionally not descended.
545
+ return;
546
+ default:
547
+ // subquery / exists — nested scope, not validated here.
548
+ // literal / identifier / parameter / windowFunction / functionSource —
549
+ // no top-level column reference to validate.
550
+ return;
551
+ }
552
+ }
553
+ /**
554
+ * Raise the structured `unknown-view-column` diagnostic for a reference that names
555
+ * something the view does not expose. `displayColumns` is the view's exposed column
556
+ * list (in display spelling) for the suggestion.
557
+ */
558
+ export function raiseUnknownViewColumn(spelling, view, displayColumns) {
559
+ raiseMutationDiagnostic({
560
+ reason: 'unknown-view-column',
561
+ column: spelling,
562
+ table: view.name,
563
+ message: `cannot write through view '${view.name}': '${spelling}' is not a column of the view`,
564
+ suggestion: `view '${view.name}' exposes: ${displayColumns.join(', ')}.`,
565
+ });
566
+ }
567
+ /**
568
+ * Enforce **view-column scope** on the TOP-LEVEL references of a user `where` /
569
+ * `returning` clause (the `set` targets are guarded separately at their resolution
570
+ * point). Without this, a name that is not a view column passes through the
571
+ * view→base remap unmapped and silently re-binds against the underlying base
572
+ * table(s) — an encapsulation leak letting a column the view projects away be
573
+ * filtered / returned. A reference must name a column the view exposes, optionally
574
+ * qualified by the view's own name; a bare base-column name (`secret`), a renamed
575
+ * column's base spelling (`label` for a `… as note` projection), or a view-qualified
576
+ * unknown (`sv.secret`) are all rejected. A computed view column passes here (it IS
577
+ * a view column) so a write to it still surfaces the existing `no-inverse`
578
+ * diagnostic. Shared by the single-source spine and the multi-source join path so
579
+ * the two read consistently.
580
+ */
581
+ /** Single-source convenience: build the scope sets from a {@link ViewAnalysis}. */
582
+ function guardTopLevelScope(expr, analysis, view) {
583
+ assertTopLevelViewColumns(expr, new Set(analysis.viewColumns.map(c => c.name.toLowerCase())), analysis.viewColumns.map(c => c.name), view);
584
+ }
585
+ export function assertTopLevelViewColumns(expr, viewColumnNames, displayColumns, view) {
586
+ const lcView = view.name.toLowerCase();
587
+ forEachTopLevelColumn(expr, (col) => {
588
+ const qualifier = col.table?.toLowerCase();
589
+ const known = viewColumnNames.has(col.name.toLowerCase());
590
+ if ((qualifier !== undefined && qualifier !== lcView) || !known) {
591
+ raiseUnknownViewColumn(col.table ? `${col.table}.${col.name}` : col.name, view, displayColumns);
592
+ }
593
+ });
594
+ }
595
+ /** Resolve a view column to a writable base column, rejecting computed columns. */
596
+ function requireBaseColumn(vc) {
597
+ if (vc.lineage.kind === 'computed') {
598
+ raiseMutationDiagnostic({
599
+ reason: 'no-inverse',
600
+ column: vc.name,
601
+ message: `cannot write through view: column '${vc.name}' is a computed (non-invertible) expression and is read-only`,
602
+ });
603
+ }
604
+ return vc.lineage.baseColumnName;
605
+ }
606
+ /**
607
+ * Resolve an insert-default column name (from the body's `with defaults (col = expr, …)`
608
+ * clause) to its base column. The name may be a base column (the documented
609
+ * projected-away case) or a view column with `base` lineage. An unknown name is
610
+ * a structured `default-target-not-found` — a typo must fail loudly, not silently
611
+ * no-op. `spelling` names the offending clause entry in the diagnostic.
612
+ */
613
+ function resolveDefaultForColumn(analysis, colName, view, spelling) {
614
+ const baseCol = analysis.baseTable.columns.find(c => c.name.toLowerCase() === colName);
615
+ if (baseCol)
616
+ return baseCol.name;
617
+ const vc = analysis.viewColumns.find(c => c.name.toLowerCase() === colName);
618
+ if (vc && vc.lineage.kind === 'base')
619
+ return vc.lineage.baseColumnName;
620
+ raiseMutationDiagnostic({
621
+ reason: 'default-target-not-found',
622
+ column: colName,
623
+ table: view.name,
624
+ message: `cannot write through view '${view.name}': ${spelling} names column '${colName}', which is not a column of the view or its base table '${analysis.baseTable.name}'`,
625
+ });
626
+ }
627
+ /** Build a substitution fn that remaps view column references to base terms. */
628
+ function remapper(analysis) {
629
+ return (col) => analysis.columnMap.get(col.name.toLowerCase());
630
+ }
631
+ // --- INSERT ---------------------------------------------------------------
632
+ export function rewriteViewInsert(ctx, stmt, view) {
633
+ const analysis = analyzeView(ctx, view);
634
+ // A view column is INSERTABLE iff it has a writable base site with NO inverse:
635
+ // `identity` / rename and `passthrough` (`b collate nocase`, no-op `cast`), whose
636
+ // inserted value is stored verbatim. An `inverse` column (a site WITH an inverse) and
637
+ // an `opaque` computed column (no site) are NOT insertable — the lowering writes the
638
+ // value raw, with no hook to apply an inverse. This is exactly the multi-source
639
+ // contract (`outColumns.filter(c => c.writable && !c.inverse)`), so the single- and
640
+ // multi-source INSERT spines now admit the identical set. (A bare "has a site" gate
641
+ // would wrongly admit an inverse column; the `inverse === undefined` check is load-bearing.)
642
+ // An AUTHORED (`with inverse`) column is the exception that supplies exactly that
643
+ // hook: it IS insertable — its puts are evaluated per VALUES row below — so the
644
+ // insertability gate is lifted for authored sites only (registry-`inverse` columns
645
+ // stay non-insertable; docs/view-updateability.md § Authored inverses).
646
+ const insertableBaseColumn = (name) => {
647
+ const site = analysis.writableSites.get(name.toLowerCase());
648
+ return site?.kind === 'base' && site.inverse === undefined ? site.baseColumn : undefined;
649
+ };
650
+ const authoredSiteOf = (name) => {
651
+ const site = analysis.writableSites.get(name.toLowerCase());
652
+ return site?.kind === 'authored' ? site : undefined;
653
+ };
654
+ // Target view columns: the explicit list, or every non-generated INSERTABLE view
655
+ // column (display order preserved) — verbatim-insertable or authored. An exposed
656
+ // `inverse` / `opaque` computed column is omitted from the implicit set so it falls
657
+ // to its base default / NOT NULL check (matching multi-source) rather than erroring.
658
+ const targetNames = stmt.columns && stmt.columns.length > 0
659
+ ? stmt.columns
660
+ : analysis.viewColumns
661
+ .filter(vc => !vc.generated && (insertableBaseColumn(vc.name) !== undefined || authoredSiteOf(vc.name) !== undefined))
662
+ .map(vc => vc.name);
663
+ if (targetNames.some(name => authoredSiteOf(name) !== undefined)) {
664
+ return rewriteAuthoredViewInsert(ctx, stmt, view, analysis, targetNames, insertableBaseColumn, authoredSiteOf);
665
+ }
666
+ // Resolve each target to its writable base column: an insertable writable site
667
+ // (identity + passthrough) routes to its base column; otherwise fall back to
668
+ // `requireBaseColumn` (the identity base column, or `no-inverse` for an inverse /
669
+ // opaque column). `findViewColumn` stays the unknown-view-column guard on the fallback.
670
+ const baseColumns = targetNames.map(name => insertableBaseColumn(name) ?? requireBaseColumn(findViewColumn(analysis, name, view)));
671
+ // Merge the view's constant-FD defaults: a base column pinned by the
672
+ // selection predicate is supplied automatically when omitted, and a
673
+ // user-supplied literal that contradicts the pin is rejected at plan time.
674
+ const { appendColumns, appendExprs } = collectAppendedDefaults(analysis, view, baseColumns, (fc, idx) => checkContradiction(stmt.source, idx, fc, view));
675
+ const finalColumns = [...baseColumns, ...appendColumns];
676
+ let source = stmt.source;
677
+ if (appendExprs.length > 0) {
678
+ if (stmt.source.type !== 'values') {
679
+ raiseMutationDiagnostic({
680
+ reason: 'unsupported-source',
681
+ table: view.name,
682
+ message: `cannot write through view '${view.name}': supplying selection-predicate defaults requires a VALUES source in phase 1`,
683
+ });
684
+ }
685
+ source = {
686
+ type: 'values',
687
+ values: stmt.source.values.map(row => [...row, ...appendExprs.map(cloneExpr)]),
688
+ };
689
+ }
690
+ return {
691
+ type: 'insert',
692
+ table: tableIdentifier(analysis.baseTable),
693
+ columns: finalColumns,
694
+ source,
695
+ onConflict: stmt.onConflict,
696
+ upsertClauses: stmt.upsertClauses,
697
+ contextValues: stmt.contextValues,
698
+ returning: rewriteViewReturning(ctx, stmt.returning, analysis, view),
699
+ schemaPath: stmt.schemaPath,
700
+ loc: stmt.loc,
701
+ };
702
+ }
703
+ /**
704
+ * Collect the appended omitted-insert defaults shared by both INSERT lowerings:
705
+ * constant-FD selection pins first, then the body's `with defaults (…)` clause
706
+ * entries — each only for a base column the insert left unsupplied
707
+ * (docs/view-updateability.md § Projection step 5, § View defaults).
708
+ * `suppliedBaseColumns` are the base columns the insert targets directly
709
+ * (verbatim targets AND authored put targets — an authored target takes the
710
+ * inverse-computed value ahead of any default for that column: it is a supplied
711
+ * value, not an omission). `onPinnedSupplied` fires for a constant-FD pin whose
712
+ * base column IS supplied, with the index into `suppliedBaseColumns` (the plain
713
+ * path uses it for the literal-contradiction check; the authored path checks
714
+ * only its verbatim subset).
715
+ */
716
+ function collectAppendedDefaults(analysis, view, suppliedBaseColumns, onPinnedSupplied) {
717
+ const appendColumns = [];
718
+ const appendExprs = [];
719
+ const isSupplied = (baseCol) => suppliedBaseColumns.some(b => b.toLowerCase() === baseCol.toLowerCase())
720
+ || appendColumns.some(b => b.toLowerCase() === baseCol.toLowerCase());
721
+ for (const fc of analysis.filterConstants) {
722
+ const idx = suppliedBaseColumns.findIndex(b => b.toLowerCase() === fc.baseColumnName.toLowerCase());
723
+ if (idx >= 0) {
724
+ onPinnedSupplied(fc, idx);
725
+ }
726
+ else {
727
+ appendColumns.push(fc.baseColumnName);
728
+ appendExprs.push(fc.valueExpr);
729
+ }
730
+ }
731
+ // Omitted-insert defaults (the body's trailing `with defaults (…)` clause),
732
+ // applied ahead of the base column's declared default: the clause fills only a
733
+ // column the insert and the constant-FD chain left omitted — an explicit user
734
+ // value or a stronger predicate pin always wins. The clause value is already an
735
+ // AST expression — no text re-lowering. Pushing the schema-held node is safe:
736
+ // the VALUES rewrite clones per row.
737
+ for (const d of bodyDefaults(view.selectAst) ?? []) {
738
+ const baseCol = resolveDefaultForColumn(analysis, d.column.toLowerCase(), view, `'with defaults (${d.column} = …)'`);
739
+ if (isSupplied(baseCol))
740
+ continue;
741
+ appendColumns.push(baseCol);
742
+ appendExprs.push(d.expr);
743
+ }
744
+ return { appendColumns, appendExprs };
745
+ }
746
+ /**
747
+ * The INSERT lowering when ≥1 target view column carries an authored inverse
748
+ * (docs/view-updateability.md § Authored inverses). Per VALUES row, each authored
749
+ * column contributes one cell per put: the authored expression with `new.<x>`
750
+ * bound to the supplied (post-view-defaulting) row values — the row's cell when
751
+ * `x` is a target column, the appended default expression when `x`'s base column
752
+ * is default-filled, NULL otherwise. Verbatim targets keep their cells; the
753
+ * appended defaults ride last, exactly as on the plain path. A SELECT source is
754
+ * rejected (the per-row cell substitution needs VALUES — same v1 boundary as the
755
+ * appended-defaults rewrite).
756
+ */
757
+ function rewriteAuthoredViewInsert(ctx, stmt, view, analysis, targetNames, insertableBaseColumn, authoredSiteOf) {
758
+ if (stmt.source.type !== 'values') {
759
+ raiseMutationDiagnostic({
760
+ reason: 'unsupported-source',
761
+ table: view.name,
762
+ message: `cannot insert through view '${view.name}': a column with an authored inverse (WITH INVERSE) requires a VALUES source in phase 1 (each put expression is evaluated per supplied row)`,
763
+ });
764
+ }
765
+ const values = stmt.source.values;
766
+ const verbatim = [];
767
+ const authored = [];
768
+ // Base column (lowercased) → the view column that supplies it — two supplied view
769
+ // columns landing on one base column (an authored put colliding with a verbatim
770
+ // target or another put) is ill-defined, mirroring the UPDATE collision guard.
771
+ const baseOwner = new Map();
772
+ const claimBase = (baseColumn, viewColumn) => {
773
+ const key = baseColumn.toLowerCase();
774
+ const prior = baseOwner.get(key);
775
+ if (prior !== undefined) {
776
+ raiseMutationDiagnostic({
777
+ reason: 'conflicting-assignment',
778
+ column: baseColumn,
779
+ table: view.name,
780
+ message: `cannot insert through view '${view.name}': columns '${prior}' and '${viewColumn}' both supply base column '${baseColumn}'`,
781
+ });
782
+ }
783
+ baseOwner.set(key, viewColumn);
784
+ };
785
+ targetNames.forEach((name, srcIndex) => {
786
+ const site = authoredSiteOf(name);
787
+ if (site) {
788
+ for (const put of site.puts)
789
+ claimBase(put.baseColumn, name);
790
+ authored.push({ viewColumn: name, site });
791
+ return;
792
+ }
793
+ const baseColumn = insertableBaseColumn(name) ?? requireBaseColumn(findViewColumn(analysis, name, view));
794
+ claimBase(baseColumn, name);
795
+ verbatim.push({ baseColumn, srcIndex });
796
+ });
797
+ // Appended defaults over the FULL supplied base set (verbatim + authored puts):
798
+ // an authored put target is a supplied value, so it shadows any `with defaults`
799
+ // entry / constant-FD pin for that base column. The literal-contradiction check
800
+ // applies only to verbatim targets (an authored cell is computed, not a literal).
801
+ const suppliedBase = [...verbatim.map(v => v.baseColumn), ...authored.flatMap(a => a.site.puts.map(p => p.baseColumn))];
802
+ const { appendColumns, appendExprs } = collectAppendedDefaults(analysis, view, suppliedBase, (fc, suppliedIndex) => {
803
+ const v = verbatim.find(t => t.baseColumn.toLowerCase() === suppliedBase[suppliedIndex].toLowerCase());
804
+ if (v)
805
+ checkContradiction(stmt.source, v.srcIndex, fc, view);
806
+ });
807
+ // `new.<x>` binding for one row: the supplied cell when `x` is a target view
808
+ // column; the appended default expression when `x` resolves to a default-filled
809
+ // base column (the post-view-defaulting row image); NULL otherwise. `x` is a
810
+ // SELECT-output name, so it bridges POSITIONALLY through the site's validated
811
+ // `newRefIndex` to the view column (an explicit `create view v(a, b)` column
812
+ // list renames outputs — a name lookup against `targetNames` would mis-bind).
813
+ const targetIndexByName = new Map();
814
+ targetNames.forEach((n, i) => {
815
+ if (!targetIndexByName.has(n.toLowerCase()))
816
+ targetIndexByName.set(n.toLowerCase(), i);
817
+ });
818
+ const appendExprFor = (name) => {
819
+ const baseCol = insertableBaseColumn(name);
820
+ if (baseCol === undefined)
821
+ return undefined;
822
+ const ai = appendColumns.findIndex(b => b.toLowerCase() === baseCol.toLowerCase());
823
+ return ai >= 0 ? appendExprs[ai] : undefined;
824
+ };
825
+ const finalColumns = [
826
+ ...verbatim.map(v => v.baseColumn),
827
+ ...authored.flatMap(a => a.site.puts.map(p => p.baseColumn)),
828
+ ...appendColumns,
829
+ ];
830
+ const newValues = values.map(row => {
831
+ if (row.length !== targetNames.length) {
832
+ raiseMutationDiagnostic({
833
+ reason: 'unsupported-source',
834
+ table: view.name,
835
+ message: `cannot insert through view '${view.name}': a VALUES row supplies ${row.length} value(s) but ${targetNames.length} view column(s) are targeted`,
836
+ });
837
+ }
838
+ const resolveNewFor = (a) => (name) => {
839
+ const idx = requireValidatedNewRefIndex(a.site.newRefIndex, name, a.viewColumn);
840
+ const viewName = analysis.viewColumns[idx]?.name;
841
+ const ti = viewName !== undefined ? targetIndexByName.get(viewName.toLowerCase()) : undefined;
842
+ if (ti !== undefined)
843
+ return row[ti];
844
+ return (viewName !== undefined ? appendExprFor(viewName) : undefined) ?? { type: 'literal', value: null };
845
+ };
846
+ return [
847
+ ...verbatim.map(v => row[v.srcIndex]),
848
+ ...authored.flatMap(a => a.site.puts.map(p => substituteNewRefs(p.expr, resolveNewFor(a)))),
849
+ ...appendExprs.map(cloneExpr),
850
+ ];
851
+ });
852
+ return {
853
+ type: 'insert',
854
+ table: tableIdentifier(analysis.baseTable),
855
+ columns: finalColumns,
856
+ source: { type: 'values', values: newValues },
857
+ onConflict: stmt.onConflict,
858
+ upsertClauses: stmt.upsertClauses,
859
+ contextValues: stmt.contextValues,
860
+ returning: rewriteViewReturning(ctx, stmt.returning, analysis, view),
861
+ schemaPath: stmt.schemaPath,
862
+ loc: stmt.loc,
863
+ };
864
+ }
865
+ /** Reject an insert literal that contradicts a selection-predicate constant. */
866
+ function checkContradiction(source, columnIndex, fc, view) {
867
+ if (source.type !== 'values' || fc.value === undefined)
868
+ return;
869
+ for (const row of source.values) {
870
+ const cell = row[columnIndex];
871
+ if (!cell || cell.type !== 'literal' || cell.value instanceof Promise)
872
+ continue;
873
+ if (!sqlValuesEqual(cell.value, fc.value)) {
874
+ raiseMutationDiagnostic({
875
+ reason: 'predicate-contradiction',
876
+ column: fc.baseColumnName,
877
+ table: view.name,
878
+ message: `insert into view '${view.name}' contradicts its selection predicate on column '${fc.baseColumnName}'`,
879
+ });
880
+ }
881
+ }
882
+ }
883
+ // --- UPDATE ---------------------------------------------------------------
884
+ export function rewriteViewUpdate(ctx, stmt, view, descendCtx) {
885
+ const analysis = analyzeView(ctx, view);
886
+ const substitute = remapper(analysis);
887
+ // Qualify substituted subquery-descent base terms with the lowered target's
888
+ // synthesised alias (SELF_ALIAS) so they correlate to the outer target row even
889
+ // when the user subquery FROM names the view's own base table (the same-base-table
890
+ // self-reference corner). The lowered statement carries `alias: SELF_ALIAS` below.
891
+ //
892
+ // `descendCtx` (a CTE-name DML target's `ctxSelfRead` — the body context with the
893
+ // target name re-added to `cteNodes`, resolving to the eager capture) drives ONLY
894
+ // the user-clause subquery descent, so a self-read `from t` resolves `t`'s columns
895
+ // against the capture (a clean shadowing local source). `analyzeView` keeps planning
896
+ // the BODY under the target-EXCLUDED `ctx` (so the body's own `from base` reaches the
897
+ // real table — the load-bearing shadow case). Absent it, `descendCtx ?? ctx` is the
898
+ // byte-identical no-self-read path.
899
+ const descend = makeViewColumnDescend(descendCtx ?? ctx, analysis.columnMap, view.name, view, makeBaseQualifier(ctx, analysis.baseTable, SELF_ALIAS));
900
+ // Scope guard: `set` targets, assigned values, and the top-level `where`
901
+ // references must name view columns (a base-only name must not leak through to
902
+ // the underlying table).
903
+ if (stmt.where)
904
+ guardTopLevelScope(stmt.where, analysis, view);
905
+ // View-aware collision guard: two distinct view columns may lower to one base
906
+ // column (e.g. `select id, b, b+1 as bp` → `set b=5, bp=100`, or a duplicate
907
+ // rename `b, b as b2` → `set b=1, b2=2`). The base backstop in building/update.ts
908
+ // would reject these but report the base column twice; detect it here so the
909
+ // message names both view columns the user actually wrote. Rejected
910
+ // unconditionally — value-agreement (`set b=5, b2=5`) is not softened.
911
+ const seenBaseColumns = new Map(); // base column (lower) → first view-column spelling
912
+ const recordBaseColumn = (baseColumn, viewColumn) => {
913
+ const key = baseColumn.toLowerCase();
914
+ const prior = seenBaseColumns.get(key);
915
+ if (prior !== undefined) {
916
+ raiseMutationDiagnostic({
917
+ reason: 'conflicting-assignment',
918
+ column: baseColumn,
919
+ table: view.name,
920
+ message: `cannot write through view '${view.name}': columns '${prior}' and '${viewColumn}' both target base column '${baseColumn}'; an UPDATE cannot assign one column twice`,
921
+ });
922
+ }
923
+ seenBaseColumns.set(key, viewColumn);
924
+ };
925
+ // `new.<x>` binds the WRITTEN view row: when `x` is also assigned in this
926
+ // statement, that assignment's value (every embedded RHS reads the pre-update
927
+ // row, exactly like the sibling assignment's own lowering — so cross-references
928
+ // are order-independent); otherwise the column's forward read image. First
929
+ // occurrence wins on a duplicate target — the collision guard below rejects the
930
+ // statement anyway. Keyed by view-column index (the `newRefIndex` domain).
931
+ const assignedValueByIdx = new Map();
932
+ stmt.assignments.forEach(a => {
933
+ const i = analysis.viewColumns.findIndex(c => c.name.toLowerCase() === a.column.toLowerCase());
934
+ if (i >= 0 && !assignedValueByIdx.has(i))
935
+ assignedValueByIdx.set(i, a.value);
936
+ });
937
+ const assignments = stmt.assignments.flatMap(asg => {
938
+ // Enforce view-column scope on the SET target (an unknown / base-only name is
939
+ // rejected here; a computed view column is found and surfaces `no-inverse` below).
940
+ const vc = findViewColumn(analysis, asg.column, view);
941
+ // The assigned VALUE's top-level references must also name view columns — a
942
+ // base-only name on the RHS would otherwise read a column the view projects
943
+ // away (the same encapsulation leak as the `where` / `set`-target guard).
944
+ guardTopLevelScope(asg.value, analysis, view);
945
+ const site = analysis.writableSites.get(asg.column.toLowerCase());
946
+ // An authored (`with inverse`) column lowers to ONE base assignment per put:
947
+ // inside each authored expression, `new.<x>` becomes the assigned value when
948
+ // `x` is assigned in this statement (including `x` = this column) and that
949
+ // view column's name otherwise — still in VIEW terms — then the standard
950
+ // view→base lowering maps everything to base terms (the forward read image
951
+ // for the non-assigned columns). The result is a plain base-table `set` per
952
+ // target riding the existing spine (docs/view-updateability.md § Authored
953
+ // inverses).
954
+ if (site?.kind === 'authored') {
955
+ return site.puts.map(put => {
956
+ const viewTermExpr = substituteNewRefs(put.expr, name => {
957
+ const idx = requireValidatedNewRefIndex(site.newRefIndex, name, asg.column);
958
+ return assignedValueByIdx.get(idx) ?? columnExpr(analysis.viewColumns[idx].name);
959
+ });
960
+ const lowered = transformExpr(viewTermExpr, substitute, descend);
961
+ recordBaseColumn(put.baseColumn, asg.column);
962
+ return { column: put.baseColumn, value: lowered };
963
+ });
964
+ }
965
+ const loweredValue = transformExpr(asg.value, substitute, descend);
966
+ // Route the SET target through the full writable-base set (identity / passthrough
967
+ // / inverse), mirroring the multi-source spine. An `inverse`-profile column (e.g.
968
+ // `b + 1 as bp`) runs the lowered value through the site's `inverse` (`set bp = 9`
969
+ // ⇒ `set b = 9 - 1`); an identity / passthrough column (`b collate nocase as bc`,
970
+ // no-op `cast`) has no inverse and stores the value verbatim. The inverse expects
971
+ // a value already in base terms, so it wraps the lowered value LAST (after
972
+ // base-term substitution). `findViewColumn` above stays the unknown-column guard;
973
+ // only an opaque `computed` column reaches `requireBaseColumn` (→ `no-inverse`).
974
+ if (site) {
975
+ recordBaseColumn(site.baseColumn, asg.column);
976
+ return [{ column: site.baseColumn, value: site.inverse ? site.inverse(loweredValue) : loweredValue }];
977
+ }
978
+ const baseColumn = requireBaseColumn(vc);
979
+ recordBaseColumn(baseColumn, asg.column);
980
+ return [{ column: baseColumn, value: loweredValue }];
981
+ });
982
+ const userWhere = stmt.where ? transformExpr(stmt.where, substitute, descend) : undefined;
983
+ const where = combineAnd(userWhere, analysis.filterPredicate ? cloneExpr(analysis.filterPredicate) : undefined);
984
+ return {
985
+ type: 'update',
986
+ table: tableIdentifier(analysis.baseTable),
987
+ // Synthesised collision-proof correlation name on the lowered target; the base
988
+ // builder registers it as the target's AliasedScope alias so an `__vm_self.col`
989
+ // term (emitted by the SELF_ALIAS qualifier above, incl. in RETURNING subqueries)
990
+ // binds the outer target row regardless of the user subquery FROM.
991
+ alias: SELF_ALIAS,
992
+ assignments,
993
+ where,
994
+ contextValues: stmt.contextValues,
995
+ returning: rewriteViewReturning(ctx, stmt.returning, analysis, view, SELF_ALIAS, descendCtx),
996
+ schemaPath: stmt.schemaPath,
997
+ loc: stmt.loc,
998
+ };
999
+ }
1000
+ // --- DELETE ---------------------------------------------------------------
1001
+ export function rewriteViewDelete(ctx, stmt, view, descendCtx) {
1002
+ const analysis = analyzeView(ctx, view);
1003
+ const substitute = remapper(analysis);
1004
+ // Qualify substituted subquery-descent base terms with the lowered target's
1005
+ // synthesised alias (SELF_ALIAS) so they correlate to the outer target row even
1006
+ // when the user subquery FROM names the view's own base table (the same-base-table
1007
+ // self-reference corner). The lowered statement carries `alias: SELF_ALIAS` below.
1008
+ // `descendCtx` (a CTE self-read `ctxSelfRead`) drives the user-WHERE subquery descent
1009
+ // so a self-read `from t` resolves to the eager capture; see {@link rewriteViewUpdate}.
1010
+ const descend = makeViewColumnDescend(descendCtx ?? ctx, analysis.columnMap, view.name, view, makeBaseQualifier(ctx, analysis.baseTable, SELF_ALIAS));
1011
+ // Scope guard: top-level `where` references must name view columns.
1012
+ if (stmt.where)
1013
+ guardTopLevelScope(stmt.where, analysis, view);
1014
+ const userWhere = stmt.where ? transformExpr(stmt.where, substitute, descend) : undefined;
1015
+ const where = combineAnd(userWhere, analysis.filterPredicate ? cloneExpr(analysis.filterPredicate) : undefined);
1016
+ return {
1017
+ type: 'delete',
1018
+ table: tableIdentifier(analysis.baseTable),
1019
+ // Synthesised collision-proof correlation name on the lowered target; see
1020
+ // rewriteViewUpdate for the rationale (binds `__vm_self.col` to the outer row).
1021
+ alias: SELF_ALIAS,
1022
+ where,
1023
+ contextValues: stmt.contextValues,
1024
+ returning: rewriteViewReturning(ctx, stmt.returning, analysis, view, SELF_ALIAS, descendCtx),
1025
+ schemaPath: stmt.schemaPath,
1026
+ loc: stmt.loc,
1027
+ };
1028
+ }
1029
+ /**
1030
+ * Rewrite a view-mediated RETURNING clause into base terms so it rides the base
1031
+ * op's own RETURNING machinery. The returned rows are projected through the
1032
+ * **view's** column list (not the base table's): each view-column reference is
1033
+ * substituted to its base-term lineage and the user's view-term output name is
1034
+ * preserved as the result-column alias. The base builder then evaluates the
1035
+ * clause against NEW (insert/update) or OLD (delete), i.e. the post-mutation
1036
+ * (or, for delete, the deleted) base row — so computed view columns re-evaluate
1037
+ * against the post-mutation base values. `returning *` expands to every view
1038
+ * column. Returns `undefined` for an absent/empty clause.
1039
+ *
1040
+ * OLD/NEW qualifiers on a view-column reference are not honored through a view
1041
+ * (the qualifier is dropped, so the base op's default NEW/OLD binding applies);
1042
+ * the documented surface is unqualified / view-qualified view columns.
1043
+ *
1044
+ * `correlationName` is the lowered target's correlation name used to qualify
1045
+ * substituted base terms emitted inside a RETURNING subquery (a RETURNING subquery can
1046
+ * correlate to the target row the same way a WHERE subquery can). UPDATE/DELETE pass
1047
+ * the synthesised {@link SELF_ALIAS}; INSERT leaves it at the base table name (default).
1048
+ */
1049
+ /** Shared guard for `RETURNING <q>.*` through a view — validates the qualifier against the view name. */
1050
+ export function assertReturningStarQualifier(rcTable, viewName) {
1051
+ if (rcTable && rcTable.toLowerCase() !== viewName.toLowerCase()) {
1052
+ throw new QuereusError(`Table '${rcTable}' not found in FROM clause for qualified RETURNING *`, StatusCode.ERROR);
1053
+ }
1054
+ }
1055
+ export function rewriteViewReturning(ctx, returning, analysis, view, correlationName = analysis.baseTable.name,
1056
+ /** A CTE self-read `ctxSelfRead` driving the RETURNING-subquery descent so a
1057
+ * self-read `from t` resolves to the eager capture (the capture is materialized
1058
+ * before the base op, so the RETURNING re-projection reads the frozen snapshot).
1059
+ * Absent it, `descendCtx ?? ctx` is the byte-identical no-self-read path. */
1060
+ descendCtx) {
1061
+ if (!returning || returning.length === 0)
1062
+ return undefined;
1063
+ const substitute = remapper(analysis);
1064
+ const descend = makeViewColumnDescend(descendCtx ?? ctx, analysis.columnMap, view.name, view, makeBaseQualifier(ctx, analysis.baseTable, correlationName));
1065
+ const out = [];
1066
+ for (const rc of returning) {
1067
+ if (rc.type === 'all') {
1068
+ // RETURNING * (or `view.*`) → every view column, projected through its
1069
+ // base-term lineage and named by the view column.
1070
+ assertReturningStarQualifier(rc.table, view.name);
1071
+ for (const vc of analysis.viewColumns) {
1072
+ const baseExpr = analysis.columnMap.get(vc.name.toLowerCase());
1073
+ if (baseExpr)
1074
+ out.push({ type: 'column', expr: cloneExpr(baseExpr), alias: vc.name });
1075
+ }
1076
+ continue;
1077
+ }
1078
+ // Scope guard: a top-level `returning` reference must name a view column —
1079
+ // the same encapsulation guard as `where` / `set` (a base-only column the
1080
+ // view projects away must not leak through RETURNING).
1081
+ guardTopLevelScope(rc.expr, analysis, view);
1082
+ // Preserve the user's view-term output name BEFORE rewriting to base terms,
1083
+ // so the result column is named as written (the view column / its alias),
1084
+ // not the underlying base column.
1085
+ const alias = rc.alias ?? deriveReturningName(rc.expr);
1086
+ out.push({ type: 'column', expr: transformExpr(rc.expr, substitute, descend), alias });
1087
+ }
1088
+ return out;
1089
+ }
1090
+ /** The output name for an unaliased RETURNING expression (view-term spelling). */
1091
+ function deriveReturningName(expr) {
1092
+ if (expr.type === 'column')
1093
+ return expr.table ? `${expr.table}.${expr.name}` : expr.name;
1094
+ return expressionToString(expr);
1095
+ }
1096
+ //# sourceMappingURL=single-source.js.map