@quereus/quereus 3.3.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (900) hide show
  1. package/README.md +7 -0
  2. package/dist/src/common/datatype.d.ts +12 -0
  3. package/dist/src/common/datatype.d.ts.map +1 -1
  4. package/dist/src/common/datatype.js.map +1 -1
  5. package/dist/src/common/types.d.ts +24 -0
  6. package/dist/src/common/types.d.ts.map +1 -1
  7. package/dist/src/common/types.js.map +1 -1
  8. package/dist/src/core/database-assertions.d.ts +37 -9
  9. package/dist/src/core/database-assertions.d.ts.map +1 -1
  10. package/dist/src/core/database-assertions.js +62 -110
  11. package/dist/src/core/database-assertions.js.map +1 -1
  12. package/dist/src/core/database-events.d.ts +163 -0
  13. package/dist/src/core/database-events.d.ts.map +1 -1
  14. package/dist/src/core/database-events.js +235 -21
  15. package/dist/src/core/database-events.js.map +1 -1
  16. package/dist/src/core/database-external-changes.d.ts +28 -0
  17. package/dist/src/core/database-external-changes.d.ts.map +1 -0
  18. package/dist/src/core/database-external-changes.js +242 -0
  19. package/dist/src/core/database-external-changes.js.map +1 -0
  20. package/dist/src/core/database-internal.d.ts +50 -1
  21. package/dist/src/core/database-internal.d.ts.map +1 -1
  22. package/dist/src/core/database-materialized-views.d.ts +1253 -0
  23. package/dist/src/core/database-materialized-views.d.ts.map +1 -0
  24. package/dist/src/core/database-materialized-views.js +3064 -0
  25. package/dist/src/core/database-materialized-views.js.map +1 -0
  26. package/dist/src/core/database-options.d.ts +4 -0
  27. package/dist/src/core/database-options.d.ts.map +1 -1
  28. package/dist/src/core/database-options.js +10 -0
  29. package/dist/src/core/database-options.js.map +1 -1
  30. package/dist/src/core/database-transaction.d.ts +19 -3
  31. package/dist/src/core/database-transaction.d.ts.map +1 -1
  32. package/dist/src/core/database-transaction.js +30 -3
  33. package/dist/src/core/database-transaction.js.map +1 -1
  34. package/dist/src/core/database-watchers.d.ts +19 -0
  35. package/dist/src/core/database-watchers.d.ts.map +1 -1
  36. package/dist/src/core/database-watchers.js +63 -3
  37. package/dist/src/core/database-watchers.js.map +1 -1
  38. package/dist/src/core/database.d.ts +204 -11
  39. package/dist/src/core/database.d.ts.map +1 -1
  40. package/dist/src/core/database.js +493 -29
  41. package/dist/src/core/database.js.map +1 -1
  42. package/dist/src/core/derived-row-validator.d.ts +137 -0
  43. package/dist/src/core/derived-row-validator.d.ts.map +1 -0
  44. package/dist/src/core/derived-row-validator.js +314 -0
  45. package/dist/src/core/derived-row-validator.js.map +1 -0
  46. package/dist/src/core/statement.d.ts.map +1 -1
  47. package/dist/src/core/statement.js +30 -9
  48. package/dist/src/core/statement.js.map +1 -1
  49. package/dist/src/emit/ast-stringify.d.ts +135 -1
  50. package/dist/src/emit/ast-stringify.d.ts.map +1 -1
  51. package/dist/src/emit/ast-stringify.js +793 -118
  52. package/dist/src/emit/ast-stringify.js.map +1 -1
  53. package/dist/src/func/builtins/aggregate.d.ts.map +1 -1
  54. package/dist/src/func/builtins/aggregate.js +11 -10
  55. package/dist/src/func/builtins/aggregate.js.map +1 -1
  56. package/dist/src/func/builtins/builtin-window-functions.d.ts.map +1 -1
  57. package/dist/src/func/builtins/builtin-window-functions.js +32 -0
  58. package/dist/src/func/builtins/builtin-window-functions.js.map +1 -1
  59. package/dist/src/func/builtins/explain.d.ts +3 -0
  60. package/dist/src/func/builtins/explain.d.ts.map +1 -1
  61. package/dist/src/func/builtins/explain.js +229 -0
  62. package/dist/src/func/builtins/explain.js.map +1 -1
  63. package/dist/src/func/builtins/index.d.ts.map +1 -1
  64. package/dist/src/func/builtins/index.js +10 -2
  65. package/dist/src/func/builtins/index.js.map +1 -1
  66. package/dist/src/func/builtins/json.d.ts.map +1 -1
  67. package/dist/src/func/builtins/json.js +3 -2
  68. package/dist/src/func/builtins/json.js.map +1 -1
  69. package/dist/src/func/builtins/mutation.d.ts +2 -0
  70. package/dist/src/func/builtins/mutation.d.ts.map +1 -0
  71. package/dist/src/func/builtins/mutation.js +53 -0
  72. package/dist/src/func/builtins/mutation.js.map +1 -0
  73. package/dist/src/func/builtins/schema.d.ts +2 -0
  74. package/dist/src/func/builtins/schema.d.ts.map +1 -1
  75. package/dist/src/func/builtins/schema.js +716 -27
  76. package/dist/src/func/builtins/schema.js.map +1 -1
  77. package/dist/src/func/builtins/string.js +1 -1
  78. package/dist/src/func/builtins/string.js.map +1 -1
  79. package/dist/src/func/registration.d.ts +13 -0
  80. package/dist/src/func/registration.d.ts.map +1 -1
  81. package/dist/src/func/registration.js +5 -0
  82. package/dist/src/func/registration.js.map +1 -1
  83. package/dist/src/index.d.ts +25 -6
  84. package/dist/src/index.d.ts.map +1 -1
  85. package/dist/src/index.js +27 -3
  86. package/dist/src/index.js.map +1 -1
  87. package/dist/src/parser/ast.d.ts +353 -21
  88. package/dist/src/parser/ast.d.ts.map +1 -1
  89. package/dist/src/parser/index.d.ts +14 -1
  90. package/dist/src/parser/index.d.ts.map +1 -1
  91. package/dist/src/parser/index.js +19 -0
  92. package/dist/src/parser/index.js.map +1 -1
  93. package/dist/src/parser/lexer.d.ts +9 -0
  94. package/dist/src/parser/lexer.d.ts.map +1 -1
  95. package/dist/src/parser/lexer.js +9 -0
  96. package/dist/src/parser/lexer.js.map +1 -1
  97. package/dist/src/parser/parser.d.ts +276 -7
  98. package/dist/src/parser/parser.d.ts.map +1 -1
  99. package/dist/src/parser/parser.js +1387 -469
  100. package/dist/src/parser/parser.js.map +1 -1
  101. package/dist/src/parser/visitor.d.ts.map +1 -1
  102. package/dist/src/parser/visitor.js +12 -8
  103. package/dist/src/parser/visitor.js.map +1 -1
  104. package/dist/src/planner/analysis/assertion-classifier.d.ts.map +1 -1
  105. package/dist/src/planner/analysis/assertion-classifier.js +4 -0
  106. package/dist/src/planner/analysis/assertion-classifier.js.map +1 -1
  107. package/dist/src/planner/analysis/assertion-hoist-cache.d.ts.map +1 -1
  108. package/dist/src/planner/analysis/assertion-hoist-cache.js +8 -4
  109. package/dist/src/planner/analysis/assertion-hoist-cache.js.map +1 -1
  110. package/dist/src/planner/analysis/authored-inverse.d.ts +22 -0
  111. package/dist/src/planner/analysis/authored-inverse.d.ts.map +1 -0
  112. package/dist/src/planner/analysis/authored-inverse.js +267 -0
  113. package/dist/src/planner/analysis/authored-inverse.js.map +1 -0
  114. package/dist/src/planner/analysis/change-scope.d.ts +34 -4
  115. package/dist/src/planner/analysis/change-scope.d.ts.map +1 -1
  116. package/dist/src/planner/analysis/change-scope.js +108 -7
  117. package/dist/src/planner/analysis/change-scope.js.map +1 -1
  118. package/dist/src/planner/analysis/check-extraction.d.ts +36 -2
  119. package/dist/src/planner/analysis/check-extraction.d.ts.map +1 -1
  120. package/dist/src/planner/analysis/check-extraction.js +174 -46
  121. package/dist/src/planner/analysis/check-extraction.js.map +1 -1
  122. package/dist/src/planner/analysis/coarsened-key.d.ts +109 -0
  123. package/dist/src/planner/analysis/coarsened-key.d.ts.map +1 -0
  124. package/dist/src/planner/analysis/coarsened-key.js +228 -0
  125. package/dist/src/planner/analysis/coarsened-key.js.map +1 -0
  126. package/dist/src/planner/analysis/comparison-collation.d.ts +216 -0
  127. package/dist/src/planner/analysis/comparison-collation.d.ts.map +1 -0
  128. package/dist/src/planner/analysis/comparison-collation.js +341 -0
  129. package/dist/src/planner/analysis/comparison-collation.js.map +1 -0
  130. package/dist/src/planner/analysis/constraint-extractor.d.ts +3 -1
  131. package/dist/src/planner/analysis/constraint-extractor.d.ts.map +1 -1
  132. package/dist/src/planner/analysis/constraint-extractor.js +192 -9
  133. package/dist/src/planner/analysis/constraint-extractor.js.map +1 -1
  134. package/dist/src/planner/analysis/coverage-prover.d.ts +321 -0
  135. package/dist/src/planner/analysis/coverage-prover.d.ts.map +1 -0
  136. package/dist/src/planner/analysis/coverage-prover.js +1038 -0
  137. package/dist/src/planner/analysis/coverage-prover.js.map +1 -0
  138. package/dist/src/planner/analysis/key-filter.d.ts +22 -0
  139. package/dist/src/planner/analysis/key-filter.d.ts.map +1 -0
  140. package/dist/src/planner/analysis/key-filter.js +105 -0
  141. package/dist/src/planner/analysis/key-filter.js.map +1 -0
  142. package/dist/src/planner/analysis/partial-unique-extraction.d.ts +36 -1
  143. package/dist/src/planner/analysis/partial-unique-extraction.d.ts.map +1 -1
  144. package/dist/src/planner/analysis/partial-unique-extraction.js +148 -22
  145. package/dist/src/planner/analysis/partial-unique-extraction.js.map +1 -1
  146. package/dist/src/planner/analysis/predicate-normalizer.d.ts.map +1 -1
  147. package/dist/src/planner/analysis/predicate-normalizer.js +30 -1
  148. package/dist/src/planner/analysis/predicate-normalizer.js.map +1 -1
  149. package/dist/src/planner/analysis/predicate-shape.d.ts +36 -1
  150. package/dist/src/planner/analysis/predicate-shape.d.ts.map +1 -1
  151. package/dist/src/planner/analysis/predicate-shape.js +51 -13
  152. package/dist/src/planner/analysis/predicate-shape.js.map +1 -1
  153. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts +314 -0
  154. package/dist/src/planner/analysis/query-rewrite-matcher.d.ts.map +1 -0
  155. package/dist/src/planner/analysis/query-rewrite-matcher.js +1081 -0
  156. package/dist/src/planner/analysis/query-rewrite-matcher.js.map +1 -0
  157. package/dist/src/planner/analysis/scalar-invertibility.d.ts +92 -0
  158. package/dist/src/planner/analysis/scalar-invertibility.d.ts.map +1 -0
  159. package/dist/src/planner/analysis/scalar-invertibility.js +129 -0
  160. package/dist/src/planner/analysis/scalar-invertibility.js.map +1 -0
  161. package/dist/src/planner/analysis/update-lineage.d.ts +196 -0
  162. package/dist/src/planner/analysis/update-lineage.d.ts.map +1 -0
  163. package/dist/src/planner/analysis/update-lineage.js +322 -0
  164. package/dist/src/planner/analysis/update-lineage.js.map +1 -0
  165. package/dist/src/planner/analysis/view-complement.d.ts +42 -0
  166. package/dist/src/planner/analysis/view-complement.d.ts.map +1 -0
  167. package/dist/src/planner/analysis/view-complement.js +54 -0
  168. package/dist/src/planner/analysis/view-complement.js.map +1 -0
  169. package/dist/src/planner/building/alter-table.d.ts +1 -1
  170. package/dist/src/planner/building/alter-table.d.ts.map +1 -1
  171. package/dist/src/planner/building/alter-table.js +211 -2
  172. package/dist/src/planner/building/alter-table.js.map +1 -1
  173. package/dist/src/planner/building/block.d.ts.map +1 -1
  174. package/dist/src/planner/building/block.js +18 -1
  175. package/dist/src/planner/building/block.js.map +1 -1
  176. package/dist/src/planner/building/constraint-builder.d.ts +33 -5
  177. package/dist/src/planner/building/constraint-builder.d.ts.map +1 -1
  178. package/dist/src/planner/building/constraint-builder.js +63 -28
  179. package/dist/src/planner/building/constraint-builder.js.map +1 -1
  180. package/dist/src/planner/building/create-view.d.ts +9 -0
  181. package/dist/src/planner/building/create-view.d.ts.map +1 -1
  182. package/dist/src/planner/building/create-view.js +41 -12
  183. package/dist/src/planner/building/create-view.js.map +1 -1
  184. package/dist/src/planner/building/ddl.d.ts.map +1 -1
  185. package/dist/src/planner/building/ddl.js +94 -0
  186. package/dist/src/planner/building/ddl.js.map +1 -1
  187. package/dist/src/planner/building/declare-schema.d.ts +1 -0
  188. package/dist/src/planner/building/declare-schema.d.ts.map +1 -1
  189. package/dist/src/planner/building/declare-schema.js +4 -1
  190. package/dist/src/planner/building/declare-schema.js.map +1 -1
  191. package/dist/src/planner/building/default-scope.d.ts +26 -0
  192. package/dist/src/planner/building/default-scope.d.ts.map +1 -0
  193. package/dist/src/planner/building/default-scope.js +41 -0
  194. package/dist/src/planner/building/default-scope.js.map +1 -0
  195. package/dist/src/planner/building/delete.d.ts +19 -1
  196. package/dist/src/planner/building/delete.d.ts.map +1 -1
  197. package/dist/src/planner/building/delete.js +109 -30
  198. package/dist/src/planner/building/delete.js.map +1 -1
  199. package/dist/src/planner/building/dml-target.d.ts +118 -0
  200. package/dist/src/planner/building/dml-target.d.ts.map +1 -0
  201. package/dist/src/planner/building/dml-target.js +282 -0
  202. package/dist/src/planner/building/dml-target.js.map +1 -0
  203. package/dist/src/planner/building/drop-index.d.ts.map +1 -1
  204. package/dist/src/planner/building/drop-index.js +4 -1
  205. package/dist/src/planner/building/drop-index.js.map +1 -1
  206. package/dist/src/planner/building/drop-view.d.ts.map +1 -1
  207. package/dist/src/planner/building/drop-view.js +4 -2
  208. package/dist/src/planner/building/drop-view.js.map +1 -1
  209. package/dist/src/planner/building/expression.d.ts.map +1 -1
  210. package/dist/src/planner/building/expression.js +60 -21
  211. package/dist/src/planner/building/expression.js.map +1 -1
  212. package/dist/src/planner/building/foreign-key-builder.d.ts +30 -0
  213. package/dist/src/planner/building/foreign-key-builder.d.ts.map +1 -1
  214. package/dist/src/planner/building/foreign-key-builder.js +160 -129
  215. package/dist/src/planner/building/foreign-key-builder.js.map +1 -1
  216. package/dist/src/planner/building/insert.d.ts +45 -2
  217. package/dist/src/planner/building/insert.d.ts.map +1 -1
  218. package/dist/src/planner/building/insert.js +257 -88
  219. package/dist/src/planner/building/insert.js.map +1 -1
  220. package/dist/src/planner/building/lens-auxiliary-access.d.ts +22 -0
  221. package/dist/src/planner/building/lens-auxiliary-access.d.ts.map +1 -0
  222. package/dist/src/planner/building/lens-auxiliary-access.js +132 -0
  223. package/dist/src/planner/building/lens-auxiliary-access.js.map +1 -0
  224. package/dist/src/planner/building/materialized-view.d.ts +16 -0
  225. package/dist/src/planner/building/materialized-view.d.ts.map +1 -0
  226. package/dist/src/planner/building/materialized-view.js +57 -0
  227. package/dist/src/planner/building/materialized-view.js.map +1 -0
  228. package/dist/src/planner/building/returning-star.d.ts +32 -0
  229. package/dist/src/planner/building/returning-star.d.ts.map +1 -0
  230. package/dist/src/planner/building/returning-star.js +45 -0
  231. package/dist/src/planner/building/returning-star.js.map +1 -0
  232. package/dist/src/planner/building/select-aggregates.d.ts.map +1 -1
  233. package/dist/src/planner/building/select-aggregates.js +47 -0
  234. package/dist/src/planner/building/select-aggregates.js.map +1 -1
  235. package/dist/src/planner/building/select-compound.d.ts.map +1 -1
  236. package/dist/src/planner/building/select-compound.js +84 -11
  237. package/dist/src/planner/building/select-compound.js.map +1 -1
  238. package/dist/src/planner/building/select-context.d.ts +10 -2
  239. package/dist/src/planner/building/select-context.d.ts.map +1 -1
  240. package/dist/src/planner/building/select-context.js +7 -1
  241. package/dist/src/planner/building/select-context.js.map +1 -1
  242. package/dist/src/planner/building/select-modifiers.js +6 -0
  243. package/dist/src/planner/building/select-modifiers.js.map +1 -1
  244. package/dist/src/planner/building/select-ordinal.d.ts +18 -0
  245. package/dist/src/planner/building/select-ordinal.d.ts.map +1 -1
  246. package/dist/src/planner/building/select-ordinal.js +30 -0
  247. package/dist/src/planner/building/select-ordinal.js.map +1 -1
  248. package/dist/src/planner/building/select-projections.d.ts +8 -2
  249. package/dist/src/planner/building/select-projections.d.ts.map +1 -1
  250. package/dist/src/planner/building/select-projections.js +26 -4
  251. package/dist/src/planner/building/select-projections.js.map +1 -1
  252. package/dist/src/planner/building/select-window.d.ts.map +1 -1
  253. package/dist/src/planner/building/select-window.js +8 -5
  254. package/dist/src/planner/building/select-window.js.map +1 -1
  255. package/dist/src/planner/building/select.d.ts.map +1 -1
  256. package/dist/src/planner/building/select.js +164 -59
  257. package/dist/src/planner/building/select.js.map +1 -1
  258. package/dist/src/planner/building/set-object-tags.d.ts +7 -0
  259. package/dist/src/planner/building/set-object-tags.d.ts.map +1 -0
  260. package/dist/src/planner/building/set-object-tags.js +38 -0
  261. package/dist/src/planner/building/set-object-tags.js.map +1 -0
  262. package/dist/src/planner/building/tag-diagnostics.d.ts +27 -0
  263. package/dist/src/planner/building/tag-diagnostics.d.ts.map +1 -0
  264. package/dist/src/planner/building/tag-diagnostics.js +37 -0
  265. package/dist/src/planner/building/tag-diagnostics.js.map +1 -0
  266. package/dist/src/planner/building/update.d.ts +18 -1
  267. package/dist/src/planner/building/update.d.ts.map +1 -1
  268. package/dist/src/planner/building/update.js +134 -58
  269. package/dist/src/planner/building/update.js.map +1 -1
  270. package/dist/src/planner/building/view-mutation-builder.d.ts +15 -0
  271. package/dist/src/planner/building/view-mutation-builder.d.ts.map +1 -0
  272. package/dist/src/planner/building/view-mutation-builder.js +1158 -0
  273. package/dist/src/planner/building/view-mutation-builder.js.map +1 -0
  274. package/dist/src/planner/building/with.d.ts +11 -0
  275. package/dist/src/planner/building/with.d.ts.map +1 -1
  276. package/dist/src/planner/building/with.js +48 -10
  277. package/dist/src/planner/building/with.js.map +1 -1
  278. package/dist/src/planner/cost/index.d.ts +83 -0
  279. package/dist/src/planner/cost/index.d.ts.map +1 -1
  280. package/dist/src/planner/cost/index.js +114 -0
  281. package/dist/src/planner/cost/index.js.map +1 -1
  282. package/dist/src/planner/framework/characteristics.d.ts +38 -4
  283. package/dist/src/planner/framework/characteristics.d.ts.map +1 -1
  284. package/dist/src/planner/framework/characteristics.js +50 -6
  285. package/dist/src/planner/framework/characteristics.js.map +1 -1
  286. package/dist/src/planner/framework/pass.d.ts.map +1 -1
  287. package/dist/src/planner/framework/pass.js +2 -1
  288. package/dist/src/planner/framework/pass.js.map +1 -1
  289. package/dist/src/planner/framework/registry.d.ts +39 -1
  290. package/dist/src/planner/framework/registry.d.ts.map +1 -1
  291. package/dist/src/planner/framework/registry.js +18 -2
  292. package/dist/src/planner/framework/registry.js.map +1 -1
  293. package/dist/src/planner/mutation/backward-body.d.ts +131 -0
  294. package/dist/src/planner/mutation/backward-body.d.ts.map +1 -0
  295. package/dist/src/planner/mutation/backward-body.js +135 -0
  296. package/dist/src/planner/mutation/backward-body.js.map +1 -0
  297. package/dist/src/planner/mutation/cte-flatten.d.ts +17 -0
  298. package/dist/src/planner/mutation/cte-flatten.d.ts.map +1 -0
  299. package/dist/src/planner/mutation/cte-flatten.js +364 -0
  300. package/dist/src/planner/mutation/cte-flatten.js.map +1 -0
  301. package/dist/src/planner/mutation/decomposition.d.ts +273 -0
  302. package/dist/src/planner/mutation/decomposition.d.ts.map +1 -0
  303. package/dist/src/planner/mutation/decomposition.js +1719 -0
  304. package/dist/src/planner/mutation/decomposition.js.map +1 -0
  305. package/dist/src/planner/mutation/lens-enforcement.d.ts +165 -0
  306. package/dist/src/planner/mutation/lens-enforcement.d.ts.map +1 -0
  307. package/dist/src/planner/mutation/lens-enforcement.js +745 -0
  308. package/dist/src/planner/mutation/lens-enforcement.js.map +1 -0
  309. package/dist/src/planner/mutation/multi-source.d.ts +568 -0
  310. package/dist/src/planner/mutation/multi-source.d.ts.map +1 -0
  311. package/dist/src/planner/mutation/multi-source.js +2915 -0
  312. package/dist/src/planner/mutation/multi-source.js.map +1 -0
  313. package/dist/src/planner/mutation/mutation-diagnostic.d.ts +37 -0
  314. package/dist/src/planner/mutation/mutation-diagnostic.d.ts.map +1 -0
  315. package/dist/src/planner/mutation/mutation-diagnostic.js +24 -0
  316. package/dist/src/planner/mutation/mutation-diagnostic.js.map +1 -0
  317. package/dist/src/planner/mutation/mutation-tags.d.ts +33 -0
  318. package/dist/src/planner/mutation/mutation-tags.d.ts.map +1 -0
  319. package/dist/src/planner/mutation/mutation-tags.js +31 -0
  320. package/dist/src/planner/mutation/mutation-tags.js.map +1 -0
  321. package/dist/src/planner/mutation/propagate.d.ts +97 -0
  322. package/dist/src/planner/mutation/propagate.d.ts.map +1 -0
  323. package/dist/src/planner/mutation/propagate.js +220 -0
  324. package/dist/src/planner/mutation/propagate.js.map +1 -0
  325. package/dist/src/planner/mutation/scope-transform.d.ts +181 -0
  326. package/dist/src/planner/mutation/scope-transform.d.ts.map +1 -0
  327. package/dist/src/planner/mutation/scope-transform.js +574 -0
  328. package/dist/src/planner/mutation/scope-transform.js.map +1 -0
  329. package/dist/src/planner/mutation/set-op.d.ts +242 -0
  330. package/dist/src/planner/mutation/set-op.d.ts.map +1 -0
  331. package/dist/src/planner/mutation/set-op.js +1687 -0
  332. package/dist/src/planner/mutation/set-op.js.map +1 -0
  333. package/dist/src/planner/mutation/single-source.d.ts +261 -0
  334. package/dist/src/planner/mutation/single-source.d.ts.map +1 -0
  335. package/dist/src/planner/mutation/single-source.js +1096 -0
  336. package/dist/src/planner/mutation/single-source.js.map +1 -0
  337. package/dist/src/planner/nodes/aggregate-node.js +3 -3
  338. package/dist/src/planner/nodes/aggregate-node.js.map +1 -1
  339. package/dist/src/planner/nodes/alias-node.d.ts.map +1 -1
  340. package/dist/src/planner/nodes/alias-node.js +5 -1
  341. package/dist/src/planner/nodes/alias-node.js.map +1 -1
  342. package/dist/src/planner/nodes/alter-table-node.d.ts +124 -1
  343. package/dist/src/planner/nodes/alter-table-node.d.ts.map +1 -1
  344. package/dist/src/planner/nodes/alter-table-node.js +27 -0
  345. package/dist/src/planner/nodes/alter-table-node.js.map +1 -1
  346. package/dist/src/planner/nodes/analyze-node.d.ts +2 -1
  347. package/dist/src/planner/nodes/analyze-node.d.ts.map +1 -1
  348. package/dist/src/planner/nodes/analyze-node.js +18 -1
  349. package/dist/src/planner/nodes/analyze-node.js.map +1 -1
  350. package/dist/src/planner/nodes/asserted-keys-node.d.ts +43 -0
  351. package/dist/src/planner/nodes/asserted-keys-node.d.ts.map +1 -0
  352. package/dist/src/planner/nodes/asserted-keys-node.js +99 -0
  353. package/dist/src/planner/nodes/asserted-keys-node.js.map +1 -0
  354. package/dist/src/planner/nodes/async-gather-node.d.ts.map +1 -1
  355. package/dist/src/planner/nodes/async-gather-node.js +33 -8
  356. package/dist/src/planner/nodes/async-gather-node.js.map +1 -1
  357. package/dist/src/planner/nodes/bloom-join-node.d.ts.map +1 -1
  358. package/dist/src/planner/nodes/bloom-join-node.js +2 -1
  359. package/dist/src/planner/nodes/bloom-join-node.js.map +1 -1
  360. package/dist/src/planner/nodes/create-view-node.d.ts +7 -2
  361. package/dist/src/planner/nodes/create-view-node.d.ts.map +1 -1
  362. package/dist/src/planner/nodes/create-view-node.js +4 -1
  363. package/dist/src/planner/nodes/create-view-node.js.map +1 -1
  364. package/dist/src/planner/nodes/declarative-schema.d.ts +13 -1
  365. package/dist/src/planner/nodes/declarative-schema.d.ts.map +1 -1
  366. package/dist/src/planner/nodes/declarative-schema.js +32 -0
  367. package/dist/src/planner/nodes/declarative-schema.js.map +1 -1
  368. package/dist/src/planner/nodes/distinct-node.d.ts.map +1 -1
  369. package/dist/src/planner/nodes/distinct-node.js +2 -0
  370. package/dist/src/planner/nodes/distinct-node.js.map +1 -1
  371. package/dist/src/planner/nodes/dml-executor-node.d.ts +29 -1
  372. package/dist/src/planner/nodes/dml-executor-node.d.ts.map +1 -1
  373. package/dist/src/planner/nodes/dml-executor-node.js +27 -3
  374. package/dist/src/planner/nodes/dml-executor-node.js.map +1 -1
  375. package/dist/src/planner/nodes/eager-prefetch-node.d.ts.map +1 -1
  376. package/dist/src/planner/nodes/eager-prefetch-node.js +2 -0
  377. package/dist/src/planner/nodes/eager-prefetch-node.js.map +1 -1
  378. package/dist/src/planner/nodes/envelope-scan-node.d.ts +42 -0
  379. package/dist/src/planner/nodes/envelope-scan-node.d.ts.map +1 -0
  380. package/dist/src/planner/nodes/envelope-scan-node.js +62 -0
  381. package/dist/src/planner/nodes/envelope-scan-node.js.map +1 -0
  382. package/dist/src/planner/nodes/fanout-lookup-join-node.d.ts.map +1 -1
  383. package/dist/src/planner/nodes/fanout-lookup-join-node.js +11 -1
  384. package/dist/src/planner/nodes/fanout-lookup-join-node.js.map +1 -1
  385. package/dist/src/planner/nodes/filter.d.ts.map +1 -1
  386. package/dist/src/planner/nodes/filter.js +63 -13
  387. package/dist/src/planner/nodes/filter.js.map +1 -1
  388. package/dist/src/planner/nodes/join-node.d.ts +41 -1
  389. package/dist/src/planner/nodes/join-node.d.ts.map +1 -1
  390. package/dist/src/planner/nodes/join-node.js +78 -8
  391. package/dist/src/planner/nodes/join-node.js.map +1 -1
  392. package/dist/src/planner/nodes/join-utils.d.ts +33 -6
  393. package/dist/src/planner/nodes/join-utils.d.ts.map +1 -1
  394. package/dist/src/planner/nodes/join-utils.js +124 -9
  395. package/dist/src/planner/nodes/join-utils.js.map +1 -1
  396. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts +104 -0
  397. package/dist/src/planner/nodes/lens-auxiliary-access-node.d.ts.map +1 -0
  398. package/dist/src/planner/nodes/lens-auxiliary-access-node.js +91 -0
  399. package/dist/src/planner/nodes/lens-auxiliary-access-node.js.map +1 -0
  400. package/dist/src/planner/nodes/limit-offset.d.ts.map +1 -1
  401. package/dist/src/planner/nodes/limit-offset.js +4 -5
  402. package/dist/src/planner/nodes/limit-offset.js.map +1 -1
  403. package/dist/src/planner/nodes/materialized-view-nodes.d.ts +69 -0
  404. package/dist/src/planner/nodes/materialized-view-nodes.d.ts.map +1 -0
  405. package/dist/src/planner/nodes/materialized-view-nodes.js +111 -0
  406. package/dist/src/planner/nodes/materialized-view-nodes.js.map +1 -0
  407. package/dist/src/planner/nodes/merge-join-node.d.ts.map +1 -1
  408. package/dist/src/planner/nodes/merge-join-node.js +2 -1
  409. package/dist/src/planner/nodes/merge-join-node.js.map +1 -1
  410. package/dist/src/planner/nodes/ordinal-slice-node.d.ts.map +1 -1
  411. package/dist/src/planner/nodes/ordinal-slice-node.js +2 -0
  412. package/dist/src/planner/nodes/ordinal-slice-node.js.map +1 -1
  413. package/dist/src/planner/nodes/plan-node-type.d.ts +9 -0
  414. package/dist/src/planner/nodes/plan-node-type.d.ts.map +1 -1
  415. package/dist/src/planner/nodes/plan-node-type.js +9 -0
  416. package/dist/src/planner/nodes/plan-node-type.js.map +1 -1
  417. package/dist/src/planner/nodes/plan-node.d.ts +265 -5
  418. package/dist/src/planner/nodes/plan-node.d.ts.map +1 -1
  419. package/dist/src/planner/nodes/plan-node.js.map +1 -1
  420. package/dist/src/planner/nodes/pragma.d.ts +2 -1
  421. package/dist/src/planner/nodes/pragma.d.ts.map +1 -1
  422. package/dist/src/planner/nodes/pragma.js +12 -0
  423. package/dist/src/planner/nodes/pragma.js.map +1 -1
  424. package/dist/src/planner/nodes/project-node.d.ts +14 -1
  425. package/dist/src/planner/nodes/project-node.d.ts.map +1 -1
  426. package/dist/src/planner/nodes/project-node.js +85 -11
  427. package/dist/src/planner/nodes/project-node.js.map +1 -1
  428. package/dist/src/planner/nodes/reference.d.ts.map +1 -1
  429. package/dist/src/planner/nodes/reference.js +62 -27
  430. package/dist/src/planner/nodes/reference.js.map +1 -1
  431. package/dist/src/planner/nodes/retrieve-node.d.ts.map +1 -1
  432. package/dist/src/planner/nodes/retrieve-node.js +7 -0
  433. package/dist/src/planner/nodes/retrieve-node.js.map +1 -1
  434. package/dist/src/planner/nodes/returning-node.d.ts.map +1 -1
  435. package/dist/src/planner/nodes/returning-node.js +10 -3
  436. package/dist/src/planner/nodes/returning-node.js.map +1 -1
  437. package/dist/src/planner/nodes/scalar.d.ts +20 -0
  438. package/dist/src/planner/nodes/scalar.d.ts.map +1 -1
  439. package/dist/src/planner/nodes/scalar.js +71 -14
  440. package/dist/src/planner/nodes/scalar.js.map +1 -1
  441. package/dist/src/planner/nodes/set-object-tags-node.d.ts +39 -0
  442. package/dist/src/planner/nodes/set-object-tags-node.d.ts.map +1 -0
  443. package/dist/src/planner/nodes/set-object-tags-node.js +41 -0
  444. package/dist/src/planner/nodes/set-object-tags-node.js.map +1 -0
  445. package/dist/src/planner/nodes/set-operation-node.d.ts +123 -1
  446. package/dist/src/planner/nodes/set-operation-node.d.ts.map +1 -1
  447. package/dist/src/planner/nodes/set-operation-node.js +291 -18
  448. package/dist/src/planner/nodes/set-operation-node.js.map +1 -1
  449. package/dist/src/planner/nodes/single-row.d.ts.map +1 -1
  450. package/dist/src/planner/nodes/single-row.js +3 -0
  451. package/dist/src/planner/nodes/single-row.js.map +1 -1
  452. package/dist/src/planner/nodes/sort.d.ts.map +1 -1
  453. package/dist/src/planner/nodes/sort.js +7 -6
  454. package/dist/src/planner/nodes/sort.js.map +1 -1
  455. package/dist/src/planner/nodes/subquery.d.ts +2 -0
  456. package/dist/src/planner/nodes/subquery.d.ts.map +1 -1
  457. package/dist/src/planner/nodes/subquery.js +18 -2
  458. package/dist/src/planner/nodes/subquery.js.map +1 -1
  459. package/dist/src/planner/nodes/table-access-nodes.d.ts.map +1 -1
  460. package/dist/src/planner/nodes/table-access-nodes.js +23 -3
  461. package/dist/src/planner/nodes/table-access-nodes.js.map +1 -1
  462. package/dist/src/planner/nodes/table-function-call.js +6 -0
  463. package/dist/src/planner/nodes/table-function-call.js.map +1 -1
  464. package/dist/src/planner/nodes/values-node.d.ts +1 -0
  465. package/dist/src/planner/nodes/values-node.d.ts.map +1 -1
  466. package/dist/src/planner/nodes/values-node.js +16 -6
  467. package/dist/src/planner/nodes/values-node.js.map +1 -1
  468. package/dist/src/planner/nodes/view-mutation-node.d.ts +259 -0
  469. package/dist/src/planner/nodes/view-mutation-node.d.ts.map +1 -0
  470. package/dist/src/planner/nodes/view-mutation-node.js +273 -0
  471. package/dist/src/planner/nodes/view-mutation-node.js.map +1 -0
  472. package/dist/src/planner/nodes/window-function.d.ts +17 -1
  473. package/dist/src/planner/nodes/window-function.d.ts.map +1 -1
  474. package/dist/src/planner/nodes/window-function.js +15 -1
  475. package/dist/src/planner/nodes/window-function.js.map +1 -1
  476. package/dist/src/planner/nodes/window-node.js +2 -2
  477. package/dist/src/planner/nodes/window-node.js.map +1 -1
  478. package/dist/src/planner/optimizer.d.ts.map +1 -1
  479. package/dist/src/planner/optimizer.js +372 -39
  480. package/dist/src/planner/optimizer.js.map +1 -1
  481. package/dist/src/planner/planning-context.d.ts +1 -1
  482. package/dist/src/planner/planning-context.d.ts.map +1 -1
  483. package/dist/src/planner/rules/access/lens-access-form-matcher.d.ts +70 -0
  484. package/dist/src/planner/rules/access/lens-access-form-matcher.d.ts.map +1 -0
  485. package/dist/src/planner/rules/access/lens-access-form-matcher.js +156 -0
  486. package/dist/src/planner/rules/access/lens-access-form-matcher.js.map +1 -0
  487. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.d.ts +31 -0
  488. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.d.ts.map +1 -0
  489. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.js +176 -0
  490. package/dist/src/planner/rules/access/rule-lens-auxiliary-access.js.map +1 -0
  491. package/dist/src/planner/rules/access/rule-select-access-path.d.ts.map +1 -1
  492. package/dist/src/planner/rules/access/rule-select-access-path.js +435 -37
  493. package/dist/src/planner/rules/access/rule-select-access-path.js.map +1 -1
  494. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.d.ts.map +1 -1
  495. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js +9 -0
  496. package/dist/src/planner/rules/aggregate/rule-groupby-fd-simplification.js.map +1 -1
  497. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts +39 -0
  498. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.d.ts.map +1 -0
  499. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js +616 -0
  500. package/dist/src/planner/rules/cache/rule-materialized-view-rewrite.js.map +1 -0
  501. package/dist/src/planner/rules/cache/rule-scalar-cse.d.ts.map +1 -1
  502. package/dist/src/planner/rules/cache/rule-scalar-cse.js +8 -1
  503. package/dist/src/planner/rules/cache/rule-scalar-cse.js.map +1 -1
  504. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts +36 -0
  505. package/dist/src/planner/rules/join/equi-pair-extractor.d.ts.map +1 -1
  506. package/dist/src/planner/rules/join/equi-pair-extractor.js +38 -1
  507. package/dist/src/planner/rules/join/equi-pair-extractor.js.map +1 -1
  508. package/dist/src/planner/rules/join/rule-fanout-batched-outer.d.ts.map +1 -1
  509. package/dist/src/planner/rules/join/rule-fanout-batched-outer.js +10 -0
  510. package/dist/src/planner/rules/join/rule-fanout-batched-outer.js.map +1 -1
  511. package/dist/src/planner/rules/join/rule-fanout-lookup-join.d.ts.map +1 -1
  512. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js +19 -1
  513. package/dist/src/planner/rules/join/rule-fanout-lookup-join.js.map +1 -1
  514. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts +130 -0
  515. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.d.ts.map +1 -0
  516. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js +206 -0
  517. package/dist/src/planner/rules/join/rule-inner-join-existence-recovery.js.map +1 -0
  518. package/dist/src/planner/rules/join/rule-join-elimination.d.ts +67 -14
  519. package/dist/src/planner/rules/join/rule-join-elimination.d.ts.map +1 -1
  520. package/dist/src/planner/rules/join/rule-join-elimination.js +81 -25
  521. package/dist/src/planner/rules/join/rule-join-elimination.js.map +1 -1
  522. package/dist/src/planner/rules/join/rule-join-existence-pruning.d.ts +84 -0
  523. package/dist/src/planner/rules/join/rule-join-existence-pruning.d.ts.map +1 -0
  524. package/dist/src/planner/rules/join/rule-join-existence-pruning.js +138 -0
  525. package/dist/src/planner/rules/join/rule-join-existence-pruning.js.map +1 -0
  526. package/dist/src/planner/rules/join/rule-join-greedy-commute.d.ts.map +1 -1
  527. package/dist/src/planner/rules/join/rule-join-greedy-commute.js +9 -1
  528. package/dist/src/planner/rules/join/rule-join-greedy-commute.js.map +1 -1
  529. package/dist/src/planner/rules/join/rule-join-physical-selection.d.ts.map +1 -1
  530. package/dist/src/planner/rules/join/rule-join-physical-selection.js +12 -1
  531. package/dist/src/planner/rules/join/rule-join-physical-selection.js.map +1 -1
  532. package/dist/src/planner/rules/join/rule-lateral-top1-asof.d.ts.map +1 -1
  533. package/dist/src/planner/rules/join/rule-lateral-top1-asof.js +4 -0
  534. package/dist/src/planner/rules/join/rule-lateral-top1-asof.js.map +1 -1
  535. package/dist/src/planner/rules/join/rule-monotonic-merge-join.d.ts.map +1 -1
  536. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js +4 -0
  537. package/dist/src/planner/rules/join/rule-monotonic-merge-join.js.map +1 -1
  538. package/dist/src/planner/rules/join/rule-quickpick-enumeration.d.ts.map +1 -1
  539. package/dist/src/planner/rules/join/rule-quickpick-enumeration.js +10 -0
  540. package/dist/src/planner/rules/join/rule-quickpick-enumeration.js.map +1 -1
  541. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.d.ts +286 -0
  542. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.d.ts.map +1 -0
  543. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.js +548 -0
  544. package/dist/src/planner/rules/join/rule-semijoin-existence-recovery.js.map +1 -0
  545. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.d.ts.map +1 -1
  546. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.js +9 -1
  547. package/dist/src/planner/rules/parallel/rule-async-gather-union-all.js.map +1 -1
  548. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.d.ts.map +1 -1
  549. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js +7 -0
  550. package/dist/src/planner/rules/parallel/rule-async-gather-zip-by-key.js.map +1 -1
  551. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.d.ts.map +1 -1
  552. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.js +10 -1
  553. package/dist/src/planner/rules/parallel/rule-eager-prefetch-probe.js.map +1 -1
  554. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.d.ts.map +1 -1
  555. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js +9 -0
  556. package/dist/src/planner/rules/predicate/rule-aggregate-predicate-pushdown.js.map +1 -1
  557. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.d.ts.map +1 -1
  558. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js +18 -0
  559. package/dist/src/planner/rules/predicate/rule-empty-relation-folding.js.map +1 -1
  560. package/dist/src/planner/rules/predicate/rule-filter-contradiction.d.ts.map +1 -1
  561. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js +7 -0
  562. package/dist/src/planner/rules/predicate/rule-filter-contradiction.js.map +1 -1
  563. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.d.ts.map +1 -1
  564. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js +9 -0
  565. package/dist/src/planner/rules/predicate/rule-predicate-inference-equivalence.js.map +1 -1
  566. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js +13 -3
  567. package/dist/src/planner/rules/predicate/rule-predicate-pushdown.js.map +1 -1
  568. package/dist/src/planner/rules/retrieve/rule-projection-pruning.d.ts.map +1 -1
  569. package/dist/src/planner/rules/retrieve/rule-projection-pruning.js +14 -0
  570. package/dist/src/planner/rules/retrieve/rule-projection-pruning.js.map +1 -1
  571. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.d.ts +1 -1
  572. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js +4 -4
  573. package/dist/src/planner/rules/sort/rule-orderby-fd-pruning.js.map +1 -1
  574. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.d.ts.map +1 -1
  575. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js +8 -0
  576. package/dist/src/planner/rules/subquery/rule-anti-join-fk-empty.js.map +1 -1
  577. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.d.ts.map +1 -1
  578. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js +7 -0
  579. package/dist/src/planner/rules/subquery/rule-semi-join-fk-trivial.js.map +1 -1
  580. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.d.ts.map +1 -1
  581. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js +12 -0
  582. package/dist/src/planner/rules/subquery/rule-subquery-decorrelation.js.map +1 -1
  583. package/dist/src/planner/type-utils.d.ts +14 -0
  584. package/dist/src/planner/type-utils.d.ts.map +1 -1
  585. package/dist/src/planner/type-utils.js +66 -21
  586. package/dist/src/planner/type-utils.js.map +1 -1
  587. package/dist/src/planner/util/fd-utils.d.ts +177 -43
  588. package/dist/src/planner/util/fd-utils.d.ts.map +1 -1
  589. package/dist/src/planner/util/fd-utils.js +396 -101
  590. package/dist/src/planner/util/fd-utils.js.map +1 -1
  591. package/dist/src/planner/util/ind-utils.d.ts +27 -1
  592. package/dist/src/planner/util/ind-utils.d.ts.map +1 -1
  593. package/dist/src/planner/util/ind-utils.js +80 -6
  594. package/dist/src/planner/util/ind-utils.js.map +1 -1
  595. package/dist/src/planner/util/key-utils.d.ts.map +1 -1
  596. package/dist/src/planner/util/key-utils.js +81 -12
  597. package/dist/src/planner/util/key-utils.js.map +1 -1
  598. package/dist/src/planner/util/set-op-wrapper.d.ts +37 -0
  599. package/dist/src/planner/util/set-op-wrapper.d.ts.map +1 -0
  600. package/dist/src/planner/util/set-op-wrapper.js +82 -0
  601. package/dist/src/planner/util/set-op-wrapper.js.map +1 -0
  602. package/dist/src/planner/validation/plan-validator.d.ts.map +1 -1
  603. package/dist/src/planner/validation/plan-validator.js +1 -0
  604. package/dist/src/planner/validation/plan-validator.js.map +1 -1
  605. package/dist/src/runtime/context-helpers.d.ts +13 -1
  606. package/dist/src/runtime/context-helpers.d.ts.map +1 -1
  607. package/dist/src/runtime/context-helpers.js +7 -1
  608. package/dist/src/runtime/context-helpers.js.map +1 -1
  609. package/dist/src/runtime/delta-executor.d.ts +30 -1
  610. package/dist/src/runtime/delta-executor.d.ts.map +1 -1
  611. package/dist/src/runtime/delta-executor.js +29 -4
  612. package/dist/src/runtime/delta-executor.js.map +1 -1
  613. package/dist/src/runtime/emit/add-constraint.d.ts.map +1 -1
  614. package/dist/src/runtime/emit/add-constraint.js +38 -5
  615. package/dist/src/runtime/emit/add-constraint.js.map +1 -1
  616. package/dist/src/runtime/emit/aggregate.d.ts.map +1 -1
  617. package/dist/src/runtime/emit/aggregate.js +10 -8
  618. package/dist/src/runtime/emit/aggregate.js.map +1 -1
  619. package/dist/src/runtime/emit/alter-table.d.ts +1 -1
  620. package/dist/src/runtime/emit/alter-table.d.ts.map +1 -1
  621. package/dist/src/runtime/emit/alter-table.js +664 -108
  622. package/dist/src/runtime/emit/alter-table.js.map +1 -1
  623. package/dist/src/runtime/emit/analyze.d.ts.map +1 -1
  624. package/dist/src/runtime/emit/analyze.js +2 -1
  625. package/dist/src/runtime/emit/analyze.js.map +1 -1
  626. package/dist/src/runtime/emit/asof-scan.d.ts.map +1 -1
  627. package/dist/src/runtime/emit/asof-scan.js +18 -5
  628. package/dist/src/runtime/emit/asof-scan.js.map +1 -1
  629. package/dist/src/runtime/emit/asserted-keys.d.ts +13 -0
  630. package/dist/src/runtime/emit/asserted-keys.d.ts.map +1 -0
  631. package/dist/src/runtime/emit/asserted-keys.js +13 -0
  632. package/dist/src/runtime/emit/asserted-keys.js.map +1 -0
  633. package/dist/src/runtime/emit/between.d.ts.map +1 -1
  634. package/dist/src/runtime/emit/between.js +24 -19
  635. package/dist/src/runtime/emit/between.js.map +1 -1
  636. package/dist/src/runtime/emit/binary.d.ts.map +1 -1
  637. package/dist/src/runtime/emit/binary.js +5 -9
  638. package/dist/src/runtime/emit/binary.js.map +1 -1
  639. package/dist/src/runtime/emit/block.d.ts.map +1 -1
  640. package/dist/src/runtime/emit/block.js +11 -2
  641. package/dist/src/runtime/emit/block.js.map +1 -1
  642. package/dist/src/runtime/emit/bloom-join.d.ts.map +1 -1
  643. package/dist/src/runtime/emit/bloom-join.js +8 -2
  644. package/dist/src/runtime/emit/bloom-join.js.map +1 -1
  645. package/dist/src/runtime/emit/constraint-check.js +15 -0
  646. package/dist/src/runtime/emit/constraint-check.js.map +1 -1
  647. package/dist/src/runtime/emit/create-table.d.ts.map +1 -1
  648. package/dist/src/runtime/emit/create-table.js +8 -0
  649. package/dist/src/runtime/emit/create-table.js.map +1 -1
  650. package/dist/src/runtime/emit/create-view.d.ts.map +1 -1
  651. package/dist/src/runtime/emit/create-view.js +16 -1
  652. package/dist/src/runtime/emit/create-view.js.map +1 -1
  653. package/dist/src/runtime/emit/dml-executor.d.ts +27 -0
  654. package/dist/src/runtime/emit/dml-executor.d.ts.map +1 -1
  655. package/dist/src/runtime/emit/dml-executor.js +413 -193
  656. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  657. package/dist/src/runtime/emit/drop-table.d.ts.map +1 -1
  658. package/dist/src/runtime/emit/drop-table.js +10 -0
  659. package/dist/src/runtime/emit/drop-table.js.map +1 -1
  660. package/dist/src/runtime/emit/drop-view.d.ts.map +1 -1
  661. package/dist/src/runtime/emit/drop-view.js +17 -0
  662. package/dist/src/runtime/emit/drop-view.js.map +1 -1
  663. package/dist/src/runtime/emit/envelope-scan.d.ts +13 -0
  664. package/dist/src/runtime/emit/envelope-scan.d.ts.map +1 -0
  665. package/dist/src/runtime/emit/envelope-scan.js +22 -0
  666. package/dist/src/runtime/emit/envelope-scan.js.map +1 -0
  667. package/dist/src/runtime/emit/join.d.ts +10 -2
  668. package/dist/src/runtime/emit/join.d.ts.map +1 -1
  669. package/dist/src/runtime/emit/join.js +128 -38
  670. package/dist/src/runtime/emit/join.js.map +1 -1
  671. package/dist/src/runtime/emit/lens-auxiliary-access.d.ts +16 -0
  672. package/dist/src/runtime/emit/lens-auxiliary-access.d.ts.map +1 -0
  673. package/dist/src/runtime/emit/lens-auxiliary-access.js +16 -0
  674. package/dist/src/runtime/emit/lens-auxiliary-access.js.map +1 -0
  675. package/dist/src/runtime/emit/materialized-view-helpers.d.ts +640 -0
  676. package/dist/src/runtime/emit/materialized-view-helpers.d.ts.map +1 -0
  677. package/dist/src/runtime/emit/materialized-view-helpers.js +2576 -0
  678. package/dist/src/runtime/emit/materialized-view-helpers.js.map +1 -0
  679. package/dist/src/runtime/emit/materialized-view.d.ts +31 -0
  680. package/dist/src/runtime/emit/materialized-view.d.ts.map +1 -0
  681. package/dist/src/runtime/emit/materialized-view.js +187 -0
  682. package/dist/src/runtime/emit/materialized-view.js.map +1 -0
  683. package/dist/src/runtime/emit/merge-join.d.ts.map +1 -1
  684. package/dist/src/runtime/emit/merge-join.js +15 -3
  685. package/dist/src/runtime/emit/merge-join.js.map +1 -1
  686. package/dist/src/runtime/emit/project.d.ts.map +1 -1
  687. package/dist/src/runtime/emit/project.js +10 -5
  688. package/dist/src/runtime/emit/project.js.map +1 -1
  689. package/dist/src/runtime/emit/schema-declarative.d.ts +1 -0
  690. package/dist/src/runtime/emit/schema-declarative.d.ts.map +1 -1
  691. package/dist/src/runtime/emit/schema-declarative.js +101 -5
  692. package/dist/src/runtime/emit/schema-declarative.js.map +1 -1
  693. package/dist/src/runtime/emit/set-object-tags.d.ts +16 -0
  694. package/dist/src/runtime/emit/set-object-tags.d.ts.map +1 -0
  695. package/dist/src/runtime/emit/set-object-tags.js +57 -0
  696. package/dist/src/runtime/emit/set-object-tags.js.map +1 -0
  697. package/dist/src/runtime/emit/set-operation.d.ts.map +1 -1
  698. package/dist/src/runtime/emit/set-operation.js +140 -24
  699. package/dist/src/runtime/emit/set-operation.js.map +1 -1
  700. package/dist/src/runtime/emit/subquery.d.ts.map +1 -1
  701. package/dist/src/runtime/emit/subquery.js +110 -5
  702. package/dist/src/runtime/emit/subquery.js.map +1 -1
  703. package/dist/src/runtime/emit/unary.d.ts.map +1 -1
  704. package/dist/src/runtime/emit/unary.js +34 -6
  705. package/dist/src/runtime/emit/unary.js.map +1 -1
  706. package/dist/src/runtime/emit/view-mutation.d.ts +70 -0
  707. package/dist/src/runtime/emit/view-mutation.d.ts.map +1 -0
  708. package/dist/src/runtime/emit/view-mutation.js +299 -0
  709. package/dist/src/runtime/emit/view-mutation.js.map +1 -0
  710. package/dist/src/runtime/emit/window.js +29 -5
  711. package/dist/src/runtime/emit/window.js.map +1 -1
  712. package/dist/src/runtime/foreign-key-actions.d.ts +66 -3
  713. package/dist/src/runtime/foreign-key-actions.d.ts.map +1 -1
  714. package/dist/src/runtime/foreign-key-actions.js +580 -172
  715. package/dist/src/runtime/foreign-key-actions.js.map +1 -1
  716. package/dist/src/runtime/parallel-driver.d.ts +4 -1
  717. package/dist/src/runtime/parallel-driver.d.ts.map +1 -1
  718. package/dist/src/runtime/parallel-driver.js +5 -1
  719. package/dist/src/runtime/parallel-driver.js.map +1 -1
  720. package/dist/src/runtime/register.d.ts.map +1 -1
  721. package/dist/src/runtime/register.js +17 -1
  722. package/dist/src/runtime/register.js.map +1 -1
  723. package/dist/src/runtime/types.d.ts +10 -0
  724. package/dist/src/runtime/types.d.ts.map +1 -1
  725. package/dist/src/runtime/types.js.map +1 -1
  726. package/dist/src/schema/basis-backfill.d.ts +63 -0
  727. package/dist/src/schema/basis-backfill.d.ts.map +1 -0
  728. package/dist/src/schema/basis-backfill.js +161 -0
  729. package/dist/src/schema/basis-backfill.js.map +1 -0
  730. package/dist/src/schema/catalog.d.ts +115 -1
  731. package/dist/src/schema/catalog.d.ts.map +1 -1
  732. package/dist/src/schema/catalog.js +249 -22
  733. package/dist/src/schema/catalog.js.map +1 -1
  734. package/dist/src/schema/change-events.d.ts +42 -1
  735. package/dist/src/schema/change-events.d.ts.map +1 -1
  736. package/dist/src/schema/change-events.js.map +1 -1
  737. package/dist/src/schema/column.d.ts +16 -0
  738. package/dist/src/schema/column.d.ts.map +1 -1
  739. package/dist/src/schema/column.js.map +1 -1
  740. package/dist/src/schema/constraint-builder.d.ts +182 -0
  741. package/dist/src/schema/constraint-builder.d.ts.map +1 -0
  742. package/dist/src/schema/constraint-builder.js +424 -0
  743. package/dist/src/schema/constraint-builder.js.map +1 -0
  744. package/dist/src/schema/ddl-generator.d.ts +86 -1
  745. package/dist/src/schema/ddl-generator.d.ts.map +1 -1
  746. package/dist/src/schema/ddl-generator.js +316 -20
  747. package/dist/src/schema/ddl-generator.js.map +1 -1
  748. package/dist/src/schema/declared-schema-manager.d.ts +51 -0
  749. package/dist/src/schema/declared-schema-manager.d.ts.map +1 -1
  750. package/dist/src/schema/declared-schema-manager.js +61 -0
  751. package/dist/src/schema/declared-schema-manager.js.map +1 -1
  752. package/dist/src/schema/derivation.d.ts +106 -0
  753. package/dist/src/schema/derivation.d.ts.map +1 -0
  754. package/dist/src/schema/derivation.js +25 -0
  755. package/dist/src/schema/derivation.js.map +1 -0
  756. package/dist/src/schema/function.d.ts +20 -0
  757. package/dist/src/schema/function.d.ts.map +1 -1
  758. package/dist/src/schema/function.js.map +1 -1
  759. package/dist/src/schema/lens-ack.d.ts +90 -0
  760. package/dist/src/schema/lens-ack.d.ts.map +1 -0
  761. package/dist/src/schema/lens-ack.js +361 -0
  762. package/dist/src/schema/lens-ack.js.map +1 -0
  763. package/dist/src/schema/lens-compiler.d.ts +62 -0
  764. package/dist/src/schema/lens-compiler.d.ts.map +1 -0
  765. package/dist/src/schema/lens-compiler.js +1594 -0
  766. package/dist/src/schema/lens-compiler.js.map +1 -0
  767. package/dist/src/schema/lens-fk-discovery.d.ts +175 -0
  768. package/dist/src/schema/lens-fk-discovery.d.ts.map +1 -0
  769. package/dist/src/schema/lens-fk-discovery.js +336 -0
  770. package/dist/src/schema/lens-fk-discovery.js.map +1 -0
  771. package/dist/src/schema/lens-prover.d.ts +336 -0
  772. package/dist/src/schema/lens-prover.d.ts.map +1 -0
  773. package/dist/src/schema/lens-prover.js +1988 -0
  774. package/dist/src/schema/lens-prover.js.map +1 -0
  775. package/dist/src/schema/lens.d.ts +254 -0
  776. package/dist/src/schema/lens.d.ts.map +1 -0
  777. package/dist/src/schema/lens.js +21 -0
  778. package/dist/src/schema/lens.js.map +1 -0
  779. package/dist/src/schema/manager.d.ts +676 -18
  780. package/dist/src/schema/manager.d.ts.map +1 -1
  781. package/dist/src/schema/manager.js +1573 -238
  782. package/dist/src/schema/manager.js.map +1 -1
  783. package/dist/src/schema/mapping-advertisement-tags.d.ts +39 -0
  784. package/dist/src/schema/mapping-advertisement-tags.d.ts.map +1 -0
  785. package/dist/src/schema/mapping-advertisement-tags.js +216 -0
  786. package/dist/src/schema/mapping-advertisement-tags.js.map +1 -0
  787. package/dist/src/schema/rename-rewriter.d.ts +45 -4
  788. package/dist/src/schema/rename-rewriter.d.ts.map +1 -1
  789. package/dist/src/schema/rename-rewriter.js +412 -19
  790. package/dist/src/schema/rename-rewriter.js.map +1 -1
  791. package/dist/src/schema/reserved-tags-policy.d.ts +32 -0
  792. package/dist/src/schema/reserved-tags-policy.d.ts.map +1 -0
  793. package/dist/src/schema/reserved-tags-policy.js +34 -0
  794. package/dist/src/schema/reserved-tags-policy.js.map +1 -0
  795. package/dist/src/schema/reserved-tags.d.ts +170 -0
  796. package/dist/src/schema/reserved-tags.d.ts.map +1 -0
  797. package/dist/src/schema/reserved-tags.js +507 -0
  798. package/dist/src/schema/reserved-tags.js.map +1 -0
  799. package/dist/src/schema/schema-differ.d.ts +158 -2
  800. package/dist/src/schema/schema-differ.d.ts.map +1 -1
  801. package/dist/src/schema/schema-differ.js +1460 -78
  802. package/dist/src/schema/schema-differ.js.map +1 -1
  803. package/dist/src/schema/schema-hasher.d.ts +8 -3
  804. package/dist/src/schema/schema-hasher.d.ts.map +1 -1
  805. package/dist/src/schema/schema-hasher.js +22 -2
  806. package/dist/src/schema/schema-hasher.js.map +1 -1
  807. package/dist/src/schema/schema.d.ts +25 -1
  808. package/dist/src/schema/schema.d.ts.map +1 -1
  809. package/dist/src/schema/schema.js +36 -2
  810. package/dist/src/schema/schema.js.map +1 -1
  811. package/dist/src/schema/table.d.ts +259 -10
  812. package/dist/src/schema/table.d.ts.map +1 -1
  813. package/dist/src/schema/table.js +309 -26
  814. package/dist/src/schema/table.js.map +1 -1
  815. package/dist/src/schema/unique-enforcement.d.ts +78 -0
  816. package/dist/src/schema/unique-enforcement.d.ts.map +1 -0
  817. package/dist/src/schema/unique-enforcement.js +93 -0
  818. package/dist/src/schema/unique-enforcement.js.map +1 -0
  819. package/dist/src/schema/view.d.ts +83 -2
  820. package/dist/src/schema/view.d.ts.map +1 -1
  821. package/dist/src/schema/view.js +67 -1
  822. package/dist/src/schema/view.js.map +1 -1
  823. package/dist/src/schema/window-function.d.ts +9 -1
  824. package/dist/src/schema/window-function.d.ts.map +1 -1
  825. package/dist/src/schema/window-function.js.map +1 -1
  826. package/dist/src/util/comparison.d.ts +24 -0
  827. package/dist/src/util/comparison.d.ts.map +1 -1
  828. package/dist/src/util/comparison.js +34 -0
  829. package/dist/src/util/comparison.js.map +1 -1
  830. package/dist/src/util/mutation-statement.d.ts.map +1 -1
  831. package/dist/src/util/mutation-statement.js +4 -1
  832. package/dist/src/util/mutation-statement.js.map +1 -1
  833. package/dist/src/util/serialization.d.ts +9 -0
  834. package/dist/src/util/serialization.d.ts.map +1 -1
  835. package/dist/src/util/serialization.js +26 -0
  836. package/dist/src/util/serialization.js.map +1 -1
  837. package/dist/src/vtab/backing-host.d.ts +286 -0
  838. package/dist/src/vtab/backing-host.d.ts.map +1 -0
  839. package/dist/src/vtab/backing-host.js +118 -0
  840. package/dist/src/vtab/backing-host.js.map +1 -0
  841. package/dist/src/vtab/best-access-plan.d.ts +21 -0
  842. package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
  843. package/dist/src/vtab/best-access-plan.js.map +1 -1
  844. package/dist/src/vtab/capabilities.d.ts +5 -5
  845. package/dist/src/vtab/capabilities.d.ts.map +1 -1
  846. package/dist/src/vtab/mapping-advertisement.d.ts +163 -0
  847. package/dist/src/vtab/mapping-advertisement.d.ts.map +1 -0
  848. package/dist/src/vtab/mapping-advertisement.js +2 -0
  849. package/dist/src/vtab/mapping-advertisement.js.map +1 -0
  850. package/dist/src/vtab/memory/index.d.ts +64 -4
  851. package/dist/src/vtab/memory/index.d.ts.map +1 -1
  852. package/dist/src/vtab/memory/index.js +119 -12
  853. package/dist/src/vtab/memory/index.js.map +1 -1
  854. package/dist/src/vtab/memory/layer/base.d.ts +38 -1
  855. package/dist/src/vtab/memory/layer/base.d.ts.map +1 -1
  856. package/dist/src/vtab/memory/layer/base.js +112 -24
  857. package/dist/src/vtab/memory/layer/base.js.map +1 -1
  858. package/dist/src/vtab/memory/layer/manager.d.ts +291 -4
  859. package/dist/src/vtab/memory/layer/manager.d.ts.map +1 -1
  860. package/dist/src/vtab/memory/layer/manager.js +1050 -91
  861. package/dist/src/vtab/memory/layer/manager.js.map +1 -1
  862. package/dist/src/vtab/memory/layer/plan-filter.d.ts.map +1 -1
  863. package/dist/src/vtab/memory/layer/plan-filter.js +35 -6
  864. package/dist/src/vtab/memory/layer/plan-filter.js.map +1 -1
  865. package/dist/src/vtab/memory/layer/scan-layer.d.ts.map +1 -1
  866. package/dist/src/vtab/memory/layer/scan-layer.js +66 -14
  867. package/dist/src/vtab/memory/layer/scan-layer.js.map +1 -1
  868. package/dist/src/vtab/memory/layer/scan-plan.d.ts +14 -0
  869. package/dist/src/vtab/memory/layer/scan-plan.d.ts.map +1 -1
  870. package/dist/src/vtab/memory/layer/scan-plan.js +27 -4
  871. package/dist/src/vtab/memory/layer/scan-plan.js.map +1 -1
  872. package/dist/src/vtab/memory/layer/transaction.d.ts.map +1 -1
  873. package/dist/src/vtab/memory/layer/transaction.js +5 -1
  874. package/dist/src/vtab/memory/layer/transaction.js.map +1 -1
  875. package/dist/src/vtab/memory/module.d.ts +17 -0
  876. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  877. package/dist/src/vtab/memory/module.js +82 -3
  878. package/dist/src/vtab/memory/module.js.map +1 -1
  879. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  880. package/dist/src/vtab/memory/table.js +15 -5
  881. package/dist/src/vtab/memory/table.js.map +1 -1
  882. package/dist/src/vtab/memory/types.d.ts +20 -2
  883. package/dist/src/vtab/memory/types.d.ts.map +1 -1
  884. package/dist/src/vtab/memory/utils/predicate.d.ts.map +1 -1
  885. package/dist/src/vtab/memory/utils/predicate.js +46 -24
  886. package/dist/src/vtab/memory/utils/predicate.js.map +1 -1
  887. package/dist/src/vtab/memory/utils/primary-key-encode.d.ts +31 -0
  888. package/dist/src/vtab/memory/utils/primary-key-encode.d.ts.map +1 -0
  889. package/dist/src/vtab/memory/utils/primary-key-encode.js +101 -0
  890. package/dist/src/vtab/memory/utils/primary-key-encode.js.map +1 -0
  891. package/dist/src/vtab/memory/utils/primary-key.d.ts +8 -0
  892. package/dist/src/vtab/memory/utils/primary-key.d.ts.map +1 -1
  893. package/dist/src/vtab/memory/utils/primary-key.js +12 -5
  894. package/dist/src/vtab/memory/utils/primary-key.js.map +1 -1
  895. package/dist/src/vtab/module.d.ts +203 -4
  896. package/dist/src/vtab/module.d.ts.map +1 -1
  897. package/dist/src/vtab/table.d.ts +9 -0
  898. package/dist/src/vtab/table.d.ts.map +1 -1
  899. package/dist/src/vtab/table.js.map +1 -1
  900. package/package.json +17 -16
