@supabase/pg-delta 1.0.0-alpha.1 → 1.0.0-alpha.10

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 (664) hide show
  1. package/README.md +41 -2
  2. package/dist/cli/app.js +26 -3
  3. package/dist/cli/bin/cli.js +5 -0
  4. package/dist/cli/commands/catalog-export.d.ts +5 -0
  5. package/dist/cli/commands/catalog-export.js +64 -0
  6. package/dist/cli/commands/declarative-apply.d.ts +6 -0
  7. package/dist/cli/commands/declarative-apply.js +288 -0
  8. package/dist/cli/commands/declarative-export.d.ts +5 -0
  9. package/dist/cli/commands/declarative-export.js +245 -0
  10. package/dist/cli/commands/plan.js +40 -6
  11. package/dist/cli/exit-code.d.ts +2 -0
  12. package/dist/cli/exit-code.js +7 -0
  13. package/dist/cli/formatters/tree/tree.js +3 -2
  14. package/dist/cli/utils/apply-display.d.ts +52 -0
  15. package/dist/cli/utils/apply-display.js +183 -0
  16. package/dist/cli/utils/export-display.d.ts +43 -0
  17. package/dist/cli/utils/export-display.js +202 -0
  18. package/dist/cli/utils/resolve-input.d.ts +7 -0
  19. package/dist/cli/utils/resolve-input.js +13 -0
  20. package/dist/cli/utils.d.ts +2 -0
  21. package/dist/cli/utils.js +1 -1
  22. package/dist/core/catalog-export/index.d.ts +11 -0
  23. package/dist/core/catalog-export/index.js +10 -0
  24. package/dist/core/catalog.diff.d.ts +1 -0
  25. package/dist/core/catalog.diff.js +64 -48
  26. package/dist/core/catalog.model.d.ts +16 -3
  27. package/dist/core/catalog.model.js +132 -30
  28. package/dist/core/catalog.snapshot.d.ts +66 -0
  29. package/dist/core/catalog.snapshot.js +206 -0
  30. package/dist/core/context.d.ts +3 -3
  31. package/dist/core/context.js +7 -10
  32. package/dist/core/declarative-apply/discover-sql.d.ts +18 -0
  33. package/dist/core/declarative-apply/discover-sql.js +86 -0
  34. package/dist/core/declarative-apply/extract-catalog-providers.d.ts +23 -0
  35. package/dist/core/declarative-apply/extract-catalog-providers.js +159 -0
  36. package/dist/core/declarative-apply/index.d.ts +49 -0
  37. package/dist/core/declarative-apply/index.js +134 -0
  38. package/dist/core/declarative-apply/round-apply.d.ts +100 -0
  39. package/dist/core/declarative-apply/round-apply.js +378 -0
  40. package/dist/core/depend.d.ts +2 -2
  41. package/dist/core/depend.js +8 -7
  42. package/dist/core/export/file-mapper.d.ts +71 -0
  43. package/dist/core/export/file-mapper.js +474 -0
  44. package/dist/core/export/grouper.d.ts +13 -0
  45. package/dist/core/export/grouper.js +76 -0
  46. package/dist/core/export/index.d.ts +45 -0
  47. package/dist/core/export/index.js +63 -0
  48. package/dist/core/export/types.d.ts +84 -0
  49. package/dist/core/export/types.js +25 -0
  50. package/dist/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
  51. package/dist/core/integrations/filter/dsl.d.ts +38 -1
  52. package/dist/core/integrations/filter/dsl.js +20 -2
  53. package/dist/core/integrations/filter/extractors.js +42 -0
  54. package/dist/core/integrations/integration-dsl.d.ts +10 -0
  55. package/dist/core/integrations/supabase.d.ts +8 -0
  56. package/dist/core/integrations/supabase.js +11 -0
  57. package/dist/core/objects/aggregate/aggregate.diff.d.ts +2 -8
  58. package/dist/core/objects/aggregate/aggregate.diff.js +16 -70
  59. package/dist/core/objects/aggregate/aggregate.model.d.ts +10 -10
  60. package/dist/core/objects/aggregate/aggregate.model.js +8 -10
  61. package/dist/core/objects/aggregate/changes/aggregate.create.js +1 -1
  62. package/dist/core/objects/aggregate/changes/aggregate.drop.js +1 -1
  63. package/dist/core/objects/base.privilege-diff.d.ts +38 -13
  64. package/dist/core/objects/base.privilege-diff.js +104 -22
  65. package/dist/core/objects/base.privilege.d.ts +1 -0
  66. package/dist/core/objects/base.privilege.js +9 -2
  67. package/dist/core/objects/collation/collation.diff.d.ts +2 -3
  68. package/dist/core/objects/collation/collation.model.d.ts +2 -2
  69. package/dist/core/objects/collation/collation.model.js +29 -28
  70. package/dist/core/objects/diff-context.d.ts +15 -0
  71. package/dist/core/objects/diff-context.js +1 -0
  72. package/dist/core/objects/domain/changes/domain.create.js +4 -2
  73. package/dist/core/objects/domain/domain.diff.d.ts +2 -8
  74. package/dist/core/objects/domain/domain.diff.js +16 -77
  75. package/dist/core/objects/domain/domain.model.d.ts +2 -2
  76. package/dist/core/objects/domain/domain.model.js +9 -11
  77. package/dist/core/objects/event-trigger/event-trigger.diff.d.ts +2 -3
  78. package/dist/core/objects/event-trigger/event-trigger.model.d.ts +2 -2
  79. package/dist/core/objects/event-trigger/event-trigger.model.js +7 -9
  80. package/dist/core/objects/extension/extension.model.d.ts +2 -2
  81. package/dist/core/objects/extension/extension.model.js +8 -10
  82. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.d.ts +2 -8
  83. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.js +13 -77
  84. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.d.ts +2 -2
  85. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.js +22 -24
  86. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.d.ts +2 -8
  87. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.js +16 -77
  88. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.d.ts +2 -2
  89. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.js +21 -23
  90. package/dist/core/objects/foreign-data-wrapper/server/server.diff.d.ts +2 -8
  91. package/dist/core/objects/foreign-data-wrapper/server/server.diff.js +13 -77
  92. package/dist/core/objects/foreign-data-wrapper/server/server.model.d.ts +2 -2
  93. package/dist/core/objects/foreign-data-wrapper/server/server.model.js +20 -22
  94. package/dist/core/objects/foreign-data-wrapper/user-mapping/user-mapping.model.d.ts +2 -2
  95. package/dist/core/objects/foreign-data-wrapper/user-mapping/user-mapping.model.js +20 -22
  96. package/dist/core/objects/index/index.model.d.ts +4 -4
  97. package/dist/core/objects/index/index.model.js +9 -11
  98. package/dist/core/objects/language/language.diff.d.ts +2 -5
  99. package/dist/core/objects/language/language.diff.js +7 -39
  100. package/dist/core/objects/language/language.model.js +5 -7
  101. package/dist/core/objects/materialized-view/materialized-view.diff.d.ts +2 -8
  102. package/dist/core/objects/materialized-view/materialized-view.diff.js +16 -158
  103. package/dist/core/objects/materialized-view/materialized-view.model.d.ts +5 -5
  104. package/dist/core/objects/materialized-view/materialized-view.model.js +9 -11
  105. package/dist/core/objects/procedure/changes/procedure.alter.js +12 -12
  106. package/dist/core/objects/procedure/procedure.diff.d.ts +2 -8
  107. package/dist/core/objects/procedure/procedure.diff.js +16 -77
  108. package/dist/core/objects/procedure/procedure.model.d.ts +11 -11
  109. package/dist/core/objects/procedure/procedure.model.js +9 -11
  110. package/dist/core/objects/publication/changes/publication.alter.d.ts +0 -9
  111. package/dist/core/objects/publication/changes/publication.alter.js +0 -14
  112. package/dist/core/objects/publication/changes/publication.types.d.ts +2 -2
  113. package/dist/core/objects/publication/publication.diff.d.ts +2 -3
  114. package/dist/core/objects/publication/publication.diff.js +8 -13
  115. package/dist/core/objects/publication/publication.model.d.ts +2 -2
  116. package/dist/core/objects/publication/publication.model.js +7 -9
  117. package/dist/core/objects/rls-policy/changes/rls-policy.alter.js +3 -3
  118. package/dist/core/objects/rls-policy/rls-policy.model.d.ts +4 -4
  119. package/dist/core/objects/rls-policy/rls-policy.model.js +8 -10
  120. package/dist/core/objects/role/role.diff.js +22 -1
  121. package/dist/core/objects/role/role.model.d.ts +6 -5
  122. package/dist/core/objects/role/role.model.js +146 -40
  123. package/dist/core/objects/rule/rule.model.d.ts +3 -3
  124. package/dist/core/objects/rule/rule.model.js +7 -9
  125. package/dist/core/objects/schema/schema.diff.d.ts +2 -8
  126. package/dist/core/objects/schema/schema.diff.js +16 -77
  127. package/dist/core/objects/schema/schema.model.d.ts +2 -2
  128. package/dist/core/objects/schema/schema.model.js +9 -11
  129. package/dist/core/objects/sequence/sequence.diff.d.ts +2 -8
  130. package/dist/core/objects/sequence/sequence.diff.js +16 -79
  131. package/dist/core/objects/sequence/sequence.model.d.ts +2 -2
  132. package/dist/core/objects/sequence/sequence.model.js +9 -11
  133. package/dist/core/objects/subscription/subscription.diff.d.ts +2 -3
  134. package/dist/core/objects/subscription/subscription.model.d.ts +2 -2
  135. package/dist/core/objects/subscription/subscription.model.js +25 -20
  136. package/dist/core/objects/table/changes/table.create.js +3 -0
  137. package/dist/core/objects/table/table.diff.d.ts +2 -8
  138. package/dist/core/objects/table/table.diff.js +26 -157
  139. package/dist/core/objects/table/table.model.d.ts +27 -24
  140. package/dist/core/objects/table/table.model.js +12 -11
  141. package/dist/core/objects/trigger/changes/trigger.alter.js +23 -0
  142. package/dist/core/objects/trigger/changes/trigger.create.js +4 -5
  143. package/dist/core/objects/trigger/trigger.model.d.ts +11 -2
  144. package/dist/core/objects/trigger/trigger.model.js +22 -10
  145. package/dist/core/objects/type/composite-type/composite-type.diff.d.ts +2 -8
  146. package/dist/core/objects/type/composite-type/composite-type.diff.js +16 -77
  147. package/dist/core/objects/type/composite-type/composite-type.model.d.ts +5 -5
  148. package/dist/core/objects/type/composite-type/composite-type.model.js +10 -11
  149. package/dist/core/objects/type/enum/enum.diff.d.ts +2 -8
  150. package/dist/core/objects/type/enum/enum.diff.js +25 -112
  151. package/dist/core/objects/type/enum/enum.model.d.ts +2 -2
  152. package/dist/core/objects/type/enum/enum.model.js +23 -25
  153. package/dist/core/objects/type/range/changes/range.create.js +6 -3
  154. package/dist/core/objects/type/range/range.diff.d.ts +2 -8
  155. package/dist/core/objects/type/range/range.diff.js +16 -77
  156. package/dist/core/objects/type/range/range.model.d.ts +2 -2
  157. package/dist/core/objects/type/range/range.model.js +8 -10
  158. package/dist/core/objects/view/view.diff.d.ts +2 -8
  159. package/dist/core/objects/view/view.diff.js +16 -158
  160. package/dist/core/objects/view/view.model.d.ts +20 -6
  161. package/dist/core/objects/view/view.model.js +11 -23
  162. package/dist/core/plan/apply.d.ts +2 -2
  163. package/dist/core/plan/apply.js +33 -16
  164. package/dist/core/plan/create.d.ts +20 -7
  165. package/dist/core/plan/create.js +153 -112
  166. package/dist/core/plan/serialize.js +16 -4
  167. package/dist/core/plan/sql-format/constants.d.ts +2 -0
  168. package/dist/core/plan/sql-format/constants.js +11 -0
  169. package/dist/core/plan/sql-format/fixtures.d.ts +2 -0
  170. package/dist/core/plan/sql-format/fixtures.js +2447 -0
  171. package/dist/core/plan/sql-format/format-utils.d.ts +37 -0
  172. package/dist/core/plan/sql-format/format-utils.js +274 -0
  173. package/dist/core/plan/sql-format/formatters.d.ts +20 -0
  174. package/dist/core/plan/sql-format/formatters.js +737 -0
  175. package/dist/core/plan/sql-format/index.d.ts +2 -0
  176. package/dist/core/plan/sql-format/index.js +98 -0
  177. package/dist/core/plan/sql-format/keyword-case.d.ts +2 -0
  178. package/dist/core/plan/sql-format/keyword-case.js +893 -0
  179. package/dist/core/plan/sql-format/protect.d.ts +3 -0
  180. package/dist/core/plan/sql-format/protect.js +269 -0
  181. package/dist/core/plan/sql-format/sql-scanner.d.ts +59 -0
  182. package/dist/core/plan/sql-format/sql-scanner.js +202 -0
  183. package/dist/core/plan/sql-format/tokenizer.d.ts +22 -0
  184. package/dist/core/plan/sql-format/tokenizer.js +118 -0
  185. package/dist/core/plan/sql-format/types.d.ts +28 -0
  186. package/dist/core/plan/sql-format/types.js +1 -0
  187. package/dist/core/plan/sql-format/wrap.d.ts +2 -0
  188. package/dist/core/plan/sql-format/wrap.js +165 -0
  189. package/dist/core/plan/sql-format.d.ts +2 -0
  190. package/dist/core/plan/sql-format.js +1 -0
  191. package/dist/core/plan/ssl-config.d.ts +32 -0
  192. package/dist/core/plan/ssl-config.js +115 -0
  193. package/dist/core/plan/statements.d.ts +2 -1
  194. package/dist/core/plan/statements.js +6 -2
  195. package/dist/core/plan/types.d.ts +6 -0
  196. package/dist/core/postgres-config.d.ts +47 -3
  197. package/dist/core/postgres-config.js +225 -39
  198. package/dist/core/sort/graph-builder.js +10 -0
  199. package/dist/core/sort/logical-sort.js +31 -23
  200. package/dist/core/test-utils/assert-valid-sql.d.ts +10 -0
  201. package/dist/core/test-utils/assert-valid-sql.js +19 -0
  202. package/dist/index.d.ts +9 -0
  203. package/dist/index.js +9 -1
  204. package/package.json +56 -22
  205. package/src/cli/app.ts +52 -0
  206. package/src/cli/bin/cli.ts +15 -0
  207. package/src/cli/commands/apply.ts +101 -0
  208. package/src/cli/commands/catalog-export.ts +78 -0
  209. package/src/cli/commands/declarative-apply.diagnostics.test.ts +77 -0
  210. package/src/cli/commands/declarative-apply.ts +380 -0
  211. package/src/cli/commands/declarative-export.ts +330 -0
  212. package/src/cli/commands/plan.ts +216 -0
  213. package/src/cli/commands/sync.ts +185 -0
  214. package/src/cli/exit-code.test.ts +19 -0
  215. package/src/cli/exit-code.ts +7 -0
  216. package/src/cli/formatters/index.ts +5 -0
  217. package/src/cli/formatters/tree/tree-builder.ts +380 -0
  218. package/src/cli/formatters/tree/tree-renderer.ts +372 -0
  219. package/src/cli/formatters/tree/tree.ts +238 -0
  220. package/src/cli/utils/apply-display.test.ts +348 -0
  221. package/src/cli/utils/apply-display.ts +238 -0
  222. package/src/cli/utils/export-display.test.ts +103 -0
  223. package/src/cli/utils/export-display.ts +275 -0
  224. package/src/cli/utils/integrations.test.ts +44 -0
  225. package/src/cli/utils/integrations.ts +42 -0
  226. package/src/cli/utils/resolve-input.test.ts +38 -0
  227. package/src/cli/utils/resolve-input.ts +17 -0
  228. package/src/cli/utils.ts +231 -0
  229. package/src/core/catalog-export/index.ts +20 -0
  230. package/src/core/catalog.diff.ts +247 -0
  231. package/src/core/catalog.model.test.ts +122 -0
  232. package/src/core/catalog.model.ts +510 -0
  233. package/src/core/catalog.snapshot.test.ts +477 -0
  234. package/src/core/catalog.snapshot.ts +289 -0
  235. package/src/core/change.types.ts +44 -0
  236. package/src/core/context.ts +26 -0
  237. package/src/core/declarative-apply/discover-sql.test.ts +103 -0
  238. package/src/core/declarative-apply/discover-sql.ts +107 -0
  239. package/src/core/declarative-apply/extract-catalog-providers.ts +220 -0
  240. package/src/core/declarative-apply/index.test.ts +67 -0
  241. package/src/core/declarative-apply/index.ts +205 -0
  242. package/src/core/declarative-apply/round-apply.test.ts +504 -0
  243. package/src/core/declarative-apply/round-apply.ts +562 -0
  244. package/src/core/depend.ts +1870 -0
  245. package/src/core/expand-replace-dependencies.test.ts +70 -0
  246. package/src/core/expand-replace-dependencies.ts +380 -0
  247. package/src/core/export/file-mapper.test.ts +816 -0
  248. package/src/core/export/file-mapper.ts +574 -0
  249. package/src/core/export/grouper.ts +108 -0
  250. package/src/core/export/index.ts +129 -0
  251. package/src/core/export/types.ts +104 -0
  252. package/src/core/fingerprint.ts +204 -0
  253. package/src/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
  254. package/src/core/integrations/filter/dsl.test.ts +211 -0
  255. package/src/core/integrations/filter/dsl.ts +266 -0
  256. package/src/core/integrations/filter/extractors.test.ts +244 -0
  257. package/src/core/integrations/filter/extractors.ts +187 -0
  258. package/src/core/integrations/filter/filter.types.ts +3 -0
  259. package/src/core/integrations/integration-dsl.ts +34 -0
  260. package/src/core/integrations/integration.types.ts +7 -0
  261. package/src/core/integrations/serialize/dsl.test.ts +91 -0
  262. package/src/core/integrations/serialize/dsl.ts +77 -0
  263. package/src/core/integrations/serialize/serialize.types.ts +3 -0
  264. package/src/core/integrations/supabase.ts +130 -0
  265. package/src/core/objects/aggregate/aggregate.diff.test.ts +215 -0
  266. package/src/core/objects/aggregate/aggregate.diff.ts +222 -0
  267. package/src/core/objects/aggregate/aggregate.model.ts +317 -0
  268. package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +66 -0
  269. package/src/core/objects/aggregate/changes/aggregate.alter.ts +32 -0
  270. package/src/core/objects/aggregate/changes/aggregate.base.ts +20 -0
  271. package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +89 -0
  272. package/src/core/objects/aggregate/changes/aggregate.comment.ts +62 -0
  273. package/src/core/objects/aggregate/changes/aggregate.create.test.ts +104 -0
  274. package/src/core/objects/aggregate/changes/aggregate.create.ts +329 -0
  275. package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +82 -0
  276. package/src/core/objects/aggregate/changes/aggregate.drop.ts +32 -0
  277. package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +136 -0
  278. package/src/core/objects/aggregate/changes/aggregate.privilege.ts +146 -0
  279. package/src/core/objects/aggregate/changes/aggregate.types.ts +12 -0
  280. package/src/core/objects/base.change.ts +62 -0
  281. package/src/core/objects/base.default-privileges.ts +204 -0
  282. package/src/core/objects/base.diff.ts +20 -0
  283. package/src/core/objects/base.model.ts +82 -0
  284. package/src/core/objects/base.privilege-diff.ts +447 -0
  285. package/src/core/objects/base.privilege.ts +191 -0
  286. package/src/core/objects/collation/changes/collation.alter.test.ts +68 -0
  287. package/src/core/objects/collation/changes/collation.alter.ts +79 -0
  288. package/src/core/objects/collation/changes/collation.base.ts +20 -0
  289. package/src/core/objects/collation/changes/collation.comment.ts +68 -0
  290. package/src/core/objects/collation/changes/collation.create.test.ts +56 -0
  291. package/src/core/objects/collation/changes/collation.create.ts +106 -0
  292. package/src/core/objects/collation/changes/collation.drop.test.ts +31 -0
  293. package/src/core/objects/collation/changes/collation.drop.ts +37 -0
  294. package/src/core/objects/collation/changes/collation.types.ts +10 -0
  295. package/src/core/objects/collation/collation.diff.test.ts +97 -0
  296. package/src/core/objects/collation/collation.diff.ts +127 -0
  297. package/src/core/objects/collation/collation.model.ts +224 -0
  298. package/src/core/objects/diff-context.ts +16 -0
  299. package/src/core/objects/domain/changes/domain.alter.test.ts +335 -0
  300. package/src/core/objects/domain/changes/domain.alter.ts +286 -0
  301. package/src/core/objects/domain/changes/domain.base.ts +20 -0
  302. package/src/core/objects/domain/changes/domain.comment.ts +59 -0
  303. package/src/core/objects/domain/changes/domain.create.test.ts +95 -0
  304. package/src/core/objects/domain/changes/domain.create.ts +124 -0
  305. package/src/core/objects/domain/changes/domain.drop.test.ts +33 -0
  306. package/src/core/objects/domain/changes/domain.drop.ts +34 -0
  307. package/src/core/objects/domain/changes/domain.privilege.ts +171 -0
  308. package/src/core/objects/domain/changes/domain.types.ts +12 -0
  309. package/src/core/objects/domain/domain.diff.test.ts +284 -0
  310. package/src/core/objects/domain/domain.diff.ts +295 -0
  311. package/src/core/objects/domain/domain.model.ts +190 -0
  312. package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +57 -0
  313. package/src/core/objects/event-trigger/changes/event-trigger.alter.ts +82 -0
  314. package/src/core/objects/event-trigger/changes/event-trigger.base.ts +20 -0
  315. package/src/core/objects/event-trigger/changes/event-trigger.comment.ts +66 -0
  316. package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +27 -0
  317. package/src/core/objects/event-trigger/changes/event-trigger.create.ts +72 -0
  318. package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +25 -0
  319. package/src/core/objects/event-trigger/changes/event-trigger.drop.ts +34 -0
  320. package/src/core/objects/event-trigger/changes/event-trigger.types.ts +10 -0
  321. package/src/core/objects/event-trigger/event-trigger.diff.test.ts +131 -0
  322. package/src/core/objects/event-trigger/event-trigger.diff.ts +127 -0
  323. package/src/core/objects/event-trigger/event-trigger.model.ts +106 -0
  324. package/src/core/objects/extension/changes/extension.alter.test.ts +63 -0
  325. package/src/core/objects/extension/changes/extension.alter.ts +78 -0
  326. package/src/core/objects/extension/changes/extension.base.ts +20 -0
  327. package/src/core/objects/extension/changes/extension.comment.ts +64 -0
  328. package/src/core/objects/extension/changes/extension.create.test.ts +28 -0
  329. package/src/core/objects/extension/changes/extension.create.ts +63 -0
  330. package/src/core/objects/extension/changes/extension.drop.test.ts +26 -0
  331. package/src/core/objects/extension/changes/extension.drop.ts +34 -0
  332. package/src/core/objects/extension/changes/extension.types.ts +10 -0
  333. package/src/core/objects/extension/extension.diff.test.ts +42 -0
  334. package/src/core/objects/extension/extension.diff.ts +90 -0
  335. package/src/core/objects/extension/extension.model.test.ts +98 -0
  336. package/src/core/objects/extension/extension.model.ts +280 -0
  337. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +136 -0
  338. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.ts +101 -0
  339. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.base.ts +20 -0
  340. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.comment.ts +72 -0
  341. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +160 -0
  342. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.ts +95 -0
  343. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +26 -0
  344. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.ts +36 -0
  345. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.privilege.ts +172 -0
  346. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.types.ts +12 -0
  347. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +286 -0
  348. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +271 -0
  349. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +149 -0
  350. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper.types.ts +10 -0
  351. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +340 -0
  352. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.ts +341 -0
  353. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +20 -0
  354. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.comment.ts +72 -0
  355. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +210 -0
  356. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.ts +81 -0
  357. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +46 -0
  358. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.ts +37 -0
  359. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.privilege.ts +181 -0
  360. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +12 -0
  361. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.test.ts +813 -0
  362. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +343 -0
  363. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +242 -0
  364. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +183 -0
  365. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.ts +126 -0
  366. package/src/core/objects/foreign-data-wrapper/server/changes/server.base.ts +20 -0
  367. package/src/core/objects/foreign-data-wrapper/server/changes/server.comment.ts +60 -0
  368. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +144 -0
  369. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.ts +81 -0
  370. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +27 -0
  371. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.ts +34 -0
  372. package/src/core/objects/foreign-data-wrapper/server/changes/server.privilege.ts +164 -0
  373. package/src/core/objects/foreign-data-wrapper/server/changes/server.types.ts +12 -0
  374. package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +262 -0
  375. package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +247 -0
  376. package/src/core/objects/foreign-data-wrapper/server/server.model.ts +133 -0
  377. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +91 -0
  378. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.ts +69 -0
  379. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.base.ts +20 -0
  380. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +96 -0
  381. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.ts +66 -0
  382. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +60 -0
  383. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.ts +40 -0
  384. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.types.ts +8 -0
  385. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.test.ts +77 -0
  386. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.ts +107 -0
  387. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.model.ts +96 -0
  388. package/src/core/objects/index/changes/index.alter.test.ts +209 -0
  389. package/src/core/objects/index/changes/index.alter.ts +144 -0
  390. package/src/core/objects/index/changes/index.base.ts +20 -0
  391. package/src/core/objects/index/changes/index.comment.ts +63 -0
  392. package/src/core/objects/index/changes/index.create.test.ts +69 -0
  393. package/src/core/objects/index/changes/index.create.ts +68 -0
  394. package/src/core/objects/index/changes/index.drop.test.ts +47 -0
  395. package/src/core/objects/index/changes/index.drop.ts +34 -0
  396. package/src/core/objects/index/changes/index.types.ts +6 -0
  397. package/src/core/objects/index/changes/utils.ts +16 -0
  398. package/src/core/objects/index/index.diff.test.ts +153 -0
  399. package/src/core/objects/index/index.diff.ts +243 -0
  400. package/src/core/objects/index/index.model.ts +370 -0
  401. package/src/core/objects/language/changes/language.alter.test.ts +36 -0
  402. package/src/core/objects/language/changes/language.alter.ts +53 -0
  403. package/src/core/objects/language/changes/language.base.ts +20 -0
  404. package/src/core/objects/language/changes/language.comment.ts +58 -0
  405. package/src/core/objects/language/changes/language.create.test.ts +30 -0
  406. package/src/core/objects/language/changes/language.create.ts +104 -0
  407. package/src/core/objects/language/changes/language.drop.test.ts +28 -0
  408. package/src/core/objects/language/changes/language.drop.ts +39 -0
  409. package/src/core/objects/language/changes/language.privilege.ts +172 -0
  410. package/src/core/objects/language/changes/language.types.ts +12 -0
  411. package/src/core/objects/language/language.diff.test.ts +135 -0
  412. package/src/core/objects/language/language.diff.ts +144 -0
  413. package/src/core/objects/language/language.model.ts +150 -0
  414. package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +130 -0
  415. package/src/core/objects/materialized-view/changes/materialized-view.alter.ts +113 -0
  416. package/src/core/objects/materialized-view/changes/materialized-view.base.ts +20 -0
  417. package/src/core/objects/materialized-view/changes/materialized-view.comment.ts +176 -0
  418. package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +69 -0
  419. package/src/core/objects/materialized-view/changes/materialized-view.create.ts +93 -0
  420. package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +37 -0
  421. package/src/core/objects/materialized-view/changes/materialized-view.drop.ts +60 -0
  422. package/src/core/objects/materialized-view/changes/materialized-view.privilege.ts +212 -0
  423. package/src/core/objects/materialized-view/changes/materialized-view.types.ts +12 -0
  424. package/src/core/objects/materialized-view/materialized-view.diff.test.ts +264 -0
  425. package/src/core/objects/materialized-view/materialized-view.diff.ts +301 -0
  426. package/src/core/objects/materialized-view/materialized-view.model.ts +258 -0
  427. package/src/core/objects/procedure/changes/procedure.alter.test.ts +1077 -0
  428. package/src/core/objects/procedure/changes/procedure.alter.ts +290 -0
  429. package/src/core/objects/procedure/changes/procedure.base.ts +20 -0
  430. package/src/core/objects/procedure/changes/procedure.comment.ts +70 -0
  431. package/src/core/objects/procedure/changes/procedure.create.test.ts +51 -0
  432. package/src/core/objects/procedure/changes/procedure.create.ts +92 -0
  433. package/src/core/objects/procedure/changes/procedure.drop.test.ts +90 -0
  434. package/src/core/objects/procedure/changes/procedure.drop.ts +49 -0
  435. package/src/core/objects/procedure/changes/procedure.privilege.ts +188 -0
  436. package/src/core/objects/procedure/changes/procedure.types.ts +12 -0
  437. package/src/core/objects/procedure/procedure.diff.test.ts +161 -0
  438. package/src/core/objects/procedure/procedure.diff.ts +341 -0
  439. package/src/core/objects/procedure/procedure.model.ts +264 -0
  440. package/src/core/objects/procedure/utils.ts +58 -0
  441. package/src/core/objects/publication/changes/publication.alter.test.ts +217 -0
  442. package/src/core/objects/publication/changes/publication.alter.ts +225 -0
  443. package/src/core/objects/publication/changes/publication.base.ts +20 -0
  444. package/src/core/objects/publication/changes/publication.comment.test.ts +73 -0
  445. package/src/core/objects/publication/changes/publication.comment.ts +64 -0
  446. package/src/core/objects/publication/changes/publication.create.test.ts +90 -0
  447. package/src/core/objects/publication/changes/publication.create.ts +82 -0
  448. package/src/core/objects/publication/changes/publication.drop.test.ts +48 -0
  449. package/src/core/objects/publication/changes/publication.drop.ts +29 -0
  450. package/src/core/objects/publication/changes/publication.types.ts +24 -0
  451. package/src/core/objects/publication/publication.diff.test.ts +297 -0
  452. package/src/core/objects/publication/publication.diff.ts +247 -0
  453. package/src/core/objects/publication/publication.model.ts +206 -0
  454. package/src/core/objects/publication/utils.ts +55 -0
  455. package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +267 -0
  456. package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +128 -0
  457. package/src/core/objects/rls-policy/changes/rls-policy.base.ts +20 -0
  458. package/src/core/objects/rls-policy/changes/rls-policy.comment.ts +69 -0
  459. package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +81 -0
  460. package/src/core/objects/rls-policy/changes/rls-policy.create.ts +100 -0
  461. package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +31 -0
  462. package/src/core/objects/rls-policy/changes/rls-policy.drop.ts +39 -0
  463. package/src/core/objects/rls-policy/changes/rls-policy.types.ts +10 -0
  464. package/src/core/objects/rls-policy/rls-policy.diff.test.ts +79 -0
  465. package/src/core/objects/rls-policy/rls-policy.diff.ts +121 -0
  466. package/src/core/objects/rls-policy/rls-policy.model.ts +140 -0
  467. package/src/core/objects/role/changes/role.alter.test.ts +362 -0
  468. package/src/core/objects/role/changes/role.alter.ts +110 -0
  469. package/src/core/objects/role/changes/role.base.ts +24 -0
  470. package/src/core/objects/role/changes/role.comment.ts +55 -0
  471. package/src/core/objects/role/changes/role.create.test.ts +56 -0
  472. package/src/core/objects/role/changes/role.create.ts +102 -0
  473. package/src/core/objects/role/changes/role.drop.test.ts +32 -0
  474. package/src/core/objects/role/changes/role.drop.ts +34 -0
  475. package/src/core/objects/role/changes/role.privilege.ts +376 -0
  476. package/src/core/objects/role/changes/role.types.ts +12 -0
  477. package/src/core/objects/role/role.diff.test.ts +279 -0
  478. package/src/core/objects/role/role.diff.ts +499 -0
  479. package/src/core/objects/role/role.model.ts +452 -0
  480. package/src/core/objects/rule/changes/rule.alter.test.ts +82 -0
  481. package/src/core/objects/rule/changes/rule.alter.ts +72 -0
  482. package/src/core/objects/rule/changes/rule.base.ts +20 -0
  483. package/src/core/objects/rule/changes/rule.comment.test.ts +58 -0
  484. package/src/core/objects/rule/changes/rule.comment.ts +62 -0
  485. package/src/core/objects/rule/changes/rule.create.test.ts +63 -0
  486. package/src/core/objects/rule/changes/rule.create.ts +42 -0
  487. package/src/core/objects/rule/changes/rule.drop.test.ts +40 -0
  488. package/src/core/objects/rule/changes/rule.drop.ts +29 -0
  489. package/src/core/objects/rule/changes/rule.types.ts +12 -0
  490. package/src/core/objects/rule/rule.diff.test.ts +132 -0
  491. package/src/core/objects/rule/rule.diff.ts +79 -0
  492. package/src/core/objects/rule/rule.model.ts +173 -0
  493. package/src/core/objects/schema/changes/schema.alter.test.ts +31 -0
  494. package/src/core/objects/schema/changes/schema.alter.ts +45 -0
  495. package/src/core/objects/schema/changes/schema.base.ts +20 -0
  496. package/src/core/objects/schema/changes/schema.comment.ts +56 -0
  497. package/src/core/objects/schema/changes/schema.create.test.ts +25 -0
  498. package/src/core/objects/schema/changes/schema.create.ts +47 -0
  499. package/src/core/objects/schema/changes/schema.drop.test.ts +23 -0
  500. package/src/core/objects/schema/changes/schema.drop.ts +34 -0
  501. package/src/core/objects/schema/changes/schema.privilege.ts +175 -0
  502. package/src/core/objects/schema/changes/schema.types.ts +12 -0
  503. package/src/core/objects/schema/schema.diff.test.ts +42 -0
  504. package/src/core/objects/schema/schema.diff.ts +146 -0
  505. package/src/core/objects/schema/schema.model.ts +107 -0
  506. package/src/core/objects/sequence/changes/sequence.alter.test.ts +157 -0
  507. package/src/core/objects/sequence/changes/sequence.alter.ts +115 -0
  508. package/src/core/objects/sequence/changes/sequence.base.ts +20 -0
  509. package/src/core/objects/sequence/changes/sequence.comment.ts +60 -0
  510. package/src/core/objects/sequence/changes/sequence.create.test.ts +89 -0
  511. package/src/core/objects/sequence/changes/sequence.create.ts +111 -0
  512. package/src/core/objects/sequence/changes/sequence.drop.test.ts +35 -0
  513. package/src/core/objects/sequence/changes/sequence.drop.ts +37 -0
  514. package/src/core/objects/sequence/changes/sequence.privilege.ts +179 -0
  515. package/src/core/objects/sequence/changes/sequence.types.ts +12 -0
  516. package/src/core/objects/sequence/sequence.diff.test.ts +255 -0
  517. package/src/core/objects/sequence/sequence.diff.ts +294 -0
  518. package/src/core/objects/sequence/sequence.model.ts +185 -0
  519. package/src/core/objects/subscription/changes/subscription.alter.test.ts +134 -0
  520. package/src/core/objects/subscription/changes/subscription.alter.ts +110 -0
  521. package/src/core/objects/subscription/changes/subscription.base.ts +20 -0
  522. package/src/core/objects/subscription/changes/subscription.comment.test.ts +70 -0
  523. package/src/core/objects/subscription/changes/subscription.comment.ts +64 -0
  524. package/src/core/objects/subscription/changes/subscription.create.test.ts +80 -0
  525. package/src/core/objects/subscription/changes/subscription.create.ts +69 -0
  526. package/src/core/objects/subscription/changes/subscription.drop.test.ts +48 -0
  527. package/src/core/objects/subscription/changes/subscription.drop.ts +20 -0
  528. package/src/core/objects/subscription/changes/subscription.types.ts +22 -0
  529. package/src/core/objects/subscription/subscription.diff.test.ts +237 -0
  530. package/src/core/objects/subscription/subscription.diff.ts +242 -0
  531. package/src/core/objects/subscription/subscription.model.ts +190 -0
  532. package/src/core/objects/subscription/utils.ts +156 -0
  533. package/src/core/objects/table/changes/table.alter.test.ts +846 -0
  534. package/src/core/objects/table/changes/table.alter.ts +806 -0
  535. package/src/core/objects/table/changes/table.base.ts +20 -0
  536. package/src/core/objects/table/changes/table.comment.ts +266 -0
  537. package/src/core/objects/table/changes/table.create.test.ts +188 -0
  538. package/src/core/objects/table/changes/table.create.ts +192 -0
  539. package/src/core/objects/table/changes/table.drop.test.ts +36 -0
  540. package/src/core/objects/table/changes/table.drop.ts +45 -0
  541. package/src/core/objects/table/changes/table.privilege.ts +200 -0
  542. package/src/core/objects/table/changes/table.types.ts +12 -0
  543. package/src/core/objects/table/table.diff.test.ts +868 -0
  544. package/src/core/objects/table/table.diff.ts +817 -0
  545. package/src/core/objects/table/table.model.ts +460 -0
  546. package/src/core/objects/trigger/changes/trigger.alter.test.ts +50 -0
  547. package/src/core/objects/trigger/changes/trigger.alter.ts +76 -0
  548. package/src/core/objects/trigger/changes/trigger.base.ts +20 -0
  549. package/src/core/objects/trigger/changes/trigger.comment.ts +64 -0
  550. package/src/core/objects/trigger/changes/trigger.create.test.ts +47 -0
  551. package/src/core/objects/trigger/changes/trigger.create.ts +88 -0
  552. package/src/core/objects/trigger/changes/trigger.drop.test.ts +47 -0
  553. package/src/core/objects/trigger/changes/trigger.drop.ts +39 -0
  554. package/src/core/objects/trigger/changes/trigger.types.ts +10 -0
  555. package/src/core/objects/trigger/trigger.diff.test.ts +84 -0
  556. package/src/core/objects/trigger/trigger.diff.ts +116 -0
  557. package/src/core/objects/trigger/trigger.model.ts +264 -0
  558. package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +208 -0
  559. package/src/core/objects/type/composite-type/changes/composite-type.alter.ts +174 -0
  560. package/src/core/objects/type/composite-type/changes/composite-type.base.ts +20 -0
  561. package/src/core/objects/type/composite-type/changes/composite-type.comment.ts +145 -0
  562. package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +106 -0
  563. package/src/core/objects/type/composite-type/changes/composite-type.create.ts +95 -0
  564. package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +36 -0
  565. package/src/core/objects/type/composite-type/changes/composite-type.drop.ts +37 -0
  566. package/src/core/objects/type/composite-type/changes/composite-type.privilege.ts +175 -0
  567. package/src/core/objects/type/composite-type/changes/composite-type.types.ts +12 -0
  568. package/src/core/objects/type/composite-type/composite-type.diff.test.ts +269 -0
  569. package/src/core/objects/type/composite-type/composite-type.diff.ts +310 -0
  570. package/src/core/objects/type/composite-type/composite-type.model.ts +253 -0
  571. package/src/core/objects/type/enum/changes/enum.alter.test.ts +113 -0
  572. package/src/core/objects/type/enum/changes/enum.alter.ts +91 -0
  573. package/src/core/objects/type/enum/changes/enum.base.ts +20 -0
  574. package/src/core/objects/type/enum/changes/enum.comment.ts +64 -0
  575. package/src/core/objects/type/enum/changes/enum.create.test.ts +31 -0
  576. package/src/core/objects/type/enum/changes/enum.create.ts +56 -0
  577. package/src/core/objects/type/enum/changes/enum.drop.test.ts +28 -0
  578. package/src/core/objects/type/enum/changes/enum.drop.ts +34 -0
  579. package/src/core/objects/type/enum/changes/enum.privilege.ts +175 -0
  580. package/src/core/objects/type/enum/changes/enum.types.ts +12 -0
  581. package/src/core/objects/type/enum/enum.diff.test.ts +372 -0
  582. package/src/core/objects/type/enum/enum.diff.ts +308 -0
  583. package/src/core/objects/type/enum/enum.model.ts +194 -0
  584. package/src/core/objects/type/range/changes/range.alter.test.ts +29 -0
  585. package/src/core/objects/type/range/changes/range.alter.ts +51 -0
  586. package/src/core/objects/type/range/changes/range.base.ts +20 -0
  587. package/src/core/objects/type/range/changes/range.comment.ts +64 -0
  588. package/src/core/objects/type/range/changes/range.create.test.ts +54 -0
  589. package/src/core/objects/type/range/changes/range.create.ts +155 -0
  590. package/src/core/objects/type/range/changes/range.drop.test.ts +28 -0
  591. package/src/core/objects/type/range/changes/range.drop.ts +34 -0
  592. package/src/core/objects/type/range/changes/range.privilege.ts +175 -0
  593. package/src/core/objects/type/range/changes/range.types.ts +12 -0
  594. package/src/core/objects/type/range/range.diff.test.ts +147 -0
  595. package/src/core/objects/type/range/range.diff.ts +197 -0
  596. package/src/core/objects/type/range/range.model.ts +187 -0
  597. package/src/core/objects/type/type.types.ts +5 -0
  598. package/src/core/objects/utils.ts +171 -0
  599. package/src/core/objects/view/changes/view.alter.test.ts +115 -0
  600. package/src/core/objects/view/changes/view.alter.ts +112 -0
  601. package/src/core/objects/view/changes/view.base.ts +20 -0
  602. package/src/core/objects/view/changes/view.comment.ts +59 -0
  603. package/src/core/objects/view/changes/view.create.test.ts +70 -0
  604. package/src/core/objects/view/changes/view.create.ts +73 -0
  605. package/src/core/objects/view/changes/view.drop.test.ts +37 -0
  606. package/src/core/objects/view/changes/view.drop.ts +40 -0
  607. package/src/core/objects/view/changes/view.privilege.ts +200 -0
  608. package/src/core/objects/view/changes/view.types.ts +12 -0
  609. package/src/core/objects/view/view.diff.test.ts +173 -0
  610. package/src/core/objects/view/view.diff.ts +215 -0
  611. package/src/core/objects/view/view.model.ts +262 -0
  612. package/src/core/plan/apply.ts +172 -0
  613. package/src/core/plan/create.ts +384 -0
  614. package/src/core/plan/hierarchy.ts +574 -0
  615. package/src/core/plan/index.ts +29 -0
  616. package/src/core/plan/io.ts +20 -0
  617. package/src/core/plan/risk.ts +48 -0
  618. package/src/core/plan/serialize.test.ts +317 -0
  619. package/src/core/plan/serialize.ts +209 -0
  620. package/src/core/plan/sql-format/constants.ts +13 -0
  621. package/src/core/plan/sql-format/fixtures.ts +2803 -0
  622. package/src/core/plan/sql-format/format-comment-literals.test.ts +96 -0
  623. package/src/core/plan/sql-format/format-functions.test.ts +127 -0
  624. package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +119 -0
  625. package/src/core/plan/sql-format/format-off.test.ts +806 -0
  626. package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +1061 -0
  627. package/src/core/plan/sql-format/format-pretty-narrow.test.ts +1279 -0
  628. package/src/core/plan/sql-format/format-pretty-preserve.test.ts +1057 -0
  629. package/src/core/plan/sql-format/format-pretty-upper.test.ts +1048 -0
  630. package/src/core/plan/sql-format/format-stress.test.ts +616 -0
  631. package/src/core/plan/sql-format/format-utils.test.ts +91 -0
  632. package/src/core/plan/sql-format/format-utils.ts +391 -0
  633. package/src/core/plan/sql-format/formatters.ts +921 -0
  634. package/src/core/plan/sql-format/index.ts +149 -0
  635. package/src/core/plan/sql-format/keyword-case.test.ts +118 -0
  636. package/src/core/plan/sql-format/keyword-case.ts +1120 -0
  637. package/src/core/plan/sql-format/protect.test.ts +127 -0
  638. package/src/core/plan/sql-format/protect.ts +337 -0
  639. package/src/core/plan/sql-format/sql-scanner.test.ts +240 -0
  640. package/src/core/plan/sql-format/sql-scanner.ts +252 -0
  641. package/src/core/plan/sql-format/tokenizer.test.ts +68 -0
  642. package/src/core/plan/sql-format/tokenizer.ts +152 -0
  643. package/src/core/plan/sql-format/types.ts +31 -0
  644. package/src/core/plan/sql-format/wrap.test.ts +119 -0
  645. package/src/core/plan/sql-format/wrap.ts +196 -0
  646. package/src/core/plan/sql-format.ts +2 -0
  647. package/src/core/plan/ssl-config.ts +172 -0
  648. package/src/core/plan/statements.ts +22 -0
  649. package/src/core/plan/types.ts +171 -0
  650. package/src/core/postgres-config.ts +293 -0
  651. package/src/core/sort/custom-constraints.ts +161 -0
  652. package/src/core/sort/debug-visualization.ts +239 -0
  653. package/src/core/sort/dependency-filter.ts +224 -0
  654. package/src/core/sort/graph-builder.ts +235 -0
  655. package/src/core/sort/graph-utils.ts +51 -0
  656. package/src/core/sort/logical-sort.test.ts +371 -0
  657. package/src/core/sort/logical-sort.ts +597 -0
  658. package/src/core/sort/sort-changes.ts +234 -0
  659. package/src/core/sort/topological-sort.test.ts +275 -0
  660. package/src/core/sort/topological-sort.ts +184 -0
  661. package/src/core/sort/types.ts +112 -0
  662. package/src/core/sort/utils.ts +69 -0
  663. package/src/core/test-utils/assert-valid-sql.ts +20 -0
  664. package/src/index.ts +41 -0
