@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,111 @@
1
+ /**
2
+ * `describeResources()` for the Postgres dialect: which declared objects exist
3
+ * on the environment's server.
4
+ *
5
+ * One catalog read per run (`./catalog.ts`), then a lookup per declared
6
+ * entity, so N entities are a fixed handful of queries. An object the catalog
7
+ * does not list is absent, and the `queried` address names the server and the
8
+ * object asked for. A server that cannot be reached, or refuses the
9
+ * credentials, leaves every entity unobserved with that reason: never absent.
10
+ *
11
+ * Ownership is chant's marker, the trailer on the object's comment
12
+ * (`../../core/ownership.ts`): `owned` when the comment carries it, `foreign`
13
+ * when it does not. With `owned: true` a foreign object is withheld as
14
+ * `filtered`. An object another tool keeps (an ORM's revision table) is
15
+ * foreign whatever its comment says.
16
+ */
17
+
18
+ import {
19
+ observeEntities,
20
+ type DeclaredEntity,
21
+ type DescribeResourcesResult,
22
+ type EntityObservation,
23
+ type ObserverAdapter,
24
+ } from "@intentius/chant/observation";
25
+ import { bindPostgres, classifyPostgresFailure, redactUrl, type BindOptions, type PostgresTarget } from "./bind";
26
+ import { liveKey, markProviderOwned, readLiveSchema, type LivePgObject } from "./catalog";
27
+ import { POSTGRES_ENTITY_TYPES } from "../entity-types";
28
+ import { isChantManaged, readMarker, stripMarker } from "../../core/ownership";
29
+ import { identValue } from "../parser";
30
+
31
+ interface Bound {
32
+ target: PostgresTarget;
33
+ byKey: Map<string, LivePgObject>;
34
+ }
35
+
36
+ /** The schema and name a declared entity is created as; a bare name is in the default schema. */
37
+ export function declaredAddress(entity: { type: string; props: Record<string, unknown> }, defaultSchema: string): { schema?: string; name: string } {
38
+ const name = String(entity.props.name ?? "");
39
+ if (entity.type === POSTGRES_ENTITY_TYPES.schema || entity.type === POSTGRES_ENTITY_TYPES.extension) return { name };
40
+ return { schema: typeof entity.props.schema === "string" ? entity.props.schema : identValue(defaultSchema), name };
41
+ }
42
+
43
+ /** A schema scope for the catalog read: the profile's schemas, else every schema the declarations name and the default one. */
44
+ export function scopeFor(target: PostgresTarget, entities: ReadonlyArray<{ type: string; props: Record<string, unknown> }>): string[] | undefined {
45
+ if (target.schemas) return target.schemas;
46
+ if (entities.length === 0) return undefined;
47
+ const out = new Set<string>([target.defaultSchema]);
48
+ for (const e of entities) {
49
+ const a = declaredAddress(e, target.defaultSchema);
50
+ if (e.type === POSTGRES_ENTITY_TYPES.schema) out.add(a.name);
51
+ else if (a.schema) out.add(a.schema);
52
+ }
53
+ return [...out].sort();
54
+ }
55
+
56
+ function adapter(options: BindOptions & { owned?: boolean; declared: DeclaredEntity[] }): ObserverAdapter<Bound> {
57
+ return {
58
+ async bind() {
59
+ const { target, client } = await bindPostgres(options);
60
+ try {
61
+ const live = markProviderOwned(await readLiveSchema(client, { schemas: scopeFor(target, options.declared.filter((d) => d.type.startsWith("Postgres::"))) }), target.provider);
62
+ return { target, byKey: new Map(live.map((o) => [liveKey(o.type, o.schema, o.name), o])) };
63
+ } finally {
64
+ await client.end();
65
+ }
66
+ },
67
+ classifyBindFailure: (err) => classifyPostgresFailure(err),
68
+ async read({ target, byKey }, entity): Promise<EntityObservation> {
69
+ if (!entity.type.startsWith("Postgres::")) return { unobserved: { reason: "unsupported-kind", detail: entity.type } };
70
+ const { schema, name } = declaredAddress(entity, target.defaultSchema);
71
+ const queried = `${redactUrl(target.endpoint.url)} ${schema ? `${schema}.` : ""}${name}`;
72
+ const live = byKey.get(liveKey(entity.type, schema, name));
73
+ if (!live) return { absent: true, queried };
74
+ const owned = !live.foreign && isChantManaged(live.comment);
75
+ if (options.owned && !owned) {
76
+ return {
77
+ unobserved: { reason: "filtered", detail: live.foreign ? `${live.foreign} keeps this object` : "the object's comment carries no chant ownership marker and owned was requested" },
78
+ queried,
79
+ };
80
+ }
81
+ const marker = readMarker(live.comment);
82
+ const comment = live.comment ? stripMarker(live.comment) : "";
83
+ return {
84
+ present: {
85
+ type: live.type,
86
+ physicalId: live.oid,
87
+ status: "PRESENT",
88
+ attributes: { oid: live.oid, ...(comment ? { comment } : {}), ...(live.foreign ? { keptBy: live.foreign } : {}) },
89
+ ownership: owned ? "owned" : "foreign",
90
+ ...(owned && marker?.stack ? { marker: { stack: marker.stack, ...(marker.env ? { env: marker.env } : {}) } } : {}),
91
+ },
92
+ queried,
93
+ };
94
+ },
95
+ };
96
+ }
97
+
98
+ export async function describeResources(
99
+ options: {
100
+ environment: string;
101
+ entityNames: string[];
102
+ entities: Map<string, { entityType: string; props: Record<string, unknown> }>;
103
+ owned?: boolean;
104
+ } & Omit<BindOptions, "environment">,
105
+ ): Promise<DescribeResourcesResult> {
106
+ const declared: DeclaredEntity[] = options.entityNames.map((name) => {
107
+ const entity = options.entities.get(name);
108
+ return { name, type: entity?.entityType ?? "", props: entity?.props ?? {} };
109
+ });
110
+ return observeEntities(declared, adapter({ ...options, declared }));
111
+ }
@@ -0,0 +1,198 @@
1
+ import { describe, expect, test } from "vitest";
2
+ import { describeObservationConformance } from "@intentius/chant-test-utils";
3
+ import { normalizeObservation } from "@intentius/chant/observation";
4
+ import { classifyPostgresFailure, PostgresBindingError, redactUrl, resolvePostgresTarget } from "./bind";
5
+ import { PostgresQueryError } from "./client";
6
+ import { describeResources } from "./describe-resources";
7
+ import { markProviderOwned, readLiveSchema, sequenceOptions, type LivePgObject } from "./catalog";
8
+ import { fakeClient, type FakeCatalog } from "../testing/fake-client";
9
+ import { dialectOfBinding, dialectOfEntities } from "../../live-dialect";
10
+ import { sqlPlugin } from "../../plugin";
11
+
12
+ const config = {
13
+ sql: {
14
+ profiles: {
15
+ prod: { url: "postgres://db.internal:5432/shop", user: { env: "PG_USER" }, password: { env: "PG_PASSWORD" }, schemas: ["app"] },
16
+ analytics: { url: "http://clickhouse:8123" },
17
+ },
18
+ },
19
+ };
20
+
21
+ describe("binding an environment to a Postgres server", () => {
22
+ test("a postgres:// profile, with its credentials from the environment", () => {
23
+ expect(resolvePostgresTarget({ environment: "prod", config, env: { PG_USER: "app", PG_PASSWORD: "s3cret" } })).toEqual({
24
+ endpoint: { url: "postgres://db.internal:5432/shop", user: "app", password: "s3cret" },
25
+ source: "sql.profiles.prod",
26
+ schemas: ["app"],
27
+ defaultSchema: "public",
28
+ });
29
+ });
30
+
31
+ test("a profile naming an unset credential is no-credentials; nothing bound is no-binding", () => {
32
+ expect(resolvePostgresTarget({ environment: "prod", config, env: {} })).toMatchObject({ reason: "no-credentials" });
33
+ expect(resolvePostgresTarget({ environment: "staging", config, env: {} })).toMatchObject({ reason: "no-binding" });
34
+ expect(resolvePostgresTarget({ environment: "staging", env: { POSTGRES_URL: "postgres://localhost/x" } })).toMatchObject({ source: "env POSTGRES_URL" });
35
+ });
36
+
37
+ test("a refused password is no-credentials, any other failure read-failed, and a URL is shown without its password", () => {
38
+ expect(classifyPostgresFailure(new PostgresQueryError("password authentication failed", "28P01")).reason).toBe("no-credentials");
39
+ expect(classifyPostgresFailure(new PostgresQueryError("connection refused")).reason).toBe("read-failed");
40
+ expect(classifyPostgresFailure(new PostgresBindingError({ reason: "no-binding", detail: "x" })).reason).toBe("no-binding");
41
+ expect(redactUrl("postgres://app:hunter2@db/shop")).toBe("postgres://app:***@db/shop");
42
+ });
43
+
44
+ test("the dialect a read is for: the declarations' type, else the binding", () => {
45
+ expect(dialectOfEntities(new Map([["a", { entityType: "Postgres::Table" }]]))).toBe("postgres");
46
+ expect(dialectOfEntities(new Map([["a", { entityType: "ClickHouse::Table" }]]))).toBe("clickhouse");
47
+ expect(dialectOfBinding({ environment: "prod", config })).toBe("postgres");
48
+ expect(dialectOfBinding({ environment: "analytics", config })).toBe("clickhouse");
49
+ expect(dialectOfBinding({ config: { sql: { dialect: "postgres" } }, env: {} })).toBe("postgres");
50
+ expect(dialectOfBinding({ env: { POSTGRES_URL: "postgres://x/y" } })).toBe("postgres");
51
+ expect(dialectOfBinding({ env: {} })).toBe("clickhouse");
52
+ });
53
+ });
54
+
55
+ describe("reading the catalog", () => {
56
+ test("a table prints as the statement that creates it, its comment's trailer taken off", async () => {
57
+ const [t] = await readLiveSchema(
58
+ fakeClient({ tables: [{ schema: "app", name: "users", comment: "Accounts [chant managed-by=chant stack=shop]", columns: [{ name: "id", type: "bigint", notnull: true }] }] }),
59
+ );
60
+ expect(t).toMatchObject({ type: "Postgres::Table", schema: "app", name: "users", comment: "Accounts [chant managed-by=chant stack=shop]" });
61
+ expect(t!.statement).toBe("CREATE TABLE app.users (\n id bigint NOT NULL\n);\nCOMMENT ON TABLE app.users IS 'Accounts'");
62
+ });
63
+
64
+ test("an ORM's revision table is read as that tool's", async () => {
65
+ const [t] = await readLiveSchema(fakeClient({ tables: [{ schema: "public", name: "_prisma_migrations" }] }));
66
+ expect(t!.foreign).toBe("Prisma Migrate");
67
+ });
68
+
69
+ test("sequence options at their defaults are left out", () => {
70
+ const p = { type: "bigint", start: "1", increment: "1", min: "1", max: "9223372036854775807", cache: "1", cycle: false };
71
+ expect(sequenceOptions(p, true)).toEqual([]);
72
+ expect(sequenceOptions({ ...p, type: "integer", max: "2147483647", start: "1000" }, true)).toEqual(["AS integer", "START WITH 1000"]);
73
+ expect(sequenceOptions({ ...p, increment: "-1", min: "-9223372036854775808", max: "-1", start: "-1" }, true)).toEqual(["INCREMENT BY -1"]);
74
+ });
75
+ });
76
+
77
+ const CATALOG: FakeCatalog = {
78
+ schemas: [{ name: "app" }],
79
+ tables: [
80
+ { schema: "app", name: "users", comment: "[chant managed-by=chant stack=shop env=prod]" },
81
+ { schema: "app", name: "legacy" },
82
+ { schema: "public", name: "schema_migrations" },
83
+ ],
84
+ };
85
+ const entity = (type: string, props: Record<string, unknown>) => ({ entityType: type, props });
86
+ const options = (names: Record<string, { entityType: string; props: Record<string, unknown> }>, owned = false) => ({
87
+ environment: "prod",
88
+ config,
89
+ env: { PG_USER: "app", PG_PASSWORD: "x" },
90
+ owned,
91
+ entityNames: Object.keys(names),
92
+ entities: new Map(Object.entries(names)),
93
+ connect: async () => fakeClient(CATALOG),
94
+ });
95
+ const DECLARED = {
96
+ app: entity("Postgres::Schema", { name: "app" }),
97
+ users: entity("Postgres::Table", { schema: "app", name: "users" }),
98
+ legacy: entity("Postgres::Table", { schema: "app", name: "legacy" }),
99
+ orders: entity("Postgres::Table", { schema: "app", name: "orders" }),
100
+ migrations: entity("Postgres::Table", { name: "schema_migrations" }),
101
+ };
102
+
103
+ describe("describeResources", () => {
104
+ test("present with its ownership, absent with the address asked", async () => {
105
+ const r = normalizeObservation(await describeResources(options(DECLARED)));
106
+ expect(r.resources.users).toMatchObject({ ownership: "owned", marker: { stack: "shop", env: "prod" } });
107
+ expect(r.resources.legacy).toMatchObject({ ownership: "foreign" });
108
+ expect(r.resources.migrations).toMatchObject({ ownership: "foreign", attributes: { keptBy: expect.stringMatching(/migration runner/) } });
109
+ expect(r.resources.orders).toBeUndefined();
110
+ expect(r.queried.orders).toBe("postgres://db.internal:5432/shop app.orders");
111
+ });
112
+
113
+ test("with owned, a foreign object is filtered, never absent", async () => {
114
+ const r = normalizeObservation(await describeResources(options(DECLARED, true)));
115
+ expect(r.unobserved.legacy).toMatchObject({ reason: "filtered" });
116
+ expect(r.unobserved.migrations?.detail).toMatch(/keeps this object/);
117
+ });
118
+ });
119
+
120
+ describeObservationConformance({
121
+ lexicon: "sql",
122
+ ownershipChannel: sqlPlugin.ownershipChannel,
123
+ scenarios: [
124
+ {
125
+ name: "Postgres: owned, foreign and absent",
126
+ declared: ["users", "legacy", "orders"],
127
+ expectPresent: ["users", "legacy"],
128
+ expectAbsent: ["orders"],
129
+ run: () => describeResources(options({ users: DECLARED.users, legacy: DECLARED.legacy, orders: DECLARED.orders })),
130
+ },
131
+ {
132
+ name: "Postgres: owned only",
133
+ declared: ["users", "legacy"],
134
+ owned: true,
135
+ expectPresent: ["users"],
136
+ expectUnobserved: ["legacy"],
137
+ expectMarker: { users: { stack: "shop", env: "prod" } },
138
+ run: () => describeResources(options({ users: DECLARED.users, legacy: DECLARED.legacy }, true)),
139
+ },
140
+ {
141
+ name: "Postgres: a server that refuses the password",
142
+ declared: ["users"],
143
+ expectUnobserved: ["users"],
144
+ run: () =>
145
+ describeResources({
146
+ ...options({ users: DECLARED.users }),
147
+ connect: async () => {
148
+ throw new PostgresQueryError("password authentication failed for user", "28P01");
149
+ },
150
+ }),
151
+ },
152
+ {
153
+ name: "Postgres: nothing bound",
154
+ declared: ["users"],
155
+ expectUnobserved: ["users"],
156
+ run: () => describeResources({ ...options({ users: DECLARED.users }), environment: "staging", env: {} }),
157
+ },
158
+ ],
159
+ });
160
+
161
+ describe("a managed provider's own objects (sql.provider)", () => {
162
+ const live: LivePgObject[] = [
163
+ { type: "Postgres::Schema", name: "auth", oid: "1", statement: "CREATE SCHEMA auth" },
164
+ { type: "Postgres::Table", schema: "auth", name: "users", oid: "2", statement: "CREATE TABLE auth.users (id uuid)" },
165
+ { type: "Postgres::Extension", name: "pg_net", oid: "3", statement: "CREATE EXTENSION pg_net WITH SCHEMA extensions" },
166
+ { type: "Postgres::Table", schema: "app", name: "orders", oid: "4", statement: "CREATE TABLE app.orders (id bigint)" },
167
+ ];
168
+
169
+ test("on Supabase, its schemas, what is in them and its extensions read as Supabase's", () => {
170
+ const marked = markProviderOwned(live, "supabase");
171
+ expect(marked.map((o) => [o.name, o.foreign])).toEqual([
172
+ ["auth", "Supabase"],
173
+ ["users", "Supabase"],
174
+ ["pg_net", "Supabase"],
175
+ ["orders", undefined],
176
+ ]);
177
+ expect(markProviderOwned(live, undefined).every((o) => o.foreign === undefined)).toBe(true);
178
+ });
179
+
180
+ test("the provider comes from the profile, else the namespace", () => {
181
+ expect(resolvePostgresTarget({ environment: "s", config: { sql: { provider: "supabase", profiles: { s: { url: "postgres://x/y" } } } }, env: {} })).toMatchObject({ provider: "supabase" });
182
+ expect(resolvePostgresTarget({ environment: "s", config: { sql: { provider: "rds", profiles: { s: { url: "postgres://x/y", provider: "neon" } } } }, env: {} })).toMatchObject({ provider: "neon" });
183
+ });
184
+
185
+ test("describeResources reports a declared object in a provider schema as foreign", async () => {
186
+ const r = normalizeObservation(
187
+ await describeResources({
188
+ environment: "prod",
189
+ config: { sql: { provider: "supabase", profiles: { prod: { url: "postgres://db/shop" } } } },
190
+ env: {},
191
+ entityNames: ["authUsers"],
192
+ entities: new Map([["authUsers", entity("Postgres::Table", { schema: "auth", name: "users" })]]),
193
+ connect: async () => fakeClient({ tables: [{ schema: "auth", name: "users", comment: "[chant managed-by=chant]" }] }),
194
+ }),
195
+ );
196
+ expect(r.resources.authUsers).toMatchObject({ ownership: "foreign", attributes: { keptBy: "Supabase" } });
197
+ });
198
+ });
@@ -0,0 +1,111 @@
1
+ /**
2
+ * The live round trip (#3279): a schema on one Postgres database is imported
3
+ * as chant declarations, built, and applied to a second, empty database;
4
+ * both catalogs then print the same statements for every object, exporting
5
+ * the second gives back the same declarations, every declared object is
6
+ * present, and the deep read of the applied database reports no drift from
7
+ * the declarations.
8
+ *
9
+ * Needs Docker; skips cleanly without it. One throwaway `postgres` container
10
+ * at the pin (18.6, by tag and digest), removed afterwards even on failure.
11
+ */
12
+
13
+ import { mkdirSync, rmSync, writeFileSync } from "node:fs";
14
+ import { join } from "node:path";
15
+ import { afterAll, beforeAll, describe, expect, test } from "vitest";
16
+ import { build } from "@intentius/chant/build";
17
+ import type { SerializerResult } from "@intentius/chant/serializer";
18
+ import { dockerAvailable, startTestPostgres, type TestPostgres } from "../testing/server";
19
+ import { ROUNDTRIP_SCHEMA } from "../testing/roundtrip-schema";
20
+ import { exportResources } from "../import/live-export";
21
+ import { PostgresGenerator } from "../import/generator";
22
+ import { readLiveSchema } from "./catalog";
23
+ import { describeResources } from "./describe-resources";
24
+ import { observeResourcesDeep } from "../plan/deep";
25
+ import { sqlPlugin } from "../../plugin";
26
+ import { POSTGRES_DDL_FILE, sqlSerializer } from "../../serializer";
27
+
28
+ const enabled = await dockerAvailable();
29
+ const projectDir = join(import.meta.dirname, "..", "..", "..", `.pg-roundtrip-tmp-${process.pid}`);
30
+ let server: TestPostgres | undefined;
31
+
32
+ beforeAll(async () => {
33
+ if (!enabled) return;
34
+ server = await startTestPostgres();
35
+ const admin = await server.connect();
36
+ await admin.query("CREATE DATABASE source");
37
+ await admin.query("CREATE DATABASE target");
38
+ await admin.end();
39
+ const source = await server.connect("source");
40
+ await source.query(ROUNDTRIP_SCHEMA);
41
+ await source.end();
42
+ }, 600_000);
43
+
44
+ afterAll(async () => {
45
+ await server?.stop();
46
+ rmSync(projectDir, { recursive: true, force: true });
47
+ });
48
+
49
+ const profile = (db: string) => ({
50
+ config: { sql: { profiles: { rt: { url: server!.endpoint(db).url, password: { env: "PG_RT_PASSWORD" } } } } },
51
+ env: { PG_RT_PASSWORD: server!.endpoint(db).password },
52
+ });
53
+
54
+ /** The props a deep diff compares: the declaration's, less what the hooks prune. */
55
+ const PRUNED = new Set(["ddl", "source", "lineage", "reads", "concurrently", "orReplace", "ifNotExists"]);
56
+ const compared = (props: Record<string, unknown>) =>
57
+ JSON.parse(JSON.stringify(Object.fromEntries(Object.entries(props).filter(([k]) => !PRUNED.has(k))), (_k, v: unknown) =>
58
+ v !== null && typeof v === "object" && "sqlName" in (v as object) && "entityType" in (v as object) ? `ref:${(v as { sqlName: string }).sqlName}` : v,
59
+ )) as Record<string, unknown>;
60
+
61
+ async function catalog(db: string): Promise<Record<string, string>> {
62
+ const client = await server!.connect(db);
63
+ try {
64
+ return Object.fromEntries((await readLiveSchema(client)).filter((o) => !o.foreign).map((o) => [`${o.type} ${o.schema ?? ""}.${o.name}`, o.statement]));
65
+ } finally {
66
+ await client.end();
67
+ }
68
+ }
69
+
70
+ describe.skipIf(!enabled)("import, build, apply, and the catalog is unchanged", () => {
71
+ test("the round trip", async () => {
72
+ // Import: the source database's schema as declarations. The ORM's table is left out, with a warning.
73
+ const exported = await exportResources({ environment: "rt", ...profile("source") });
74
+ expect(exported.warnings?.some((w) => /_prisma_migrations is kept by Prisma Migrate/.test(w))).toBe(true);
75
+ const [file] = new PostgresGenerator().generate(exported);
76
+ mkdirSync(join(projectDir, "src"), { recursive: true });
77
+ writeFileSync(join(projectDir, "chant.config.ts"), 'export default { lexicons: ["sql"] };\n');
78
+ writeFileSync(join(projectDir, "src", file!.path), file!.content);
79
+
80
+ // Build: the declarations fold to the statements.
81
+ const result = await build(join(projectDir, "src"), [sqlSerializer], undefined, { fold: true, intrinsics: sqlPlugin.intrinsics!(), lexicons: ["sql"] });
82
+ expect(result.errors).toEqual([]);
83
+ const out = result.outputs.get("sql") as SerializerResult;
84
+
85
+ // Apply: run the statements, in the order the build wrote them, on the empty database.
86
+ const target = await server!.connect("target");
87
+ await target.query(out.files![POSTGRES_DDL_FILE]!);
88
+ await target.end();
89
+
90
+ // The catalog is unchanged.
91
+ expect(await catalog("target")).toEqual(await catalog("source"));
92
+
93
+ // Exporting the applied database gives back the same declarations.
94
+ const again = await exportResources({ environment: "rt", ...profile("target") });
95
+ expect(new PostgresGenerator().generate(again)[0]!.content).toBe(file!.content);
96
+
97
+ // Every declared object is present: nothing to create.
98
+ const entities = new Map(
99
+ [...result.entities].map(([k, v]) => [k, { entityType: v.entityType, props: (v as unknown as { props: Record<string, unknown> }).props }]),
100
+ );
101
+ const observed = await describeResources({ environment: "rt", entityNames: [...entities.keys()], entities, ...profile("target") });
102
+ expect(Object.keys((observed as { resources: object }).resources).sort()).toEqual([...entities.keys()].sort());
103
+
104
+ // The deep read reports no property drift from the declarations.
105
+ const deep = await observeResourcesDeep({ environment: "rt", entityNames: [...entities.keys()], entities, ...profile("target") });
106
+ expect(deep.unobserved ?? {}).toEqual({});
107
+ for (const [name, e] of entities) {
108
+ expect(compared(deep.resources[name]!.properties), name).toEqual(JSON.parse(JSON.stringify(compared(e.props))));
109
+ }
110
+ }, 600_000);
111
+ });
@@ -0,0 +1,233 @@
1
+ /**
2
+ * The backfill and the verification of the expand-and-contract migration
3
+ * (#3281).
4
+ *
5
+ * ## Backfill
6
+ *
7
+ * The rows that were in the table before the dual write started are filled
8
+ * in batches: one range of the primary key per batch (`./batches.ts`:
9
+ * `[b * size, (b + 1) * size)` of an integer key, else between boundaries
10
+ * recorded in the receipt store), so a batch is the same rows on every run
11
+ * however many rows were written since. Each batch is one transaction:
12
+ *
13
+ * UPDATE t SET new = <expression> WHERE key >= lo AND key < hi AND new IS DISTINCT FROM <expression>;
14
+ * INSERT INTO __chant_receipts ... -- the batch's receipt, last
15
+ * COMMIT;
16
+ *
17
+ * under `lock_timeout` (a row an application transaction holds makes the
18
+ * batch give up and try again rather than queue behind it) and the
19
+ * statement timeout for a catalog change, which bounds how long one batch
20
+ * may hold its row locks.
21
+ *
22
+ * Per batch, the cycle core's `effect()` step runs
23
+ * (concepts/effect-receipts.mdx): read the receipt, skip the batch when it
24
+ * matches, otherwise update and write the receipt last, on success only.
25
+ * The batches are only known when the run reads the table, so the cycle runs
26
+ * here over the shared core's `ReceiptStore` seam (`./receipts.ts`), as the
27
+ * ClickHouse rebuild's does per partition. Unlike ClickHouse, the receipt
28
+ * commits in the batch's own transaction: a run killed anywhere leaves a
29
+ * batch with its receipt or neither, and a resumed backfill starts at the
30
+ * first batch with no receipt and updates no batch twice.
31
+ *
32
+ * Before each batch the backfill waits while a replica is further behind
33
+ * than the bound (`./replication.ts`).
34
+ *
35
+ * ## Verification
36
+ *
37
+ * One statement over the whole table, one snapshot: the rows, the rows whose
38
+ * new column differs from the expression over the old one, the new column's
39
+ * NULLs, and a checksum (the sum of a 64-bit hash of each value) of the new
40
+ * column and of the expression. Any difference, or a NULL where the column
41
+ * is declared NOT NULL, fails the run, whose onFailure then drops what the
42
+ * expand added. The dual-write trigger keeps writes going during the
43
+ * verification consistent; the statement reads the table under ACCESS SHARE
44
+ * only.
45
+ */
46
+
47
+ import { EffectReceipt, receiptExpectation } from "@intentius/chant/effect-receipt";
48
+ import { computePlanDigest } from "@intentius/chant/op";
49
+ import { col } from "./names";
50
+ import { MigrationRefusal, migrationPlanSubject, type MigrationObservation } from "./observe";
51
+ import { postgresReceiptStore, receiptAddress, type PostgresReceiptStore } from "./receipts";
52
+ import { waitForReplicas } from "./replication";
53
+ import { batchPrefix, identityOf, inTransaction, observe, type MigrationRun } from "./steps";
54
+ import { carriedNotReady, requiresNotNull } from "./carry";
55
+ import { integerBatches, isIntegerKey, recordedBatches, type Batch } from "./batches";
56
+
57
+ export interface BackfillResult {
58
+ state: MigrationObservation["state"];
59
+ /** Batches of the table's key ranges that hold rows. */
60
+ batches: number;
61
+ /** Batches filled in this run. */
62
+ filled: number;
63
+ /** Batches skipped: their receipt matched. */
64
+ skipped: number;
65
+ /** Rows this run updated. */
66
+ rows: number;
67
+ /** How long the backfill paused for replicas, in ms. */
68
+ pausedMs: number;
69
+ }
70
+
71
+ /** The effect a batch is, and its receipt's address suffix. */
72
+ export const batchEffect = (key: string, batch: string): string => `migrate/${key}/${batch}`;
73
+
74
+ /** The receipt's expected value for one batch: bound to the table, the new column's attribute number, the batch's rows and the expression. */
75
+ export function batchExpectation(o: MigrationObservation, batch: Pick<Batch, "id" | "inputs">): string {
76
+ const effect = batchEffect(o.names.key, batch.id);
77
+ return receiptExpectation(
78
+ EffectReceipt(effect, {
79
+ effect,
80
+ flavor: "hash",
81
+ inputs: { migration: o.names.key, table: o.oid, column: o.newColumn!.attnum, ...batch.inputs, expression: o.expression },
82
+ }),
83
+ );
84
+ }
85
+
86
+ /** The address suffix of the recorded batch boundaries of a key that is not one integer column. */
87
+ export const BATCHES_RECORD = "batches";
88
+
89
+ export interface BackfillDeps {
90
+ /** The receipt store. Default: `<schema>.__chant_receipts` over the run's connection. */
91
+ receipts?: PostgresReceiptStore;
92
+ /** Called after a batch's receipt is written and before its transaction commits; a test kills the run here. */
93
+ beforeCommit?: (batch: string) => void | Promise<void>;
94
+ /** Called after each batch commits; a test interrupts the backfill here. */
95
+ afterBatch?: (batch: string) => void | Promise<void>;
96
+ /** Wait for replicas with this (tests). */
97
+ waitForReplicas?: typeof waitForReplicas;
98
+ }
99
+
100
+ export async function backfill(run: MigrationRun, deps: BackfillDeps = {}): Promise<BackfillResult> {
101
+ const o = await observe(run);
102
+ const result: BackfillResult = { state: o.state, batches: 0, filled: 0, skipped: 0, rows: 0, pausedMs: 0 };
103
+ if (o.state !== "migrate") return result;
104
+ const n = o.names;
105
+ if (!o.newColumn) throw new MigrationRefusal(`${n.key}: the new column is not there yet; the Expand phase adds it`);
106
+ if (!o.trigger) throw new MigrationRefusal(`${n.key}: the dual write is not on; the Dual write phase starts it, and the backfill fills only rows written before it`);
107
+ if (!Number.isInteger(run.batchSize) || run.batchSize < 1) throw new MigrationRefusal(`${n.key}: batchSize must be a positive integer, got ${run.batchSize}`);
108
+
109
+ const identity = identityOf(run.marker);
110
+ const receipts = deps.receipts ?? postgresReceiptStore(run.client, n.schema, identity, run.runId ? { runId: run.runId } : {});
111
+ await receipts.ensure();
112
+ const recorded = await receipts.readAll(batchPrefix(identity, n.key));
113
+
114
+ const batches = isIntegerKey(o.keyColumns)
115
+ ? await integerBatches(run.client, n.qualifiedTable, o.keyColumns[0]!, run.batchSize)
116
+ : (
117
+ await recordedBatches(run.client, {
118
+ table: n.qualifiedTable,
119
+ oid: o.oid,
120
+ attnum: o.newColumn.attnum,
121
+ keys: o.keyColumns,
122
+ size: run.batchSize,
123
+ effect: batchEffect(n.key, BATCHES_RECORD),
124
+ receipts,
125
+ log: run.log,
126
+ ...(run.signal ? { signal: run.signal } : {}),
127
+ })
128
+ ).batches;
129
+ result.batches = batches.length;
130
+ const wait = deps.waitForReplicas ?? waitForReplicas;
131
+ const target = `${col(n.newColumn)}`;
132
+
133
+ for (const b of batches) {
134
+ run.signal?.throwIfAborted();
135
+ const effect = batchEffect(n.key, b.id);
136
+ const expectation = batchExpectation(o, b);
137
+ if (recorded.get(receiptAddress(identity, effect)) === expectation) {
138
+ result.skipped++;
139
+ continue;
140
+ }
141
+ if (run.replicationLag) result.pausedMs += await wait(run.client, run.replicationLag, { log: run.log, ...(run.signal ? { signal: run.signal } : {}) });
142
+ const updated = await inTransaction(run, async (exec) => {
143
+ const [row] = await exec(
144
+ `WITH u AS (UPDATE ${n.qualifiedTable} SET ${target} = (${o.expression}) WHERE ${b.where} AND ${target} IS DISTINCT FROM (${o.expression}) RETURNING 1) ` +
145
+ "SELECT count(*)::int AS n FROM u",
146
+ b.params,
147
+ );
148
+ // The receipt, last, in the batch's own transaction.
149
+ await receipts.write({ name: effect, effect, flavor: "hash", inputs: {} }, expectation);
150
+ await deps.beforeCommit?.(b.id);
151
+ return Number(row?.n ?? 0);
152
+ });
153
+ result.rows += updated;
154
+ result.filled++;
155
+ await deps.afterBatch?.(b.id);
156
+ }
157
+ run.log(`-- backfill of ${n.key}: ${result.batches} batch(es), ${result.filled} filled (${result.rows} row(s)), ${result.skipped} already filled`);
158
+ return result;
159
+ }
160
+
161
+ // ── verify ─────────────────────────────────────────────────────────────
162
+
163
+ export interface VerifyResult {
164
+ state: MigrationObservation["state"];
165
+ /** The digest the switch gate binds: the plan and the verified new column. Absent once the switch has run. */
166
+ planDigest?: string;
167
+ rows: number;
168
+ /** Rows whose new column differs from the expression over the old one. */
169
+ mismatched: number;
170
+ /** Rows whose new column is NULL. */
171
+ nulls: number;
172
+ /** The sum of a 64-bit hash of every new value, and of every value the expression gives. */
173
+ checksum: string;
174
+ expected: string;
175
+ /** One line for the run record and the gate. */
176
+ summary: string;
177
+ }
178
+
179
+ /** A verification that found the columns different. */
180
+ export class MigrationVerificationError extends Error {
181
+ constructor(
182
+ readonly key: string,
183
+ readonly result: Omit<VerifyResult, "summary" | "planDigest">,
184
+ reason: string,
185
+ ) {
186
+ super(`${key}: ${reason}. Nothing was switched; onFailure drops what the expand added, and the next run starts again.`);
187
+ this.name = "MigrationVerificationError";
188
+ }
189
+ }
190
+
191
+ export async function verifyMigration(run: MigrationRun): Promise<VerifyResult> {
192
+ const o = await observe(run);
193
+ const empty = { rows: 0, mismatched: 0, nulls: 0, checksum: "0", expected: "0" };
194
+ if (o.state !== "migrate") return { state: o.state, ...empty, summary: `nothing to verify: ${o.state}` };
195
+ const n = o.names;
196
+ if (!o.newColumn || !o.trigger) throw new MigrationRefusal(`${n.key}: the new column and its dual write are not there; the Expand and Dual write phases make them`);
197
+ const nw = col(n.newColumn);
198
+ const [row] = await inTransaction(
199
+ run,
200
+ (exec) =>
201
+ exec(
202
+ `SELECT count(*)::text AS rows, count(*) FILTER (WHERE ${nw} IS DISTINCT FROM (${o.expression}))::text AS mismatched,
203
+ count(*) FILTER (WHERE ${nw} IS NULL)::text AS nulls,
204
+ COALESCE(sum(pg_catalog.hashtextextended(${nw}::text, 0)), 0)::text AS checksum,
205
+ COALESCE(sum(pg_catalog.hashtextextended((${o.expression})::text, 0)), 0)::text AS expected
206
+ FROM ${n.qualifiedTable}`,
207
+ ),
208
+ { scan: true },
209
+ );
210
+ const r = { rows: Number(row?.rows ?? 0), mismatched: Number(row?.mismatched ?? 0), nulls: Number(row?.nulls ?? 0), checksum: String(row?.checksum ?? "0"), expected: String(row?.expected ?? "0") };
211
+ if (r.mismatched > 0 || r.checksum !== r.expected) {
212
+ throw new MigrationVerificationError(n.key, { state: o.state, ...r }, `${r.mismatched} of ${r.rows} row(s) have ${n.newColumn} different from ${o.expression} (checksums ${r.checksum} and ${r.expected})`);
213
+ }
214
+ if (requiresNotNull(o.column, o.carried) && r.nulls > 0) {
215
+ throw new MigrationVerificationError(n.key, { state: o.state, ...r }, `${r.nulls} of ${r.rows} row(s) have ${n.newColumn} NULL, and ${n.column} is declared NOT NULL or is in the primary key`);
216
+ }
217
+ const notReady = carriedNotReady(o.carried, o.carriedStates);
218
+ if (notReady.length > 0) {
219
+ throw new MigrationRefusal(`${n.key}: ${notReady.map((c) => `${c.kind} ${c.working}`).join(", ")} on the new column is not there or not yet valid; the Carry over phase makes them`);
220
+ }
221
+ const carried =
222
+ o.carried.length > 0 || o.views.length > 0
223
+ ? `; ${o.carried.map((c) => `${c.kind} ${c.name}${c.target !== c.name ? ` (as ${c.target})` : ""}`).join(", ") || "no index or constraint"} carried over${o.views.length > 0 ? `, view(s) ${o.views.map((v) => v.name).join(", ")} made again at the switch` : ""}`
224
+ : "";
225
+ const summary = `${n.key}: ${r.rows} row(s), ${n.newColumn} equal to ${o.expression} in every one (checksum ${r.checksum})${carried}`;
226
+ run.log(`-- ${summary}`);
227
+ return {
228
+ state: o.state,
229
+ planDigest: computePlanDigest("postgres-migration", { plan: migrationPlanSubject(o), table: o.oid, column: o.newColumn.attnum, verified: { mismatched: 0 } }),
230
+ ...r,
231
+ summary,
232
+ };
233
+ }