@intentius/chant-lexicon-sql 0.0.0-stage → 0.112.1

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 (936) hide show
  1. package/README.md +39 -2
  2. package/dist/clickhouse/apply/apply.d.ts +82 -0
  3. package/dist/clickhouse/apply/apply.d.ts.map +1 -0
  4. package/dist/clickhouse/apply/mutations.d.ts +46 -0
  5. package/dist/clickhouse/apply/mutations.d.ts.map +1 -0
  6. package/dist/clickhouse/apply/statements.d.ts +99 -0
  7. package/dist/clickhouse/apply/statements.d.ts.map +1 -0
  8. package/dist/clickhouse/catalog-types.d.ts +76 -0
  9. package/dist/clickhouse/catalog-types.d.ts.map +1 -0
  10. package/dist/clickhouse/container.d.ts +63 -0
  11. package/dist/clickhouse/container.d.ts.map +1 -0
  12. package/dist/clickhouse/engine-syntax.d.ts +43 -0
  13. package/dist/clickhouse/engine-syntax.d.ts.map +1 -0
  14. package/dist/clickhouse/entities.d.ts +183 -0
  15. package/dist/clickhouse/entities.d.ts.map +1 -0
  16. package/dist/clickhouse/http.d.ts +40 -0
  17. package/dist/clickhouse/http.d.ts.map +1 -0
  18. package/dist/clickhouse/import/generator.d.ts +16 -0
  19. package/dist/clickhouse/import/generator.d.ts.map +1 -0
  20. package/dist/clickhouse/import/ir.d.ts +52 -0
  21. package/dist/clickhouse/import/ir.d.ts.map +1 -0
  22. package/dist/clickhouse/import/live-export.d.ts +28 -0
  23. package/dist/clickhouse/import/live-export.d.ts.map +1 -0
  24. package/dist/clickhouse/import/parser.d.ts +10 -0
  25. package/dist/clickhouse/import/parser.d.ts.map +1 -0
  26. package/dist/clickhouse/live/bind.d.ts +56 -0
  27. package/dist/clickhouse/live/bind.d.ts.map +1 -0
  28. package/dist/clickhouse/live/catalog.d.ts +39 -0
  29. package/dist/clickhouse/live/catalog.d.ts.map +1 -0
  30. package/dist/clickhouse/live/describe-resources.d.ts +34 -0
  31. package/dist/clickhouse/live/describe-resources.d.ts.map +1 -0
  32. package/dist/clickhouse/overlays/codecs.d.ts +28 -0
  33. package/dist/clickhouse/overlays/codecs.d.ts.map +1 -0
  34. package/dist/clickhouse/overlays/engines.d.ts +20 -0
  35. package/dist/clickhouse/overlays/engines.d.ts.map +1 -0
  36. package/dist/clickhouse/overlays/kinds.d.ts +38 -0
  37. package/dist/clickhouse/overlays/kinds.d.ts.map +1 -0
  38. package/dist/clickhouse/overlays/projections.d.ts +27 -0
  39. package/dist/clickhouse/overlays/projections.d.ts.map +1 -0
  40. package/dist/clickhouse/overlays/skip-indexes.d.ts +10 -0
  41. package/dist/clickhouse/overlays/skip-indexes.d.ts.map +1 -0
  42. package/dist/clickhouse/overlays/ttl.d.ts +35 -0
  43. package/dist/clickhouse/overlays/ttl.d.ts.map +1 -0
  44. package/dist/clickhouse/overlays/types.d.ts +21 -0
  45. package/dist/clickhouse/overlays/types.d.ts.map +1 -0
  46. package/dist/clickhouse/ownership.d.ts +71 -0
  47. package/dist/clickhouse/ownership.d.ts.map +1 -0
  48. package/dist/clickhouse/parser.d.ts +130 -0
  49. package/dist/clickhouse/parser.d.ts.map +1 -0
  50. package/dist/clickhouse/plan/commands.d.ts +26 -0
  51. package/dist/clickhouse/plan/commands.d.ts.map +1 -0
  52. package/dist/clickhouse/plan/deep.d.ts +32 -0
  53. package/dist/clickhouse/plan/deep.d.ts.map +1 -0
  54. package/dist/clickhouse/plan/diff.d.ts +37 -0
  55. package/dist/clickhouse/plan/diff.d.ts.map +1 -0
  56. package/dist/clickhouse/plan/disruption.d.ts +17 -0
  57. package/dist/clickhouse/plan/disruption.d.ts.map +1 -0
  58. package/dist/clickhouse/plan/normalize.d.ts +97 -0
  59. package/dist/clickhouse/plan/normalize.d.ts.map +1 -0
  60. package/dist/clickhouse/plan/rebuild-handoff.d.ts +38 -0
  61. package/dist/clickhouse/plan/rebuild-handoff.d.ts.map +1 -0
  62. package/dist/clickhouse/plan/report.d.ts +6 -0
  63. package/dist/clickhouse/plan/report.d.ts.map +1 -0
  64. package/dist/clickhouse/plan/rules.d.ts +60 -0
  65. package/dist/clickhouse/plan/rules.d.ts.map +1 -0
  66. package/dist/clickhouse/plan/schema.d.ts +23 -0
  67. package/dist/clickhouse/plan/schema.d.ts.map +1 -0
  68. package/dist/clickhouse/plan/server-format.d.ts +12 -0
  69. package/dist/clickhouse/plan/server-format.d.ts.map +1 -0
  70. package/dist/clickhouse/rebuild/backfill.d.ts +70 -0
  71. package/dist/clickhouse/rebuild/backfill.d.ts.map +1 -0
  72. package/dist/clickhouse/rebuild/observe.d.ts +157 -0
  73. package/dist/clickhouse/rebuild/observe.d.ts.map +1 -0
  74. package/dist/clickhouse/rebuild/op.d.ts +108 -0
  75. package/dist/clickhouse/rebuild/op.d.ts.map +1 -0
  76. package/dist/clickhouse/rebuild/partitions.d.ts +24 -0
  77. package/dist/clickhouse/rebuild/partitions.d.ts.map +1 -0
  78. package/dist/clickhouse/rebuild/receipts.d.ts +76 -0
  79. package/dist/clickhouse/rebuild/receipts.d.ts.map +1 -0
  80. package/dist/clickhouse/rebuild/replicas.d.ts +78 -0
  81. package/dist/clickhouse/rebuild/replicas.d.ts.map +1 -0
  82. package/dist/clickhouse/rebuild/steps.d.ts +151 -0
  83. package/dist/clickhouse/rebuild/steps.d.ts.map +1 -0
  84. package/dist/clickhouse/rebuild/verify.d.ts +51 -0
  85. package/dist/clickhouse/rebuild/verify.d.ts.map +1 -0
  86. package/dist/clickhouse/testing/fake-server.d.ts +27 -0
  87. package/dist/clickhouse/testing/fake-server.d.ts.map +1 -0
  88. package/dist/clickhouse/testing/roundtrip-schema.d.ts +3 -0
  89. package/dist/clickhouse/testing/roundtrip-schema.d.ts.map +1 -0
  90. package/dist/clickhouse/testing/writable-server.d.ts +35 -0
  91. package/dist/clickhouse/testing/writable-server.d.ts.map +1 -0
  92. package/dist/clickhouse/tokens.d.ts +15 -0
  93. package/dist/clickhouse/tokens.d.ts.map +1 -0
  94. package/dist/clickhouse.d.ts +24 -0
  95. package/dist/clickhouse.d.ts.map +1 -0
  96. package/dist/codegen/classifier-page.d.ts +6 -0
  97. package/dist/codegen/classifier-page.d.ts.map +1 -0
  98. package/dist/codegen/clickhouse-module.d.ts +23 -0
  99. package/dist/codegen/clickhouse-module.d.ts.map +1 -0
  100. package/dist/codegen/docs-cli.d.ts +3 -0
  101. package/dist/codegen/docs-cli.d.ts.map +1 -0
  102. package/dist/codegen/docs.d.ts +8 -0
  103. package/dist/codegen/docs.d.ts.map +1 -0
  104. package/dist/codegen/generate-cli.d.ts +3 -0
  105. package/dist/codegen/generate-cli.d.ts.map +1 -0
  106. package/dist/codegen/generate.d.ts +40 -0
  107. package/dist/codegen/generate.d.ts.map +1 -0
  108. package/dist/codegen/package.d.ts +7 -0
  109. package/dist/codegen/package.d.ts.map +1 -0
  110. package/dist/codegen/postgres-classifier-page.d.ts +7 -0
  111. package/dist/codegen/postgres-classifier-page.d.ts.map +1 -0
  112. package/dist/codegen/postgres-module.d.ts +30 -0
  113. package/dist/codegen/postgres-module.d.ts.map +1 -0
  114. package/dist/codegen/registry.d.ts +12 -0
  115. package/dist/codegen/registry.d.ts.map +1 -0
  116. package/dist/composites/audit-log-table.d.ts +31 -0
  117. package/dist/composites/audit-log-table.d.ts.map +1 -0
  118. package/dist/composites/catalog.d.ts +3 -0
  119. package/dist/composites/catalog.d.ts.map +1 -0
  120. package/dist/composites/cdc-mirror.d.ts +32 -0
  121. package/dist/composites/cdc-mirror.d.ts.map +1 -0
  122. package/dist/composites/clickhouse.d.ts +7 -0
  123. package/dist/composites/clickhouse.d.ts.map +1 -0
  124. package/dist/composites/events-table.d.ts +32 -0
  125. package/dist/composites/events-table.d.ts.map +1 -0
  126. package/dist/composites/index.d.ts +9 -0
  127. package/dist/composites/index.d.ts.map +1 -0
  128. package/dist/composites/join-table.d.ts +41 -0
  129. package/dist/composites/join-table.d.ts.map +1 -0
  130. package/dist/composites/postgres.d.ts +7 -0
  131. package/dist/composites/postgres.d.ts.map +1 -0
  132. package/dist/composites/refreshed-view.d.ts +32 -0
  133. package/dist/composites/refreshed-view.d.ts.map +1 -0
  134. package/dist/composites/replacing-table.d.ts +34 -0
  135. package/dist/composites/replacing-table.d.ts.map +1 -0
  136. package/dist/composites/rollup-view.d.ts +39 -0
  137. package/dist/composites/rollup-view.d.ts.map +1 -0
  138. package/dist/composites/sharded-table.d.ts +35 -0
  139. package/dist/composites/sharded-table.d.ts.map +1 -0
  140. package/dist/composites/soft-delete-table.d.ts +40 -0
  141. package/dist/composites/soft-delete-table.d.ts.map +1 -0
  142. package/dist/composites/tenant-table.d.ts +34 -0
  143. package/dist/composites/tenant-table.d.ts.map +1 -0
  144. package/dist/config.d.ts +213 -0
  145. package/dist/config.d.ts.map +1 -0
  146. package/dist/core/apply.d.ts +89 -0
  147. package/dist/core/apply.d.ts.map +1 -0
  148. package/dist/core/classifier.d.ts +88 -0
  149. package/dist/core/classifier.d.ts.map +1 -0
  150. package/dist/core/container.d.ts +45 -0
  151. package/dist/core/container.d.ts.map +1 -0
  152. package/dist/core/cursor.d.ts +67 -0
  153. package/dist/core/cursor.d.ts.map +1 -0
  154. package/dist/core/diff.d.ts +49 -0
  155. package/dist/core/diff.d.ts.map +1 -0
  156. package/dist/core/entity.d.ts +41 -0
  157. package/dist/core/entity.d.ts.map +1 -0
  158. package/dist/core/find-templates.d.ts +69 -0
  159. package/dist/core/find-templates.d.ts.map +1 -0
  160. package/dist/core/handoff.d.ts +36 -0
  161. package/dist/core/handoff.d.ts.map +1 -0
  162. package/dist/core/index.d.ts +61 -0
  163. package/dist/core/index.d.ts.map +1 -0
  164. package/dist/core/interpolation.d.ts +88 -0
  165. package/dist/core/interpolation.d.ts.map +1 -0
  166. package/dist/core/normalize.d.ts +18 -0
  167. package/dist/core/normalize.d.ts.map +1 -0
  168. package/dist/core/ownership.d.ts +60 -0
  169. package/dist/core/ownership.d.ts.map +1 -0
  170. package/dist/core/receipts.d.ts +28 -0
  171. package/dist/core/receipts.d.ts.map +1 -0
  172. package/dist/core/references.d.ts +37 -0
  173. package/dist/core/references.d.ts.map +1 -0
  174. package/dist/core/template.d.ts +41 -0
  175. package/dist/core/template.d.ts.map +1 -0
  176. package/dist/core/testing/http-stub.d.ts +17 -0
  177. package/dist/core/testing/http-stub.d.ts.map +1 -0
  178. package/dist/core/tokens.d.ts +102 -0
  179. package/dist/core/tokens.d.ts.map +1 -0
  180. package/dist/coverage.d.ts +25 -0
  181. package/dist/coverage.d.ts.map +1 -0
  182. package/dist/detect.d.ts +15 -0
  183. package/dist/detect.d.ts.map +1 -0
  184. package/dist/dialects.d.ts +20 -0
  185. package/dist/dialects.d.ts.map +1 -0
  186. package/dist/generated/clickhouse-types.d.ts +4380 -0
  187. package/dist/generated/clickhouse-types.d.ts.map +1 -0
  188. package/dist/generated/clickhouse.d.ts +11 -0
  189. package/dist/generated/clickhouse.d.ts.map +1 -0
  190. package/dist/generated/postgres-types.d.ts +1579 -0
  191. package/dist/generated/postgres-types.d.ts.map +1 -0
  192. package/dist/generated/postgres.d.ts +9 -0
  193. package/dist/generated/postgres.d.ts.map +1 -0
  194. package/dist/import-generator.d.ts +8 -0
  195. package/dist/import-generator.d.ts.map +1 -0
  196. package/dist/index.d.ts +7 -0
  197. package/dist/index.d.ts.map +1 -0
  198. package/dist/init-templates.d.ts +20 -0
  199. package/dist/init-templates.d.ts.map +1 -0
  200. package/dist/integrity.json +61 -0
  201. package/dist/lint/audit-catalog.d.ts +10 -0
  202. package/dist/lint/audit-catalog.d.ts.map +1 -0
  203. package/dist/lint/audit-lineage.d.ts +25 -0
  204. package/dist/lint/audit-lineage.d.ts.map +1 -0
  205. package/dist/lint/post-synth/audit-entries.d.ts +8 -0
  206. package/dist/lint/post-synth/audit-entries.d.ts.map +1 -0
  207. package/dist/lint/post-synth/clickhouse-helpers.d.ts +85 -0
  208. package/dist/lint/post-synth/clickhouse-helpers.d.ts.map +1 -0
  209. package/dist/lint/post-synth/index.d.ts +3 -0
  210. package/dist/lint/post-synth/index.d.ts.map +1 -0
  211. package/dist/lint/post-synth/postgres-audit-entries.d.ts +9 -0
  212. package/dist/lint/post-synth/postgres-audit-entries.d.ts.map +1 -0
  213. package/dist/lint/post-synth/postgres-helpers.d.ts +89 -0
  214. package/dist/lint/post-synth/postgres-helpers.d.ts.map +1 -0
  215. package/dist/lint/post-synth/sql-helpers.d.ts +27 -0
  216. package/dist/lint/post-synth/sql-helpers.d.ts.map +1 -0
  217. package/dist/lint/post-synth/sqlch101.d.ts +12 -0
  218. package/dist/lint/post-synth/sqlch101.d.ts.map +1 -0
  219. package/dist/lint/post-synth/sqlch102.d.ts +9 -0
  220. package/dist/lint/post-synth/sqlch102.d.ts.map +1 -0
  221. package/dist/lint/post-synth/sqlch103.d.ts +10 -0
  222. package/dist/lint/post-synth/sqlch103.d.ts.map +1 -0
  223. package/dist/lint/post-synth/sqlch104.d.ts +9 -0
  224. package/dist/lint/post-synth/sqlch104.d.ts.map +1 -0
  225. package/dist/lint/post-synth/sqlch105.d.ts +10 -0
  226. package/dist/lint/post-synth/sqlch105.d.ts.map +1 -0
  227. package/dist/lint/post-synth/sqlch106.d.ts +11 -0
  228. package/dist/lint/post-synth/sqlch106.d.ts.map +1 -0
  229. package/dist/lint/post-synth/sqlch107.d.ts +10 -0
  230. package/dist/lint/post-synth/sqlch107.d.ts.map +1 -0
  231. package/dist/lint/post-synth/sqlch108.d.ts +11 -0
  232. package/dist/lint/post-synth/sqlch108.d.ts.map +1 -0
  233. package/dist/lint/post-synth/sqlch109.d.ts +10 -0
  234. package/dist/lint/post-synth/sqlch109.d.ts.map +1 -0
  235. package/dist/lint/post-synth/sqlch110.d.ts +12 -0
  236. package/dist/lint/post-synth/sqlch110.d.ts.map +1 -0
  237. package/dist/lint/post-synth/sqlch111.d.ts +11 -0
  238. package/dist/lint/post-synth/sqlch111.d.ts.map +1 -0
  239. package/dist/lint/post-synth/sqlch112.d.ts +12 -0
  240. package/dist/lint/post-synth/sqlch112.d.ts.map +1 -0
  241. package/dist/lint/post-synth/sqlch113.d.ts +9 -0
  242. package/dist/lint/post-synth/sqlch113.d.ts.map +1 -0
  243. package/dist/lint/post-synth/sqlch114.d.ts +8 -0
  244. package/dist/lint/post-synth/sqlch114.d.ts.map +1 -0
  245. package/dist/lint/post-synth/sqlch115.d.ts +13 -0
  246. package/dist/lint/post-synth/sqlch115.d.ts.map +1 -0
  247. package/dist/lint/post-synth/sqlch116.d.ts +10 -0
  248. package/dist/lint/post-synth/sqlch116.d.ts.map +1 -0
  249. package/dist/lint/post-synth/sqlch117.d.ts +9 -0
  250. package/dist/lint/post-synth/sqlch117.d.ts.map +1 -0
  251. package/dist/lint/post-synth/sqlch118.d.ts +10 -0
  252. package/dist/lint/post-synth/sqlch118.d.ts.map +1 -0
  253. package/dist/lint/post-synth/sqlch119.d.ts +11 -0
  254. package/dist/lint/post-synth/sqlch119.d.ts.map +1 -0
  255. package/dist/lint/post-synth/sqlch120.d.ts +10 -0
  256. package/dist/lint/post-synth/sqlch120.d.ts.map +1 -0
  257. package/dist/lint/post-synth/sqlpg101.d.ts +12 -0
  258. package/dist/lint/post-synth/sqlpg101.d.ts.map +1 -0
  259. package/dist/lint/post-synth/sqlpg102.d.ts +11 -0
  260. package/dist/lint/post-synth/sqlpg102.d.ts.map +1 -0
  261. package/dist/lint/post-synth/sqlpg103.d.ts +11 -0
  262. package/dist/lint/post-synth/sqlpg103.d.ts.map +1 -0
  263. package/dist/lint/post-synth/sqlpg104.d.ts +10 -0
  264. package/dist/lint/post-synth/sqlpg104.d.ts.map +1 -0
  265. package/dist/lint/post-synth/sqlpg105.d.ts +10 -0
  266. package/dist/lint/post-synth/sqlpg105.d.ts.map +1 -0
  267. package/dist/lint/post-synth/sqlpg106.d.ts +9 -0
  268. package/dist/lint/post-synth/sqlpg106.d.ts.map +1 -0
  269. package/dist/lint/post-synth/sqlpg107.d.ts +10 -0
  270. package/dist/lint/post-synth/sqlpg107.d.ts.map +1 -0
  271. package/dist/lint/post-synth/sqlpg108.d.ts +11 -0
  272. package/dist/lint/post-synth/sqlpg108.d.ts.map +1 -0
  273. package/dist/lint/post-synth/sqlpg109.d.ts +11 -0
  274. package/dist/lint/post-synth/sqlpg109.d.ts.map +1 -0
  275. package/dist/lint/post-synth/sqlpg110.d.ts +12 -0
  276. package/dist/lint/post-synth/sqlpg110.d.ts.map +1 -0
  277. package/dist/lint/post-synth/sqlpg111.d.ts +10 -0
  278. package/dist/lint/post-synth/sqlpg111.d.ts.map +1 -0
  279. package/dist/lint/post-synth/sqlpg112.d.ts +10 -0
  280. package/dist/lint/post-synth/sqlpg112.d.ts.map +1 -0
  281. package/dist/lint/post-synth/sqlpg113.d.ts +11 -0
  282. package/dist/lint/post-synth/sqlpg113.d.ts.map +1 -0
  283. package/dist/lint/post-synth/sqlpg114.d.ts +13 -0
  284. package/dist/lint/post-synth/sqlpg114.d.ts.map +1 -0
  285. package/dist/lint/post-synth/sqlpg115.d.ts +13 -0
  286. package/dist/lint/post-synth/sqlpg115.d.ts.map +1 -0
  287. package/dist/lint/post-synth/sqlpg116.d.ts +11 -0
  288. package/dist/lint/post-synth/sqlpg116.d.ts.map +1 -0
  289. package/dist/lint/post-synth/sqlpg117.d.ts +12 -0
  290. package/dist/lint/post-synth/sqlpg117.d.ts.map +1 -0
  291. package/dist/lint/post-synth/sqlpg118.d.ts +12 -0
  292. package/dist/lint/post-synth/sqlpg118.d.ts.map +1 -0
  293. package/dist/lint/rules/index.d.ts +12 -0
  294. package/dist/lint/rules/index.d.ts.map +1 -0
  295. package/dist/lint/rules/postgres-templates.d.ts +18 -0
  296. package/dist/lint/rules/postgres-templates.d.ts.map +1 -0
  297. package/dist/lint/rules/sqlch001.d.ts +12 -0
  298. package/dist/lint/rules/sqlch001.d.ts.map +1 -0
  299. package/dist/lint/rules/sqlch002.d.ts +11 -0
  300. package/dist/lint/rules/sqlch002.d.ts.map +1 -0
  301. package/dist/lint/rules/sqlch003.d.ts +12 -0
  302. package/dist/lint/rules/sqlch003.d.ts.map +1 -0
  303. package/dist/lint/rules/sqlpg001.d.ts +16 -0
  304. package/dist/lint/rules/sqlpg001.d.ts.map +1 -0
  305. package/dist/lint/rules/sqlpg002.d.ts +12 -0
  306. package/dist/lint/rules/sqlpg002.d.ts.map +1 -0
  307. package/dist/lint/rules/sqlpg003.d.ts +16 -0
  308. package/dist/lint/rules/sqlpg003.d.ts.map +1 -0
  309. package/dist/lint/rules/sqlpg004.d.ts +21 -0
  310. package/dist/lint/rules/sqlpg004.d.ts.map +1 -0
  311. package/dist/lint/rules/templates.d.ts +23 -0
  312. package/dist/lint/rules/templates.d.ts.map +1 -0
  313. package/dist/live-dialect.d.ts +25 -0
  314. package/dist/live-dialect.d.ts.map +1 -0
  315. package/dist/lsp/catalog.d.ts +22 -0
  316. package/dist/lsp/catalog.d.ts.map +1 -0
  317. package/dist/lsp/completions.d.ts +13 -0
  318. package/dist/lsp/completions.d.ts.map +1 -0
  319. package/dist/lsp/hover.d.ts +12 -0
  320. package/dist/lsp/hover.d.ts.map +1 -0
  321. package/dist/lsp/postgres-catalog.d.ts +85 -0
  322. package/dist/lsp/postgres-catalog.d.ts.map +1 -0
  323. package/dist/lsp/postgres-template.d.ts +35 -0
  324. package/dist/lsp/postgres-template.d.ts.map +1 -0
  325. package/dist/lsp/postgres.d.ts +20 -0
  326. package/dist/lsp/postgres.d.ts.map +1 -0
  327. package/dist/lsp/refs.d.ts +8 -0
  328. package/dist/lsp/refs.d.ts.map +1 -0
  329. package/dist/lsp/registry.d.ts +4 -0
  330. package/dist/lsp/registry.d.ts.map +1 -0
  331. package/dist/lsp/template.d.ts +34 -0
  332. package/dist/lsp/template.d.ts.map +1 -0
  333. package/dist/manifest.json +8 -0
  334. package/dist/mcp/index.d.ts +13 -0
  335. package/dist/mcp/index.d.ts.map +1 -0
  336. package/dist/mcp/postgres.d.ts +32 -0
  337. package/dist/mcp/postgres.d.ts.map +1 -0
  338. package/dist/meta.json +67 -0
  339. package/dist/okf/index.md +67 -0
  340. package/dist/okf/rules/SQLCH001.md +11 -0
  341. package/dist/okf/rules/SQLCH002.md +11 -0
  342. package/dist/okf/rules/SQLCH003.md +11 -0
  343. package/dist/okf/rules/SQLCH101.md +15 -0
  344. package/dist/okf/rules/SQLCH102.md +11 -0
  345. package/dist/okf/rules/SQLCH103.md +11 -0
  346. package/dist/okf/rules/SQLCH104.md +11 -0
  347. package/dist/okf/rules/SQLCH105.md +11 -0
  348. package/dist/okf/rules/SQLCH106.md +11 -0
  349. package/dist/okf/rules/SQLCH107.md +11 -0
  350. package/dist/okf/rules/SQLCH108.md +15 -0
  351. package/dist/okf/rules/SQLCH109.md +11 -0
  352. package/dist/okf/rules/SQLCH110.md +11 -0
  353. package/dist/okf/rules/SQLCH111.md +11 -0
  354. package/dist/okf/rules/SQLCH112.md +11 -0
  355. package/dist/okf/rules/SQLCH113.md +11 -0
  356. package/dist/okf/rules/SQLCH114.md +11 -0
  357. package/dist/okf/rules/SQLCH115.md +11 -0
  358. package/dist/okf/rules/SQLCH116.md +11 -0
  359. package/dist/okf/rules/SQLCH117.md +15 -0
  360. package/dist/okf/rules/SQLCH118.md +15 -0
  361. package/dist/okf/rules/SQLCH119.md +15 -0
  362. package/dist/okf/rules/SQLCH120.md +15 -0
  363. package/dist/okf/rules/SQLPG001.md +11 -0
  364. package/dist/okf/rules/SQLPG002.md +11 -0
  365. package/dist/okf/rules/SQLPG003.md +11 -0
  366. package/dist/okf/rules/SQLPG004.md +11 -0
  367. package/dist/okf/rules/SQLPG101.md +11 -0
  368. package/dist/okf/rules/SQLPG102.md +11 -0
  369. package/dist/okf/rules/SQLPG103.md +11 -0
  370. package/dist/okf/rules/SQLPG104.md +11 -0
  371. package/dist/okf/rules/SQLPG105.md +11 -0
  372. package/dist/okf/rules/SQLPG106.md +11 -0
  373. package/dist/okf/rules/SQLPG107.md +11 -0
  374. package/dist/okf/rules/SQLPG108.md +11 -0
  375. package/dist/okf/rules/SQLPG109.md +11 -0
  376. package/dist/okf/rules/SQLPG110.md +11 -0
  377. package/dist/okf/rules/SQLPG111.md +11 -0
  378. package/dist/okf/rules/SQLPG112.md +11 -0
  379. package/dist/okf/rules/SQLPG113.md +24 -0
  380. package/dist/okf/rules/SQLPG114.md +11 -0
  381. package/dist/okf/rules/SQLPG115.md +11 -0
  382. package/dist/okf/rules/SQLPG116.md +15 -0
  383. package/dist/okf/rules/SQLPG117.md +11 -0
  384. package/dist/okf/rules/SQLPG118.md +11 -0
  385. package/dist/okf/types/Database.md +15 -0
  386. package/dist/okf/types/MaterializedView.md +14 -0
  387. package/dist/okf/types/PostgresDomain.md +13 -0
  388. package/dist/okf/types/PostgresEnum.md +13 -0
  389. package/dist/okf/types/PostgresExtension.md +13 -0
  390. package/dist/okf/types/PostgresIndex.md +9 -0
  391. package/dist/okf/types/PostgresMaterializedView.md +13 -0
  392. package/dist/okf/types/PostgresSchema.md +13 -0
  393. package/dist/okf/types/PostgresSequence.md +13 -0
  394. package/dist/okf/types/PostgresTable.md +13 -0
  395. package/dist/okf/types/PostgresView.md +13 -0
  396. package/dist/okf/types/Table.md +15 -0
  397. package/dist/okf/types/View.md +13 -0
  398. package/dist/op/activities/clickhouse-apply.d.ts +56 -0
  399. package/dist/op/activities/clickhouse-apply.d.ts.map +1 -0
  400. package/dist/op/activities/clickhouse-emulator.d.ts +26 -0
  401. package/dist/op/activities/clickhouse-emulator.d.ts.map +1 -0
  402. package/dist/op/activities/clickhouse-rebuild.d.ts +43 -0
  403. package/dist/op/activities/clickhouse-rebuild.d.ts.map +1 -0
  404. package/dist/op/activities/index.d.ts +19 -0
  405. package/dist/op/activities/index.d.ts.map +1 -0
  406. package/dist/op/activities/postgres-apply.d.ts +69 -0
  407. package/dist/op/activities/postgres-apply.d.ts.map +1 -0
  408. package/dist/op/activities/postgres-emulator.d.ts +33 -0
  409. package/dist/op/activities/postgres-emulator.d.ts.map +1 -0
  410. package/dist/op/activities/postgres-migration.d.ts +48 -0
  411. package/dist/op/activities/postgres-migration.d.ts.map +1 -0
  412. package/dist/op/activity-contracts.d.ts +464 -0
  413. package/dist/op/activity-contracts.d.ts.map +1 -0
  414. package/dist/package-cli.d.ts +3 -0
  415. package/dist/package-cli.d.ts.map +1 -0
  416. package/dist/plugin.d.ts +12 -0
  417. package/dist/plugin.d.ts.map +1 -0
  418. package/dist/postgres/apply/apply.d.ts +163 -0
  419. package/dist/postgres/apply/apply.d.ts.map +1 -0
  420. package/dist/postgres/apply/statements.d.ts +138 -0
  421. package/dist/postgres/apply/statements.d.ts.map +1 -0
  422. package/dist/postgres/catalog-types.d.ts +50 -0
  423. package/dist/postgres/catalog-types.d.ts.map +1 -0
  424. package/dist/postgres/container.d.ts +23 -0
  425. package/dist/postgres/container.d.ts.map +1 -0
  426. package/dist/postgres/entities.d.ts +322 -0
  427. package/dist/postgres/entities.d.ts.map +1 -0
  428. package/dist/postgres/entity-types.d.ts +17 -0
  429. package/dist/postgres/entity-types.d.ts.map +1 -0
  430. package/dist/postgres/import/generator.d.ts +28 -0
  431. package/dist/postgres/import/generator.d.ts.map +1 -0
  432. package/dist/postgres/import/ir.d.ts +24 -0
  433. package/dist/postgres/import/ir.d.ts.map +1 -0
  434. package/dist/postgres/import/live-export.d.ts +26 -0
  435. package/dist/postgres/import/live-export.d.ts.map +1 -0
  436. package/dist/postgres/keywords.d.ts +22 -0
  437. package/dist/postgres/keywords.d.ts.map +1 -0
  438. package/dist/postgres/live/bind.d.ts +76 -0
  439. package/dist/postgres/live/bind.d.ts.map +1 -0
  440. package/dist/postgres/live/catalog.d.ts +98 -0
  441. package/dist/postgres/live/catalog.d.ts.map +1 -0
  442. package/dist/postgres/live/client.d.ts +32 -0
  443. package/dist/postgres/live/client.d.ts.map +1 -0
  444. package/dist/postgres/live/describe-resources.d.ts +41 -0
  445. package/dist/postgres/live/describe-resources.d.ts.map +1 -0
  446. package/dist/postgres/migrate/backfill.d.ts +103 -0
  447. package/dist/postgres/migrate/backfill.d.ts.map +1 -0
  448. package/dist/postgres/migrate/batches.d.ts +90 -0
  449. package/dist/postgres/migrate/batches.d.ts.map +1 -0
  450. package/dist/postgres/migrate/carry.d.ts +196 -0
  451. package/dist/postgres/migrate/carry.d.ts.map +1 -0
  452. package/dist/postgres/migrate/handoff.d.ts +46 -0
  453. package/dist/postgres/migrate/handoff.d.ts.map +1 -0
  454. package/dist/postgres/migrate/names.d.ts +55 -0
  455. package/dist/postgres/migrate/names.d.ts.map +1 -0
  456. package/dist/postgres/migrate/observe.d.ts +139 -0
  457. package/dist/postgres/migrate/observe.d.ts.map +1 -0
  458. package/dist/postgres/migrate/op.d.ts +128 -0
  459. package/dist/postgres/migrate/op.d.ts.map +1 -0
  460. package/dist/postgres/migrate/receipts.d.ts +63 -0
  461. package/dist/postgres/migrate/receipts.d.ts.map +1 -0
  462. package/dist/postgres/migrate/replication.d.ts +80 -0
  463. package/dist/postgres/migrate/replication.d.ts.map +1 -0
  464. package/dist/postgres/migrate/steps.d.ts +225 -0
  465. package/dist/postgres/migrate/steps.d.ts.map +1 -0
  466. package/dist/postgres/overlays/columns.d.ts +6 -0
  467. package/dist/postgres/overlays/columns.d.ts.map +1 -0
  468. package/dist/postgres/overlays/constraints.d.ts +8 -0
  469. package/dist/postgres/overlays/constraints.d.ts.map +1 -0
  470. package/dist/postgres/overlays/indexes.d.ts +8 -0
  471. package/dist/postgres/overlays/indexes.d.ts.map +1 -0
  472. package/dist/postgres/overlays/kinds.d.ts +48 -0
  473. package/dist/postgres/overlays/kinds.d.ts.map +1 -0
  474. package/dist/postgres/overlays/partitioning.d.ts +5 -0
  475. package/dist/postgres/overlays/partitioning.d.ts.map +1 -0
  476. package/dist/postgres/overlays/relations.d.ts +6 -0
  477. package/dist/postgres/overlays/relations.d.ts.map +1 -0
  478. package/dist/postgres/overlays/storage.d.ts +28 -0
  479. package/dist/postgres/overlays/storage.d.ts.map +1 -0
  480. package/dist/postgres/overlays/type-ddl.d.ts +7 -0
  481. package/dist/postgres/overlays/type-ddl.d.ts.map +1 -0
  482. package/dist/postgres/overlays/types.d.ts +24 -0
  483. package/dist/postgres/overlays/types.d.ts.map +1 -0
  484. package/dist/postgres/parser.d.ts +216 -0
  485. package/dist/postgres/parser.d.ts.map +1 -0
  486. package/dist/postgres/plan/commands.d.ts +61 -0
  487. package/dist/postgres/plan/commands.d.ts.map +1 -0
  488. package/dist/postgres/plan/deep.d.ts +33 -0
  489. package/dist/postgres/plan/deep.d.ts.map +1 -0
  490. package/dist/postgres/plan/diff.d.ts +45 -0
  491. package/dist/postgres/plan/diff.d.ts.map +1 -0
  492. package/dist/postgres/plan/disruption.d.ts +14 -0
  493. package/dist/postgres/plan/disruption.d.ts.map +1 -0
  494. package/dist/postgres/plan/normalize.d.ts +108 -0
  495. package/dist/postgres/plan/normalize.d.ts.map +1 -0
  496. package/dist/postgres/plan/report.d.ts +6 -0
  497. package/dist/postgres/plan/report.d.ts.map +1 -0
  498. package/dist/postgres/plan/rules.d.ts +84 -0
  499. package/dist/postgres/plan/rules.d.ts.map +1 -0
  500. package/dist/postgres/plan/schema.d.ts +50 -0
  501. package/dist/postgres/plan/schema.d.ts.map +1 -0
  502. package/dist/postgres/plan/server-normalize.d.ts +26 -0
  503. package/dist/postgres/plan/server-normalize.d.ts.map +1 -0
  504. package/dist/postgres/providers/aurora.d.ts +12 -0
  505. package/dist/postgres/providers/aurora.d.ts.map +1 -0
  506. package/dist/postgres/providers/azure.d.ts +14 -0
  507. package/dist/postgres/providers/azure.d.ts.map +1 -0
  508. package/dist/postgres/providers/cloud-sql.d.ts +11 -0
  509. package/dist/postgres/providers/cloud-sql.d.ts.map +1 -0
  510. package/dist/postgres/providers/index.d.ts +35 -0
  511. package/dist/postgres/providers/index.d.ts.map +1 -0
  512. package/dist/postgres/providers/neon.d.ts +13 -0
  513. package/dist/postgres/providers/neon.d.ts.map +1 -0
  514. package/dist/postgres/providers/rds.d.ts +10 -0
  515. package/dist/postgres/providers/rds.d.ts.map +1 -0
  516. package/dist/postgres/providers/supabase.d.ts +12 -0
  517. package/dist/postgres/providers/supabase.d.ts.map +1 -0
  518. package/dist/postgres/providers/types.d.ts +59 -0
  519. package/dist/postgres/providers/types.d.ts.map +1 -0
  520. package/dist/postgres/testing/fake-client.d.ts +38 -0
  521. package/dist/postgres/testing/fake-client.d.ts.map +1 -0
  522. package/dist/postgres/testing/migration.d.ts +25 -0
  523. package/dist/postgres/testing/migration.d.ts.map +1 -0
  524. package/dist/postgres/testing/roundtrip-schema.d.ts +11 -0
  525. package/dist/postgres/testing/roundtrip-schema.d.ts.map +1 -0
  526. package/dist/postgres/testing/server.d.ts +17 -0
  527. package/dist/postgres/testing/server.d.ts.map +1 -0
  528. package/dist/postgres/testing/writable-server.d.ts +45 -0
  529. package/dist/postgres/testing/writable-server.d.ts.map +1 -0
  530. package/dist/postgres/tokens.d.ts +26 -0
  531. package/dist/postgres/tokens.d.ts.map +1 -0
  532. package/dist/postgres.d.ts +13 -0
  533. package/dist/postgres.d.ts.map +1 -0
  534. package/dist/rules/audit-entries.ts +29 -0
  535. package/dist/rules/clickhouse-helpers.ts +206 -0
  536. package/dist/rules/postgres-audit-entries.ts +29 -0
  537. package/dist/rules/postgres-helpers.ts +126 -0
  538. package/dist/rules/postgres-templates.ts +36 -0
  539. package/dist/rules/sql-helpers.ts +53 -0
  540. package/dist/rules/sqlch001.ts +53 -0
  541. package/dist/rules/sqlch002.ts +115 -0
  542. package/dist/rules/sqlch003.ts +68 -0
  543. package/dist/rules/sqlch101.ts +35 -0
  544. package/dist/rules/sqlch102.ts +23 -0
  545. package/dist/rules/sqlch103.ts +45 -0
  546. package/dist/rules/sqlch104.ts +42 -0
  547. package/dist/rules/sqlch105.ts +35 -0
  548. package/dist/rules/sqlch106.ts +27 -0
  549. package/dist/rules/sqlch107.ts +35 -0
  550. package/dist/rules/sqlch108.ts +27 -0
  551. package/dist/rules/sqlch109.ts +21 -0
  552. package/dist/rules/sqlch110.ts +29 -0
  553. package/dist/rules/sqlch111.ts +40 -0
  554. package/dist/rules/sqlch112.ts +30 -0
  555. package/dist/rules/sqlch113.ts +20 -0
  556. package/dist/rules/sqlch114.ts +26 -0
  557. package/dist/rules/sqlch115.ts +31 -0
  558. package/dist/rules/sqlch116.ts +22 -0
  559. package/dist/rules/sqlch117.ts +25 -0
  560. package/dist/rules/sqlch118.ts +26 -0
  561. package/dist/rules/sqlch119.ts +31 -0
  562. package/dist/rules/sqlch120.ts +21 -0
  563. package/dist/rules/sqlpg001.ts +88 -0
  564. package/dist/rules/sqlpg002.ts +68 -0
  565. package/dist/rules/sqlpg003.ts +59 -0
  566. package/dist/rules/sqlpg004.ts +73 -0
  567. package/dist/rules/sqlpg101.ts +24 -0
  568. package/dist/rules/sqlpg102.ts +30 -0
  569. package/dist/rules/sqlpg103.ts +23 -0
  570. package/dist/rules/sqlpg104.ts +23 -0
  571. package/dist/rules/sqlpg105.ts +22 -0
  572. package/dist/rules/sqlpg106.ts +22 -0
  573. package/dist/rules/sqlpg107.ts +22 -0
  574. package/dist/rules/sqlpg108.ts +27 -0
  575. package/dist/rules/sqlpg109.ts +37 -0
  576. package/dist/rules/sqlpg110.ts +33 -0
  577. package/dist/rules/sqlpg111.ts +23 -0
  578. package/dist/rules/sqlpg112.ts +25 -0
  579. package/dist/rules/sqlpg113.ts +28 -0
  580. package/dist/rules/sqlpg114.ts +37 -0
  581. package/dist/rules/sqlpg115.ts +38 -0
  582. package/dist/rules/sqlpg116.ts +25 -0
  583. package/dist/rules/sqlpg117.ts +24 -0
  584. package/dist/rules/sqlpg118.ts +22 -0
  585. package/dist/rules/templates.ts +35 -0
  586. package/dist/serializer.d.ts +37 -0
  587. package/dist/serializer.d.ts.map +1 -0
  588. package/dist/skill-defs.d.ts +3 -0
  589. package/dist/skill-defs.d.ts.map +1 -0
  590. package/dist/spec/catalog.d.ts +125 -0
  591. package/dist/spec/catalog.d.ts.map +1 -0
  592. package/dist/spec/fetch.d.ts +43 -0
  593. package/dist/spec/fetch.d.ts.map +1 -0
  594. package/dist/spec/pin.d.ts +39 -0
  595. package/dist/spec/pin.d.ts.map +1 -0
  596. package/dist/spec/postgres-catalog.d.ts +108 -0
  597. package/dist/spec/postgres-catalog.d.ts.map +1 -0
  598. package/dist/spec/postgres-fetch.d.ts +46 -0
  599. package/dist/spec/postgres-fetch.d.ts.map +1 -0
  600. package/dist/spec/postgres-pin.d.ts +67 -0
  601. package/dist/spec/postgres-pin.d.ts.map +1 -0
  602. package/dist/types/index.d.ts +4386 -0
  603. package/dist/validate-cli.d.ts +3 -0
  604. package/dist/validate-cli.d.ts.map +1 -0
  605. package/dist/validate.d.ts +15 -0
  606. package/dist/validate.d.ts.map +1 -0
  607. package/package.json +74 -4
  608. package/src/clickhouse/apply/apply.ts +288 -0
  609. package/src/clickhouse/apply/mutations.ts +90 -0
  610. package/src/clickhouse/apply/statements.ts +393 -0
  611. package/src/clickhouse/catalog-types.ts +84 -0
  612. package/src/clickhouse/container.ts +176 -0
  613. package/src/clickhouse/engine-syntax.test.ts +53 -0
  614. package/src/clickhouse/engine-syntax.ts +173 -0
  615. package/src/clickhouse/entities.test.ts +188 -0
  616. package/src/clickhouse/entities.ts +425 -0
  617. package/src/clickhouse/http.ts +76 -0
  618. package/src/clickhouse/import/generator.ts +153 -0
  619. package/src/clickhouse/import/import.test.ts +157 -0
  620. package/src/clickhouse/import/ir.ts +171 -0
  621. package/src/clickhouse/import/live-export.ts +53 -0
  622. package/src/clickhouse/import/parser.ts +27 -0
  623. package/src/clickhouse/import/roundtrip.test.ts +90 -0
  624. package/src/clickhouse/live/bind.ts +126 -0
  625. package/src/clickhouse/live/catalog.ts +96 -0
  626. package/src/clickhouse/live/describe-resources.ts +98 -0
  627. package/src/clickhouse/live/live.test.ts +143 -0
  628. package/src/clickhouse/live/roundtrip.e2e.test.ts +93 -0
  629. package/src/clickhouse/overlays/codecs.ts +68 -0
  630. package/src/clickhouse/overlays/engines.ts +108 -0
  631. package/src/clickhouse/overlays/kinds.ts +38 -0
  632. package/src/clickhouse/overlays/projections.ts +36 -0
  633. package/src/clickhouse/overlays/skip-indexes.ts +44 -0
  634. package/src/clickhouse/overlays/ttl.ts +55 -0
  635. package/src/clickhouse/overlays/types.ts +58 -0
  636. package/src/clickhouse/ownership.test.ts +20 -0
  637. package/src/clickhouse/ownership.ts +103 -0
  638. package/src/clickhouse/parser.test.ts +166 -0
  639. package/src/clickhouse/parser.ts +459 -0
  640. package/src/clickhouse/plan/commands.ts +101 -0
  641. package/src/clickhouse/plan/deep.ts +124 -0
  642. package/src/clickhouse/plan/diff.ts +203 -0
  643. package/src/clickhouse/plan/disruption.ts +61 -0
  644. package/src/clickhouse/plan/normalize.ts +352 -0
  645. package/src/clickhouse/plan/plan-wiring.test.ts +77 -0
  646. package/src/clickhouse/plan/plan.e2e.test.ts +77 -0
  647. package/src/clickhouse/plan/plan.test.ts +201 -0
  648. package/src/clickhouse/plan/rebuild-handoff.ts +59 -0
  649. package/src/clickhouse/plan/report.ts +19 -0
  650. package/src/clickhouse/plan/rules.ts +241 -0
  651. package/src/clickhouse/plan/schema.ts +56 -0
  652. package/src/clickhouse/plan/server-format.ts +39 -0
  653. package/src/clickhouse/rebuild/backfill.ts +186 -0
  654. package/src/clickhouse/rebuild/observe.ts +380 -0
  655. package/src/clickhouse/rebuild/op.ts +206 -0
  656. package/src/clickhouse/rebuild/partitions.ts +62 -0
  657. package/src/clickhouse/rebuild/rebuild-replicated.e2e.test.ts +513 -0
  658. package/src/clickhouse/rebuild/rebuild.e2e.test.ts +351 -0
  659. package/src/clickhouse/rebuild/rebuild.test.ts +190 -0
  660. package/src/clickhouse/rebuild/receipts.ts +143 -0
  661. package/src/clickhouse/rebuild/replicas.test.ts +70 -0
  662. package/src/clickhouse/rebuild/replicas.ts +148 -0
  663. package/src/clickhouse/rebuild/steps.ts +382 -0
  664. package/src/clickhouse/rebuild/verify.ts +124 -0
  665. package/src/clickhouse/testdata/NOTICE +5 -0
  666. package/src/clickhouse/testdata/clickhouse-tests-corpus.json +302 -0
  667. package/src/clickhouse/testing/fake-server.ts +65 -0
  668. package/src/clickhouse/testing/roundtrip-schema.ts +25 -0
  669. package/src/clickhouse/testing/writable-server.ts +141 -0
  670. package/src/clickhouse/tokens.ts +28 -0
  671. package/src/clickhouse.ts +63 -0
  672. package/src/codegen/classifier-page.test.ts +16 -0
  673. package/src/codegen/classifier-page.ts +76 -0
  674. package/src/codegen/clickhouse-module.test.ts +63 -0
  675. package/src/codegen/clickhouse-module.ts +269 -0
  676. package/src/codegen/docs-cli.ts +4 -0
  677. package/src/codegen/docs.ts +225 -0
  678. package/src/codegen/generate-cli.ts +13 -0
  679. package/src/codegen/generate.ts +126 -0
  680. package/src/codegen/package.ts +36 -0
  681. package/src/codegen/postgres-classifier-page.ts +81 -0
  682. package/src/codegen/postgres-module.test.ts +77 -0
  683. package/src/codegen/postgres-module.ts +434 -0
  684. package/src/codegen/registry.ts +36 -0
  685. package/src/composites/audit-log-table.ts +54 -0
  686. package/src/composites/catalog.test.ts +61 -0
  687. package/src/composites/catalog.ts +529 -0
  688. package/src/composites/cdc-mirror.ts +54 -0
  689. package/src/composites/clickhouse.ts +7 -0
  690. package/src/composites/composites.test.ts +758 -0
  691. package/src/composites/events-table.ts +49 -0
  692. package/src/composites/index.ts +9 -0
  693. package/src/composites/join-table.ts +57 -0
  694. package/src/composites/postgres.ts +7 -0
  695. package/src/composites/refreshed-view.ts +46 -0
  696. package/src/composites/replacing-table.ts +49 -0
  697. package/src/composites/rollup-view.ts +55 -0
  698. package/src/composites/sharded-table.ts +49 -0
  699. package/src/composites/soft-delete-table.ts +61 -0
  700. package/src/composites/tenant-table.ts +50 -0
  701. package/src/config.ts +157 -0
  702. package/src/core/apply.ts +153 -0
  703. package/src/core/classifier.ts +186 -0
  704. package/src/core/container.ts +93 -0
  705. package/src/core/core.test.ts +254 -0
  706. package/src/core/cursor.ts +189 -0
  707. package/src/core/diff.ts +72 -0
  708. package/src/core/entity.ts +85 -0
  709. package/src/core/find-templates.ts +158 -0
  710. package/src/core/handoff.ts +44 -0
  711. package/src/core/index.ts +61 -0
  712. package/src/core/interpolation.ts +225 -0
  713. package/src/core/normalize.ts +39 -0
  714. package/src/core/ownership.test.ts +36 -0
  715. package/src/core/ownership.ts +133 -0
  716. package/src/core/receipts.ts +29 -0
  717. package/src/core/references.ts +74 -0
  718. package/src/core/template.ts +83 -0
  719. package/src/core/testing/http-stub.ts +33 -0
  720. package/src/core/tokens.ts +252 -0
  721. package/src/coverage.ts +64 -0
  722. package/src/detect.ts +32 -0
  723. package/src/dialects.ts +21 -0
  724. package/src/generated/clickhouse-types.ts +4386 -0
  725. package/src/generated/clickhouse.ts +2476 -0
  726. package/src/generated/index.d.ts +4386 -0
  727. package/src/generated/lexicon-sql.json +67 -0
  728. package/src/generated/postgres-types.ts +1190 -0
  729. package/src/generated/postgres.ts +1039 -0
  730. package/src/import-generator.ts +18 -0
  731. package/src/index.ts +21 -0
  732. package/src/init-templates.test.ts +108 -0
  733. package/src/init-templates.ts +327 -0
  734. package/src/lint/audit-catalog.ts +73 -0
  735. package/src/lint/audit-lineage.ts +47 -0
  736. package/src/lint/post-synth/audit-entries.ts +29 -0
  737. package/src/lint/post-synth/clickhouse-checks.test.ts +278 -0
  738. package/src/lint/post-synth/clickhouse-helpers.ts +206 -0
  739. package/src/lint/post-synth/index.ts +81 -0
  740. package/src/lint/post-synth/post-synth.test.ts +33 -0
  741. package/src/lint/post-synth/postgres-audit-entries.ts +29 -0
  742. package/src/lint/post-synth/postgres-checks.test.ts +257 -0
  743. package/src/lint/post-synth/postgres-helpers.ts +126 -0
  744. package/src/lint/post-synth/sql-helpers.ts +53 -0
  745. package/src/lint/post-synth/sqlch101.ts +35 -0
  746. package/src/lint/post-synth/sqlch102.ts +23 -0
  747. package/src/lint/post-synth/sqlch103.ts +45 -0
  748. package/src/lint/post-synth/sqlch104.ts +42 -0
  749. package/src/lint/post-synth/sqlch105.ts +35 -0
  750. package/src/lint/post-synth/sqlch106.ts +27 -0
  751. package/src/lint/post-synth/sqlch107.ts +35 -0
  752. package/src/lint/post-synth/sqlch108.ts +27 -0
  753. package/src/lint/post-synth/sqlch109.ts +21 -0
  754. package/src/lint/post-synth/sqlch110.ts +29 -0
  755. package/src/lint/post-synth/sqlch111.ts +40 -0
  756. package/src/lint/post-synth/sqlch112.ts +30 -0
  757. package/src/lint/post-synth/sqlch113.ts +20 -0
  758. package/src/lint/post-synth/sqlch114.ts +26 -0
  759. package/src/lint/post-synth/sqlch115.ts +31 -0
  760. package/src/lint/post-synth/sqlch116.ts +22 -0
  761. package/src/lint/post-synth/sqlch117.ts +25 -0
  762. package/src/lint/post-synth/sqlch118.ts +26 -0
  763. package/src/lint/post-synth/sqlch119.ts +31 -0
  764. package/src/lint/post-synth/sqlch120.ts +21 -0
  765. package/src/lint/post-synth/sqlpg101.ts +24 -0
  766. package/src/lint/post-synth/sqlpg102.ts +30 -0
  767. package/src/lint/post-synth/sqlpg103.ts +23 -0
  768. package/src/lint/post-synth/sqlpg104.ts +23 -0
  769. package/src/lint/post-synth/sqlpg105.ts +22 -0
  770. package/src/lint/post-synth/sqlpg106.ts +22 -0
  771. package/src/lint/post-synth/sqlpg107.ts +22 -0
  772. package/src/lint/post-synth/sqlpg108.ts +27 -0
  773. package/src/lint/post-synth/sqlpg109.ts +37 -0
  774. package/src/lint/post-synth/sqlpg110.ts +33 -0
  775. package/src/lint/post-synth/sqlpg111.ts +23 -0
  776. package/src/lint/post-synth/sqlpg112.ts +25 -0
  777. package/src/lint/post-synth/sqlpg113.ts +28 -0
  778. package/src/lint/post-synth/sqlpg114.ts +37 -0
  779. package/src/lint/post-synth/sqlpg115.ts +38 -0
  780. package/src/lint/post-synth/sqlpg116.ts +25 -0
  781. package/src/lint/post-synth/sqlpg117.ts +24 -0
  782. package/src/lint/post-synth/sqlpg118.ts +22 -0
  783. package/src/lint/rules/index.ts +13 -0
  784. package/src/lint/rules/postgres-templates.ts +36 -0
  785. package/src/lint/rules/rules.test.ts +228 -0
  786. package/src/lint/rules/sqlch001.ts +53 -0
  787. package/src/lint/rules/sqlch002.ts +115 -0
  788. package/src/lint/rules/sqlch003.ts +68 -0
  789. package/src/lint/rules/sqlpg001.ts +88 -0
  790. package/src/lint/rules/sqlpg002.ts +68 -0
  791. package/src/lint/rules/sqlpg003.ts +59 -0
  792. package/src/lint/rules/sqlpg004.ts +73 -0
  793. package/src/lint/rules/templates.ts +35 -0
  794. package/src/live-dialect.ts +37 -0
  795. package/src/lsp/catalog.ts +60 -0
  796. package/src/lsp/completions.test.ts +111 -0
  797. package/src/lsp/completions.ts +128 -0
  798. package/src/lsp/diagnostics.test.ts +26 -0
  799. package/src/lsp/hover.test.ts +90 -0
  800. package/src/lsp/hover.ts +113 -0
  801. package/src/lsp/postgres-catalog.ts +234 -0
  802. package/src/lsp/postgres-template.ts +161 -0
  803. package/src/lsp/postgres.test.ts +150 -0
  804. package/src/lsp/postgres.ts +270 -0
  805. package/src/lsp/refs.ts +53 -0
  806. package/src/lsp/registry.ts +19 -0
  807. package/src/lsp/template.ts +166 -0
  808. package/src/mcp/index.ts +304 -0
  809. package/src/mcp/mcp.test.ts +184 -0
  810. package/src/mcp/postgres.ts +125 -0
  811. package/src/op/activities/clickhouse-apply.e2e.test.ts +150 -0
  812. package/src/op/activities/clickhouse-apply.test.ts +265 -0
  813. package/src/op/activities/clickhouse-apply.ts +113 -0
  814. package/src/op/activities/clickhouse-emulator.test.ts +23 -0
  815. package/src/op/activities/clickhouse-emulator.ts +37 -0
  816. package/src/op/activities/clickhouse-rebuild.ts +136 -0
  817. package/src/op/activities/index.ts +50 -0
  818. package/src/op/activities/postgres-apply.e2e.test.ts +184 -0
  819. package/src/op/activities/postgres-apply.test.ts +304 -0
  820. package/src/op/activities/postgres-apply.ts +170 -0
  821. package/src/op/activities/postgres-emulator.test.ts +26 -0
  822. package/src/op/activities/postgres-emulator.ts +44 -0
  823. package/src/op/activities/postgres-migration.ts +182 -0
  824. package/src/op/activity-contracts.ts +210 -0
  825. package/src/package-cli.ts +17 -0
  826. package/src/plugin.test.ts +74 -0
  827. package/src/plugin.ts +242 -0
  828. package/src/postgres/apply/apply.ts +582 -0
  829. package/src/postgres/apply/statements.test.ts +155 -0
  830. package/src/postgres/apply/statements.ts +603 -0
  831. package/src/postgres/catalog-types.ts +59 -0
  832. package/src/postgres/container.ts +72 -0
  833. package/src/postgres/entities.test.ts +170 -0
  834. package/src/postgres/entities.ts +1016 -0
  835. package/src/postgres/entity-types.ts +18 -0
  836. package/src/postgres/import/generator.ts +176 -0
  837. package/src/postgres/import/import.test.ts +71 -0
  838. package/src/postgres/import/ir.ts +67 -0
  839. package/src/postgres/import/live-export.ts +53 -0
  840. package/src/postgres/import/live-warnings.test.ts +45 -0
  841. package/src/postgres/keywords.ts +40 -0
  842. package/src/postgres/live/bind.ts +146 -0
  843. package/src/postgres/live/catalog.ts +581 -0
  844. package/src/postgres/live/client.ts +84 -0
  845. package/src/postgres/live/describe-resources.ts +111 -0
  846. package/src/postgres/live/live.test.ts +198 -0
  847. package/src/postgres/live/roundtrip.e2e.test.ts +111 -0
  848. package/src/postgres/migrate/backfill.ts +233 -0
  849. package/src/postgres/migrate/batches.e2e.test.ts +163 -0
  850. package/src/postgres/migrate/batches.test.ts +36 -0
  851. package/src/postgres/migrate/batches.ts +159 -0
  852. package/src/postgres/migrate/carry.e2e.test.ts +335 -0
  853. package/src/postgres/migrate/carry.test.ts +103 -0
  854. package/src/postgres/migrate/carry.ts +653 -0
  855. package/src/postgres/migrate/handoff.ts +73 -0
  856. package/src/postgres/migrate/kinds.e2e.test.ts +204 -0
  857. package/src/postgres/migrate/migrate.e2e.test.ts +362 -0
  858. package/src/postgres/migrate/migrate.test.ts +322 -0
  859. package/src/postgres/migrate/names.ts +93 -0
  860. package/src/postgres/migrate/observe.ts +521 -0
  861. package/src/postgres/migrate/op.ts +242 -0
  862. package/src/postgres/migrate/receipts.ts +135 -0
  863. package/src/postgres/migrate/replication.ts +151 -0
  864. package/src/postgres/migrate/steps.ts +657 -0
  865. package/src/postgres/overlays/columns.ts +34 -0
  866. package/src/postgres/overlays/constraints.ts +56 -0
  867. package/src/postgres/overlays/indexes.ts +27 -0
  868. package/src/postgres/overlays/kinds.ts +53 -0
  869. package/src/postgres/overlays/partitioning.ts +26 -0
  870. package/src/postgres/overlays/relations.ts +29 -0
  871. package/src/postgres/overlays/storage.ts +75 -0
  872. package/src/postgres/overlays/type-ddl.ts +38 -0
  873. package/src/postgres/overlays/types.ts +56 -0
  874. package/src/postgres/parser.test.ts +214 -0
  875. package/src/postgres/parser.ts +1062 -0
  876. package/src/postgres/plan/commands.ts +124 -0
  877. package/src/postgres/plan/deep.ts +177 -0
  878. package/src/postgres/plan/diff.ts +323 -0
  879. package/src/postgres/plan/disruption.ts +52 -0
  880. package/src/postgres/plan/normalize.test.ts +148 -0
  881. package/src/postgres/plan/normalize.ts +542 -0
  882. package/src/postgres/plan/plan.e2e.test.ts +117 -0
  883. package/src/postgres/plan/plan.test.ts +244 -0
  884. package/src/postgres/plan/report.ts +24 -0
  885. package/src/postgres/plan/rules.ts +276 -0
  886. package/src/postgres/plan/schema.ts +114 -0
  887. package/src/postgres/plan/server-normalize.ts +123 -0
  888. package/src/postgres/providers/aurora.ts +45 -0
  889. package/src/postgres/providers/azure.ts +54 -0
  890. package/src/postgres/providers/cloud-sql.ts +42 -0
  891. package/src/postgres/providers/index.ts +90 -0
  892. package/src/postgres/providers/neon.ts +45 -0
  893. package/src/postgres/providers/providers.test.ts +136 -0
  894. package/src/postgres/providers/rds.ts +48 -0
  895. package/src/postgres/providers/supabase.ts +46 -0
  896. package/src/postgres/providers/types.ts +70 -0
  897. package/src/postgres/testdata/NOTICE +31 -0
  898. package/src/postgres/testdata/postgres-regress-corpus.json +460 -0
  899. package/src/postgres/testing/fake-client.ts +42 -0
  900. package/src/postgres/testing/migration.ts +52 -0
  901. package/src/postgres/testing/roundtrip-schema.ts +46 -0
  902. package/src/postgres/testing/server.ts +58 -0
  903. package/src/postgres/testing/writable-server.ts +188 -0
  904. package/src/postgres/tokens.ts +46 -0
  905. package/src/postgres.ts +75 -0
  906. package/src/serializer.test.ts +128 -0
  907. package/src/serializer.ts +148 -0
  908. package/src/skill-defs.test.ts +81 -0
  909. package/src/skill-defs.ts +102 -0
  910. package/src/skills/chant-sql-plan.md +123 -0
  911. package/src/skills/chant-sql-postgres-migration.md +126 -0
  912. package/src/skills/chant-sql-postgres-plan.md +194 -0
  913. package/src/skills/chant-sql-postgres.md +165 -0
  914. package/src/skills/chant-sql-rebuild.md +68 -0
  915. package/src/skills/chant-sql.md +123 -0
  916. package/src/spec/catalog.e2e.test.ts +29 -0
  917. package/src/spec/catalog.test.ts +56 -0
  918. package/src/spec/catalog.ts +311 -0
  919. package/src/spec/clickhouse-catalog.snapshot.json +5246 -0
  920. package/src/spec/fetch.test.ts +77 -0
  921. package/src/spec/fetch.ts +112 -0
  922. package/src/spec/pin.ts +47 -0
  923. package/src/spec/postgres-catalog-14.snapshot.json +3494 -0
  924. package/src/spec/postgres-catalog-15.snapshot.json +3529 -0
  925. package/src/spec/postgres-catalog-16.snapshot.json +3597 -0
  926. package/src/spec/postgres-catalog-17.snapshot.json +3656 -0
  927. package/src/spec/postgres-catalog-18.snapshot.json +3747 -0
  928. package/src/spec/postgres-catalog.test.ts +43 -0
  929. package/src/spec/postgres-catalog.ts +301 -0
  930. package/src/spec/postgres-fetch.test.ts +75 -0
  931. package/src/spec/postgres-fetch.ts +112 -0
  932. package/src/spec/postgres-pin.test.ts +64 -0
  933. package/src/spec/postgres-pin.ts +101 -0
  934. package/src/typecheck.test.ts +104 -0
  935. package/src/validate-cli.ts +6 -0
  936. package/src/validate.ts +149 -0