@@ -0,0 +1,452 @@
1
+ import { sql } from "@ts-safeql/sql-tag";
2
+ import type { Pool } from "pg";
3
+ import z from "zod";
4
+ import { BasePgModel } from "../base.model.ts";
5
+
6
+ const membershipInfoSchema = z.object({
7
+ member: z.string(),
8
+ grantor: z.string(),
9
+ admin_option: z.boolean(),
10
+ inherit_option: z.boolean().nullish(),
11
+ set_option: z.boolean().nullish(),
12
+ });
13
+
14
+ const defaultPrivilegeSchema = z.object({
15
+ in_schema: z.string().nullable(),
16
+ objtype: z.enum(["r", "S", "f", "T", "n"]),
17
+ grantee: z.string(),
18
+ privileges: z.array(
19
+ z.object({ privilege: z.string(), grantable: z.boolean() }),
20
+ ),
21
+ is_implicit: z.boolean(),
22
+ });
23
+
24
+ const rolePropsSchema = z.object({
25
+ name: z.string(),
26
+ is_superuser: z.boolean(),
27
+ can_inherit: z.boolean(),
28
+ can_create_roles: z.boolean(),
29
+ can_create_databases: z.boolean(),
30
+ can_login: z.boolean(),
31
+ can_replicate: z.boolean(),
32
+ connection_limit: z.number().nullable(),
33
+ can_bypass_rls: z.boolean(),
34
+ config: z.array(z.string()).nullable(),
35
+ comment: z.string().nullable(),
36
+ members: z.array(membershipInfoSchema),
37
+ default_privileges: z.array(defaultPrivilegeSchema),
38
+ });
39
+
40
+ export type RoleProps = z.infer<typeof rolePropsSchema>;
41
+
42
+ export class Role extends BasePgModel {
43
+ public readonly name: RoleProps["name"];
44
+ public readonly is_superuser: RoleProps["is_superuser"];
45
+ public readonly can_inherit: RoleProps["can_inherit"];
46
+ public readonly can_create_roles: RoleProps["can_create_roles"];
47
+ public readonly can_create_databases: RoleProps["can_create_databases"];
48
+ public readonly can_login: RoleProps["can_login"];
49
+ public readonly can_replicate: RoleProps["can_replicate"];
50
+ public readonly connection_limit: RoleProps["connection_limit"];
51
+ public readonly can_bypass_rls: RoleProps["can_bypass_rls"];
52
+ public readonly config: RoleProps["config"];
53
+ public readonly comment: RoleProps["comment"];
54
+ public readonly members: RoleProps["members"];
55
+ public readonly default_privileges: RoleProps["default_privileges"];
56
+
57
+ constructor(props: RoleProps) {
58
+ super();
59
+
60
+ // Identity fields
61
+ this.name = props.name;
62
+
63
+ // Data fields
64
+ this.is_superuser = props.is_superuser;
65
+ this.can_inherit = props.can_inherit;
66
+ this.can_create_roles = props.can_create_roles;
67
+ this.can_create_databases = props.can_create_databases;
68
+ this.can_login = props.can_login;
69
+ this.can_replicate = props.can_replicate;
70
+ this.connection_limit = props.connection_limit;
71
+ this.can_bypass_rls = props.can_bypass_rls;
72
+ this.config = props.config;
73
+ this.comment = props.comment;
74
+ this.members = deduplicateMembers(props.members);
75
+ this.default_privileges = props.default_privileges;
76
+ }
77
+
78
+ get stableId(): `role:${string}` {
79
+ return `role:${this.name}`;
80
+ }
81
+
82
+ get identityFields() {
83
+ return {
84
+ name: this.name,
85
+ };
86
+ }
87
+
88
+ get dataFields() {
89
+ const sortedMembers = [...this.members].sort((a, b) => {
90
+ return (
91
+ a.member.localeCompare(b.member) ||
92
+ a.grantor.localeCompare(b.grantor) ||
93
+ Number(a.admin_option) - Number(b.admin_option) ||
94
+ Number(a.inherit_option ?? false) - Number(b.inherit_option ?? false) ||
95
+ Number(a.set_option ?? false) - Number(b.set_option ?? false)
96
+ );
97
+ });
98
+
99
+ const sortedDefaultPrivs = [...this.default_privileges].map((dp) => {
100
+ const { is_implicit: _, ...rest } = dp;
101
+ return {
102
+ ...rest,
103
+ privileges: [...dp.privileges].sort((a, b) => {
104
+ return (
105
+ a.privilege.localeCompare(b.privilege) ||
106
+ Number(a.grantable) - Number(b.grantable)
107
+ );
108
+ }),
109
+ };
110
+ });
111
+ sortedDefaultPrivs.sort((a, b) => {
112
+ return (
113
+ (a.in_schema ?? "").localeCompare(b.in_schema ?? "") ||
114
+ a.objtype.localeCompare(b.objtype) ||
115
+ a.grantee.localeCompare(b.grantee)
116
+ );
117
+ });
118
+
119
+ return {
120
+ is_superuser: this.is_superuser,
121
+ can_inherit: this.can_inherit,
122
+ can_create_roles: this.can_create_roles,
123
+ can_create_databases: this.can_create_databases,
124
+ can_login: this.can_login,
125
+ can_replicate: this.can_replicate,
126
+ connection_limit: this.connection_limit,
127
+ can_bypass_rls: this.can_bypass_rls,
128
+ config: this.config,
129
+ comment: this.comment,
130
+ members: sortedMembers,
131
+ default_privileges: sortedDefaultPrivs,
132
+ };
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Deduplicate members by member name.
138
+ *
139
+ * In PostgreSQL 16+, `pg_auth_members` can have multiple rows for the same
140
+ * (roleid, member) pair with different grantors. Merge them into a single
141
+ * entry per member, combining options with OR so the most permissive wins.
142
+ *
143
+ * When merging, prefer a non-self grantor (grantor !== member) so that
144
+ * downstream code can detect true self-grants (auto-created by CREATE ROLE)
145
+ * by checking `grantor === member`.
146
+ */
147
+ function deduplicateMembers(
148
+ members: RoleProps["members"],
149
+ ): RoleProps["members"] {
150
+ const map = new Map<string, RoleProps["members"][number]>();
151
+ for (const m of members) {
152
+ const existing = map.get(m.member);
153
+ if (existing) {
154
+ // admin_option is always boolean (non-nullable in schema)
155
+ existing.admin_option = existing.admin_option || m.admin_option;
156
+ // inherit_option and set_option are nullish (only available in PG 16+)
157
+ if (m.inherit_option != null) {
158
+ existing.inherit_option =
159
+ (existing.inherit_option ?? false) || m.inherit_option;
160
+ }
161
+ if (m.set_option != null) {
162
+ existing.set_option = (existing.set_option ?? false) || m.set_option;
163
+ }
164
+ // Prefer a non-self grantor so diff can detect true self-grants.
165
+ // Once a non-self grantor is chosen the value is kept (the specific
166
+ // non-self grantor doesn't matter — only the self vs non-self
167
+ // distinction is used downstream).
168
+ if (existing.grantor === existing.member && m.grantor !== m.member) {
169
+ existing.grantor = m.grantor;
170
+ }
171
+ } else {
172
+ map.set(m.member, { ...m });
173
+ }
174
+ }
175
+ return [...map.values()];
176
+ }
177
+
178
+ export async function extractRoles(pool: Pool): Promise<Role[]> {
179
+ // Check PostgreSQL version capabilities for membership options
180
+ const { rows: capabilitiesRows } = await pool.query<{
181
+ has_inherit: boolean;
182
+ has_set: boolean;
183
+ }>(sql`
184
+ select
185
+ exists (
186
+ select 1
187
+ from pg_attribute
188
+ where attrelid = 'pg_auth_members'::regclass
189
+ and attname = 'inherit_option'
190
+ ) as has_inherit,
191
+ exists (
192
+ select 1
193
+ from pg_attribute
194
+ where attrelid = 'pg_auth_members'::regclass
195
+ and attname = 'set_option'
196
+ ) as has_set
197
+ `);
198
+
199
+ const capabilities = capabilitiesRows[0];
200
+
201
+ let roleRows: RoleProps[];
202
+
203
+ if (capabilities?.has_inherit && capabilities?.has_set) {
204
+ const result = await pool.query<RoleProps>(sql`
205
+ WITH role_memberships AS (
206
+ SELECT
207
+ r.rolname AS role_name,
208
+ json_agg(
209
+ json_build_object(
210
+ 'member', m.rolname,
211
+ 'grantor', g.rolname,
212
+ 'admin_option', am.admin_option,
213
+ 'inherit_option', am.inherit_option,
214
+ 'set_option', am.set_option
215
+ )
216
+ ) FILTER (WHERE m.rolname IS NOT NULL) AS members
217
+ FROM pg_catalog.pg_roles r
218
+ LEFT JOIN pg_auth_members am ON am.roleid = r.oid
219
+ LEFT JOIN pg_roles m ON m.oid = am.member
220
+ LEFT JOIN pg_roles g ON g.oid = am.grantor
221
+ GROUP BY r.rolname
222
+ )
223
+ SELECT
224
+ quote_ident(r.rolname) AS name,
225
+ r.rolsuper AS is_superuser,
226
+ r.rolinherit AS can_inherit,
227
+ r.rolcreaterole AS can_create_roles,
228
+ r.rolcreatedb AS can_create_databases,
229
+ r.rolcanlogin AS can_login,
230
+ r.rolreplication AS can_replicate,
231
+ r.rolconnlimit AS connection_limit,
232
+ r.rolbypassrls AS can_bypass_rls,
233
+ r.rolconfig AS config,
234
+ obj_description(r.oid, 'pg_authid') AS comment,
235
+ COALESCE(rm.members, '[]') AS members,
236
+ COALESCE(
237
+ (
238
+ SELECT json_agg(
239
+ json_build_object(
240
+ 'in_schema',
241
+ CASE WHEN s.defaclnamespace = 0
242
+ THEN NULL
243
+ ELSE s.defaclnamespace::regnamespace::text
244
+ END,
245
+ 'objtype', s.defaclobjtype,
246
+ 'grantee',
247
+ CASE WHEN s.grantee = 0
248
+ THEN 'PUBLIC'
249
+ ELSE s.grantee::regrole::text
250
+ END,
251
+ 'privileges', s.privileges,
252
+ 'is_implicit', s.is_implicit
253
+ )
254
+ ORDER BY s.defaclnamespace NULLS FIRST,
255
+ s.defaclobjtype,
256
+ s.grantee
257
+ )
258
+ FROM (
259
+ -- Explicit entries from pg_default_acl
260
+ SELECT
261
+ d.defaclnamespace,
262
+ d.defaclobjtype,
263
+ x.grantee,
264
+ json_agg(
265
+ json_build_object(
266
+ 'privilege', x.privilege_type,
267
+ 'grantable', x.is_grantable
268
+ )
269
+ ORDER BY x.privilege_type, x.is_grantable
270
+ ) AS privileges,
271
+ false AS is_implicit
272
+ FROM pg_default_acl d
273
+ CROSS JOIN LATERAL aclexplode(COALESCE(d.defaclacl, ARRAY[]::aclitem[]))
274
+ AS x(grantor, grantee, privilege_type, is_grantable)
275
+ WHERE d.defaclrole = r.oid
276
+ GROUP BY d.defaclnamespace, d.defaclobjtype, x.grantee
277
+ UNION ALL
278
+ -- Implicit defaults from acldefault() for objtypes without a
279
+ -- global pg_default_acl entry. PostgreSQL applies these implicit
280
+ -- defaults (e.g. PUBLIC gets EXECUTE on functions) when no
281
+ -- explicit ALTER DEFAULT PRIVILEGES has been issued. Including
282
+ -- them lets the diff detect REVOKEs of implicit grants.
283
+ SELECT
284
+ 0 AS defaclnamespace,
285
+ v.t::"char" AS defaclobjtype,
286
+ x.grantee,
287
+ json_agg(
288
+ json_build_object(
289
+ 'privilege', x.privilege_type,
290
+ 'grantable', x.is_grantable
291
+ )
292
+ ORDER BY x.privilege_type, x.is_grantable
293
+ ) AS privileges,
294
+ true AS is_implicit
295
+ FROM (VALUES ('r'), ('S'), ('f'), ('T'), ('n')) AS v(t)
296
+ CROSS JOIN LATERAL aclexplode(acldefault(v.t::"char", r.oid))
297
+ AS x(grantor, grantee, privilege_type, is_grantable)
298
+ WHERE NOT EXISTS (
299
+ SELECT 1 FROM pg_default_acl d2
300
+ WHERE d2.defaclrole = r.oid
301
+ AND d2.defaclobjtype = v.t::"char"
302
+ AND d2.defaclnamespace = 0
303
+ )
304
+ GROUP BY v.t, x.grantee
305
+ ) AS s
306
+ ),
307
+ '[]'
308
+ ) AS default_privileges
309
+ FROM pg_catalog.pg_roles r
310
+ LEFT JOIN role_memberships rm ON rm.role_name = r.rolname
311
+ WHERE
312
+ r.rolname !~ '^pg_'
313
+ AND NOT EXISTS (
314
+ SELECT 1
315
+ FROM pg_catalog.pg_shdepend d
316
+ WHERE d.classid = 'pg_authid'::regclass
317
+ AND d.objid = r.oid
318
+ AND d.refclassid = 'pg_extension'::regclass
319
+ AND d.deptype IN ('e','x')
320
+ )
321
+ ORDER BY 1
322
+ `);
323
+ roleRows = result.rows;
324
+ } else {
325
+ const result = await pool.query<RoleProps>(sql`
326
+ WITH role_memberships AS (
327
+ SELECT
328
+ r.rolname AS role_name,
329
+ json_agg(
330
+ json_build_object(
331
+ 'member', m.rolname,
332
+ 'grantor', g.rolname,
333
+ 'admin_option', am.admin_option,
334
+ 'inherit_option', NULL,
335
+ 'set_option', NULL
336
+ )
337
+ ) FILTER (WHERE m.rolname IS NOT NULL) AS members
338
+ FROM pg_catalog.pg_roles r
339
+ LEFT JOIN pg_auth_members am ON am.roleid = r.oid
340
+ LEFT JOIN pg_roles m ON m.oid = am.member
341
+ LEFT JOIN pg_roles g ON g.oid = am.grantor
342
+ GROUP BY r.rolname
343
+ )
344
+ SELECT
345
+ quote_ident(r.rolname) AS name,
346
+ r.rolsuper AS is_superuser,
347
+ r.rolinherit AS can_inherit,
348
+ r.rolcreaterole AS can_create_roles,
349
+ r.rolcreatedb AS can_create_databases,
350
+ r.rolcanlogin AS can_login,
351
+ r.rolreplication AS can_replicate,
352
+ r.rolconnlimit AS connection_limit,
353
+ r.rolbypassrls AS can_bypass_rls,
354
+ r.rolconfig AS config,
355
+ obj_description(r.oid, 'pg_authid') AS comment,
356
+ COALESCE(rm.members, '[]') AS members,
357
+ COALESCE(
358
+ (
359
+ SELECT json_agg(
360
+ json_build_object(
361
+ 'in_schema',
362
+ CASE WHEN s.defaclnamespace = 0
363
+ THEN NULL
364
+ ELSE s.defaclnamespace::regnamespace::text
365
+ END,
366
+ 'objtype', s.defaclobjtype,
367
+ 'grantee',
368
+ CASE WHEN s.grantee = 0
369
+ THEN 'PUBLIC'
370
+ ELSE s.grantee::regrole::text
371
+ END,
372
+ 'privileges', s.privileges,
373
+ 'is_implicit', s.is_implicit
374
+ )
375
+ ORDER BY s.defaclnamespace NULLS FIRST,
376
+ s.defaclobjtype,
377
+ s.grantee
378
+ )
379
+ FROM (
380
+ -- Explicit entries from pg_default_acl
381
+ SELECT
382
+ d.defaclnamespace,
383
+ d.defaclobjtype,
384
+ x.grantee,
385
+ json_agg(
386
+ json_build_object(
387
+ 'privilege', x.privilege_type,
388
+ 'grantable', x.is_grantable
389
+ )
390
+ ORDER BY x.privilege_type, x.is_grantable
391
+ ) AS privileges,
392
+ false AS is_implicit
393
+ FROM pg_default_acl d
394
+ CROSS JOIN LATERAL aclexplode(COALESCE(d.defaclacl, ARRAY[]::aclitem[]))
395
+ AS x(grantor, grantee, privilege_type, is_grantable)
396
+ WHERE d.defaclrole = r.oid
397
+ GROUP BY d.defaclnamespace, d.defaclobjtype, x.grantee
398
+ UNION ALL
399
+ -- Implicit defaults from acldefault() for objtypes without a
400
+ -- global pg_default_acl entry. PostgreSQL applies these implicit
401
+ -- defaults (e.g. PUBLIC gets EXECUTE on functions) when no
402
+ -- explicit ALTER DEFAULT PRIVILEGES has been issued. Including
403
+ -- them lets the diff detect REVOKEs of implicit grants.
404
+ SELECT
405
+ 0 AS defaclnamespace,
406
+ v.t::"char" AS defaclobjtype,
407
+ x.grantee,
408
+ json_agg(
409
+ json_build_object(
410
+ 'privilege', x.privilege_type,
411
+ 'grantable', x.is_grantable
412
+ )
413
+ ORDER BY x.privilege_type, x.is_grantable
414
+ ) AS privileges,
415
+ true AS is_implicit
416
+ FROM (VALUES ('r'), ('S'), ('f'), ('T'), ('n')) AS v(t)
417
+ CROSS JOIN LATERAL aclexplode(acldefault(v.t::"char", r.oid))
418
+ AS x(grantor, grantee, privilege_type, is_grantable)
419
+ WHERE NOT EXISTS (
420
+ SELECT 1 FROM pg_default_acl d2
421
+ WHERE d2.defaclrole = r.oid
422
+ AND d2.defaclobjtype = v.t::"char"
423
+ AND d2.defaclnamespace = 0
424
+ )
425
+ GROUP BY v.t, x.grantee
426
+ ) AS s
427
+ ),
428
+ '[]'
429
+ ) AS default_privileges
430
+ FROM pg_catalog.pg_roles r
431
+ LEFT JOIN role_memberships rm ON rm.role_name = r.rolname
432
+ WHERE
433
+ r.rolname !~ '^pg_'
434
+ AND NOT EXISTS (
435
+ SELECT 1
436
+ FROM pg_catalog.pg_shdepend d
437
+ WHERE d.classid = 'pg_authid'::regclass
438
+ AND d.objid = r.oid
439
+ AND d.refclassid = 'pg_extension'::regclass
440
+ AND d.deptype IN ('e','x')
441
+ )
442
+ ORDER BY 1
443
+ `);
444
+ roleRows = result.rows;
445
+ }
446
+
447
+ // Validate and parse each row using the Zod schema
448
+ const validatedRows = roleRows.map((row: unknown) =>
449
+ rolePropsSchema.parse(row),
450
+ );
451
+ return validatedRows.map((row: RoleProps) => new Role(row));
452
+ }
@@ -0,0 +1,82 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
3
+ import { stableId } from "../../utils.ts";
4
+ import { Rule } from "../rule.model.ts";
5
+ import { ReplaceRule, SetRuleEnabledState } from "./rule.alter.ts";
6
+
7
+ type RuleProps = ConstructorParameters<typeof Rule>[0];
8
+
9
+ const base: RuleProps = {
10
+ schema: "public",
11
+ name: '"my_rule"',
12
+ table_name: '"my_table"',
13
+ relation_kind: "r",
14
+ event: "INSERT",
15
+ enabled: "O",
16
+ is_instead: true,
17
+ owner: "owner1",
18
+ definition:
19
+ 'CREATE RULE "my_rule" AS ON INSERT TO public."my_table" DO INSTEAD NOTHING',
20
+ comment: null,
21
+ columns: ["id"],
22
+ };
23
+
24
+ const makeRule = (override: Partial<RuleProps> = {}) =>
25
+ new Rule({
26
+ ...base,
27
+ ...override,
28
+ columns: override.columns ? [...override.columns] : [...base.columns],
29
+ });
30
+
31
+ describe("rule.alter", () => {
32
+ test("replace rule serializes using create or replace and tracks dependencies", async () => {
33
+ const rule = makeRule({ columns: ["id", "amount"] });
34
+ const change = new ReplaceRule({ rule });
35
+
36
+ expect(change.requires).toEqual([
37
+ rule.stableId,
38
+ rule.relationStableId,
39
+ ...rule.columns.map((column) =>
40
+ stableId.column(rule.schema, rule.table_name, column),
41
+ ),
42
+ ]);
43
+ await assertValidSql(change.serialize());
44
+ expect(change.serialize()).toBe(
45
+ 'CREATE OR REPLACE RULE "my_rule" AS ON INSERT TO public."my_table" DO INSTEAD NOTHING',
46
+ );
47
+ });
48
+
49
+ test("set rule enabled state serializes appropriate clause", async () => {
50
+ const rule = makeRule({ columns: ["id", "amount"] });
51
+ const change = new SetRuleEnabledState({ rule, enabled: "D" });
52
+
53
+ expect(change.requires).toEqual([
54
+ rule.stableId,
55
+ rule.relationStableId,
56
+ ...rule.columns.map((column) =>
57
+ stableId.column(rule.schema, rule.table_name, column),
58
+ ),
59
+ ]);
60
+ await assertValidSql(change.serialize());
61
+ expect(change.serialize()).toBe(
62
+ 'ALTER TABLE public."my_table" DISABLE RULE "my_rule"',
63
+ );
64
+ });
65
+
66
+ test("set rule enabled state defaults to rule value and supports views", async () => {
67
+ const rule = makeRule({
68
+ table_name: '"my_view"',
69
+ relation_kind: "v",
70
+ enabled: "R",
71
+ columns: [],
72
+ });
73
+
74
+ const change = new SetRuleEnabledState({ rule });
75
+
76
+ expect(change.requires).toEqual([rule.stableId, rule.relationStableId]);
77
+ await assertValidSql(change.serialize());
78
+ expect(change.serialize()).toBe(
79
+ 'ALTER TABLE public."my_view" ENABLE REPLICA RULE "my_rule"',
80
+ );
81
+ });
82
+ });
@@ -0,0 +1,72 @@
1
+ import { stableId } from "../../utils.ts";
2
+ import type { Rule, RuleEnabledState } from "../rule.model.ts";
3
+ import { AlterRuleChange } from "./rule.base.ts";
4
+ import { CreateRule } from "./rule.create.ts";
5
+
6
+ export class ReplaceRule extends AlterRuleChange {
7
+ public readonly rule: Rule;
8
+ public readonly scope = "object" as const;
9
+
10
+ constructor(props: { rule: Rule }) {
11
+ super();
12
+ this.rule = props.rule;
13
+ }
14
+
15
+ get requires() {
16
+ return [
17
+ this.rule.stableId,
18
+ this.rule.relationStableId,
19
+ ...this.rule.columns.map((column) =>
20
+ stableId.column(this.rule.schema, this.rule.table_name, column),
21
+ ),
22
+ ];
23
+ }
24
+
25
+ serialize(): string {
26
+ return new CreateRule({ rule: this.rule, orReplace: true }).serialize();
27
+ }
28
+ }
29
+
30
+ export class SetRuleEnabledState extends AlterRuleChange {
31
+ public readonly rule: Rule;
32
+ public readonly scope = "object" as const;
33
+ public readonly enabled: RuleEnabledState;
34
+
35
+ constructor(props: { rule: Rule; enabled?: RuleEnabledState }) {
36
+ super();
37
+ this.rule = props.rule;
38
+ this.enabled = props.enabled ?? props.rule.enabled;
39
+ }
40
+
41
+ get requires() {
42
+ return [
43
+ this.rule.stableId,
44
+ this.rule.relationStableId,
45
+ ...this.rule.columns.map((column) =>
46
+ stableId.column(this.rule.schema, this.rule.table_name, column),
47
+ ),
48
+ ];
49
+ }
50
+
51
+ serialize(): string {
52
+ const clause = clauseForState(this.enabled);
53
+ return `ALTER TABLE ${this.rule.schema}.${this.rule.table_name} ${clause} ${this.rule.name}`;
54
+ }
55
+ }
56
+
57
+ function clauseForState(state: RuleEnabledState) {
58
+ switch (state) {
59
+ case "O":
60
+ return "ENABLE RULE";
61
+ case "D":
62
+ return "DISABLE RULE";
63
+ case "R":
64
+ return "ENABLE REPLICA RULE";
65
+ case "A":
66
+ return "ENABLE ALWAYS RULE";
67
+ default: {
68
+ const _exhaustive: never = state;
69
+ return _exhaustive;
70
+ }
71
+ }
72
+ }
@@ -0,0 +1,20 @@
1
+ import { BaseChange } from "../../base.change.ts";
2
+ import type { Rule } from "../rule.model.ts";
3
+
4
+ abstract class BaseRuleChange extends BaseChange {
5
+ abstract readonly rule: Rule;
6
+ abstract readonly scope: "object" | "comment";
7
+ readonly objectType = "rule" as const;
8
+ }
9
+
10
+ export abstract class CreateRuleChange extends BaseRuleChange {
11
+ readonly operation = "create" as const;
12
+ }
13
+
14
+ export abstract class AlterRuleChange extends BaseRuleChange {
15
+ readonly operation = "alter" as const;
16
+ }
17
+
18
+ export abstract class DropRuleChange extends BaseRuleChange {
19
+ readonly operation = "drop" as const;
20
+ }
@@ -0,0 +1,58 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
3
+ import { stableId } from "../../utils.ts";
4
+ import { Rule } from "../rule.model.ts";
5
+ import { CreateCommentOnRule, DropCommentOnRule } from "./rule.comment.ts";
6
+
7
+ type RuleProps = ConstructorParameters<typeof Rule>[0];
8
+
9
+ const base: RuleProps = {
10
+ schema: "public",
11
+ name: '"my_rule"',
12
+ table_name: '"my_table"',
13
+ relation_kind: "r",
14
+ event: "INSERT",
15
+ enabled: "O",
16
+ is_instead: true,
17
+ owner: "owner1",
18
+ definition:
19
+ 'CREATE RULE "my_rule" AS ON INSERT TO public."my_table" DO INSTEAD NOTHING',
20
+ comment: null,
21
+ columns: ["id"],
22
+ };
23
+
24
+ const makeRule = (override: Partial<RuleProps> = {}) =>
25
+ new Rule({
26
+ ...base,
27
+ ...override,
28
+ columns: override.columns ? [...override.columns] : [...base.columns],
29
+ });
30
+
31
+ describe("rule.comment", () => {
32
+ test("create comment serializes and tracks dependencies", async () => {
33
+ const rule = makeRule({ comment: "rule's description" });
34
+ const change = new CreateCommentOnRule({ rule });
35
+
36
+ expect(change.creates).toEqual([stableId.comment(rule.stableId)]);
37
+ expect(change.requires).toEqual([rule.stableId]);
38
+ await assertValidSql(change.serialize());
39
+ expect(change.serialize()).toBe(
40
+ "COMMENT ON RULE \"my_rule\" ON public.\"my_table\" IS 'rule''s description'",
41
+ );
42
+ });
43
+
44
+ test("drop comment serializes and tracks dependencies", async () => {
45
+ const rule = makeRule({ comment: "temporary comment" });
46
+ const change = new DropCommentOnRule({ rule });
47
+
48
+ expect(change.drops).toEqual([stableId.comment(rule.stableId)]);
49
+ expect(change.requires).toEqual([
50
+ stableId.comment(rule.stableId),
51
+ rule.stableId,
52
+ ]);
53
+ await assertValidSql(change.serialize());
54
+ expect(change.serialize()).toBe(
55
+ 'COMMENT ON RULE "my_rule" ON public."my_table" IS NULL',
56
+ );
57
+ });
58
+ });