@@ -1,5 +1,5 @@
1
1
  import { ConflictResolution } from '../common/constants.js';
2
- import { KEYWORDS } from '../parser/lexer.js';
2
+ import { KEYWORDS, CONTEXTUAL_KEYWORDS } from '../parser/lexer.js';
3
3
  import { uint8ArrayToHex } from '../util/serialization.js';
4
4
  // --- Identifier Quoting Logic ---
5
5
  // Basic check for valid SQL identifiers (adjust regex as needed)
@@ -18,6 +18,23 @@ export function quoteIdentifier(name) {
18
18
  }
19
19
  return name;
20
20
  }
21
+ /**
22
+ * Keyword function names the parser still accepts *bare* in a call position
23
+ * (`consumeIdentifier([...CONTEXTUAL_KEYWORDS, 'replace'])` in parser.ts). For
24
+ * these, emitting bare both round-trips and keeps the auto-derived result-column
25
+ * name readable (`like('a%', x)`, not `"like"('a%', x)`).
26
+ */
27
+ const BARE_CALLABLE_FUNCTION_NAMES = new Set([...CONTEXTUAL_KEYWORDS, 'replace']);
28
+ /**
29
+ * Quote a function name only when a bare emit would not re-parse as a call.
30
+ * Ordinary names and bare-callable keyword names stay bare (lowercased, matching
31
+ * the historical style); only a keyword the parser would reject bare (e.g.
32
+ * `select`) is quoted so an exotic `"select"(x)` call still round-trips.
33
+ */
34
+ function quoteFunctionName(name) {
35
+ const lower = name.toLowerCase();
36
+ return BARE_CALLABLE_FUNCTION_NAMES.has(lower) ? lower : quoteIdentifier(lower);
37
+ }
21
38
  // Main function to convert any AST node to SQL string