@@ -0,0 +1,653 @@
1
+ /**
2
+ * What uses the migrated column, carried over to the new one (#3322).
3
+ *
4
+ * An index, a constraint or a view on the column binds the column by its
5
+ * attribute number, not its name, so a swap of names at the switch would
6
+ * leave it on the old column, and the contract could not drop that column
7
+ * while something uses it. Each is made again on the new column before the
8
+ * switch, under a working name, and the switch swaps the names:
9
+ *
10
+ * | On the old column | Before the switch | In the switch's transaction |
11
+ * |---|---|---|
12
+ * | an index | `CREATE INDEX CONCURRENTLY` on the new column | the old one dropped (a type change) or kept as `<name>__chant_old` (a rename), the new one renamed to the name |
13
+ * | a primary key or unique constraint | its unique index built `CONCURRENTLY` | the old constraint dropped (or a rename's unique one kept as `__chant_old`), `ADD CONSTRAINT ... USING INDEX` |
14
+ * | a check or foreign key, this table's or another's that references the column | added `NOT VALID`, then `VALIDATE` | the old one dropped, the new one renamed to the name |
15
+ * | a view (and the views that read it) | nothing | dropped, then created again from its declaration once the columns are swapped, with its grants and owner |
16
+ *
17
+ * `CREATE INDEX CONCURRENTLY` reads the table without blocking writes, and
18
+ * `VALIDATE CONSTRAINT` holds SHARE UPDATE EXCLUSIVE, so both run while the
19
+ * application keeps writing; the dual-write trigger keeps the new column
20
+ * equal to the old one, so the index and the constraints hold the same rows
21
+ * as the old ones. A foreign key from another table is added against the
22
+ * new column's working unique index, which the switch then attaches to the
23
+ * key constraint. Everything in the switch changes only the catalog.
24
+ *
25
+ * Working objects carry chant's trailer with `migration=<key>` and
26
+ * `role=carry`, so the catalog read leaves them out of plans until the
27
+ * switch, and onFailure drops them (`./steps.ts`). The switch gives each its
28
+ * old comment back.
29
+ *
30
+ * Names: a type change keeps every name. A rename keeps a name the
31
+ * declaration does not give otherwise, except one Postgres made from the
32
+ * old column (`users_email_key` becomes `users_login_key`); a key, foreign
33
+ * key or index the build declares on the new column takes the declared name.
34
+ *
35
+ * Refused, each named with what to do: exclusion constraints and constraint
36
+ * triggers (no `USING INDEX` form), materialized views (made again only by
37
+ * a full scan in the switch), rules, triggers, policies and statistics on the
38
+ * column, a generated column computed from it, an INVALID index on it, a view
39
+ * the build does not declare, a view something other than a view depends on.
40
+ */
41
+
42
+ import type { OwnershipMarker } from "@intentius/chant/ownership";
43
+ import { quoteIdent } from "../keywords";
44
+ import type { PostgresClient } from "../live/client";
45
+ import { tokenizeText, type Token } from "../tokens";
46
+ import { identValue } from "../parser";
47
+ import { createSteps, pgString, type DeclaredPgObject } from "../apply/statements";
48
+ import type { ColumnDef, ForeignKeyDef, KeyDef } from "../entities";
49
+ import { POSTGRES_ENTITY_TYPES } from "../entity-types";
50
+ import { canonicalName } from "../plan/normalize";
51
+ import { pgName, type MigrationNames } from "./names";
52
+
53
+ export type CarriedKind = "index" | "key" | "check" | "foreign-key";
54
+
55
+ /** One index or constraint on the old column, and how it is made on the new one. */
56
+ export interface CarriedObject {
57
+ kind: CarriedKind;
58
+ /** Its name now. */
59
+ name: string;
60
+ /** The table it is on, quoted and qualified (the referencing table for a foreign key). */
61
+ table: string;
62
+ /** The same, as `schema.table`, for messages. */
63
+ tableName: string;
64
+ tableOid: string;
65
+ /** The schema an index lives in (its table's). */
66
+ schema: string;
67
+ /** Its name on the new column until the switch. */
68
+ working: string;
69
+ /** Its name after the switch. */
70
+ target: string;
71
+ /**
72
+ * What makes the working object: for an index or a key, the `CREATE INDEX
73
+ * CONCURRENTLY` statement; for a check or a foreign key, the constraint's
74
+ * body (`CHECK (...)`, `FOREIGN KEY ... REFERENCES ...`), added `NOT VALID`.
75
+ */
76
+ definition: string;
77
+ /** A key: `PRIMARY KEY` or `UNIQUE`, and its deferral. */
78
+ primary?: boolean;
79
+ deferral?: string;
80
+ /** A constraint: validated on the server, so validated on the new column before the switch. */
81
+ validated: boolean;
82
+ comment?: string;
83
+ /** A key: the comment of its index. */
84
+ indexComment?: string;
85
+ replicaIdentity?: boolean;
86
+ clustered?: boolean;
87
+ }
88
+
89
+ /** A view on the old column (or on such a view), made again at the switch from its declaration. */
90
+ export interface CarriedView {
91
+ /** `schema.name`. */
92
+ name: string;
93
+ /** Quoted and qualified. */
94
+ ident: string;
95
+ materialized: false;
96
+ /** How many views lie between it and the table: dropped deepest first, created shallowest first. */
97
+ depth: number;
98
+ declared: DeclaredPgObject;
99
+ owner: string;
100
+ grants: Array<{ grantee: string; privilege: string; grantable: boolean }>;
101
+ }
102
+
103
+ /** The sequence that belongs to the column: its identity's, or a `serial` column's. A type change moves it to the new column at the switch. */
104
+ export interface ColumnSequence {
105
+ kind: "identity" | "serial";
106
+ schema: string;
107
+ name: string;
108
+ /** Quoted and qualified. */
109
+ ident: string;
110
+ }
111
+
112
+ export interface Dependents {
113
+ carried: CarriedObject[];
114
+ views: CarriedView[];
115
+ sequence?: ColumnSequence;
116
+ /** What the Op does not carry, each as a sentence naming the object. */
117
+ refused: string[];
118
+ }
119
+
120
+ /** The working name of a carried object, and the name a rename keeps the old one under. */
121
+ export const carriedWorkingName = (name: string): string => pgName(`${name}__chant_new`);
122
+ export const carriedOldName = (name: string): string => pgName(`${name}__chant_old`);
123
+
124
+ /**
125
+ * `sql` with every reference to the column `from` replaced by `to`: an
126
+ * identifier token naming it, not a qualifier (`x.`), a qualified name's
127
+ * last part, a function's name, a cast's type or an access method. Within
128
+ * `[start, end)` token indexes when given.
129
+ */
130
+ export function replaceColumn(sql: string, from: string, to: string, range?: (tokens: readonly Token[]) => Array<[number, number]>): string {
131
+ const tokens = tokenizeText(sql, 0);
132
+ const ranges = range ? range(tokens) : [[0, tokens.length] as [number, number]];
133
+ const significant = (i: number, step: number): Token | undefined => {
134
+ for (let j = i + step; j >= 0 && j < tokens.length; j += step) if (tokens[j]!.kind !== "ws" && tokens[j]!.kind !== "comment") return tokens[j];
135
+ return undefined;
136
+ };
137
+ const inRange = (i: number) => ranges.some(([a, b]) => i >= a && i < b);
138
+ return tokens
139
+ .map((t, i) => {
140
+ if ((t.kind !== "ident" && t.kind !== "qident") || !inRange(i) || identValue(t) !== from) return t.text;
141
+ const prev = significant(i, -1);
142
+ const next = significant(i, 1);
143
+ if (prev?.text === "." || next?.text === "." || next?.text === "(") return t.text;
144
+ if (prev?.kind === "op" && prev.text === "::") return t.text;
145
+ if (prev?.kind === "ident" && /^using$/i.test(prev.text)) return t.text;
146
+ return quoteIdent(to);
147
+ })
148
+ .join("");
149
+ }
150
+
151
+ /**
152
+ * A foreign key's token ranges: the referencing side (before `REFERENCES`,
153
+ * and an `ON DELETE SET NULL (...)` list after it) and the referenced
154
+ * column list.
155
+ */
156
+ function foreignKeyRanges(tokens: readonly Token[]): { local: Array<[number, number]>; referenced: Array<[number, number]> } {
157
+ const at = tokens.findIndex((t) => t.kind === "ident" && /^references$/i.test(t.text));
158
+ if (at < 0) return { local: [[0, tokens.length]], referenced: [] };
159
+ let open = at + 1;
160
+ while (open < tokens.length && !(tokens[open]!.kind === "punct" && tokens[open]!.text === "(")) open++;
161
+ let close = open;
162
+ for (let depth = 0; close < tokens.length; close++) {
163
+ if (tokens[close]!.text === "(") depth++;
164
+ else if (tokens[close]!.text === ")" && --depth === 0) break;
165
+ }
166
+ return { local: [[0, at], [close + 1, tokens.length]], referenced: open < tokens.length ? [[open, close + 1]] : [] };
167
+ }
168
+
169
+ /** A foreign key's body with the column replaced on the side(s) that are the migrated table. */
170
+ export function replaceInForeignKey(def: string, from: string, to: string, sides: { local: boolean; referenced: boolean }): string {
171
+ return replaceColumn(def, from, to, (tokens) => {
172
+ const r = foreignKeyRanges(tokens);
173
+ return [...(sides.local ? r.local : []), ...(sides.referenced ? r.referenced : [])];
174
+ });
175
+ }
176
+
177
+ /** A constraint's body without a trailing `NOT VALID`, which the carry adds itself. */
178
+ const withoutNotValid = (def: string): string => def.replace(/\s+NOT VALID\s*$/i, "");
179
+
180
+ /**
181
+ * `CREATE [UNIQUE] INDEX <name> ON ...` as `pg_get_indexdef` prints it, as
182
+ * the `CONCURRENTLY` build of `working` on the new column.
183
+ */
184
+ export function carriedIndexStatement(def: string, working: string, from: string, to: string): string {
185
+ const m = /^CREATE (UNIQUE )?INDEX (?:"(?:[^"]|"")+"|\S+) ON (.*)$/s.exec(def);
186
+ if (!m) throw new Error(`unexpected index definition: ${def}`);
187
+ return `CREATE ${m[1] ?? ""}INDEX CONCURRENTLY ${quoteIdent(working)} ON ${replaceColumn(m[2]!, from, to)}`;
188
+ }
189
+
190
+ /**
191
+ * The name Postgres gives an object it names after its columns
192
+ * (`users_email_key`, `orders_user_id_fkey`, `users_email_idx`), when `name`
193
+ * is that name for the old columns: the same name for the new ones. Only a
194
+ * name that fits untruncated; any other name is kept.
195
+ */
196
+ export function renamedDefault(name: string, table: string, oldCols: readonly string[], newCols: readonly string[], suffix: string): string | undefined {
197
+ const made = (cols: readonly string[]) => `${table}_${cols.join("_")}_${suffix}`;
198
+ if (name !== made(oldCols)) return undefined;
199
+ const next = made(newCols);
200
+ return Buffer.byteLength(next, "utf8") <= 63 && next !== name ? next : undefined;
201
+ }
202
+
203
+ const sameColumns = (a: readonly string[], b: readonly string[]) => a.length === b.length && a.every((c, i) => c === b[i]);
204
+
205
+ interface DiscoverInput {
206
+ client: PostgresClient;
207
+ names: MigrationNames;
208
+ oid: string;
209
+ attnum: number;
210
+ /** Every object the build declares: views are made again from theirs, and a declared name wins on a rename. */
211
+ objects: readonly DeclaredPgObject[];
212
+ /** The declared table. */
213
+ declared: DeclaredPgObject;
214
+ defaultSchema: string;
215
+ /** The table is partitioned: its indexes cannot be built CONCURRENTLY, nor its keys attached USING INDEX. */
216
+ partitioned?: boolean;
217
+ }
218
+
219
+ interface Row {
220
+ [key: string]: unknown;
221
+ }
222
+
223
+ /** What uses the column the values come from, sorted into what the Op carries over and what it refuses. */
224
+ export async function discoverDependents(input: DiscoverInput): Promise<Dependents> {
225
+ const { client, names: n, oid, attnum } = input;
226
+ const from = n.source;
227
+ const to = n.newColumn;
228
+ const deps = await client.query<{ kind: string; objid: string; objsubid: number; what: string; deptype: string }>(
229
+ `SELECT d.deptype::text AS deptype, CASE d.classid WHEN 'pg_catalog.pg_constraint'::pg_catalog.regclass THEN 'constraint' WHEN 'pg_catalog.pg_class'::pg_catalog.regclass THEN 'class'
230
+ WHEN 'pg_catalog.pg_rewrite'::pg_catalog.regclass THEN 'rewrite' WHEN 'pg_catalog.pg_attrdef'::pg_catalog.regclass THEN 'attrdef' ELSE 'other' END AS kind,
231
+ d.objid::text AS objid, d.objsubid, pg_catalog.pg_describe_object(d.classid, d.objid, d.objsubid) AS what
232
+ FROM pg_catalog.pg_depend d
233
+ WHERE d.refclassid = 'pg_catalog.pg_class'::pg_catalog.regclass AND d.refobjid = $1::oid AND d.refobjsubid = $2 AND d.deptype IN ('n', 'a', 'i')
234
+ UNION
235
+ SELECT 'n', 'constraint', c.oid::text, 0, pg_catalog.pg_describe_object('pg_catalog.pg_constraint'::pg_catalog.regclass, c.oid, 0)
236
+ FROM pg_catalog.pg_constraint c WHERE c.confrelid = $1::oid AND $2 = ANY(c.confkey)`,
237
+ [oid, attnum],
238
+ );
239
+ const refused: string[] = [];
240
+ const carried: CarriedObject[] = [];
241
+ let sequence: ColumnSequence | undefined;
242
+ const byKind = (k: string) => [...new Set(deps.filter((d) => d.kind === k).map((d) => d.objid))];
243
+ const table = n.table;
244
+ const rename = n.change === "rename";
245
+ const tprops = input.declared.props as { primaryKey?: KeyDef; uniques?: KeyDef[]; foreignKeys?: ForeignKeyDef[] };
246
+
247
+ // ── constraints ─────────────────────────────────────────────────────
248
+ const constraintIds = byKind("constraint");
249
+ const keyIndexes = new Set<string>();
250
+ if (constraintIds.length > 0) {
251
+ const rows = await client.query<Row>(
252
+ `SELECT c.oid::text AS oid, c.conname AS name, c.contype::text AS type, c.conrelid::text AS rel, c.confrelid::text AS frel, c.conindid::text AS idx,
253
+ pg_catalog.pg_get_constraintdef(c.oid) AS def, c.convalidated AS validated, c.condeferrable AS deferrable, c.condeferred AS deferred,
254
+ pg_catalog.obj_description(c.oid, 'pg_constraint') AS comment, n.nspname AS schema, t.relname AS table_name,
255
+ CASE WHEN c.conindid <> 0 THEN pg_catalog.obj_description(c.conindid, 'pg_class') END AS index_comment,
256
+ CASE WHEN c.conindid <> 0 AND c.contype IN ('p', 'u') THEN pg_catalog.pg_get_indexdef(c.conindid) END AS indexdef,
257
+ COALESCE(i.indisreplident, false) AS replident, COALESCE(i.indisclustered, false) AS clustered,
258
+ (SELECT a.attname FROM pg_catalog.pg_attribute a WHERE a.attrelid = c.conrelid AND a.attnum = c.conkey[1]) AS first_col,
259
+ ARRAY(SELECT a.attname FROM pg_catalog.unnest(c.conkey) WITH ORDINALITY k(n, o) JOIN pg_catalog.pg_attribute a ON a.attrelid = c.conrelid AND a.attnum = k.n ORDER BY k.o)::text[] AS cols,
260
+ t.relkind = 'p' OR EXISTS (SELECT 1 FROM pg_catalog.pg_class f WHERE f.oid = c.confrelid AND f.relkind = 'p') AS frel_partitioned
261
+ FROM pg_catalog.pg_constraint c JOIN pg_catalog.pg_class t ON t.oid = c.conrelid JOIN pg_catalog.pg_namespace n ON n.oid = t.relnamespace
262
+ LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.conindid
263
+ WHERE c.oid = ANY($1::oid[]) ORDER BY c.conname`,
264
+ [constraintIds],
265
+ );
266
+ for (const r of rows) {
267
+ const name = String(r.name);
268
+ const own = String(r.rel) === oid;
269
+ const where = `${String(r.schema)}.${String(r.table_name)}`;
270
+ const qtable = `${quoteIdent(String(r.schema))}.${quoteIdent(String(r.table_name))}`;
271
+ const type = String(r.type);
272
+ if (type === "n" && own) continue; // the column's own NOT NULL (18)
273
+ const comment = r.comment === null ? undefined : String(r.comment);
274
+ const base = { name, table: qtable, tableName: where, tableOid: String(r.rel), schema: String(r.schema), working: carriedWorkingName(name), validated: r.validated === true, ...(comment !== undefined ? { comment } : {}) };
275
+ const cols = (r.cols as string[] | null) ?? [];
276
+ const newCols = cols.map((c) => (own && c === from ? n.column : c));
277
+ if (input.partitioned && (type === "p" || type === "u" || type === "f")) {
278
+ keyIndexes.add(String(r.idx));
279
+ refused.push(
280
+ `${type === "f" ? "foreign key" : type === "p" ? "primary key" : "unique constraint"} ${name} on ${where}: on a partitioned table ${type === "f" ? "a foreign key cannot be added NOT VALID and validated while writes go on" : "a key cannot be attached from an index built CONCURRENTLY (ADD CONSTRAINT ... USING INDEX is not supported on partitioned tables)"}, so carrying it over would hold ACCESS EXCLUSIVE for a full build; drop it, migrate, then declare it again (chant #3333)`,
281
+ );
282
+ continue;
283
+ }
284
+ if (type === "f" && !own && r.frel_partitioned === true) {
285
+ refused.push(`foreign key ${name} on ${where} references a partitioned table, where it cannot be added NOT VALID and validated while writes go on; drop it, migrate, then declare it again`);
286
+ continue;
287
+ }
288
+ if (type === "p" || type === "u") {
289
+ keyIndexes.add(String(r.idx));
290
+ const declaredKey = type === "p" ? (tprops.primaryKey?.name ? tprops.primaryKey : undefined) : tprops.uniques?.find((u) => u.name && sameColumns(u.columns, newCols));
291
+ const target = !rename ? name : (declaredKey?.name ?? (type === "u" ? renamedDefault(name, table, cols, newCols, "key") : undefined) ?? name);
292
+ const deferral = r.deferrable === true ? ` DEFERRABLE${r.deferred === true ? " INITIALLY DEFERRED" : ""}` : "";
293
+ carried.push({
294
+ ...base,
295
+ kind: "key",
296
+ target,
297
+ primary: type === "p",
298
+ ...(deferral ? { deferral } : {}),
299
+ definition: carriedIndexStatement(String(r.indexdef), base.working, from, to),
300
+ ...(r.index_comment !== null && r.index_comment !== undefined ? { indexComment: String(r.index_comment) } : {}),
301
+ ...(r.replident === true ? { replicaIdentity: true } : {}),
302
+ ...(r.clustered === true ? { clustered: true } : {}),
303
+ });
304
+ } else if (type === "c") {
305
+ const first = String(r.first_col ?? "");
306
+ const target = !rename ? name : (renamedDefault(name, table, [first], [first === from ? n.column : first], "check") ?? name);
307
+ carried.push({ ...base, kind: "check", target, definition: replaceColumn(withoutNotValid(String(r.def)), from, to) });
308
+ } else if (type === "f") {
309
+ const referenced = String(r.frel) === oid;
310
+ const def = replaceInForeignKey(withoutNotValid(String(r.def)), from, to, { local: own, referenced });
311
+ let target = name;
312
+ if (rename && own) {
313
+ const declaredFk = tprops.foreignKeys?.find((f) => f.name && sameColumns(f.columns, newCols));
314
+ target = declaredFk?.name ?? renamedDefault(name, table, cols, newCols, "fkey") ?? name;
315
+ }
316
+ carried.push({ ...base, kind: "foreign-key", target, definition: def });
317
+ } else if (type === "x") {
318
+ refused.push(`exclusion constraint ${name} on ${where}: an exclusion constraint cannot be attached from an index built CONCURRENTLY, so adding it again would hold ACCESS EXCLUSIVE for a full build; drop it, migrate, then declare it again`);
319
+ } else if (type === "t") {
320
+ refused.push(`constraint trigger ${name} on ${where}: its function reads the column by name, which the Op cannot rewrite; drop it, migrate, then create it again`);
321
+ } else {
322
+ refused.push(`constraint ${name} on ${where} (type ${type})`);
323
+ }
324
+ }
325
+ }
326
+
327
+ // ── indexes, sequences, columns ─────────────────────────────────────
328
+ const classIds = byKind("class");
329
+ if (classIds.length > 0) {
330
+ const rows = await client.query<Row>(
331
+ `SELECT c.oid::text AS oid, c.relname AS name, c.relkind::text AS kind, n.nspname AS schema, pg_catalog.obj_description(c.oid, 'pg_class') AS comment,
332
+ CASE WHEN c.relkind IN ('i', 'I') THEN pg_catalog.pg_get_indexdef(c.oid) END AS def,
333
+ i.indisvalid AS valid, i.indisunique AS is_unique, COALESCE(i.indisreplident, false) AS replident, COALESCE(i.indisclustered, false) AS clustered,
334
+ ARRAY(SELECT a.attname FROM pg_catalog.unnest(i.indkey::int2[]) WITH ORDINALITY k(n, o) JOIN pg_catalog.pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = k.n ORDER BY k.o)::text[] AS cols,
335
+ i.indexprs IS NOT NULL OR i.indpred IS NOT NULL AS has_exprs
336
+ FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid
337
+ WHERE c.oid = ANY($1::oid[]) ORDER BY c.relname`,
338
+ [classIds],
339
+ );
340
+ const declaredIndexes = input.objects.filter((o) => o.type === POSTGRES_ENTITY_TYPES.index);
341
+ for (const r of rows) {
342
+ const name = String(r.name);
343
+ const kind = String(r.kind);
344
+ if (kind === "i" || kind === "I") {
345
+ if (keyIndexes.has(String(r.oid))) continue;
346
+ if (kind === "I") {
347
+ refused.push(`index ${r.schema}.${name} is a partitioned index, which cannot be built CONCURRENTLY; drop it, migrate, then declare it again (chant #3333)`);
348
+ continue;
349
+ }
350
+ if (r.valid !== true) {
351
+ refused.push(`index ${r.schema}.${name} is INVALID (a failed CONCURRENTLY build); drop it, or REINDEX it, first`);
352
+ continue;
353
+ }
354
+ const working = carriedWorkingName(name);
355
+ let target = name;
356
+ if (rename) {
357
+ const oldCols = (r.cols as string[] | null) ?? [];
358
+ const cols = oldCols.map((c) => (c === from ? n.column : c));
359
+ const declaredIndex =
360
+ r.has_exprs === true
361
+ ? undefined
362
+ : declaredIndexes.find((d) => {
363
+ const p = d.props as { tableName?: string; unique?: boolean; elements?: Array<{ column?: string }>; where?: string };
364
+ const els = p.elements ?? [];
365
+ return (
366
+ canonicalName(String(p.tableName ?? ""), input.defaultSchema) === `${n.schema}.${n.table}` &&
367
+ (p.unique === true) === (r.is_unique === true) &&
368
+ !p.where &&
369
+ els.every((e) => e.column !== undefined) &&
370
+ sameColumns(
371
+ els.map((e) => e.column!),
372
+ cols,
373
+ )
374
+ );
375
+ });
376
+ target = declaredIndex?.canonical.name ?? (r.has_exprs === true ? undefined : renamedDefault(name, table, oldCols, cols, "idx")) ?? name;
377
+ }
378
+ carried.push({
379
+ kind: "index",
380
+ name,
381
+ table: n.qualifiedTable,
382
+ tableName: `${n.schema}.${n.table}`,
383
+ tableOid: oid,
384
+ schema: String(r.schema),
385
+ working,
386
+ target,
387
+ definition: carriedIndexStatement(String(r.def), working, from, to),
388
+ validated: true,
389
+ ...(r.comment !== null ? { comment: String(r.comment) } : {}),
390
+ ...(r.replident === true ? { replicaIdentity: true } : {}),
391
+ ...(r.clustered === true ? { clustered: true } : {}),
392
+ });
393
+ } else if (kind === "S") {
394
+ const dep = deps.find((d) => d.kind === "class" && d.objid === String(r.oid));
395
+ const seq: ColumnSequence = { kind: dep?.deptype === "i" ? "identity" : "serial", schema: String(r.schema), name, ident: `${quoteIdent(String(r.schema))}.${quoteIdent(name)}` };
396
+ if (rename) {
397
+ refused.push(
398
+ `sequence ${r.schema}.${name} gives the column its values (${seq.kind === "identity" ? "an identity column" : "a serial column's default"}); during a rename a writer that names the new column would be given the old one's next value by the trigger, which it cannot tell from a value the writer chose; a rename that keeps its sequence needs versioned views (chant #3331)`,
399
+ );
400
+ } else sequence = seq;
401
+ } else {
402
+ const what = deps.find((d) => d.kind === "class" && d.objid === String(r.oid))?.what ?? `${r.schema}.${name}`;
403
+ refused.push(what);
404
+ }
405
+ }
406
+ }
407
+
408
+ // ── generated columns computed from it ──────────────────────────────
409
+ const attrdefIds = byKind("attrdef");
410
+ if (attrdefIds.length > 0) {
411
+ const rows = await client.query<{ name: string; adnum: number }>(
412
+ "SELECT a.attname AS name, d.adnum FROM pg_catalog.pg_attrdef d JOIN pg_catalog.pg_attribute a ON a.attrelid = d.adrelid AND a.attnum = d.adnum WHERE d.oid = ANY($1::oid[])",
413
+ [attrdefIds],
414
+ );
415
+ for (const r of rows) {
416
+ if (Number(r.adnum) === attnum) continue; // its own default
417
+ refused.push(`generated column ${n.schema}.${n.table}.${r.name} is computed from it; computing it from the new column would rewrite the table, so drop the generated column, migrate, then declare it again`);
418
+ }
419
+ }
420
+
421
+ // ── views, rules ────────────────────────────────────────────────────
422
+ const views: CarriedView[] = [];
423
+ const rewriteIds = byKind("rewrite");
424
+ if (rewriteIds.length > 0) {
425
+ const rows = await client.query<Row>(
426
+ `WITH RECURSIVE v(oid, depth) AS (
427
+ SELECT r.ev_class, 0 FROM pg_catalog.pg_rewrite r WHERE r.oid = ANY($1::oid[]) AND r.ev_class <> $2::oid
428
+ UNION
429
+ SELECT r.ev_class, v.depth + 1 FROM v
430
+ JOIN pg_catalog.pg_depend d ON d.refclassid = 'pg_catalog.pg_class'::pg_catalog.regclass AND d.refobjid = v.oid AND d.classid = 'pg_catalog.pg_rewrite'::pg_catalog.regclass
431
+ JOIN pg_catalog.pg_rewrite r ON r.oid = d.objid AND r.ev_class <> v.oid
432
+ )
433
+ SELECT c.oid::text AS oid, n.nspname AS schema, c.relname AS name, c.relkind::text AS kind, max(v.depth) AS depth,
434
+ pg_catalog.pg_get_userbyid(c.relowner) AS owner,
435
+ ARRAY(SELECT CASE WHEN x.grantee = 0 THEN 'PUBLIC' ELSE pg_catalog.quote_ident(pg_catalog.pg_get_userbyid(x.grantee)) END || E'\\t' || x.privilege_type || E'\\t' || x.is_grantable::text
436
+ FROM pg_catalog.aclexplode(c.relacl) x WHERE x.grantee <> c.relowner)::text[] AS grants,
437
+ ARRAY(SELECT pg_catalog.pg_describe_object(d.classid, d.objid, d.objsubid) FROM pg_catalog.pg_depend d
438
+ WHERE d.refclassid = 'pg_catalog.pg_class'::pg_catalog.regclass AND d.refobjid = c.oid AND d.deptype = 'n'
439
+ AND d.classid NOT IN ('pg_catalog.pg_rewrite'::pg_catalog.regclass, 'pg_catalog.pg_type'::pg_catalog.regclass))::text[] AS others
440
+ FROM v JOIN pg_catalog.pg_class c ON c.oid = v.oid JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
441
+ GROUP BY c.oid, n.nspname, c.relname, c.relkind, c.relowner, c.relacl ORDER BY 5, 2, 3`,
442
+ [rewriteIds, oid],
443
+ );
444
+ const ownRules = await client.query<{ name: string }>("SELECT r.rulename AS name FROM pg_catalog.pg_rewrite r WHERE r.oid = ANY($1::oid[]) AND r.ev_class = $2::oid", [rewriteIds, oid]);
445
+ for (const r of ownRules) refused.push(`rule ${r.name} on ${n.schema}.${n.table} reads the column; drop it, migrate, then create it again`);
446
+ for (const r of rows) {
447
+ const name = `${String(r.schema)}.${String(r.name)}`;
448
+ if (r.kind === "m") {
449
+ refused.push(`materialized view ${name} reads the column; making it again would scan in the switch's transaction, so drop it, migrate, then declare it again`);
450
+ continue;
451
+ }
452
+ if (r.kind !== "v") {
453
+ refused.push(`${name} (relkind ${String(r.kind)}) reads the column`);
454
+ continue;
455
+ }
456
+ const others = (r.others as string[] | null) ?? [];
457
+ if (others.length > 0) refused.push(`view ${name} is used by ${others.join(", ")}, which dropping and creating the view again would break`);
458
+ const declared = input.objects.find((o) => (o.type === POSTGRES_ENTITY_TYPES.view || o.type === POSTGRES_ENTITY_TYPES.materializedView) && `${o.canonical.schema ?? input.defaultSchema}.${o.canonical.name}` === name);
459
+ if (!declared) {
460
+ refused.push(
461
+ `view ${name} reads ${rename ? `${from}, which the rename takes away` : "the column"}, and the build does not declare it; the switch makes each such view again from its declaration, so declare it (reading ${n.column}) in the build`,
462
+ );
463
+ continue;
464
+ }
465
+ if (declared.type !== POSTGRES_ENTITY_TYPES.view) {
466
+ refused.push(`view ${name} is declared as a ${declared.type}`);
467
+ continue;
468
+ }
469
+ views.push({
470
+ name,
471
+ ident: `${quoteIdent(String(r.schema))}.${quoteIdent(String(r.name))}`,
472
+ materialized: false,
473
+ depth: Number(r.depth),
474
+ declared,
475
+ owner: String(r.owner),
476
+ grants: ((r.grants as string[] | null) ?? []).map((g) => {
477
+ const [grantee, privilege, grantable] = g.split("\t") as [string, string, string];
478
+ return { grantee, privilege, grantable: grantable === "true" };
479
+ }),
480
+ });
481
+ }
482
+ }
483
+
484
+ for (const d of deps.filter((x) => x.kind === "other")) refused.push(`${d.what} uses the column; drop it, migrate, then create it again`);
485
+
486
+ // A new name already taken by something else stops the switch; say so now.
487
+ const renamed = carried.filter((c) => c.target !== c.name);
488
+ if (renamed.length > 0) {
489
+ const taken = await client.query<{ name: string }>(
490
+ `SELECT x.name FROM ROWS FROM (pg_catalog.unnest($1::text[]), pg_catalog.unnest($2::text[]), pg_catalog.unnest($3::oid[])) AS x(name, schema, rel)
491
+ WHERE EXISTS (SELECT 1 FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace s ON s.oid = c.relnamespace WHERE s.nspname = x.schema AND c.relname = x.name)
492
+ OR EXISTS (SELECT 1 FROM pg_catalog.pg_constraint k WHERE k.conrelid = x.rel AND k.conname = x.name)`,
493
+ [renamed.map((c) => c.target), renamed.map((c) => c.schema), renamed.map((c) => c.tableOid)],
494
+ );
495
+ for (const t of taken) refused.push(`${t.name}, the name ${renamed.find((c) => c.target === t.name)!.name} takes after the rename, is already used; rename that object first`);
496
+ }
497
+
498
+ return { carried, views, refused, ...(sequence ? { sequence } : {}) };
499
+ }
500
+
501
+ // ── statements ──────────────────────────────────────────────────────
502
+
503
+ /** `ALTER TABLE ... ADD CONSTRAINT <working> <body> NOT VALID`: a check or foreign key on the new column. */
504
+ export const addCarriedConstraint = (c: CarriedObject): string => `ALTER TABLE ${c.table} ADD CONSTRAINT ${quoteIdent(c.working)} ${c.definition} NOT VALID`;
505
+
506
+ const commentOn = (what: string, text: string | undefined) => `COMMENT ON ${what} IS ${text === undefined ? "NULL" : pgString(text)}`;
507
+ const indexIdent = (c: CarriedObject, name: string) => `${quoteIdent(c.schema)}.${quoteIdent(name)}`;
508
+
509
+ /**
510
+ * The switch's statements for the carried objects, around the swap of the
511
+ * columns: `before` drops the views and swaps every index and constraint;
512
+ * `after` creates the views again from their declarations once the column
513
+ * they read has its name.
514
+ *
515
+ * Foreign keys that reference the column go first: the old key constraint
516
+ * cannot be dropped while one depends on its index.
517
+ */
518
+ export function carriedSwitchStatements(
519
+ carried: readonly CarriedObject[],
520
+ views: readonly CarriedView[],
521
+ change: "rename" | "type",
522
+ oldComment: (c: CarriedObject) => string,
523
+ marker: OwnershipMarker | undefined,
524
+ ): { before: string[]; after: string[] } {
525
+ const before: string[] = [];
526
+ const after: string[] = [];
527
+ for (const v of [...views].sort((a, b) => b.depth - a.depth)) before.push(`DROP VIEW ${v.ident}`);
528
+ const order: CarriedKind[] = ["foreign-key", "check", "key", "index"];
529
+ const sorted = [...carried].sort((a, b) => order.indexOf(a.kind) - order.indexOf(b.kind));
530
+ for (const c of sorted) {
531
+ const keepOld = change === "rename" && (c.kind === "index" || (c.kind === "key" && !c.primary));
532
+ if (c.kind === "check" || c.kind === "foreign-key") {
533
+ before.push(`ALTER TABLE ${c.table} DROP CONSTRAINT ${quoteIdent(c.name)}`);
534
+ before.push(`ALTER TABLE ${c.table} RENAME CONSTRAINT ${quoteIdent(c.working)} TO ${quoteIdent(c.target)}`);
535
+ before.push(commentOn(`CONSTRAINT ${quoteIdent(c.target)} ON ${c.table}`, c.comment));
536
+ } else if (c.kind === "key") {
537
+ if (keepOld) {
538
+ before.push(`ALTER TABLE ${c.table} RENAME CONSTRAINT ${quoteIdent(c.name)} TO ${quoteIdent(carriedOldName(c.name))}`);
539
+ before.push(commentOn(`CONSTRAINT ${quoteIdent(carriedOldName(c.name))} ON ${c.table}`, oldComment(c)));
540
+ } else {
541
+ before.push(`ALTER TABLE ${c.table} DROP CONSTRAINT ${quoteIdent(c.name)}`);
542
+ }
543
+ before.push(`ALTER TABLE ${c.table} ADD CONSTRAINT ${quoteIdent(c.target)} ${c.primary ? "PRIMARY KEY" : "UNIQUE"} USING INDEX ${quoteIdent(c.working)}${c.deferral ?? ""}`);
544
+ before.push(commentOn(`CONSTRAINT ${quoteIdent(c.target)} ON ${c.table}`, c.comment));
545
+ before.push(commentOn(`INDEX ${indexIdent(c, c.target)}`, c.indexComment));
546
+ } else {
547
+ if (keepOld) {
548
+ before.push(`ALTER INDEX ${indexIdent(c, c.name)} RENAME TO ${quoteIdent(carriedOldName(c.name))}`);
549
+ before.push(commentOn(`INDEX ${indexIdent(c, carriedOldName(c.name))}`, oldComment(c)));
550
+ } else {
551
+ before.push(`DROP INDEX ${indexIdent(c, c.name)}`);
552
+ }
553
+ before.push(`ALTER INDEX ${indexIdent(c, c.working)} RENAME TO ${quoteIdent(c.target)}`);
554
+ before.push(commentOn(`INDEX ${indexIdent(c, c.target)}`, c.comment));
555
+ }
556
+ if (c.replicaIdentity) before.push(`ALTER TABLE ${c.table} REPLICA IDENTITY USING INDEX ${quoteIdent(c.target)}`);
557
+ if (c.clustered) before.push(`ALTER TABLE ${c.table} CLUSTER ON ${quoteIdent(c.target)}`);
558
+ }
559
+ for (const v of [...views].sort((a, b) => a.depth - b.depth)) {
560
+ for (const s of createSteps(v.declared, marker)) after.push(s.sql);
561
+ after.push(`ALTER VIEW ${v.ident} OWNER TO ${quoteIdent(v.owner)}`);
562
+ for (const g of v.grants) after.push(`GRANT ${g.privilege} ON TABLE ${v.ident} TO ${g.grantee}${g.grantable ? " WITH GRANT OPTION" : ""}`);
563
+ }
564
+ return { before, after };
565
+ }
566
+
567
+ /** What the gate binds about the carried objects: each one's kind, names and definition, and each view. */
568
+ export function carriedSubject(d: Pick<Dependents, "carried" | "views" | "sequence">): unknown {
569
+ return {
570
+ ...(d.sequence ? { sequence: { kind: d.sequence.kind, name: `${d.sequence.schema}.${d.sequence.name}` } } : {}),
571
+ carried: d.carried.map((c) => ({ kind: c.kind, table: c.tableName, name: c.name, target: c.target, definition: c.definition, ...(c.primary !== undefined ? { primary: c.primary } : {}) })),
572
+ views: d.views.map((v) => ({ name: v.name, ddl: v.declared.ddl })),
573
+ };
574
+ }
575
+
576
+ /** Whether a declared column is NOT NULL once it is switched: declared so, an identity column, or part of a carried primary key. */
577
+ export const requiresNotNull = (column: ColumnDef, carried: readonly CarriedObject[]): boolean =>
578
+ column.notNull === true || column.generated?.kind === "identity" || SERIAL_TYPES[column.type ?? ""] !== undefined || carried.some((c) => c.kind === "key" && c.primary === true);
579
+
580
+ /** The integer type of each `serial` spelling: what the column holds, and the sequence's type. */
581
+ export const SERIAL_TYPES: Readonly<Record<string, string>> = {
582
+ smallserial: "smallint",
583
+ serial2: "smallint",
584
+ serial: "integer",
585
+ serial4: "integer",
586
+ bigserial: "bigint",
587
+ serial8: "bigint",
588
+ };
589
+
590
+ /** A declared column's type as the server holds it: a `serial` spelling is its integer type. */
591
+ export const storedType = (type: string | undefined): string | undefined => (type === undefined ? undefined : (SERIAL_TYPES[type.replace(/^(public|pg_catalog)\./, "")] ?? type));
592
+
593
+ /** How far a carried object's working copy has got on the server. */
594
+ export interface CarriedState {
595
+ /** The working object is there. */
596
+ present: boolean;
597
+ /** An index: valid (its CONCURRENTLY build finished). A constraint: validated. */
598
+ ready: boolean;
599
+ /** It carries this migration's trailer; an index built and killed before its comment is adopted when its definition is the one expected. */
600
+ marked: boolean;
601
+ }
602
+
603
+ /**
604
+ * The working copies of the carried objects on the server, by working name.
605
+ * One under a working name that is somebody else's is refused, as for the
606
+ * other working objects (`./observe.ts`).
607
+ */
608
+ export async function carriedStates(
609
+ client: PostgresClient,
610
+ carried: readonly CarriedObject[],
611
+ ours: (comment: string | undefined) => "ours" | "theirs" | "none",
612
+ refuse: (what: string) => never,
613
+ ): Promise<Map<string, CarriedState>> {
614
+ const out = new Map<string, CarriedState>();
615
+ const indexes = carried.filter((c) => c.kind === "index" || c.kind === "key");
616
+ const constraints = carried.filter((c) => c.kind === "check" || c.kind === "foreign-key");
617
+ if (indexes.length > 0) {
618
+ const rows = await client.query<{ name: string; valid: boolean; comment: string | null; def: string }>(
619
+ `SELECT c.relname AS name, i.indisvalid AS valid, pg_catalog.obj_description(c.oid, 'pg_class') AS comment, pg_catalog.pg_get_indexdef(c.oid) AS def
620
+ FROM ROWS FROM (pg_catalog.unnest($1::text[]), pg_catalog.unnest($2::text[])) AS x(name, schema)
621
+ JOIN pg_catalog.pg_namespace s ON s.nspname = x.schema JOIN pg_catalog.pg_class c ON c.relnamespace = s.oid AND c.relname = x.name
622
+ LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid`,
623
+ [indexes.map((c) => c.working), indexes.map((c) => c.schema)],
624
+ );
625
+ for (const r of rows) {
626
+ const c = indexes.find((x) => x.working === r.name)!;
627
+ const owner = ours(r.comment ?? undefined);
628
+ const expected = c.definition.replace(/ INDEX CONCURRENTLY /, " INDEX ");
629
+ if (owner === "theirs" || (owner === "none" && r.def !== expected)) refuse(`index ${c.schema}.${c.working}`);
630
+ out.set(c.working, { present: true, ready: r.valid === true, marked: owner === "ours" });
631
+ }
632
+ }
633
+ if (constraints.length > 0) {
634
+ const rows = await client.query<{ name: string; rel: string; validated: boolean; comment: string | null }>(
635
+ `SELECT k.conname AS name, k.conrelid::text AS rel, k.convalidated AS validated, pg_catalog.obj_description(k.oid, 'pg_constraint') AS comment
636
+ FROM ROWS FROM (pg_catalog.unnest($1::text[]), pg_catalog.unnest($2::oid[])) AS x(name, rel) JOIN pg_catalog.pg_constraint k ON k.conrelid = x.rel AND k.conname = x.name`,
637
+ [constraints.map((c) => c.working), constraints.map((c) => c.tableOid)],
638
+ );
639
+ for (const r of rows) {
640
+ const c = constraints.find((x) => x.working === r.name && x.tableOid === r.rel)!;
641
+ if (ours(r.comment ?? undefined) !== "ours") refuse(`constraint ${c.working} on ${c.tableName}`);
642
+ out.set(c.working, { present: true, ready: r.validated === true || !c.validated, marked: true });
643
+ }
644
+ }
645
+ return out;
646
+ }
647
+
648
+ /** The carried objects whose working copy is not there, not marked, or not yet valid. */
649
+ export const carriedNotReady = (carried: readonly CarriedObject[], states: ReadonlyMap<string, CarriedState>): CarriedObject[] =>
650
+ carried.filter((c) => {
651
+ const s = states.get(c.working);
652
+ return !s || !s.ready || !s.marked;
653
+ });