22
39
  export function astToString(node) {
23
40
  switch (node.type) {
@@ -55,10 +72,20 @@ export function astToString(node) {
55
72
  return createIndexToString(node);
56
73
  case 'createView':
57
74
  return createViewToString(node);
75
+ case 'createMaterializedView':
76
+ return createMaterializedViewToString(node);
77
+ case 'refreshMaterializedView':
78
+ return refreshMaterializedViewToString(node);
58
79
  case 'createAssertion':
59
80
  return createAssertionToString(node);
60
81
  case 'alterTable':
61
82
  return alterTableToString(node);
83
+ case 'alterView':
84
+ return alterViewToString(node);
85
+ case 'alterMaterializedView':
86
+ return alterMaterializedViewToString(node);
87
+ case 'alterIndex':
88
+ return alterIndexToString(node);
62
89
  case 'analyze':
63
90
  return analyzeToString(node);
64
91
  case 'drop':
@@ -77,11 +104,13 @@ export function astToString(node) {
77
104
  return pragmaToString(node);
78
105
  case 'declareSchema':
79
106
  return declareSchemaToString(node);
107
+ case 'declareLens':
108
+ return declareLensToString(node);
80
109
  case 'diffSchema':
81
- return `diff schema ${node.schemaName || 'main'}`;
110
+ return `diff schema ${quoteIdentifier(node.schemaName || 'main')}`;
82
111
  case 'applySchema': {
83
112
  const n = node;
84
- let s = `apply schema ${n.schemaName || 'main'}`;
113
+ let s = `apply schema ${quoteIdentifier(n.schemaName || 'main')}`;
85
114
  if (n.toVersion)
86
115
  s += ` to version '${n.toVersion}'`;
87
116
  if (n.withSeed)
@@ -102,7 +131,7 @@ export function astToString(node) {
102
131
  return s;
103
132
  }
104
133
  case 'explainSchema':
105
- return `explain schema ${node.schemaName || 'main'}`;
134
+ return `explain schema ${quoteIdentifier(node.schemaName || 'main')}`;
106
135
  default:
107
136
  return `[${node.type}]`; // Fallback for unknown node types
108
137
  }
@@ -163,11 +192,12 @@ export function expressionToString(expr) {
163
192
  const exprStr = unaryBodyNeedsParens(expr)
164
193
  ? `(${expressionToString(expr.expr)})`
165
194
  : expressionToString(expr.expr);
166
- // Handle postfix operators like IS NULL, IS NOT NULL
167
- if (expr.operator === 'IS NULL' || expr.operator === 'IS NOT NULL') {
195
+ // Handle postfix operators: IS [NOT] NULL/TRUE/FALSE
196
+ const upperOp = expr.operator.toUpperCase();
197
+ if (POSTFIX_IS_OPERATORS.has(upperOp)) {
168
198
  return `${exprStr} ${expr.operator.toLowerCase()}`;
169
199
  }
170
- else if (expr.operator.toUpperCase() === 'NOT') {
200
+ else if (upperOp === 'NOT') {
171
201
  return `not ${exprStr}`;
172
202
  }
173
203
  return `${expr.operator.toLowerCase()}${exprStr}`;
@@ -178,7 +208,7 @@ export function expressionToString(expr) {
178
208
  }
179
209
  const argsStr = expr.args.map(arg => expressionToString(arg)).join(', ');
180
210
  const distinctStr = expr.distinct ? 'distinct ' : '';
181
- return `${expr.name.toLowerCase()}(${distinctStr}${argsStr})`;
211
+ return `${quoteFunctionName(expr.name)}(${distinctStr}${argsStr})`;
182
212
  }
183
213
  case 'cast':
184
214
  return `cast(${expressionToString(expr.expr)} as ${expr.targetType.toLowerCase()})`;
@@ -194,9 +224,9 @@ export function expressionToString(expr) {
194
224
  return '?';
195
225
  }
196
226
  case 'subquery':
197
- return `(${selectToString(expr.query)})`;
227
+ return `(${astToString(expr.query)})`;
198
228
  case 'exists':
199
- return `exists (${selectToString(expr.subquery)})`;
229
+ return `exists (${astToString(expr.subquery)})`;
200
230
  case 'in': {
201
231
  const inExpr = expr;
202
232
  let result = expressionToString(inExpr.expr) + ' in ';
@@ -204,7 +234,7 @@ export function expressionToString(expr) {
204
234
  result += `(${inExpr.values.map(expressionToString).join(', ')})`;
205
235
  }
206
236
  else if (inExpr.subquery) {
207
- result += `(${selectToString(inExpr.subquery)})`;
237
+ result += `(${astToString(inExpr.subquery)})`;
208
238
  }
209
239
  return result;
210
240
  }
@@ -217,7 +247,7 @@ export function expressionToString(expr) {
217
247
  return `${exprStr} ${notStr}between ${lowerStr} and ${upperStr}`;
218
248
  }
219
249
  case 'collate':
220
- return `${expressionToString(expr.expr)} collate ${expr.collation.toLowerCase()}`;
250
+ return `${expressionToString(expr.expr)} collate ${quoteIdentifier(expr.collation.toLowerCase())}`;
221
251
  case 'case': {
222
252
  // TODO: preserve and emit with original case
223
253
  let caseStr = 'case';
@@ -244,6 +274,13 @@ export function expressionToString(expr) {
244
274
  return '[unknown_expr]';
245
275
  }
246
276
  }
277
+ // Unary operators rendered as postfix `<expr> <op>` (e.g. `a is null`,
278
+ // `a is not true`) rather than the default prefix form.
279
+ const POSTFIX_IS_OPERATORS = new Set([
280
+ 'IS NULL', 'IS NOT NULL',
281
+ 'IS TRUE', 'IS NOT TRUE',
282
+ 'IS FALSE', 'IS NOT FALSE',
283
+ ]);
247
284
  // Determines whether the body of a unary expression must be parenthesised so
248
285
  // the emitted SQL re-parses to the same AST. With prefix NOT bound above all
249
286
  // predicates (IS [NOT] NULL, IN, BETWEEN, LIKE, comparison), most inner shapes
@@ -322,6 +359,122 @@ function windowFrameBoundToString(bound) {
322
359
  default: return '[unknown_bound]';
323
360
  }
324
361
  }
362
+ /**
363
+ * Returns a structural clone of an expression with every bare column / identifier
364
+ * reference case-folded — `column` and `identifier` node `name` / `table` / `schema`
365
+ * lowercased — and everything else left byte-exact. This is the expression-level
366
+ * analogue of {@link lowercaseTableConstraintColumnNames}'s column-list fold: it makes
367
+ * the canonical body of a CHECK expression / partial-index WHERE predicate
368
+ * case-insensitive, matching Quereus's uniformly case-folding column resolution (the
369
+ * AST never records identifier quoting; every resolver folds via `.toLowerCase()`), so
370
+ * a reference whose case diverges from the column definition (or across re-declares)
371
+ * renders identically on both diff sides instead of churning a spurious drop+recreate.
372
+ *
373
+ * Folds ONLY identifier references. Left byte-exact: string / blob / number / JSON /
374
+ * NULL literals (`value` / `lexeme`), parameters, `cast.targetType`, `function.name`
375
+ * (already lowercased at render), and `collate.collation` (already lowercased at
376
+ * render — folding it here would double-handle). The full {@link expressionToString}
377
+ * node set is mirrored so every nested shape recurses and folds its inner refs.
378
+ *
379
+ * Bounded limitation: subquery bodies (`subquery` / `exists` / `in (select …)`) pass
380
+ * through structurally — the inner query is NOT descended into. This is symmetric on
381
+ * both diff sides (no NEW churn versus today), and CHECK / partial-WHERE subqueries
382
+ * are rare; full coverage is intentionally NOT implied.
383
+ *
384
+ * MUST NOT mutate the input: every folded node is rebuilt as a fresh object
385
+ * (`{ ...node, ...recursed }`) and only `name` / `table` / `schema` are overridden on
386
+ * a leaf ref. A `literal`'s `value` (a possibly-shared Uint8Array / JSON object /
387
+ * Promise) is passed through by reference, never recursed into or copied. Used ONLY by
388
+ * the canonical renderers ({@link constraintBodyToCanonicalString} via
389
+ * {@link lowercaseTableConstraintColumnNames}, {@link createIndexBodyToCanonicalString});
390
+ * the persistence renderers keep original case.
391
+ */
392
+ function lowerExprIdentifiers(expr) {
393
+ switch (expr.type) {
394
+ case 'column':
395
+ return { ...expr, name: expr.name.toLowerCase(), table: expr.table?.toLowerCase(), schema: expr.schema?.toLowerCase() };
396
+ case 'identifier':
397
+ return { ...expr, name: expr.name.toLowerCase(), schema: expr.schema?.toLowerCase() };
398
+ case 'binary':
399
+ return { ...expr, left: lowerExprIdentifiers(expr.left), right: lowerExprIdentifiers(expr.right) };
400
+ case 'unary':
401
+ return { ...expr, expr: lowerExprIdentifiers(expr.expr) };
402
+ case 'function':
403
+ return { ...expr, args: expr.args.map(arg => lowerExprIdentifiers(arg)) };
404
+ case 'cast':
405
+ return { ...expr, expr: lowerExprIdentifiers(expr.expr) };
406
+ case 'collate':
407
+ // `collation` is left alone — the render lowercases it (`quoteIdentifier(collation.toLowerCase())`).
408
+ return { ...expr, expr: lowerExprIdentifiers(expr.expr) };
409
+ case 'case':
410
+ return {
411
+ ...expr,
412
+ baseExpr: expr.baseExpr ? lowerExprIdentifiers(expr.baseExpr) : undefined,
413
+ whenThenClauses: expr.whenThenClauses.map(c => ({ when: lowerExprIdentifiers(c.when), then: lowerExprIdentifiers(c.then) })),
414
+ elseExpr: expr.elseExpr ? lowerExprIdentifiers(expr.elseExpr) : undefined,
415
+ };
416
+ case 'between':
417
+ return { ...expr, expr: lowerExprIdentifiers(expr.expr), lower: lowerExprIdentifiers(expr.lower), upper: lowerExprIdentifiers(expr.upper) };
418
+ case 'in':
419
+ // `subquery` (when present) passes through structurally — bounded limitation, see doc.
420
+ return { ...expr, expr: lowerExprIdentifiers(expr.expr), values: expr.values?.map(v => lowerExprIdentifiers(v)) };
421
+ case 'windowFunction':
422
+ return { ...expr, function: lowerExprIdentifiers(expr.function), window: expr.window ? lowerWindowDefinitionIdentifiers(expr.window) : undefined };
423
+ case 'literal':
424
+ case 'parameter':
425
+ case 'subquery':
426
+ case 'exists':
427
+ default:
428
+ // Identifier-free or pass-through-structurally (subquery / exists) nodes: returned
429
+ // as-is. Never mutated, so aliasing the input subtree back into the output is safe
430
+ // (read-only at render); a literal's `value` is therefore never touched.
431
+ return expr;
432
+ }
433
+ }
434
+ /** Window-definition analogue of {@link lowerExprIdentifiers} — folds identifier refs in
435
+ * PARTITION BY / ORDER BY exprs and frame bounds. Window functions never appear in a CHECK /
436
+ * partial-WHERE today, but the fold mirrors {@link windowDefinitionToString} for symmetry. */
437
+ function lowerWindowDefinitionIdentifiers(win) {
438
+ return {
439
+ ...win,
440
+ partitionBy: win.partitionBy?.map(e => lowerExprIdentifiers(e)),
441
+ orderBy: win.orderBy?.map(o => ({ ...o, expr: lowerExprIdentifiers(o.expr) })),
442
+ frame: win.frame ? lowerWindowFrameIdentifiers(win.frame) : undefined,
443
+ };
444
+ }
445
+ function lowerWindowFrameIdentifiers(frame) {
446
+ return {
447
+ ...frame,
448
+ start: lowerWindowFrameBoundIdentifiers(frame.start),
449
+ end: frame.end ? lowerWindowFrameBoundIdentifiers(frame.end) : frame.end,
450
+ };
451
+ }
452
+ function lowerWindowFrameBoundIdentifiers(bound) {
453
+ return (bound.type === 'preceding' || bound.type === 'following')
454
+ ? { ...bound, value: lowerExprIdentifiers(bound.value) }
455
+ : bound;
456
+ }
457
+ /**
458
+ * Convert a result column (SELECT column list / RETURNING) to string:
459
+ * `*` / `t.*` / `expr [as alias] [with inverse (col = expr, …)]`.
460
+ */
461
+ function resultColumnToString(col) {
462
+ if (col.type === 'all') {
463
+ return col.table ? `${quoteIdentifier(col.table)}.*` : '*';
464
+ }
465
+ let colStr = expressionToString(col.expr);
466
+ if (col.alias)
467
+ colStr += ` as ${quoteIdentifier(col.alias)}`;
468
+ if (col.inverse && col.inverse.length > 0) {
469
+ const assignments = col.inverse.map(a => `${quoteIdentifier(a.column)} = ${expressionToString(a.expr)}`);
470
+ colStr += ` with inverse (${assignments.join(', ')})`;
471
+ }
472
+ return colStr;
473
+ }
474
+ /** Renders the `with schema s1, s2` search-path clause (WITH SCHEMA). */
475
+ function schemaPathClauseToString(schemaPath) {
476
+ return `with schema ${schemaPath.map(quoteIdentifier).join(', ')}`;
477
+ }
325
478
  // Statement stringify functions
326
479
  export function selectToString(stmt) {
327
480
  const parts = [];
@@ -333,18 +486,7 @@ export function selectToString(stmt) {
333
486
  parts.push('distinct');
334
487
  if (stmt.all)
335
488
  parts.push('all');
336
- const columns = stmt.columns.map(col => {
337
- if (col.type === 'all') {
338
- return col.table ? `${quoteIdentifier(col.table)}.*` : '*';
339
- }
340
- else {
341
- let colStr = expressionToString(col.expr);
342
- if (col.alias)
343
- colStr += ` as ${quoteIdentifier(col.alias)}`;
344
- return colStr;
345
- }
346
- });
347
- parts.push(columns.join(', '));
489
+ parts.push(stmt.columns.map(resultColumnToString).join(', '));
348
490
  if (stmt.from && stmt.from.length > 0) {
349
491
  parts.push('from', stmt.from.map(fromClauseToString).join(', '));
350
492
  }
@@ -357,6 +499,19 @@ export function selectToString(stmt) {
357
499
  if (stmt.having) {
358
500
  parts.push('having', expressionToString(stmt.having));
359
501
  }
502
+ // WITH SCHEMA binds before the compound operator and before ORDER BY / LIMIT
503
+ // (see `parseSchemaPath` in `selectStatement`; compound legs parse with
504
+ // `isCompoundSubquery` and never consume it) — emit it here so re-parse
505
+ // re-binds it to this statement rather than a leg or the trailing position.
506
+ if (stmt.schemaPath && stmt.schemaPath.length > 0) {
507
+ parts.push(schemaPathClauseToString(stmt.schemaPath));
508
+ }
509
+ // Trailing ORDER BY / LIMIT / OFFSET. On a COMPOUND select these apply to the
510
+ // whole compound result and so are emitted AFTER the compound chain below —
511
+ // rendering them in their normal position would re-bind them to the LEFT leg on
512
+ // re-parse (and produce un-reparseable `… order by … union …` SQL). Built once
513
+ // here and appended last in both the compound and non-compound cases.
514
+ const trailing = [];
360
515
  if (stmt.orderBy && stmt.orderBy.length > 0) {
361
516
  const orderParts = stmt.orderBy.map(clause => {
362
517
  let orderStr = expressionToString(clause.expr);
@@ -366,21 +521,64 @@ export function selectToString(stmt) {
366
521
  orderStr += ` nulls ${clause.nulls.toLowerCase()}`;
367
522
  return orderStr;
368
523
  });
369
- parts.push('order by', orderParts.join(', '));
524
+ trailing.push('order by', orderParts.join(', '));
370
525
  }
371
526
  if (stmt.limit) {
372
- parts.push('limit', expressionToString(stmt.limit));
527
+ trailing.push('limit', expressionToString(stmt.limit));
373
528
  }
374
529
  if (stmt.offset) {
375
- parts.push('offset', expressionToString(stmt.offset));
530
+ trailing.push('offset', expressionToString(stmt.offset));
376
531
  }
532
+ // `with defaults (col = expr, …)` binds to the whole compound, after
533
+ // limit/offset (mirrors trailing ORDER BY) — appended last in both the
534
+ // compound and non-compound cases below so re-parse re-binds it to the whole
535
+ // result, not the left leg.
536
+ const defaultsStr = defaultsClauseToString(stmt.defaults);
537
+ if (defaultsStr)
538
+ trailing.push(defaultsStr);
377
539
  let result = parts.join(' ');
378
540
  if (stmt.compound) {
379
541
  result += ` ${compoundOpToKeyword(stmt.compound.op)} `;
380
- result += selectToString(stmt.compound.select);
542
+ // `exists <branch> as <name>` membership columns sit BETWEEN the operator keyword
543
+ // and the right leg, so `parse(stringify(ast)) ≡ ast`.
544
+ if (stmt.compound.existence && stmt.compound.existence.length > 0) {
545
+ result += stmt.compound.existence
546
+ .map(e => `exists ${e.branch} as ${quoteIdentifier(e.name)}`)
547
+ .join(', ') + ' ';
548
+ }
549
+ result += compoundLegToString(stmt.compound.select);
550
+ }
551
+ if (trailing.length > 0) {
552
+ result += ' ' + trailing.join(' ');
381
553
  }
382
554
  return result;
383
555
  }
556
+ /**
557
+ * Renders one compound set-operation leg. A SELECT leg that carries its OWN
558
+ * trailing ORDER BY / LIMIT / OFFSET — or a WITH SCHEMA path, which bare legs
559
+ * never parse (`isCompoundSubquery` suppresses it) — is wrapped in parentheses
560
+ * so those clauses re-bind INSIDE the leg on re-parse; without the parens they
561
+ * would attach to the enclosing compound (or fail to parse) and change the
562
+ * parse. Every other leg — a bare SELECT, a VALUES leg, or a nested compound
563
+ * (whose right-leaning re-parse is identical) — renders without parens, so
564
+ * existing round-trips are unchanged.
565
+ */
566
+ function compoundLegToString(leg) {
567
+ const s = astToString(leg);
568
+ if (leg.type === 'select' && ((leg.orderBy && leg.orderBy.length > 0) || leg.limit || leg.offset
569
+ || (leg.schemaPath && leg.schemaPath.length > 0)
570
+ || (leg.defaults && leg.defaults.length > 0))) {
571
+ return `(${s})`;
572
+ }
573
+ return s;
574
+ }
575
+ /** `with defaults (col = expr, …)` clause of a select body, or '' when absent. */
576
+ function defaultsClauseToString(defaults) {
577
+ if (!defaults || defaults.length === 0)
578
+ return '';
579
+ const entries = defaults.map(d => `${quoteIdentifier(d.column)} = ${expressionToString(d.expr)}`);
580
+ return `with defaults (${entries.join(', ')})`;
581
+ }
384
582
  function compoundOpToKeyword(op) {
385
583
  switch (op) {
386
584
  case 'union': return 'union';
@@ -390,6 +588,13 @@ function compoundOpToKeyword(op) {
390
588
  case 'diff': return 'diff';
391
589
  }
392
590
  }
591
+ function materializationHintToKeyword(hint) {
592
+ switch (hint) {
593
+ case 'materialized': return 'materialized';
594
+ case 'not_materialized': return 'not materialized';
595
+ case undefined: return undefined;
596
+ }
597
+ }
393
598
  function withClauseToString(withClause) {
394
599
  let result = 'with';
395
600
  if (withClause.recursive)
@@ -399,7 +604,11 @@ function withClauseToString(withClause) {
399
604
  if (cte.columns && cte.columns.length > 0) {
400
605
  cteStr += ` (${cte.columns.map(quoteIdentifier).join(', ')})`;
401
606
  }
402
- cteStr += ` as (${astToString(cte.query)})`;
607
+ cteStr += ' as';
608
+ const hint = materializationHintToKeyword(cte.materializationHint);
609
+ if (hint)
610
+ cteStr += ` ${hint}`;
611
+ cteStr += ` (${astToString(cte.query)})`;
403
612
  return cteStr;
404
613
  });
405
614
  result += ` ${ctes.join(', ')}`;
@@ -421,18 +630,9 @@ function fromClauseToString(from) {
421
630
  return tableStr;
422
631
  }
423
632
  case 'subquerySource': {
424
- let subqueryStr;
425
- if (from.subquery.type === 'select') {
426
- subqueryStr = selectToString(from.subquery);
427
- }
428
- else if (from.subquery.type === 'values') {
429
- subqueryStr = valuesToString(from.subquery);
430
- }
431
- else {
432
- // Handle the case where subquery type is not recognized
433
- const exhaustiveCheck = from.subquery;
434
- subqueryStr = astToString(exhaustiveCheck);
435
- }
633
+ // QueryExpr body: SELECT / VALUES / INSERT|UPDATE|DELETE w/ RETURNING.
634
+ // astToString dispatches on the inner discriminator.
635
+ const subqueryStr = astToString(from.subquery);
436
636
  let aliasStr = `as ${quoteIdentifier(from.alias)}`;
437
637
  if (from.columns && from.columns.length > 0) {
438
638
  aliasStr += ` (${from.columns.map(quoteIdentifier).join(', ')})`;
@@ -444,7 +644,7 @@ function fromClauseToString(from) {
444
644
  // Check if from.name is a function expression or identifier expression
445
645
  let funcName;
446
646
  if (from.name.type === 'identifier') {
447
- funcName = from.name.name.toLowerCase();
647
+ funcName = quoteIdentifier(from.name.name.toLowerCase());
448
648
  }
449
649
  else if (from.name.type === 'function') {
450
650
  funcName = expressionToString(from.name);
@@ -460,22 +660,26 @@ function fromClauseToString(from) {
460
660
  case 'join': {
461
661
  const leftStr = fromClauseToString(from.left);
462
662
  const rightStr = fromClauseToString(from.right);
463
- let joinStr = `${leftStr} ${from.joinType.toLowerCase()} join ${rightStr}`;
663
+ // Preserve LATERAL so a correlated right side (e.g. a lateral TVF
664
+ // `cross join lateral json_each(t.arr)`) round-trips — without it the
665
+ // re-parsed body cannot resolve the correlation and fails to plan.
666
+ const lateralStr = from.isLateral ? 'lateral ' : '';
667
+ let joinStr = `${leftStr} ${from.joinType.toLowerCase()} join ${lateralStr}${rightStr}`;
464
668
  if (from.condition) {
465
669
  joinStr += ` on ${expressionToString(from.condition)}`;
466
670
  }
467
671
  else if (from.columns) {
468
672
  joinStr += ` using (${from.columns.map(quoteIdentifier).join(', ')})`;
469
673
  }
470
- return joinStr;
471
- }
472
- case 'mutatingSubquerySource': {
473
- const stmtStr = astToString(from.stmt);
474
- let aliasStr = `as ${quoteIdentifier(from.alias)}`;
475
- if (from.columns && from.columns.length > 0) {
476
- aliasStr += ` (${from.columns.map(quoteIdentifier).join(', ')})`;
674
+ // `exists <side> as <name>` existence columns after the ON/USING predicate.
675
+ // The side is always emitted (the parser resolves the elided form) so the
676
+ // clause round-trips structurally.
677
+ if (from.existence && from.existence.length > 0) {
678
+ joinStr += ' ' + from.existence
679
+ .map(e => `exists ${e.side} as ${quoteIdentifier(e.name)}`)
680
+ .join(', ');
477
681
  }
478
- return `(${stmtStr}) ${aliasStr}`;
682
+ return joinStr;
479
683
  }
480
684
  default:
481
685
  return '[unknown_from]';
@@ -498,32 +702,30 @@ export function insertToString(stmt) {
498
702
  const contextAssignments = stmt.contextValues.map(assign => `${quoteIdentifier(assign.name)} = ${expressionToString(assign.value)}`);
499
703
  parts.push('with context', contextAssignments.join(', '));
500
704
  }
501
- if (stmt.values) {
502
- const valueRows = stmt.values.map(row => `(${row.map(expressionToString).join(', ')})`);
503
- parts.push('values', valueRows.join(', '));
504
- }
505
- else if (stmt.select) {
506
- parts.push(selectToString(stmt.select));
507
- }
705
+ // Body is a QueryExpr — bare SELECT/VALUES at top-level of INSERT, or a
706
+ // nested DML form (must carry RETURNING; outer INSERT is the consumer).
707
+ // astToString dispatches on the discriminator.
708
+ parts.push(astToString(stmt.source));
508
709
  // UPSERT clauses (ON CONFLICT DO ...)
509
710
  if (stmt.upsertClauses) {
510
711
  for (const upsert of stmt.upsertClauses) {
511
712
  parts.push(upsertClauseToString(upsert));
512
713
  }
513
714
  }
715
+ if (stmt.tags) {
716
+ const tagsClause = tagsClauseToString(stmt.tags).trimStart();
717
+ if (tagsClause)
718
+ parts.push(tagsClause);
719
+ }
720
+ // Trailing WITH SCHEMA (parseTrailingWithClauses accepts context/schema/tags
721
+ // in any order). Emitted after WITH TAGS deliberately: an intervening trailing
722
+ // clause stops a bare SELECT source from greedily consuming the schema path
723
+ // onto itself on re-parse.
724
+ if (stmt.schemaPath && stmt.schemaPath.length > 0) {
725
+ parts.push(schemaPathClauseToString(stmt.schemaPath));
726
+ }
514
727
  if (stmt.returning && stmt.returning.length > 0) {
515
- const returning = stmt.returning.map(col => {
516
- if (col.type === 'all') {
517
- return col.table ? `${quoteIdentifier(col.table)}.*` : '*';
518
- }
519
- else {
520
- let colStr = expressionToString(col.expr);
521
- if (col.alias)
522
- colStr += ` as ${quoteIdentifier(col.alias)}`;
523
- return colStr;
524
- }
525
- });
526
- parts.push('returning', returning.join(', '));
728
+ parts.push('returning', stmt.returning.map(resultColumnToString).join(', '));
527
729
  }
528
730
  return parts.join(' ');
529
731
  }
@@ -550,12 +752,37 @@ function upsertClauseToString(upsert) {
550
752
  }
551
753
  return parts.join(' ');
552
754
  }
755
+ /**
756
+ * Render an inline subquery DML write target: `(<body>) as <alias>[(cols)]`. Reuses the
757
+ * FROM-subquery body+alias rendering so a nested DML/RETURNING body round-trips. The
758
+ * alias is folded in here, so the caller must NOT also emit the standalone `as <alias>`
759
+ * push (it would double-emit). Mirrors the `subquerySource` case of {@link fromClauseToString}.
760
+ */
761
+ function subqueryTargetToString(target) {
762
+ let aliasStr = `as ${quoteIdentifier(target.alias)}`;
763
+ if (target.columns && target.columns.length > 0) {
764
+ aliasStr += ` (${target.columns.map(quoteIdentifier).join(', ')})`;
765
+ }
766
+ return `(${astToString(target.subquery)}) ${aliasStr}`;
767
+ }
553
768
  export function updateToString(stmt) {
554
769
  const parts = [];
555
770
  if (stmt.withClause) {
556
771
  parts.push(withClauseToString(stmt.withClause));
557
772
  }
558
- parts.push('update', expressionToString(stmt.table));
773
+ if (stmt.targetSource) {
774
+ // Inline subquery target: render `(body) as alias[(cols)]` in place of the named
775
+ // target. The alias rides the targetSource rendering, so the standalone `as alias`
776
+ // push below is skipped to avoid double-emitting it.
777
+ parts.push('update', subqueryTargetToString(stmt.targetSource));
778
+ }
779
+ else {
780
+ parts.push('update', expressionToString(stmt.table));
781
+ // Synthesised internal correlation name (view-mutation single-source lowering) —
782
+ // render it for plan/debug round-trip fidelity.
783
+ if (stmt.alias)
784
+ parts.push('as', quoteIdentifier(stmt.alias));
785
+ }
559
786
  if (stmt.contextValues && stmt.contextValues.length > 0) {
560
787
  const contextAssignments = stmt.contextValues.map(assign => `${quoteIdentifier(assign.name)} = ${expressionToString(assign.value)}`);
561
788
  parts.push('with context', contextAssignments.join(', '));
@@ -566,19 +793,17 @@ export function updateToString(stmt) {
566
793
  if (stmt.where) {
567
794
  parts.push('where', expressionToString(stmt.where));
568
795
  }
796
+ if (stmt.tags) {
797
+ const tagsClause = tagsClauseToString(stmt.tags).trimStart();
798
+ if (tagsClause)
799
+ parts.push(tagsClause);
800
+ }
801
+ // Trailing WITH SCHEMA (parseTrailingWithClauses accepts context/schema/tags in any order).
802
+ if (stmt.schemaPath && stmt.schemaPath.length > 0) {
803
+ parts.push(schemaPathClauseToString(stmt.schemaPath));
804
+ }
569
805
  if (stmt.returning && stmt.returning.length > 0) {
570
- const returning = stmt.returning.map(col => {
571
- if (col.type === 'all') {
572
- return col.table ? `${quoteIdentifier(col.table)}.*` : '*';
573
- }
574
- else {
575
- let colStr = expressionToString(col.expr);
576
- if (col.alias)
577
- colStr += ` as ${quoteIdentifier(col.alias)}`;
578
- return colStr;
579
- }
580
- });
581
- parts.push('returning', returning.join(', '));
806
+ parts.push('returning', stmt.returning.map(resultColumnToString).join(', '));
582
807
  }
583
808
  return parts.join(' ');
584
809
  }
@@ -587,7 +812,19 @@ export function deleteToString(stmt) {
587
812
  if (stmt.withClause) {
588
813
  parts.push(withClauseToString(stmt.withClause));
589
814
  }
590
- parts.push('delete from', expressionToString(stmt.table));
815
+ if (stmt.targetSource) {
816
+ // Inline subquery target: render `(body) as alias[(cols)]` in place of the named
817
+ // target. The alias rides the targetSource rendering, so the standalone `as alias`
818
+ // push below is skipped to avoid double-emitting it.
819
+ parts.push('delete from', subqueryTargetToString(stmt.targetSource));
820
+ }
821
+ else {
822
+ parts.push('delete from', expressionToString(stmt.table));
823
+ // Synthesised internal correlation name (view-mutation single-source lowering) —
824
+ // render it for plan/debug round-trip fidelity.
825
+ if (stmt.alias)
826
+ parts.push('as', quoteIdentifier(stmt.alias));
827
+ }
591
828
  if (stmt.contextValues && stmt.contextValues.length > 0) {
592
829
  const contextAssignments = stmt.contextValues.map(assign => `${quoteIdentifier(assign.name)} = ${expressionToString(assign.value)}`);
593
830
  parts.push('with context', contextAssignments.join(', '));
@@ -595,19 +832,17 @@ export function deleteToString(stmt) {
595
832
  if (stmt.where) {
596
833
  parts.push('where', expressionToString(stmt.where));
597
834
  }
835
+ if (stmt.tags) {
836
+ const tagsClause = tagsClauseToString(stmt.tags).trimStart();
837
+ if (tagsClause)
838
+ parts.push(tagsClause);
839
+ }
840
+ // Trailing WITH SCHEMA (parseTrailingWithClauses accepts context/schema/tags in any order).
841
+ if (stmt.schemaPath && stmt.schemaPath.length > 0) {
842
+ parts.push(schemaPathClauseToString(stmt.schemaPath));
843
+ }
598
844
  if (stmt.returning && stmt.returning.length > 0) {
599
- const returning = stmt.returning.map(col => {
600
- if (col.type === 'all') {
601
- return col.table ? `${quoteIdentifier(col.table)}.*` : '*';
602
- }
603
- else {
604
- let colStr = expressionToString(col.expr);
605
- if (col.alias)
606
- colStr += ` as ${quoteIdentifier(col.alias)}`;
607
- return colStr;
608
- }
609
- });
610
- parts.push('returning', returning.join(', '));
845
+ parts.push('returning', stmt.returning.map(resultColumnToString).join(', '));
611
846
  }
612
847
  return parts.join(' ');
613
848
  }
@@ -620,13 +855,19 @@ function indexedColumnsToString(cols) {
620
855
  if (col.name) {
621
856
  let colStr = quoteIdentifier(col.name);
622
857
  if (col.collation)
623
- colStr += ` collate ${col.collation.toLowerCase()}`;
858
+ colStr += ` collate ${quoteIdentifier(col.collation.toLowerCase())}`;
624
859
  if (col.direction === 'desc')
625
860
  colStr += ' desc';
626
861
  return colStr;
627
862
  }
628
863
  else if (col.expr) {
629
- return expressionToString(col.expr);
864
+ // Collate-folded form (`col COLLATE x [desc]`): expressionToString renders
865
+ // the column + collation, but the direction lives on col.direction and
866
+ // must be re-appended (asc is the default and stays elided).
867
+ let colStr = expressionToString(col.expr);
868
+ if (col.direction === 'desc')
869
+ colStr += ' desc';
870
+ return colStr;
630
871
  }
631
872
  return '';
632
873
  }).filter(s => s).join(', ');
@@ -648,10 +889,150 @@ export function createIndexToString(stmt) {
648
889
  parts.push(indexTagStr.trimStart());
649
890
  return parts.join(' ');
650
891
  }
892
+ /**
893
+ * The bare column name an indexed-column AST node refers to. A plain column
894
+ * carries it on `col.name`; the parser folds `col COLLATE x` into a `collate`
895
+ * expression over a column reference, so for that form the name lives on
896
+ * `col.expr.expr.name`. Returns undefined for a genuine expression-index column
897
+ * (no resolvable column name).
898
+ *
899
+ * Exported so the declarative differ can resolve a declared index column's
900
+ * effective collation (it needs the bare name to look up the table column).
901
+ */
902
+ export function indexedColumnBareName(col) {
903
+ if (col.name)
904
+ return col.name;
905
+ if (col.expr?.type === 'collate' && col.expr.expr.type === 'column')
906
+ return col.expr.expr.name;
907
+ return undefined;
908
+ }
909
+ /**
910
+ * The effective per-column collation to render in the canonical index body, or
911
+ * undefined when none / `BINARY` (both elided; comparison is case-insensitive).
912
+ *
913
+ * Reads the resolved collation off the plain `IndexedColumn.collation`: the two
914
+ * callers ({@link createIndexBodyToCanonicalString} via the differ's
915
+ * `declaredIndexCanonicalBody`, and the actual catalog's `indexToCanonicalDDL`)
916
+ * BOTH pre-resolve the effective collation onto that field (explicit index
917
+ * COLLATE, else table-column collation, else BINARY; normalized), so rendering it
918
+ * here makes an unchanged inherited/BINARY collation render identically on both
919
+ * diff sides while a genuine collation change diverges. The defensive fallback
920
+ * reads the parser's collate-folded form (`col.expr.collation`) so a future raw
921
+ * caller that skips the pre-resolve step does not silently drop the collation.
922
+ */
923
+ function canonicalIndexColumnCollation(col) {
924
+ const c = col.collation ?? (col.expr?.type === 'collate' ? col.expr.collation : undefined);
925
+ if (!c || c.toUpperCase() === 'BINARY')
926
+ return undefined;
927
+ return c;
928
+ }
929
+ /**
930
+ * Canonical renderer for an index's column list, used only by
931
+ * {@link createIndexBodyToCanonicalString} for body-drift comparison — NOT a
932
+ * persistence path (see {@link indexedColumnsToString} for the persistence form).
933
+ * For each column emit the bare column name, then an effective `collate <c>` (only
934
+ * when non-BINARY), then ` desc` when descending — the same name/collate/desc order
935
+ * the persistence renderer uses. The bare name is extracted from both indexed-column
936
+ * forms (plain `col.name` and the parser's collate-folded form — see
937
+ * {@link indexedColumnBareName}); a genuine expression-index column with no
938
+ * resolvable name falls back to `expressionToString(col.expr)` (such indexes are
939
+ * rejected on import and never name-match a real actual).
940
+ *
941
+ * The bare name is lowercased before `quoteIdentifier` so the comparison key is
942
+ * case-insensitive — matching Quereus's uniformly case-folding column resolution
943
+ * (the AST never records identifier quoting; every resolver folds via
944
+ * `.toLowerCase()`). The actual side lifts the column *definition* case while the
945
+ * declared side carries the as-written index reference case; folding both makes a
946
+ * case-only divergence (e.g. column `Email` indexed as `email`) render identically
947
+ * instead of churning a spurious drop+recreate.
948
+ *
949
+ * Collation is rendered from the pre-resolved effective value
950
+ * ({@link canonicalIndexColumnCollation}): both diff sides resolve the column's
951
+ * collation the same way the engine does at create/import time, so an inherited or
952
+ * default-BINARY collation that is unchanged renders identically (no churn) while a
953
+ * genuine per-column collation change renders differently (drop+recreate).
954
+ */
955
+ function canonicalIndexedColumnsToString(cols) {
956
+ return cols.map(col => {
957
+ const name = indexedColumnBareName(col);
958
+ if (name) {
959
+ let colStr = quoteIdentifier(name.toLowerCase());
960
+ const collation = canonicalIndexColumnCollation(col);
961
+ if (collation)
962
+ colStr += ` collate ${quoteIdentifier(collation.toLowerCase())}`;
963
+ if (col.direction === 'desc')
964
+ colStr += ' desc';
965
+ return colStr;
966
+ }
967
+ return col.expr ? expressionToString(col.expr) : '';
968
+ }).filter(s => s).join(', ');
969
+ }
970
+ /**
971
+ * Renders the **canonical body** of an index — the comparison key the declarative
972
+ * differ uses to detect a name-matched index whose body changed (UNIQUE-ness,
973
+ * column set/order/direction, or partial WHERE predicate). Two semantically-equal
974
+ * indexes must render identically here or a spurious drop+recreate churns; two
975
+ * different ones must render differently or a real change silently no-ops.
976
+ *
977
+ * Excludes the index `name`, the `on <table>` reference, `if not exists`, AND the
978
+ * `with tags (...)` suffix (tags are a separate diff channel — `ALTER INDEX … SET
979
+ * TAGS`). Per-column collation IS included, but only as an already-resolved
980
+ * effective value: both sides pre-resolve each column's effective collation the
981
+ * way the engine does at create/import time (explicit index COLLATE, else the
982
+ * table column's collation, else BINARY; normalized) before calling this renderer
983
+ * — the actual side in `ddl-generator`'s `indexToCanonicalDDL`, the declared side
984
+ * in `schema-differ`'s `declaredIndexCanonicalBody`. An unchanged inherited or
985
+ * default-BINARY collation therefore renders identically (no churn) while a genuine
986
+ * collation change renders differently (drop+recreate). Both sides funnel through
987
+ * here so their fragments are byte-comparable.
988
+ *
989
+ * The partial-index WHERE predicate's bare column references are case-folded
990
+ * ({@link lowerExprIdentifiers}) so a reference whose case diverges between schema
991
+ * versions (the stored predicate keeps the as-written case; a re-declare may differ)
992
+ * renders identically on both sides — literals are preserved byte-exact.
993
+ */
994
+ export function createIndexBodyToCanonicalString(stmt) {
995
+ const parts = [];
996
+ if (stmt.isUnique)
997
+ parts.push('unique');
998
+ parts.push('index');
999
+ parts.push(`(${canonicalIndexedColumnsToString(stmt.columns)})`);
1000
+ if (stmt.where)
1001
+ parts.push('where', expressionToString(lowerExprIdentifiers(stmt.where)));
1002
+ return parts.join(' ');
1003
+ }
1004
+ /**
1005
+ * Renders the **canonical definition** of a view or materialized view — the
1006
+ * comparison key the declarative differ uses to detect a name-matched view whose
1007
+ * definition changed. Covers the two definitional parts: the explicit column
1008
+ * list (`v(a, b)` — for an MV it also names the backing-table columns) and the
1009
+ * body (`astToString` of the QueryExpr). The body string already carries any
1010
+ * trailing `with defaults (col = expr, …)` clause (write-through behavior) via
1011
+ * `selectToString`, so a defaults-only edit drifts this string automatically.
1012
+ * Excludes the view name / schema / `if not exists` / tags — tags are a separate
1013
+ * diff channel (`ALTER VIEW … SET TAGS`), mirroring `CatalogIndex.definition`.
1014
+ *
1015
+ * Both diff sides funnel through here (the actual side from the live
1016
+ * `ViewSchema` / `TableDerivation` fields, the declared side from the
1017
+ * `CreateViewStmt` / `CreateMaterializedViewStmt` fields), and both ASTs come
1018
+ * from the same parser and render through this same emitter, so keyword case /
1019
+ * whitespace cannot churn. Deliberately NO identifier case-folding — unlike the
1020
+ * constraint / index canonical bodies (whose recreates re-validate or rebuild,
1021
+ * so they fold to avoid expensive churn), a case-only edit here recreates a
1022
+ * plain view (free — data-less) or rebuilds an MV (pre-existing behavior of the
1023
+ * select-only hash). See docs/schema.md § View / materialized-view definition
1024
+ * changes.
1025
+ */
1026
+ export function viewDefinitionToCanonicalString(columns, select) {
1027
+ const parts = [];
1028
+ if (columns && columns.length > 0) {
1029
+ parts.push(`(${columns.map(quoteIdentifier).join(', ')})`);
1030
+ }
1031
+ parts.push(astToString(select));
1032
+ return parts.join(' ');
1033
+ }
651
1034
  export function createViewToString(stmt) {
652
1035
  const parts = ['create'];
653
- if (stmt.isTemporary)
654
- parts.push('temp');
655
1036
  parts.push('view');
656
1037
  if (stmt.ifNotExists)
657
1038
  parts.push('if not exists');
@@ -659,12 +1040,47 @@ export function createViewToString(stmt) {
659
1040
  if (stmt.columns && stmt.columns.length > 0) {
660
1041
  parts.push(`(${stmt.columns.map(quoteIdentifier).join(', ')})`);
661
1042
  }
662
- parts.push('as', selectToString(stmt.select));
1043
+ // View body is a QueryExpr — astToString dispatches on the discriminator.
1044
+ // A trailing `with defaults (…)` rides inside the body string (selectToString).
1045
+ parts.push('as', astToString(stmt.select));
1046
+ const viewTagStr = tagsClauseToString(stmt.tags);
1047
+ if (viewTagStr)
1048
+ parts.push(viewTagStr.trimStart());
1049
+ return parts.join(' ');
1050
+ }
1051
+ export function createMaterializedViewToString(stmt) {
1052
+ const parts = ['create'];
1053
+ parts.push('materialized', 'view');
1054
+ if (stmt.ifNotExists)
1055
+ parts.push('if not exists');
1056
+ parts.push(expressionToString(stmt.view));
1057
+ if (stmt.columns && stmt.columns.length > 0) {
1058
+ parts.push(`(${stmt.columns.map(quoteIdentifier).join(', ')})`);
1059
+ }
1060
+ const usingClause = mvModuleClauseToString(stmt);
1061
+ if (usingClause)
1062
+ parts.push(usingClause);
1063
+ // A trailing `with defaults (…)` rides inside the body string (selectToString).
1064
+ parts.push('as', astToString(stmt.select));
663
1065
  const viewTagStr = tagsClauseToString(stmt.tags);
664
1066
  if (viewTagStr)
665
1067
  parts.push(viewTagStr.trimStart());
666
1068
  return parts.join(' ');
667
1069
  }
1070
+ /** `using <module>(args)` clause for a materialized view, or '' when absent. */
1071
+ function mvModuleClauseToString(stmt) {
1072
+ if (!stmt.moduleName)
1073
+ return '';
1074
+ let s = `using ${quoteIdentifier(stmt.moduleName)}`;
1075
+ if (stmt.moduleArgs && Object.keys(stmt.moduleArgs).length > 0) {
1076
+ const args = Object.entries(stmt.moduleArgs).map(([k, v]) => `${quoteIdentifier(k)} = ${JSON.stringify(v)}`);
1077
+ s += ` (${args.join(', ')})`;
1078
+ }
1079
+ return s;
1080
+ }
1081
+ export function refreshMaterializedViewToString(stmt) {
1082
+ return `refresh materialized view ${expressionToString(stmt.name)}`;
1083
+ }
668
1084
  export function createAssertionToString(stmt) {
669
1085
  return `create assertion ${quoteIdentifier(stmt.name)} check (${expressionToString(stmt.check)})`;
670
1086
  }
@@ -681,6 +1097,10 @@ function alterTableToString(stmt) {
681
1097
  return `alter table ${table} drop column ${quoteIdentifier(stmt.action.name)}`;
682
1098
  case 'addConstraint':
683
1099
  return `alter table ${table} add ${tableConstraintsToString([stmt.action.constraint])}`;
1100
+ case 'dropConstraint':
1101
+ return `alter table ${table} drop constraint ${quoteIdentifier(stmt.action.name)}`;
1102
+ case 'renameConstraint':
1103
+ return `alter table ${table} rename constraint ${quoteIdentifier(stmt.action.oldName)} to ${quoteIdentifier(stmt.action.newName)}`;
684
1104
  case 'alterPrimaryKey': {
685
1105
  const cols = stmt.action.columns
686
1106
  .map(c => {
@@ -703,6 +1123,9 @@ function alterTableToString(stmt) {
703
1123
  ? `alter table ${table} alter column ${colName} drop default`
704
1124
  : `alter table ${table} alter column ${colName} set default ${expressionToString(a.setDefault)}`;
705
1125
  }
1126
+ if (a.setCollation !== undefined) {
1127
+ return `alter table ${table} alter column ${colName} set collate ${a.setCollation}`;
1128
+ }
706
1129
  if (a.setNotNull !== undefined) {
707
1130
  return a.setNotNull
708
1131
  ? `alter table ${table} alter column ${colName} set not null`
@@ -710,8 +1133,65 @@ function alterTableToString(stmt) {
710
1133
  }
711
1134
  return `alter table ${table} alter column ${colName}`;
712
1135
  }
1136
+ case 'setTags': {
1137
+ const a = stmt.action;
1138
+ const body = tagsBodyToString(a.tags);
1139
+ const verb = a.mode === 'merge' ? 'add tags' : 'set tags';
1140
+ if (a.target.kind === 'column') {
1141
+ return `alter table ${table} alter column ${quoteIdentifier(a.target.columnName)} ${verb} ${body}`;
1142
+ }
1143
+ if (a.target.kind === 'constraint') {
1144
+ return `alter table ${table} alter constraint ${quoteIdentifier(a.target.constraintName)} ${verb} ${body}`;
1145
+ }
1146
+ return `alter table ${table} ${verb} ${body}`;
1147
+ }
1148
+ case 'dropTags': {
1149
+ const a = stmt.action;
1150
+ const body = tagKeysBodyToString(a.keys);
1151
+ if (a.target.kind === 'column') {
1152
+ return `alter table ${table} alter column ${quoteIdentifier(a.target.columnName)} drop tags ${body}`;
1153
+ }
1154
+ if (a.target.kind === 'constraint') {
1155
+ return `alter table ${table} alter constraint ${quoteIdentifier(a.target.constraintName)} drop tags ${body}`;
1156
+ }
1157
+ return `alter table ${table} drop tags ${body}`;
1158
+ }
1159
+ case 'setMaintained': {
1160
+ // `(cols)` rename list is emitted only when present (an explicit MV-sugar
1161
+ // rename — the differ's lossless encoding); its absence is the implicit
1162
+ // signal. Byte-identical to the bare `set maintained as` form otherwise.
1163
+ const cols = stmt.action.columns?.length
1164
+ ? ` (${stmt.action.columns.map(quoteIdentifier).join(', ')})`
1165
+ : '';
1166
+ // A trailing `with defaults (…)` rides inside the body string (selectToString).
1167
+ return `alter table ${table} set maintained${cols} as ${astToString(stmt.action.select)}`;
1168
+ }
1169
+ case 'dropMaintained':
1170
+ return `alter table ${table} drop maintained`;
713
1171
  }
714
1172
  }
1173
+ /**
1174
+ * Renders the trailing `{set|add|drop} tags (...)` clause shared by ALTER VIEW /
1175
+ * MATERIALIZED VIEW / INDEX: `setTags` is `add tags` when `mode === 'merge'` else
1176
+ * `set tags` (body via `tagsBodyToString`); `dropTags` is `drop tags` (body via
1177
+ * `tagKeysBodyToString`).
1178
+ */
1179
+ function objectTagsActionToString(action) {
1180
+ if (action.type === 'dropTags') {
1181
+ return `drop tags ${tagKeysBodyToString(action.keys)}`;
1182
+ }
1183
+ const verb = action.mode === 'merge' ? 'add tags' : 'set tags';
1184
+ return `${verb} ${tagsBodyToString(action.tags)}`;
1185
+ }
1186
+ function alterViewToString(stmt) {
1187
+ return `alter view ${expressionToString(stmt.name)} ${objectTagsActionToString(stmt.action)}`;
1188
+ }
1189
+ function alterMaterializedViewToString(stmt) {
1190
+ return `alter materialized view ${expressionToString(stmt.name)} ${objectTagsActionToString(stmt.action)}`;
1191
+ }
1192
+ export function alterIndexToString(stmt) {
1193
+ return `alter index ${expressionToString(stmt.name)} ${objectTagsActionToString(stmt.action)}`;
1194
+ }
715
1195
  function analyzeToString(stmt) {
716
1196
  if (stmt.schemaName && stmt.tableName)
717
1197
  return `analyze ${quoteIdentifier(stmt.schemaName)}.${quoteIdentifier(stmt.tableName)}`;
@@ -722,7 +1202,8 @@ function analyzeToString(stmt) {
722
1202
  return 'analyze';
723
1203
  }
724
1204
  function dropToString(stmt) {
725
- const parts = ['drop', stmt.objectType.toLowerCase()];
1205
+ const objectKeyword = stmt.objectType === 'materializedView' ? 'materialized view' : stmt.objectType.toLowerCase();
1206
+ const parts = ['drop', objectKeyword];
726
1207
  if (stmt.ifExists)
727
1208
  parts.push('if exists');
728
1209
  parts.push(expressionToString(stmt.name));
@@ -734,17 +1215,17 @@ function beginToString(_stmt) {
734
1215
  function rollbackToString(stmt) {
735
1216
  let result = 'rollback';
736
1217
  if (stmt.savepoint) {
737
- result += ` to ${stmt.savepoint}`;
1218
+ result += ` to ${quoteIdentifier(stmt.savepoint)}`;
738
1219
  }
739
1220
  return result;
740
1221
  }
741
1222
  function savepointToString(stmt) {
742
- return `savepoint ${stmt.name}`;
1223
+ return `savepoint ${quoteIdentifier(stmt.name)}`;
743
1224
  }
744
1225
  function releaseToString(stmt) {
745
1226
  let result = 'release';
746
1227
  if (stmt.savepoint) {
747
- result += ` ${stmt.savepoint}`;
1228
+ result += ` ${quoteIdentifier(stmt.savepoint)}`;
748
1229
  }
749
1230
  return result;
750
1231
  }
@@ -756,7 +1237,7 @@ function pragmaToString(stmt) {
756
1237
  return result;
757
1238
  }
758
1239
  function declareSchemaToString(stmt) {
759
- let s = `declare schema ${quoteIdentifier(stmt.schemaName || 'main')}`;
1240
+ let s = `declare ${stmt.isLogical ? 'logical ' : ''}schema ${quoteIdentifier(stmt.schemaName || 'main')}`;
760
1241
  if (stmt.version)
761
1242
  s += ` version '${stmt.version}'`;
762
1243
  if (stmt.using && (stmt.using.defaultVtabModule || stmt.using.defaultVtabArgs)) {
@@ -774,11 +1255,21 @@ function declareSchemaToString(stmt) {
774
1255
  s += ' }';
775
1256
  return s;
776
1257
  }
1258
+ function declareLensToString(stmt) {
1259
+ let s = `declare lens for ${quoteIdentifier(stmt.logicalSchema)} over ${quoteIdentifier(stmt.basisSchema)} {`;
1260
+ for (const ov of stmt.overrides) {
1261
+ s += ` view ${quoteIdentifier(ov.table)} as ${selectToString(ov.select)}`;
1262
+ s += ';';
1263
+ }
1264
+ s += ' }';
1265
+ return s;
1266
+ }
777
1267
  function declareItemToString(it) {
778
1268
  switch (it.type) {
779
1269
  case 'declaredTable': return declaredTableToString(it);
780
1270
  case 'declaredIndex': return declaredIndexToString(it);
781
1271
  case 'declaredView': return declaredViewToString(it);
1272
+ case 'declaredMaterializedView': return declaredMaterializedViewToString(it);
782
1273
  case 'declaredSeed': return declaredSeedToString(it);
783
1274
  case 'declaredAssertion': return declaredAssertionToString(it);
784
1275
  case 'declareIgnored': return it.text || '-- ignored';
@@ -818,7 +1309,25 @@ function declaredViewToString(it) {
818
1309
  if (stmt.columns && stmt.columns.length > 0) {
819
1310
  parts.push(`(${stmt.columns.map(quoteIdentifier).join(', ')})`);
820
1311
  }
821
- parts.push('as', selectToString(stmt.select));
1312
+ // View body is a QueryExpr — astToString dispatches on the discriminator.
1313
+ // A trailing `with defaults (…)` rides inside the body string (selectToString).
1314
+ parts.push('as', astToString(stmt.select));
1315
+ const tagStr = tagsClauseToString(stmt.tags);
1316
+ if (tagStr)
1317
+ parts.push(tagStr.trimStart());
1318
+ return parts.join(' ');
1319
+ }
1320
+ function declaredMaterializedViewToString(it) {
1321
+ const stmt = it.viewStmt;
1322
+ const parts = ['materialized', 'view', quoteIdentifier(stmt.view.name)];
1323
+ if (stmt.columns && stmt.columns.length > 0) {
1324
+ parts.push(`(${stmt.columns.map(quoteIdentifier).join(', ')})`);
1325
+ }
1326
+ const usingClause = mvModuleClauseToString(stmt);
1327
+ if (usingClause)
1328
+ parts.push(usingClause);
1329
+ // A trailing `with defaults (…)` rides inside the body string (selectToString).
1330
+ parts.push('as', astToString(stmt.select));
822
1331
  const tagStr = tagsClauseToString(stmt.tags);
823
1332
  if (tagStr)
824
1333
  parts.push(tagStr.trimStart());
@@ -903,7 +1412,7 @@ function columnConstraintsToString(constraints) {
903
1412
  s += `default ${expressionToString(c.expr)}`;
904
1413
  break;
905
1414
  case 'collate':
906
- s += `collate ${c.collation.toLowerCase()}`;
1415
+ s += `collate ${quoteIdentifier(c.collation.toLowerCase())}`;
907
1416
  break;
908
1417
  case 'foreignKey':
909
1418
  if (c.foreignKey) {
@@ -922,7 +1431,7 @@ function columnConstraintsToString(constraints) {
922
1431
  }).filter(s => s.length > 0).join(' ');
923
1432
  }
924
1433
  // Helper to stringify table constraints
925
- function tableConstraintsToString(constraints) {
1434
+ export function tableConstraintsToString(constraints) {
926
1435
  return constraints.map(c => {
927
1436
  let s = '';
928
1437
  if (c.name)
@@ -956,6 +1465,140 @@ function tableConstraintsToString(constraints) {
956
1465
  return s;
957
1466
  }).filter(s => s.length > 0).join(', ');
958
1467
  }
1468
+ /** Canonical insert→update→delete ordering for a CHECK `on` operation list. */
1469
+ const ROWOP_CANONICAL_ORDER = ['insert', 'update', 'delete'];
1470
+ /**
1471
+ * Normalizes a CHECK constraint's `on` operation list to its canonical form for
1472
+ * body comparison: the bare-CHECK default (INSERT + UPDATE) renders identically
1473
+ * whether written as `check (...)` (parser leaves `operations` undefined) or
1474
+ * `check on insert, update (...)`, so the default collapses to `undefined` (no
1475
+ * `on` clause). Any other mask emits in fixed insert→update→delete order.
1476
+ */
1477
+ function canonicalCheckOperations(ops) {
1478
+ const set = new Set(ops && ops.length > 0 ? ops : ['insert', 'update']);
1479
+ if (set.size === 2 && set.has('insert') && set.has('update'))
1480
+ return undefined;
1481
+ return ROWOP_CANONICAL_ORDER.filter(op => set.has(op));
1482
+ }
1483
+ /**
1484
+ * Normalizes a foreign-key clause for body comparison: the referenced (parent)
1485
+ * TABLE name is case-folded (the catalog stores it as-written — see
1486
+ * `constraint-builder`'s `referencedTable: fk.table` — so a parent-name case change
1487
+ * between versions would otherwise churn a spurious drop+add); the default `restrict`
1488
+ * action on DELETE / UPDATE renders the same whether written explicitly or
1489
+ * omitted, so it collapses to `undefined` (no `on delete/update` clause); an
1490
+ * empty referenced-column list collapses to `undefined` (bare `references t`);
1491
+ * and the deferrable clause is dropped entirely (it is not a body-change
1492
+ * channel the declarative differ tracks). `quoteIdentifier` still runs after the
1493
+ * lowercase at render, so a reserved-word parent name re-quotes correctly on both
1494
+ * sides. (The referenced COLUMN list is folded upstream by
1495
+ * {@link lowercaseTableConstraintColumnNames}.)
1496
+ */
1497
+ function canonicalForeignKeyClause(fk, childSchemaName) {
1498
+ return {
1499
+ table: fk.table.toLowerCase(),
1500
+ // The parent-schema qualifier is canonical iff it differs (case-insensitively)
1501
+ // from the CHILD table's schema: a genuine cross-schema FK keeps its qualifier,
1502
+ // but an explicit own-schema qualifier elides to `undefined` so `references main.t`
1503
+ // declared on a child IN `main` canonicalizes equal to the bare `references t`
1504
+ // (and to the actual-catalog side, which already elides a parent == child schema).
1505
+ // `childSchemaName` is absent for non-FK contexts / callers without a child schema;
1506
+ // then any present qualifier is kept (case-folded) — a cross-schema FK and a
1507
+ // same-schema FK to a like-named parent still don't collapse to one canonical key.
1508
+ schema: fk.schema && fk.schema.toLowerCase() !== childSchemaName?.toLowerCase()
1509
+ ? fk.schema.toLowerCase()
1510
+ : undefined,
1511
+ columns: fk.columns && fk.columns.length > 0 ? fk.columns : undefined,
1512
+ onDelete: fk.onDelete && fk.onDelete !== 'restrict' ? fk.onDelete : undefined,
1513
+ onUpdate: fk.onUpdate && fk.onUpdate !== 'restrict' ? fk.onUpdate : undefined,
1514
+ };
1515
+ }
1516
+ /**
1517
+ * Returns a clone of a table constraint with every bare column-name identifier in
1518
+ * its column list(s) lowercased — the canonical-body normalization that makes the
1519
+ * comparison key case-insensitive, matching Quereus's uniformly case-folding column
1520
+ * resolution (the AST never records identifier quoting, and every resolver folds via
1521
+ * `.toLowerCase()`). Applied ONLY by {@link constraintBodyToCanonicalString} (the
1522
+ * canonical-comparison entry point); the persistence renderer
1523
+ * {@link tableConstraintsToString} keeps the original case so a stored CREATE TABLE
1524
+ * round-trips its declared casing.
1525
+ *
1526
+ * Covers the UNIQUE / PRIMARY KEY column list, the FK local (child) column list, the
1527
+ * FK referenced (parent) column list, AND the bare column references embedded in a
1528
+ * CHECK expression — the last via {@link lowerExprIdentifiers} (a structural clone),
1529
+ * since CHECK carries no column list and its refs live in the expression.
1530
+ *
1531
+ * MUST NOT mutate the input: the declared side passes `DeclaredNamedConstraint.bodyAst`,
1532
+ * which backs the differ's `ddl` / `definition` — so the column arrays (and the CHECK
1533
+ * expression tree) are cloned before rewriting. `quoteIdentifier` still runs *after*
1534
+ * the lowercase, so a reserved-word column name (`Order` → `order`) re-quotes to
1535
+ * `"order"` on both sides (keyword detection is already case-insensitive).
1536
+ */
1537
+ function lowercaseTableConstraintColumnNames(tc) {
1538
+ switch (tc.type) {
1539
+ case 'primaryKey':
1540
+ case 'unique':
1541
+ return tc.columns
1542
+ ? { ...tc, columns: tc.columns.map(c => ({ ...c, name: c.name.toLowerCase() })) }
1543
+ : tc;
1544
+ case 'foreignKey':
1545
+ return {
1546
+ ...tc,
1547
+ columns: tc.columns?.map(c => ({ ...c, name: c.name.toLowerCase() })),
1548
+ foreignKey: tc.foreignKey
1549
+ ? { ...tc.foreignKey, columns: tc.foreignKey.columns?.map(n => n.toLowerCase()) }
1550
+ : tc.foreignKey,
1551
+ };
1552
+ case 'check':
1553
+ // No column list — bare column refs live in the expression; fold them via a
1554
+ // structural clone. String / blob / numeric / JSON literals, parameters,
1555
+ // collation and cast/function names pass through byte-exact (see lowerExprIdentifiers).
1556
+ return tc.expr ? { ...tc, expr: lowerExprIdentifiers(tc.expr) } : tc;
1557
+ }
1558
+ }
1559
+ /**
1560
+ * Renders the **canonical body fragment** of a named table constraint — the
1561
+ * comparison key the declarative differ uses to detect a constraint whose name
1562
+ * is unchanged but whose body changed (an edited CHECK expression, a changed FK
1563
+ * action / referenced table / columns, a changed UNIQUE column set / conflict
1564
+ * action). Two semantically-equal constraints must render identically here or a
1565
+ * spurious drop+recreate churns; two semantically-different ones must render
1566
+ * differently or a real change silently no-ops.
1567
+ *
1568
+ * Excludes the `constraint <name>` prefix (constraints are matched by name first,
1569
+ * and a rename must not block body comparison) AND the `with tags (...)` suffix
1570
+ * (tags are a separate diff channel — `ALTER CONSTRAINT … SET TAGS`, so a
1571
+ * tag-only change must NOT masquerade as a body change). Bare column-name
1572
+ * identifiers are case-folded ({@link lowercaseTableConstraintColumnNames}) BEFORE
1573
+ * the default-form normalization so `canonicalForeignKeyClause` reads the already-
1574
+ * lowercased referenced columns. Parser-default-equivalent forms are normalized
1575
+ * (see {@link canonicalCheckOperations}, {@link canonicalForeignKeyClause}). The fold
1576
+ * reaches every identifier channel: the UNIQUE / PK / FK column lists (here, via
1577
+ * {@link lowercaseTableConstraintColumnNames}), the bare column refs inside a CHECK
1578
+ * expression (also via {@link lowercaseTableConstraintColumnNames} → {@link lowerExprIdentifiers}),
1579
+ * and the FK referenced (parent) table name (via {@link canonicalForeignKeyClause}). Both
1580
+ * the declared-AST side (`schema-differ`) and the actual-catalog side
1581
+ * (`ddl-generator`'s `constraintToCanonicalDDL`) funnel through here so their
1582
+ * fragments are byte-comparable.
1583
+ *
1584
+ * `childSchemaName` (the schema of the table OWNING this constraint) makes the FK
1585
+ * parent-schema qualifier symmetric between the two sides: an explicit qualifier
1586
+ * equal to the child schema elides to nothing (see {@link canonicalForeignKeyClause}),
1587
+ * so a declared `references main.t` on a child in `main` and the actual catalog's
1588
+ * elided form canonicalize identically (no spurious churn), while a genuine
1589
+ * cross-schema parent survives as a body-change channel. It is optional so non-FK
1590
+ * callers (CHECK / UNIQUE — no schema channel) are unaffected.
1591
+ */
1592
+ export function constraintBodyToCanonicalString(tc, childSchemaName) {
1593
+ const normalized = lowercaseTableConstraintColumnNames({ ...tc, name: undefined, tags: undefined });
1594
+ if (normalized.type === 'check') {
1595
+ normalized.operations = canonicalCheckOperations(normalized.operations);
1596
+ }
1597
+ if (normalized.type === 'foreignKey' && normalized.foreignKey) {
1598
+ normalized.foreignKey = canonicalForeignKeyClause(normalized.foreignKey, childSchemaName);
1599
+ }
1600
+ return tableConstraintsToString([normalized]);
1601
+ }
959
1602
  function foreignKeyActionToString(action) {
960
1603
  switch (action) {
961
1604
  case 'setNull': return 'set null';
@@ -964,9 +1607,10 @@ function foreignKeyActionToString(action) {
964
1607
  case 'restrict': return 'restrict';
965
1608
  }
966
1609
  }
967
- /** Emits `references TBL(cols) [on delete …] [on update …] [[not] deferrable [initially …]]`. */
1610
+ /** Emits `references [SCHEMA.]TBL(cols) [on delete …] [on update …] [[not] deferrable [initially …]]`. */
968
1611
  function foreignKeyClauseTail(fk) {
969
- let s = `references ${quoteIdentifier(fk.table)}`;
1612
+ const qualified = fk.schema ? `${quoteIdentifier(fk.schema)}.${quoteIdentifier(fk.table)}` : quoteIdentifier(fk.table);
1613
+ let s = `references ${qualified}`;
970
1614
  if (fk.columns && fk.columns.length > 0) {
971
1615
  s += `(${fk.columns.map(quoteIdentifier).join(', ')})`;
972
1616
  }
@@ -995,13 +1639,28 @@ function tagValueToString(value) {
995
1639
  return String(value);
996
1640
  }
997
1641
  /** Formats a tags record as a WITH TAGS (...) clause */
1642
+ /**
1643
+ * Renders the inner `(k = v, …)` body of a tag list. Shared by the `WITH TAGS`
1644
+ * clause and the `ALTER TABLE … SET TAGS` forms. An empty list renders `()`
1645
+ * (the explicit clear-all form for SET TAGS).
1646
+ */
1647
+ export function tagsBodyToString(tags) {
1648
+ const entries = Object.entries(tags ?? {})
1649
+ .map(([key, value]) => `${quoteIdentifier(key)} = ${tagValueToString(value)}`)
1650
+ .join(', ');
1651
+ return `(${entries})`;
1652
+ }
1653
+ /**
1654
+ * Renders the inner `(k[, …])` body of a bare tag-key list for the
1655
+ * `ALTER TABLE … DROP TAGS` form. An empty list renders `()` (a no-op drop).
1656
+ */
1657
+ export function tagKeysBodyToString(keys) {
1658
+ return `(${keys.map(quoteIdentifier).join(', ')})`;
1659
+ }
998
1660
  function tagsClauseToString(tags) {
999
1661
  if (!tags || Object.keys(tags).length === 0)
1000
1662
  return '';
1001
- const entries = Object.entries(tags)
1002
- .map(([key, value]) => `${quoteIdentifier(key)} = ${tagValueToString(value)}`)
1003
- .join(', ');
1004
- return ` with tags (${entries})`;
1663
+ return ` with tags ${tagsBodyToString(tags)}`;
1005
1664
  }
1006
1665
  export function columnDefToString(col) {
1007
1666
  let colDef = quoteIdentifier(col.name);
@@ -1023,7 +1682,7 @@ function tableBodyDefsToString(stmt) {
1023
1682
  function moduleClauseToString(stmt) {
1024
1683
  if (!stmt.moduleName)
1025
1684
  return '';
1026
- let s = `using ${stmt.moduleName}`;
1685
+ let s = `using ${quoteIdentifier(stmt.moduleName)}`;
1027
1686
  if (stmt.moduleArgs && Object.keys(stmt.moduleArgs).length > 0) {
1028
1687
  const args = Object.entries(stmt.moduleArgs).map(([key, value]) => `${quoteIdentifier(key)} = ${JSON.stringify(value)}`).join(', ');
1029
1688
  s += ` (${args})`;
@@ -1045,8 +1704,6 @@ function contextClauseToString(stmt) {
1045
1704
  }
1046
1705
  export function createTableToString(stmt) {
1047
1706
  const parts = ['create'];
1048
- if (stmt.isTemporary)
1049
- parts.push('temp');
1050
1707
  parts.push('table');
1051
1708
  if (stmt.ifNotExists)
1052
1709
  parts.push('if not exists');
@@ -1058,6 +1715,9 @@ export function createTableToString(stmt) {
1058
1715
  const using = moduleClauseToString(stmt);
1059
1716
  if (using)
1060
1717
  parts.push(using);
1718
+ const maintained = maintainedClauseToString(stmt.maintained);
1719
+ if (maintained)
1720
+ parts.push(maintained);
1061
1721
  const ctx = contextClauseToString(stmt);
1062
1722
  if (ctx)
1063
1723
  parts.push(ctx);
@@ -1066,4 +1726,19 @@ export function createTableToString(stmt) {
1066
1726
  parts.push(tagStr.trimStart());
1067
1727
  return parts.join(' ');
1068
1728
  }
1729
+ /** `maintained [(columns)] as <body>` clause of a CREATE TABLE, or '' when absent.
1730
+ * Clause order matches the parser grammar: using → maintained [(columns)] as <body … with defaults> → with tags.
1731
+ * Any omitted-insert defaults ride inside the body string (selectToString's `with defaults (…)`).
1732
+ * The `(columns)` rename list is emitted only when present (an explicit MV-sugar rename); its absence is
1733
+ * the lossless signal that the body is implicit and may reshape to follow its source on reopen. */
1734
+ export function maintainedClauseToString(maintained) {
1735
+ if (!maintained)
1736
+ return '';
1737
+ const parts = ['maintained'];
1738
+ if (maintained.columns && maintained.columns.length > 0) {
1739
+ parts.push(`(${maintained.columns.map(quoteIdentifier).join(', ')})`);
1740
+ }
1741
+ parts.push('as', astToString(maintained.select));
1742
+ return parts.join(' ');
1743
+ }
1069
1744
  //# sourceMappingURL=ast-stringify.js.map