@supabase/pg-delta 1.0.0-alpha.4 → 1.0.0-alpha.6

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 (359) hide show
  1. package/README.md +40 -23
  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 +19 -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/core/catalog-export/index.d.ts +11 -0
  21. package/dist/core/catalog-export/index.js +10 -0
  22. package/dist/core/catalog.diff.d.ts +1 -0
  23. package/dist/core/catalog.diff.js +64 -48
  24. package/dist/core/catalog.model.d.ts +14 -1
  25. package/dist/core/catalog.model.js +103 -1
  26. package/dist/core/catalog.snapshot.d.ts +66 -0
  27. package/dist/core/catalog.snapshot.js +206 -0
  28. package/dist/core/declarative-apply/discover-sql.d.ts +18 -0
  29. package/dist/core/declarative-apply/discover-sql.js +86 -0
  30. package/dist/core/declarative-apply/extract-catalog-providers.d.ts +23 -0
  31. package/dist/core/declarative-apply/extract-catalog-providers.js +159 -0
  32. package/dist/core/declarative-apply/index.d.ts +49 -0
  33. package/dist/core/declarative-apply/index.js +134 -0
  34. package/dist/core/declarative-apply/round-apply.d.ts +100 -0
  35. package/dist/core/declarative-apply/round-apply.js +378 -0
  36. package/dist/core/export/file-mapper.d.ts +71 -0
  37. package/dist/core/export/file-mapper.js +474 -0
  38. package/dist/core/export/grouper.d.ts +13 -0
  39. package/dist/core/export/grouper.js +76 -0
  40. package/dist/core/export/index.d.ts +45 -0
  41. package/dist/core/export/index.js +63 -0
  42. package/dist/core/export/types.d.ts +84 -0
  43. package/dist/core/export/types.js +25 -0
  44. package/dist/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
  45. package/dist/core/integrations/filter/dsl.d.ts +38 -1
  46. package/dist/core/integrations/filter/dsl.js +20 -2
  47. package/dist/core/integrations/filter/extractors.js +42 -0
  48. package/dist/core/integrations/integration-dsl.d.ts +10 -0
  49. package/dist/core/integrations/supabase.d.ts +8 -0
  50. package/dist/core/integrations/supabase.js +9 -0
  51. package/dist/core/objects/aggregate/aggregate.diff.d.ts +2 -8
  52. package/dist/core/objects/aggregate/aggregate.diff.js +16 -70
  53. package/dist/core/objects/aggregate/aggregate.model.d.ts +8 -8
  54. package/dist/core/objects/aggregate/aggregate.model.js +1 -1
  55. package/dist/core/objects/aggregate/changes/aggregate.create.js +1 -1
  56. package/dist/core/objects/aggregate/changes/aggregate.drop.js +1 -1
  57. package/dist/core/objects/base.privilege-diff.d.ts +38 -13
  58. package/dist/core/objects/base.privilege-diff.js +104 -22
  59. package/dist/core/objects/base.privilege.d.ts +1 -0
  60. package/dist/core/objects/base.privilege.js +9 -2
  61. package/dist/core/objects/collation/collation.diff.d.ts +2 -3
  62. package/dist/core/objects/diff-context.d.ts +15 -0
  63. package/dist/core/objects/diff-context.js +1 -0
  64. package/dist/core/objects/domain/changes/domain.create.js +4 -2
  65. package/dist/core/objects/domain/domain.diff.d.ts +2 -8
  66. package/dist/core/objects/domain/domain.diff.js +16 -77
  67. package/dist/core/objects/domain/domain.model.js +1 -1
  68. package/dist/core/objects/event-trigger/event-trigger.diff.d.ts +2 -3
  69. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.d.ts +2 -8
  70. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.js +13 -77
  71. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.js +2 -2
  72. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.d.ts +2 -8
  73. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.js +16 -77
  74. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.js +1 -1
  75. package/dist/core/objects/foreign-data-wrapper/server/server.diff.d.ts +2 -8
  76. package/dist/core/objects/foreign-data-wrapper/server/server.diff.js +13 -77
  77. package/dist/core/objects/language/language.diff.d.ts +2 -5
  78. package/dist/core/objects/language/language.diff.js +7 -39
  79. package/dist/core/objects/materialized-view/materialized-view.diff.d.ts +2 -8
  80. package/dist/core/objects/materialized-view/materialized-view.diff.js +16 -158
  81. package/dist/core/objects/materialized-view/materialized-view.model.d.ts +3 -3
  82. package/dist/core/objects/materialized-view/materialized-view.model.js +1 -1
  83. package/dist/core/objects/procedure/changes/procedure.alter.js +12 -12
  84. package/dist/core/objects/procedure/procedure.diff.d.ts +2 -8
  85. package/dist/core/objects/procedure/procedure.diff.js +16 -77
  86. package/dist/core/objects/procedure/procedure.model.d.ts +9 -9
  87. package/dist/core/objects/procedure/procedure.model.js +1 -1
  88. package/dist/core/objects/publication/changes/publication.alter.d.ts +0 -9
  89. package/dist/core/objects/publication/changes/publication.alter.js +0 -14
  90. package/dist/core/objects/publication/changes/publication.types.d.ts +2 -2
  91. package/dist/core/objects/publication/publication.diff.d.ts +2 -3
  92. package/dist/core/objects/publication/publication.diff.js +8 -13
  93. package/dist/core/objects/rls-policy/changes/rls-policy.alter.js +3 -3
  94. package/dist/core/objects/rls-policy/rls-policy.model.d.ts +2 -2
  95. package/dist/core/objects/role/role.diff.js +22 -1
  96. package/dist/core/objects/role/role.model.d.ts +4 -3
  97. package/dist/core/objects/role/role.model.js +118 -12
  98. package/dist/core/objects/rule/rule.model.d.ts +1 -1
  99. package/dist/core/objects/schema/schema.diff.d.ts +2 -8
  100. package/dist/core/objects/schema/schema.diff.js +16 -77
  101. package/dist/core/objects/schema/schema.model.js +1 -1
  102. package/dist/core/objects/sequence/sequence.diff.d.ts +2 -8
  103. package/dist/core/objects/sequence/sequence.diff.js +16 -79
  104. package/dist/core/objects/sequence/sequence.model.js +1 -1
  105. package/dist/core/objects/subscription/subscription.diff.d.ts +2 -3
  106. package/dist/core/objects/table/changes/table.create.js +3 -0
  107. package/dist/core/objects/table/table.diff.d.ts +2 -8
  108. package/dist/core/objects/table/table.diff.js +26 -157
  109. package/dist/core/objects/table/table.model.d.ts +23 -22
  110. package/dist/core/objects/table/table.model.js +1 -1
  111. package/dist/core/objects/trigger/changes/trigger.create.js +2 -4
  112. package/dist/core/objects/trigger/trigger.model.d.ts +8 -0
  113. package/dist/core/objects/trigger/trigger.model.js +11 -0
  114. package/dist/core/objects/type/composite-type/composite-type.diff.d.ts +2 -8
  115. package/dist/core/objects/type/composite-type/composite-type.diff.js +16 -77
  116. package/dist/core/objects/type/composite-type/composite-type.model.d.ts +3 -3
  117. package/dist/core/objects/type/composite-type/composite-type.model.js +2 -1
  118. package/dist/core/objects/type/enum/enum.diff.d.ts +2 -8
  119. package/dist/core/objects/type/enum/enum.diff.js +25 -112
  120. package/dist/core/objects/type/enum/enum.model.js +1 -1
  121. package/dist/core/objects/type/range/changes/range.create.js +6 -3
  122. package/dist/core/objects/type/range/range.diff.d.ts +2 -8
  123. package/dist/core/objects/type/range/range.diff.js +16 -77
  124. package/dist/core/objects/type/range/range.model.js +1 -1
  125. package/dist/core/objects/view/view.diff.d.ts +2 -8
  126. package/dist/core/objects/view/view.diff.js +16 -158
  127. package/dist/core/objects/view/view.model.d.ts +18 -4
  128. package/dist/core/objects/view/view.model.js +3 -13
  129. package/dist/core/plan/apply.js +9 -26
  130. package/dist/core/plan/create.d.ts +19 -6
  131. package/dist/core/plan/create.js +134 -174
  132. package/dist/core/plan/serialize.js +16 -4
  133. package/dist/core/plan/sql-format/fixtures.js +3 -5
  134. package/dist/core/plan/sql-format/keyword-case.js +26 -1
  135. package/dist/core/plan/ssl-config.d.ts +32 -0
  136. package/dist/core/plan/ssl-config.js +115 -0
  137. package/dist/core/plan/types.d.ts +6 -0
  138. package/dist/core/postgres-config.d.ts +14 -0
  139. package/dist/core/postgres-config.js +53 -2
  140. package/dist/core/sort/graph-builder.js +10 -0
  141. package/dist/core/sort/logical-sort.js +31 -23
  142. package/dist/core/test-utils/assert-valid-sql.d.ts +10 -0
  143. package/dist/core/test-utils/assert-valid-sql.js +19 -0
  144. package/dist/index.d.ts +6 -0
  145. package/dist/index.js +6 -1
  146. package/package.json +21 -4
  147. package/src/cli/app.ts +27 -3
  148. package/src/cli/bin/cli.ts +6 -0
  149. package/src/cli/commands/catalog-export.ts +78 -0
  150. package/src/cli/commands/declarative-apply.diagnostics.test.ts +77 -0
  151. package/src/cli/commands/declarative-apply.ts +380 -0
  152. package/src/cli/commands/declarative-export.ts +330 -0
  153. package/src/cli/commands/plan.ts +28 -7
  154. package/src/cli/exit-code.test.ts +19 -0
  155. package/src/cli/exit-code.ts +7 -0
  156. package/src/cli/formatters/tree/tree.ts +3 -2
  157. package/src/cli/utils/apply-display.test.ts +348 -0
  158. package/src/cli/utils/apply-display.ts +238 -0
  159. package/src/cli/utils/export-display.test.ts +103 -0
  160. package/src/cli/utils/export-display.ts +275 -0
  161. package/src/cli/utils/integrations.test.ts +44 -0
  162. package/src/cli/utils/resolve-input.test.ts +38 -0
  163. package/src/cli/utils/resolve-input.ts +17 -0
  164. package/src/core/catalog-export/index.ts +20 -0
  165. package/src/core/catalog.diff.ts +79 -78
  166. package/src/core/catalog.model.test.ts +122 -0
  167. package/src/core/catalog.model.ts +127 -1
  168. package/src/core/catalog.snapshot.test.ts +464 -0
  169. package/src/core/catalog.snapshot.ts +289 -0
  170. package/src/core/declarative-apply/discover-sql.test.ts +103 -0
  171. package/src/core/declarative-apply/discover-sql.ts +107 -0
  172. package/src/core/declarative-apply/extract-catalog-providers.ts +220 -0
  173. package/src/core/declarative-apply/index.test.ts +67 -0
  174. package/src/core/declarative-apply/index.ts +205 -0
  175. package/src/core/declarative-apply/round-apply.test.ts +504 -0
  176. package/src/core/declarative-apply/round-apply.ts +562 -0
  177. package/src/core/expand-replace-dependencies.test.ts +70 -0
  178. package/src/core/export/file-mapper.test.ts +816 -0
  179. package/src/core/export/file-mapper.ts +574 -0
  180. package/src/core/export/grouper.ts +108 -0
  181. package/src/core/export/index.ts +129 -0
  182. package/src/core/export/types.ts +104 -0
  183. package/src/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
  184. package/src/core/integrations/filter/dsl.test.ts +211 -0
  185. package/src/core/integrations/filter/dsl.ts +65 -3
  186. package/src/core/integrations/filter/extractors.test.ts +244 -0
  187. package/src/core/integrations/filter/extractors.ts +42 -0
  188. package/src/core/integrations/integration-dsl.ts +10 -0
  189. package/src/core/integrations/serialize/dsl.test.ts +91 -0
  190. package/src/core/integrations/supabase.ts +9 -0
  191. package/src/core/objects/aggregate/aggregate.diff.ts +39 -95
  192. package/src/core/objects/aggregate/aggregate.model.ts +1 -1
  193. package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +3 -1
  194. package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +5 -2
  195. package/src/core/objects/aggregate/changes/aggregate.create.test.ts +6 -3
  196. package/src/core/objects/aggregate/changes/aggregate.create.ts +1 -1
  197. package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +7 -3
  198. package/src/core/objects/aggregate/changes/aggregate.drop.ts +1 -1
  199. package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +9 -3
  200. package/src/core/objects/base.privilege-diff.ts +178 -30
  201. package/src/core/objects/base.privilege.ts +9 -2
  202. package/src/core/objects/collation/changes/collation.alter.test.ts +7 -2
  203. package/src/core/objects/collation/changes/collation.create.test.ts +7 -2
  204. package/src/core/objects/collation/changes/collation.drop.test.ts +4 -1
  205. package/src/core/objects/collation/collation.diff.test.ts +9 -12
  206. package/src/core/objects/collation/collation.diff.ts +2 -1
  207. package/src/core/objects/diff-context.ts +16 -0
  208. package/src/core/objects/domain/changes/domain.alter.test.ts +28 -9
  209. package/src/core/objects/domain/changes/domain.create.test.ts +32 -2
  210. package/src/core/objects/domain/changes/domain.create.ts +7 -1
  211. package/src/core/objects/domain/changes/domain.drop.test.ts +4 -1
  212. package/src/core/objects/domain/domain.diff.ts +39 -102
  213. package/src/core/objects/domain/domain.model.ts +1 -1
  214. package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +10 -3
  215. package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +4 -1
  216. package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +4 -1
  217. package/src/core/objects/event-trigger/event-trigger.diff.test.ts +12 -7
  218. package/src/core/objects/event-trigger/event-trigger.diff.ts +2 -1
  219. package/src/core/objects/extension/changes/extension.alter.test.ts +7 -2
  220. package/src/core/objects/extension/changes/extension.create.test.ts +4 -1
  221. package/src/core/objects/extension/changes/extension.drop.test.ts +4 -1
  222. package/src/core/objects/extension/extension.model.test.ts +98 -0
  223. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +16 -5
  224. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +51 -16
  225. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +4 -1
  226. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +111 -4
  227. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +31 -101
  228. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +2 -2
  229. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +46 -15
  230. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +13 -4
  231. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +4 -1
  232. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +39 -102
  233. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +1 -1
  234. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +22 -7
  235. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +19 -6
  236. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +4 -1
  237. package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +95 -0
  238. package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +31 -101
  239. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +13 -4
  240. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +16 -5
  241. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +10 -3
  242. package/src/core/objects/index/changes/index.alter.test.ts +13 -4
  243. package/src/core/objects/index/changes/index.create.test.ts +4 -1
  244. package/src/core/objects/index/changes/index.drop.test.ts +4 -1
  245. package/src/core/objects/language/changes/language.alter.test.ts +4 -1
  246. package/src/core/objects/language/changes/language.create.test.ts +4 -1
  247. package/src/core/objects/language/changes/language.drop.test.ts +4 -1
  248. package/src/core/objects/language/language.diff.test.ts +86 -4
  249. package/src/core/objects/language/language.diff.ts +17 -49
  250. package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +10 -3
  251. package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +7 -2
  252. package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +4 -1
  253. package/src/core/objects/materialized-view/materialized-view.diff.test.ts +162 -0
  254. package/src/core/objects/materialized-view/materialized-view.diff.ts +41 -191
  255. package/src/core/objects/materialized-view/materialized-view.model.ts +1 -1
  256. package/src/core/objects/procedure/changes/procedure.alter.test.ts +121 -49
  257. package/src/core/objects/procedure/changes/procedure.alter.ts +15 -12
  258. package/src/core/objects/procedure/changes/procedure.create.test.ts +4 -1
  259. package/src/core/objects/procedure/changes/procedure.drop.test.ts +7 -2
  260. package/src/core/objects/procedure/procedure.diff.ts +39 -102
  261. package/src/core/objects/procedure/procedure.model.ts +1 -1
  262. package/src/core/objects/publication/changes/publication.alter.test.ts +15 -21
  263. package/src/core/objects/publication/changes/publication.alter.ts +0 -18
  264. package/src/core/objects/publication/changes/publication.comment.test.ts +5 -2
  265. package/src/core/objects/publication/changes/publication.create.test.ts +5 -2
  266. package/src/core/objects/publication/changes/publication.drop.test.ts +3 -1
  267. package/src/core/objects/publication/changes/publication.types.ts +0 -2
  268. package/src/core/objects/publication/publication.diff.test.ts +24 -19
  269. package/src/core/objects/publication/publication.diff.ts +9 -15
  270. package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +31 -14
  271. package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +3 -3
  272. package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +10 -3
  273. package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +4 -1
  274. package/src/core/objects/role/changes/role.alter.test.ts +31 -15
  275. package/src/core/objects/role/changes/role.create.test.ts +6 -2
  276. package/src/core/objects/role/changes/role.drop.test.ts +4 -1
  277. package/src/core/objects/role/role.diff.test.ts +235 -0
  278. package/src/core/objects/role/role.diff.ts +21 -1
  279. package/src/core/objects/role/role.model.ts +122 -14
  280. package/src/core/objects/rule/changes/rule.alter.test.ts +7 -3
  281. package/src/core/objects/rule/changes/rule.comment.test.ts +5 -2
  282. package/src/core/objects/rule/changes/rule.create.test.ts +6 -2
  283. package/src/core/objects/rule/changes/rule.drop.test.ts +3 -1
  284. package/src/core/objects/schema/changes/schema.alter.test.ts +4 -1
  285. package/src/core/objects/schema/changes/schema.create.test.ts +4 -1
  286. package/src/core/objects/schema/changes/schema.drop.test.ts +4 -1
  287. package/src/core/objects/schema/schema.diff.ts +39 -102
  288. package/src/core/objects/schema/schema.model.ts +1 -1
  289. package/src/core/objects/sequence/changes/sequence.alter.test.ts +11 -5
  290. package/src/core/objects/sequence/changes/sequence.create.test.ts +8 -3
  291. package/src/core/objects/sequence/changes/sequence.drop.test.ts +4 -1
  292. package/src/core/objects/sequence/sequence.diff.test.ts +114 -0
  293. package/src/core/objects/sequence/sequence.diff.ts +39 -104
  294. package/src/core/objects/sequence/sequence.model.ts +1 -1
  295. package/src/core/objects/subscription/changes/subscription.alter.test.ts +15 -5
  296. package/src/core/objects/subscription/changes/subscription.comment.test.ts +5 -2
  297. package/src/core/objects/subscription/changes/subscription.create.test.ts +5 -2
  298. package/src/core/objects/subscription/changes/subscription.drop.test.ts +3 -1
  299. package/src/core/objects/subscription/subscription.diff.test.ts +16 -11
  300. package/src/core/objects/subscription/subscription.diff.ts +2 -1
  301. package/src/core/objects/table/changes/table.alter.test.ts +38 -15
  302. package/src/core/objects/table/changes/table.create.test.ts +41 -3
  303. package/src/core/objects/table/changes/table.create.ts +4 -0
  304. package/src/core/objects/table/changes/table.drop.test.ts +3 -1
  305. package/src/core/objects/table/table.diff.test.ts +157 -0
  306. package/src/core/objects/table/table.diff.ts +54 -190
  307. package/src/core/objects/table/table.model.ts +1 -1
  308. package/src/core/objects/trigger/changes/trigger.alter.test.ts +8 -4
  309. package/src/core/objects/trigger/changes/trigger.create.test.ts +5 -1
  310. package/src/core/objects/trigger/changes/trigger.create.ts +7 -4
  311. package/src/core/objects/trigger/changes/trigger.drop.test.ts +5 -1
  312. package/src/core/objects/trigger/trigger.diff.test.ts +1 -0
  313. package/src/core/objects/trigger/trigger.model.ts +12 -0
  314. package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +10 -4
  315. package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +7 -2
  316. package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +4 -1
  317. package/src/core/objects/type/composite-type/composite-type.diff.test.ts +78 -0
  318. package/src/core/objects/type/composite-type/composite-type.diff.ts +39 -101
  319. package/src/core/objects/type/composite-type/composite-type.model.ts +2 -1
  320. package/src/core/objects/type/enum/changes/enum.alter.test.ts +14 -5
  321. package/src/core/objects/type/enum/changes/enum.create.test.ts +4 -1
  322. package/src/core/objects/type/enum/changes/enum.drop.test.ts +4 -1
  323. package/src/core/objects/type/enum/enum.diff.test.ts +181 -0
  324. package/src/core/objects/type/enum/enum.diff.ts +58 -146
  325. package/src/core/objects/type/enum/enum.model.ts +1 -1
  326. package/src/core/objects/type/range/changes/range.alter.test.ts +3 -1
  327. package/src/core/objects/type/range/changes/range.create.test.ts +5 -2
  328. package/src/core/objects/type/range/changes/range.create.ts +6 -2
  329. package/src/core/objects/type/range/changes/range.drop.test.ts +3 -1
  330. package/src/core/objects/type/range/range.diff.test.ts +77 -0
  331. package/src/core/objects/type/range/range.diff.ts +39 -101
  332. package/src/core/objects/type/range/range.model.ts +1 -1
  333. package/src/core/objects/view/changes/view.alter.test.ts +8 -3
  334. package/src/core/objects/view/changes/view.create.test.ts +7 -2
  335. package/src/core/objects/view/changes/view.drop.test.ts +4 -1
  336. package/src/core/objects/view/view.diff.test.ts +82 -0
  337. package/src/core/objects/view/view.diff.ts +41 -191
  338. package/src/core/objects/view/view.model.ts +3 -17
  339. package/src/core/plan/apply.ts +9 -27
  340. package/src/core/plan/create.ts +173 -237
  341. package/src/core/plan/serialize.test.ts +317 -0
  342. package/src/core/plan/serialize.ts +18 -4
  343. package/src/core/plan/sql-format/fixtures.ts +2 -5
  344. package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +52 -0
  345. package/src/core/plan/sql-format/format-off.test.ts +14 -17
  346. package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +27 -22
  347. package/src/core/plan/sql-format/format-pretty-narrow.test.ts +17 -21
  348. package/src/core/plan/sql-format/format-pretty-preserve.test.ts +25 -20
  349. package/src/core/plan/sql-format/format-pretty-upper.test.ts +23 -20
  350. package/src/core/plan/sql-format/keyword-case.ts +36 -1
  351. package/src/core/plan/ssl-config.ts +172 -0
  352. package/src/core/plan/types.ts +6 -0
  353. package/src/core/postgres-config.ts +71 -2
  354. package/src/core/sort/graph-builder.ts +12 -0
  355. package/src/core/sort/logical-sort.test.ts +371 -0
  356. package/src/core/sort/logical-sort.ts +32 -25
  357. package/src/core/sort/topological-sort.test.ts +275 -0
  358. package/src/core/test-utils/assert-valid-sql.ts +20 -0
  359. package/src/index.ts +26 -2
@@ -64,6 +64,9 @@ export class CreateTable extends CreateTableChange {
64
64
  }
65
65
  }
66
66
  }
67
+ // Function dependencies from DEFAULT expressions are handled by pg_depend
68
+ // catalog constraints in the sort pipeline, which provides exact argument
69
+ // types and covers all expression contexts (not just column defaults).
67
70
  }
68
71
  return Array.from(dependencies);
69
72
  }
@@ -1,5 +1,4 @@
1
- import type { DefaultPrivilegeState } from "../base.default-privileges.ts";
2
- import type { Role } from "../role/role.model.ts";
1
+ import type { ObjectDiffContext } from "../diff-context.ts";
3
2
  import type { TableChange } from "./changes/table.types.ts";
4
3
  import { Table } from "./table.model.ts";
5
4
  /**
@@ -10,9 +9,4 @@ import { Table } from "./table.model.ts";
10
9
  * @param branch - The tables in the branch catalog.
11
10
  * @returns A list of changes to apply to main to make it match branch.
12
11
  */
13
- export declare function diffTables(ctx: {
14
- version: number;
15
- currentUser: string;
16
- defaultPrivilegeState: DefaultPrivilegeState;
17
- mainRoles: Record<string, Role>;
18
- }, main: Record<string, Table>, branch: Record<string, Table>): TableChange[];
12
+ export declare function diffTables(ctx: Pick<ObjectDiffContext, "version" | "currentUser" | "defaultPrivilegeState">, main: Record<string, Table>, branch: Record<string, Table>): TableChange[];
@@ -1,5 +1,5 @@
1
1
  import { diffObjects } from "../base.diff.js";
2
- import { diffPrivileges, groupPrivilegesByColumns, } from "../base.privilege-diff.js";
2
+ import { diffPrivileges, emitColumnPrivilegeChanges, } from "../base.privilege-diff.js";
3
3
  import { deepEqual } from "../utils.js";
4
4
  import { AlterTableAddColumn, AlterTableAddConstraint, AlterTableAlterColumnDropDefault, AlterTableAlterColumnDropNotNull, AlterTableAlterColumnSetDefault, AlterTableAlterColumnSetNotNull, AlterTableAlterColumnType, AlterTableAttachPartition, AlterTableChangeOwner, AlterTableDetachPartition, AlterTableDisableRowLevelSecurity, AlterTableDropColumn, AlterTableDropConstraint, AlterTableEnableRowLevelSecurity, AlterTableForceRowLevelSecurity, AlterTableNoForceRowLevelSecurity, AlterTableResetStorageParams, AlterTableSetLogged, AlterTableSetReplicaIdentity, AlterTableSetStorageParams, AlterTableSetUnlogged, AlterTableValidateConstraint, } from "./changes/table.alter.js";
5
5
  import { CreateCommentOnColumn, CreateCommentOnConstraint, CreateCommentOnTable, DropCommentOnColumn, DropCommentOnConstraint, DropCommentOnTable, } from "./changes/table.comment.js";
@@ -149,6 +149,16 @@ export function diffTables(ctx, main, branch) {
149
149
  if (branchTable.force_row_security) {
150
150
  changes.push(new AlterTableForceRowLevelSecurity({ table: branchTable }));
151
151
  }
152
+ // REPLICA IDENTITY: If non-default, emit ALTER TABLE ... REPLICA IDENTITY
153
+ if (branchTable.replica_identity !== "d") {
154
+ // Skip 'i' (USING INDEX) — handled by index changes
155
+ if (branchTable.replica_identity !== "i") {
156
+ changes.push(new AlterTableSetReplicaIdentity({
157
+ table: branchTable,
158
+ mode: branchTable.replica_identity,
159
+ }));
160
+ }
161
+ }
152
162
  changes.push(...createAlterConstraintChange(
153
163
  // Create a dummy table with no constraints do diff constraints against
154
164
  new Table({
@@ -171,86 +181,18 @@ export function diffTables(ctx, main, branch) {
171
181
  // We compare default privileges against desired privileges to generate REVOKE/GRANT statements
172
182
  // needed to reach the final desired state.
173
183
  const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(ctx.currentUser, "table", branchTable.schema ?? "");
184
+ const creatorFilteredDefaults = branchTable.owner !== ctx.currentUser
185
+ ? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
186
+ : effectiveDefaults;
174
187
  const desiredPrivileges = branchTable.privileges;
175
188
  // Filter out owner privileges - owner always has ALL privileges implicitly
176
189
  // and shouldn't be compared. Use the table owner as the reference.
177
- const privilegeResults = diffPrivileges(effectiveDefaults, desiredPrivileges, branchTable.owner, ctx.mainRoles);
178
- // Generate grant changes
179
- for (const [grantee, result] of privilegeResults) {
180
- if (result.grants.length > 0) {
181
- const grantGroups = groupPrivilegesByColumns(result.grants);
182
- for (const [, group] of grantGroups) {
183
- for (const [grantable, privSet] of group.byGrant) {
184
- const privileges = Array.from(privSet).map((priv) => ({
185
- privilege: priv,
186
- grantable,
187
- }));
188
- changes.push(new GrantTablePrivileges({
189
- table: branchTable,
190
- grantee,
191
- privileges,
192
- columns: group.columns,
193
- version: ctx.version,
194
- }));
195
- }
196
- }
197
- }
198
- // Generate revoke changes
199
- if (result.revokes.length > 0) {
200
- const revokeGroups = groupPrivilegesByColumns(result.revokes);
201
- for (const [, group] of revokeGroups) {
202
- const allPrivileges = new Set();
203
- for (const [, privSet] of group.byGrant) {
204
- for (const priv of privSet) {
205
- allPrivileges.add(priv);
206
- }
207
- }
208
- const privileges = Array.from(allPrivileges).map((priv) => ({
209
- privilege: priv,
210
- grantable: false,
211
- }));
212
- changes.push(new RevokeTablePrivileges({
213
- table: branchTable,
214
- grantee,
215
- privileges,
216
- columns: group.columns,
217
- version: ctx.version,
218
- }));
219
- }
220
- }
221
- // Generate revoke grant option changes
222
- if (result.revokeGrantOption.length > 0) {
223
- const revokeGrantGroups = new Map();
224
- for (const r of result.revokeGrantOption) {
225
- const originalPriv = effectiveDefaults.find((p) => p.grantee === grantee && p.privilege === r);
226
- const key = originalPriv?.columns
227
- ? originalPriv.columns.sort().join(",")
228
- : "";
229
- if (!revokeGrantGroups.has(key)) {
230
- revokeGrantGroups.set(key, {
231
- columns: originalPriv?.columns
232
- ? [...originalPriv.columns]
233
- : undefined,
234
- privileges: new Set(),
235
- });
236
- }
237
- const group = revokeGrantGroups.get(key);
238
- if (!group)
239
- continue;
240
- group.privileges.add(r);
241
- }
242
- for (const [, group] of revokeGrantGroups) {
243
- const privilegeNames = Array.from(group.privileges);
244
- changes.push(new RevokeGrantOptionTablePrivileges({
245
- table: branchTable,
246
- grantee,
247
- privilegeNames,
248
- columns: group.columns,
249
- version: ctx.version,
250
- }));
251
- }
252
- }
253
- }
190
+ const privilegeResults = diffPrivileges(creatorFilteredDefaults, desiredPrivileges, branchTable.owner);
191
+ changes.push(...emitColumnPrivilegeChanges(privilegeResults, branchTable, branchTable, "table", {
192
+ Grant: GrantTablePrivileges,
193
+ Revoke: RevokeTablePrivileges,
194
+ RevokeGrantOption: RevokeGrantOptionTablePrivileges,
195
+ }, effectiveDefaults, ctx.version));
254
196
  }
255
197
  for (const tableId of dropped) {
256
198
  changes.push(new DropTable({ table: main[tableId] }));
@@ -584,85 +526,12 @@ export function diffTables(ctx, main, branch) {
584
526
  // PRIVILEGES (unified object and column privileges)
585
527
  // Filter out owner privileges - owner always has ALL privileges implicitly
586
528
  // and shouldn't be compared. Use branch owner as the reference.
587
- const privilegeResults = diffPrivileges(mainTable.privileges, branchTable.privileges, branchTable.owner, ctx.mainRoles);
588
- for (const [grantee, result] of privilegeResults) {
589
- // Generate grant changes
590
- if (result.grants.length > 0) {
591
- const grantGroups = groupPrivilegesByColumns(result.grants);
592
- for (const [, group] of grantGroups) {
593
- for (const [grantable, privSet] of group.byGrant) {
594
- const privileges = Array.from(privSet).map((priv) => ({
595
- privilege: priv,
596
- grantable,
597
- }));
598
- changes.push(new GrantTablePrivileges({
599
- table: branchTable,
600
- grantee,
601
- privileges,
602
- columns: group.columns,
603
- version: ctx.version,
604
- }));
605
- }
606
- }
607
- }
608
- // Generate revoke changes
609
- if (result.revokes.length > 0) {
610
- const revokeGroups = groupPrivilegesByColumns(result.revokes);
611
- for (const [, group] of revokeGroups) {
612
- // Collapse all grantable groups into a single revoke (grantable: false)
613
- const allPrivileges = new Set();
614
- for (const [, privSet] of group.byGrant) {
615
- for (const priv of privSet) {
616
- allPrivileges.add(priv);
617
- }
618
- }
619
- const privileges = Array.from(allPrivileges).map((priv) => ({
620
- privilege: priv,
621
- grantable: false,
622
- }));
623
- changes.push(new RevokeTablePrivileges({
624
- table: mainTable,
625
- grantee,
626
- privileges,
627
- columns: group.columns,
628
- version: ctx.version,
629
- }));
630
- }
631
- }
632
- // Generate revoke grant option changes
633
- if (result.revokeGrantOption.length > 0) {
634
- const revokeGrantGroups = new Map();
635
- for (const r of result.revokeGrantOption) {
636
- // For revoke grant option, we need to find the columns from the original privilege
637
- const originalPriv = mainTable.privileges.find((p) => p.grantee === grantee && p.privilege === r);
638
- const key = originalPriv?.columns
639
- ? originalPriv.columns.sort().join(",")
640
- : "";
641
- if (!revokeGrantGroups.has(key)) {
642
- revokeGrantGroups.set(key, {
643
- columns: originalPriv?.columns
644
- ? [...originalPriv.columns]
645
- : undefined,
646
- privileges: new Set(),
647
- });
648
- }
649
- const group = revokeGrantGroups.get(key);
650
- if (!group)
651
- continue;
652
- group.privileges.add(r);
653
- }
654
- for (const [, group] of revokeGrantGroups) {
655
- const privilegeNames = Array.from(group.privileges);
656
- changes.push(new RevokeGrantOptionTablePrivileges({
657
- table: mainTable,
658
- grantee,
659
- privilegeNames,
660
- columns: group.columns,
661
- version: ctx.version,
662
- }));
663
- }
664
- }
665
- }
529
+ const privilegeResults = diffPrivileges(mainTable.privileges, branchTable.privileges, branchTable.owner);
530
+ changes.push(...emitColumnPrivilegeChanges(privilegeResults, branchTable, mainTable, "table", {
531
+ Grant: GrantTablePrivileges,
532
+ Revoke: RevokeTablePrivileges,
533
+ RevokeGrantOption: RevokeGrantOptionTablePrivileges,
534
+ }, mainTable.privileges, ctx.version));
666
535
  }
667
536
  return changes;
668
537
  }
@@ -3,19 +3,19 @@ import z from "zod";
3
3
  import { BasePgModel, type TableLikeObject } from "../base.model.ts";
4
4
  import { type PrivilegeProps } from "../base.privilege-diff.ts";
5
5
  export declare const ReplicaIdentitySchema: z.ZodEnum<{
6
- f: "f";
7
6
  n: "n";
8
7
  i: "i";
9
8
  d: "d";
9
+ f: "f";
10
10
  }>;
11
11
  declare const tableConstraintPropsSchema: z.ZodObject<{
12
12
  name: z.ZodString;
13
13
  constraint_type: z.ZodEnum<{
14
- f: "f";
15
14
  u: "u";
16
15
  t: "t";
17
- p: "p";
18
16
  c: "c";
17
+ p: "p";
18
+ f: "f";
19
19
  x: "x";
20
20
  }>;
21
21
  deferrable: z.ZodBoolean;
@@ -38,24 +38,24 @@ declare const tableConstraintPropsSchema: z.ZodObject<{
38
38
  foreign_key_effective_schema: z.ZodNullable<z.ZodString>;
39
39
  foreign_key_effective_table: z.ZodNullable<z.ZodString>;
40
40
  on_update: z.ZodNullable<z.ZodEnum<{
41
- r: "r";
42
41
  n: "n";
43
42
  a: "a";
43
+ r: "r";
44
44
  d: "d";
45
45
  c: "c";
46
46
  }>>;
47
47
  on_delete: z.ZodNullable<z.ZodEnum<{
48
- r: "r";
49
48
  n: "n";
50
49
  a: "a";
50
+ r: "r";
51
51
  d: "d";
52
52
  c: "c";
53
53
  }>>;
54
54
  match_type: z.ZodNullable<z.ZodEnum<{
55
- f: "f";
56
55
  u: "u";
57
56
  s: "s";
58
57
  p: "p";
58
+ f: "f";
59
59
  }>>;
60
60
  check_expression: z.ZodNullable<z.ZodString>;
61
61
  owner: z.ZodString;
@@ -79,10 +79,10 @@ declare const tablePropsSchema: z.ZodObject<{
79
79
  has_subclasses: z.ZodBoolean;
80
80
  is_populated: z.ZodBoolean;
81
81
  replica_identity: z.ZodEnum<{
82
- f: "f";
83
82
  n: "n";
84
83
  i: "i";
85
84
  d: "d";
85
+ f: "f";
86
86
  }>;
87
87
  is_partition: z.ZodBoolean;
88
88
  options: z.ZodNullable<z.ZodArray<z.ZodString>>;
@@ -113,11 +113,11 @@ declare const tablePropsSchema: z.ZodObject<{
113
113
  constraints: z.ZodOptional<z.ZodArray<z.ZodObject<{
114
114
  name: z.ZodString;
115
115
  constraint_type: z.ZodEnum<{
116
- f: "f";
117
116
  u: "u";
118
117
  t: "t";
119
- p: "p";
120
118
  c: "c";
119
+ p: "p";
120
+ f: "f";
121
121
  x: "x";
122
122
  }>;
123
123
  deferrable: z.ZodBoolean;
@@ -140,24 +140,24 @@ declare const tablePropsSchema: z.ZodObject<{
140
140
  foreign_key_effective_schema: z.ZodNullable<z.ZodString>;
141
141
  foreign_key_effective_table: z.ZodNullable<z.ZodString>;
142
142
  on_update: z.ZodNullable<z.ZodEnum<{
143
- r: "r";
144
143
  n: "n";
145
144
  a: "a";
145
+ r: "r";
146
146
  d: "d";
147
147
  c: "c";
148
148
  }>>;
149
149
  on_delete: z.ZodNullable<z.ZodEnum<{
150
- r: "r";
151
150
  n: "n";
152
151
  a: "a";
152
+ r: "r";
153
153
  d: "d";
154
154
  c: "c";
155
155
  }>>;
156
156
  match_type: z.ZodNullable<z.ZodEnum<{
157
- f: "f";
158
157
  u: "u";
159
158
  s: "s";
160
159
  p: "p";
160
+ f: "f";
161
161
  }>>;
162
162
  check_expression: z.ZodNullable<z.ZodString>;
163
163
  owner: z.ZodString;
@@ -206,7 +206,7 @@ export declare class Table extends BasePgModel implements TableLikeObject {
206
206
  persistence: "u" | "t" | "p";
207
207
  row_security: boolean;
208
208
  force_row_security: boolean;
209
- replica_identity: "f" | "n" | "i" | "d";
209
+ replica_identity: "n" | "i" | "d" | "f";
210
210
  options: string[] | null;
211
211
  parent_schema: string | null;
212
212
  parent_name: string | null;
@@ -233,7 +233,7 @@ export declare class Table extends BasePgModel implements TableLikeObject {
233
233
  }[];
234
234
  constraints: {
235
235
  name: string;
236
- constraint_type: "f" | "u" | "t" | "p" | "c" | "x";
236
+ constraint_type: "u" | "t" | "c" | "p" | "f" | "x";
237
237
  deferrable: boolean;
238
238
  initially_deferred: boolean;
239
239
  validated: boolean;
@@ -253,9 +253,9 @@ export declare class Table extends BasePgModel implements TableLikeObject {
253
253
  foreign_key_parent_table: string | null;
254
254
  foreign_key_effective_schema: string | null;
255
255
  foreign_key_effective_table: string | null;
256
- on_update: "r" | "n" | "a" | "d" | "c" | null;
257
- on_delete: "r" | "n" | "a" | "d" | "c" | null;
258
- match_type: "f" | "u" | "s" | "p" | null;
256
+ on_update: "n" | "a" | "r" | "d" | "c" | null;
257
+ on_delete: "n" | "a" | "r" | "d" | "c" | null;
258
+ match_type: "u" | "s" | "p" | "f" | null;
259
259
  check_expression: string | null;
260
260
  owner: string;
261
261
  definition: string;
@@ -294,7 +294,7 @@ export declare class Table extends BasePgModel implements TableLikeObject {
294
294
  options: string[] | null;
295
295
  constraints: {
296
296
  name: string;
297
- constraint_type: "f" | "u" | "t" | "p" | "c" | "x";
297
+ constraint_type: "u" | "t" | "c" | "p" | "f" | "x";
298
298
  deferrable: boolean;
299
299
  initially_deferred: boolean;
300
300
  validated: boolean;
@@ -314,9 +314,9 @@ export declare class Table extends BasePgModel implements TableLikeObject {
314
314
  foreign_key_parent_table: string | null;
315
315
  foreign_key_effective_schema: string | null;
316
316
  foreign_key_effective_table: string | null;
317
- on_update: "r" | "n" | "a" | "d" | "c" | null;
318
- on_delete: "r" | "n" | "a" | "d" | "c" | null;
319
- match_type: "f" | "u" | "s" | "p" | null;
317
+ on_update: "n" | "a" | "r" | "d" | "c" | null;
318
+ on_delete: "n" | "a" | "r" | "d" | "c" | null;
319
+ match_type: "u" | "s" | "p" | "f" | null;
320
320
  check_expression: string | null;
321
321
  owner: string;
322
322
  definition: string;
@@ -326,11 +326,12 @@ export declare class Table extends BasePgModel implements TableLikeObject {
326
326
  grantee: string;
327
327
  privilege: string;
328
328
  grantable: boolean;
329
+ columns: string[] | null | undefined;
329
330
  }[];
330
331
  persistence: "u" | "t" | "p";
331
332
  row_security: boolean;
332
333
  force_row_security: boolean;
333
- replica_identity: "f" | "n" | "i" | "d";
334
+ replica_identity: "n" | "i" | "d" | "f";
334
335
  parent_schema: string | null;
335
336
  parent_name: string | null;
336
337
  partition_bound: string | null;
@@ -397,7 +397,7 @@ select
397
397
  from (
398
398
  -- one row for object ACL + one row per column ACL
399
399
  select null::name as attname, t.oid as relacl_oid, (
400
- select c_rel.relacl from pg_class c_rel where c_rel.oid = t.oid
400
+ select COALESCE(c_rel.relacl, acldefault('r', c_rel.relowner)) from pg_class c_rel where c_rel.oid = t.oid
401
401
  ) as acl
402
402
  union all
403
403
  select a2.attname, t.oid as relacl_oid, a2.attacl
@@ -45,10 +45,8 @@ export class CreateTrigger extends CreateTriggerChange {
45
45
  // Table dependency
46
46
  dependencies.add(stableId.table(this.trigger.schema, this.trigger.table_name));
47
47
  // Function dependency
48
- // Note: We can't build the exact procedure stableId without argument types.
49
- // The trigger definition contains the full function call, but parsing it would be complex.
50
- // For now, we rely on pg_depend extraction for procedure dependencies.
51
- // If needed, we could parse the trigger definition to extract the full function signature.
48
+ // Trigger functions always have signature () RETURNS trigger, so no arguments.
49
+ dependencies.add(stableId.procedure(this.trigger.function_schema, this.trigger.function_name));
52
50
  // Owner dependency
53
51
  dependencies.add(stableId.role(this.trigger.owner));
54
52
  return Array.from(dependencies);
@@ -5,6 +5,13 @@ declare const triggerPropsSchema: z.ZodObject<{
5
5
  schema: z.ZodString;
6
6
  name: z.ZodString;
7
7
  table_name: z.ZodString;
8
+ table_relkind: z.ZodEnum<{
9
+ r: "r";
10
+ v: "v";
11
+ m: "m";
12
+ p: "p";
13
+ f: "f";
14
+ }>;
8
15
  function_schema: z.ZodString;
9
16
  function_name: z.ZodString;
10
17
  trigger_type: z.ZodNumber;
@@ -37,6 +44,7 @@ export declare class Trigger extends BasePgModel {
37
44
  readonly schema: TriggerProps["schema"];
38
45
  readonly name: TriggerProps["name"];
39
46
  readonly table_name: TriggerProps["table_name"];
47
+ readonly table_relkind: TriggerProps["table_relkind"];
40
48
  readonly function_schema: TriggerProps["function_schema"];
41
49
  readonly function_name: TriggerProps["function_name"];
42
50
  readonly trigger_type: TriggerProps["trigger_type"];
@@ -7,10 +7,18 @@ const TriggerEnabledSchema = z.enum([
7
7
  "R", // REPLICA - trigger fires only in "replica" mode
8
8
  "A", // ALWAYS - trigger fires regardless of replication mode
9
9
  ]);
10
+ const TriggerTableRelkindSchema = z.enum([
11
+ "r", // ordinary table
12
+ "p", // partitioned table
13
+ "f", // foreign table
14
+ "v", // view
15
+ "m", // materialized view
16
+ ]);
10
17
  const triggerPropsSchema = z.object({
11
18
  schema: z.string(),
12
19
  name: z.string(),
13
20
  table_name: z.string(),
21
+ table_relkind: TriggerTableRelkindSchema,
14
22
  function_schema: z.string(),
15
23
  function_name: z.string(),
16
24
  trigger_type: z.number(),
@@ -37,6 +45,7 @@ export class Trigger extends BasePgModel {
37
45
  schema;
38
46
  name;
39
47
  table_name;
48
+ table_relkind;
40
49
  function_schema;
41
50
  function_name;
42
51
  trigger_type;
@@ -64,6 +73,7 @@ export class Trigger extends BasePgModel {
64
73
  this.schema = props.schema;
65
74
  this.name = props.name;
66
75
  this.table_name = props.table_name;
76
+ this.table_relkind = props.table_relkind;
67
77
  // Data fields
68
78
  this.function_schema = props.function_schema;
69
79
  this.function_name = props.function_name;
@@ -150,6 +160,7 @@ export async function extractTriggers(pool) {
150
160
  tc.relnamespace::regnamespace::text as schema,
151
161
  quote_ident(t.tgname) as name,
152
162
  quote_ident(tc.relname) as table_name,
163
+ tc.relkind as table_relkind,
153
164
 
154
165
  fc.pronamespace::regnamespace::text as function_schema,
155
166
  quote_ident(fc.proname) as function_name,
@@ -1,5 +1,4 @@
1
- import type { DefaultPrivilegeState } from "../../base.default-privileges.ts";
2
- import type { Role } from "../../role/role.model.ts";
1
+ import type { ObjectDiffContext } from "../../diff-context.ts";
3
2
  import type { CompositeTypeChange } from "./changes/composite-type.types.ts";
4
3
  import type { CompositeType } from "./composite-type.model.ts";
5
4
  /**
@@ -10,9 +9,4 @@ import type { CompositeType } from "./composite-type.model.ts";
10
9
  * @param branch - The composite types in the branch catalog.
11
10
  * @returns A list of changes to apply to main to make it match branch.
12
11
  */
13
- export declare function diffCompositeTypes(ctx: {
14
- version: number;
15
- currentUser: string;
16
- defaultPrivilegeState: DefaultPrivilegeState;
17
- mainRoles: Record<string, Role>;
18
- }, main: Record<string, CompositeType>, branch: Record<string, CompositeType>): CompositeTypeChange[];
12
+ export declare function diffCompositeTypes(ctx: Pick<ObjectDiffContext, "version" | "currentUser" | "defaultPrivilegeState">, main: Record<string, CompositeType>, branch: Record<string, CompositeType>): CompositeTypeChange[];
@@ -1,5 +1,5 @@
1
1
  import { diffObjects } from "../../base.diff.js";
2
- import { diffPrivileges, filterPublicBuiltInDefaults, groupPrivilegesByGrantable, } from "../../base.privilege-diff.js";
2
+ import { diffPrivileges, emitObjectPrivilegeChanges, filterPublicBuiltInDefaults, } from "../../base.privilege-diff.js";
3
3
  import { deepEqual, hasNonAlterableChanges } from "../../utils.js";
4
4
  import { AlterCompositeTypeAddAttribute, AlterCompositeTypeAlterAttributeType, AlterCompositeTypeChangeOwner, AlterCompositeTypeDropAttribute, } from "./changes/composite-type.alter.js";
5
5
  import { CreateCommentOnCompositeType, CreateCommentOnCompositeTypeAttribute, DropCommentOnCompositeType, DropCommentOnCompositeTypeAttribute, } from "./changes/composite-type.comment.js";
@@ -47,50 +47,21 @@ export function diffCompositeTypes(ctx, main, branch) {
47
47
  // We compare default privileges against desired privileges to generate REVOKE/GRANT statements
48
48
  // needed to reach the final desired state.
49
49
  const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(ctx.currentUser, "composite_type", ct.schema ?? "");
50
+ const creatorFilteredDefaults = ct.owner !== ctx.currentUser
51
+ ? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
52
+ : effectiveDefaults;
50
53
  // Filter out PUBLIC's built-in default USAGE privilege (PostgreSQL grants it automatically)
51
54
  // Reference: https://www.postgresql.org/docs/17/ddl-priv.html Table 5.2
52
55
  // This prevents generating unnecessary "GRANT USAGE TO PUBLIC" statements
53
56
  const desiredPrivileges = filterPublicBuiltInDefaults("composite_type", ct.privileges);
54
57
  // Filter out owner privileges - owner always has ALL privileges implicitly
55
58
  // and shouldn't be compared. Use the composite type owner as the reference.
56
- const privilegeResults = diffPrivileges(effectiveDefaults, desiredPrivileges, ct.owner);
57
- // Generate grant changes
58
- for (const [grantee, result] of privilegeResults) {
59
- if (result.grants.length > 0) {
60
- const grantGroups = groupPrivilegesByGrantable(result.grants);
61
- for (const [grantable, list] of grantGroups) {
62
- void grantable;
63
- changes.push(new GrantCompositeTypePrivileges({
64
- compositeType: ct,
65
- grantee,
66
- privileges: list,
67
- version: ctx.version,
68
- }));
69
- }
70
- }
71
- // Generate revoke changes
72
- if (result.revokes.length > 0) {
73
- const revokeGroups = groupPrivilegesByGrantable(result.revokes);
74
- for (const [grantable, list] of revokeGroups) {
75
- void grantable;
76
- changes.push(new RevokeCompositeTypePrivileges({
77
- compositeType: ct,
78
- grantee,
79
- privileges: list,
80
- version: ctx.version,
81
- }));
82
- }
83
- }
84
- // Generate revoke grant option changes
85
- if (result.revokeGrantOption.length > 0) {
86
- changes.push(new RevokeGrantOptionCompositeTypePrivileges({
87
- compositeType: ct,
88
- grantee,
89
- privilegeNames: result.revokeGrantOption,
90
- version: ctx.version,
91
- }));
92
- }
93
- }
59
+ const privilegeResults = diffPrivileges(filterPublicBuiltInDefaults("composite_type", creatorFilteredDefaults), desiredPrivileges, ct.owner);
60
+ changes.push(...emitObjectPrivilegeChanges(privilegeResults, ct, ct, "compositeType", {
61
+ Grant: GrantCompositeTypePrivileges,
62
+ Revoke: RevokeCompositeTypePrivileges,
63
+ RevokeGrantOption: RevokeGrantOptionCompositeTypePrivileges,
64
+ }, ctx.version));
94
65
  }
95
66
  for (const compositeTypeId of dropped) {
96
67
  changes.push(new DropCompositeType({ compositeType: main[compositeTypeId] }));
@@ -203,44 +174,12 @@ export function diffCompositeTypes(ctx, main, branch) {
203
174
  const branchPrivilegesFiltered = filterPublicBuiltInDefaults("composite_type", branchCompositeType.privileges);
204
175
  // Filter out owner privileges - owner always has ALL privileges implicitly
205
176
  // and shouldn't be compared. Use branch owner as the reference.
206
- const privilegeResults = diffPrivileges(mainPrivilegesFiltered, branchPrivilegesFiltered, branchCompositeType.owner, ctx.mainRoles);
207
- for (const [grantee, result] of privilegeResults) {
208
- // Generate grant changes
209
- if (result.grants.length > 0) {
210
- const grantGroups = groupPrivilegesByGrantable(result.grants);
211
- for (const [grantable, list] of grantGroups) {
212
- void grantable;
213
- changes.push(new GrantCompositeTypePrivileges({
214
- compositeType: branchCompositeType,
215
- grantee,
216
- privileges: list,
217
- version: ctx.version,
218
- }));
219
- }
220
- }
221
- // Generate revoke changes
222
- if (result.revokes.length > 0) {
223
- const revokeGroups = groupPrivilegesByGrantable(result.revokes);
224
- for (const [grantable, list] of revokeGroups) {
225
- void grantable;
226
- changes.push(new RevokeCompositeTypePrivileges({
227
- compositeType: mainCompositeType,
228
- grantee,
229
- privileges: list,
230
- version: ctx.version,
231
- }));
232
- }
233
- }
234
- // Generate revoke grant option changes
235
- if (result.revokeGrantOption.length > 0) {
236
- changes.push(new RevokeGrantOptionCompositeTypePrivileges({
237
- compositeType: mainCompositeType,
238
- grantee,
239
- privilegeNames: result.revokeGrantOption,
240
- version: ctx.version,
241
- }));
242
- }
243
- }
177
+ const privilegeResults = diffPrivileges(mainPrivilegesFiltered, branchPrivilegesFiltered, branchCompositeType.owner);
178
+ changes.push(...emitObjectPrivilegeChanges(privilegeResults, branchCompositeType, mainCompositeType, "compositeType", {
179
+ Grant: GrantCompositeTypePrivileges,
180
+ Revoke: RevokeCompositeTypePrivileges,
181
+ RevokeGrantOption: RevokeGrantOptionCompositeTypePrivileges,
182
+ }, ctx.version));
244
183
  // Note: Composite type renaming would also use ALTER TYPE ... RENAME TO ...
245
184
  // But since our CompositeType model uses 'name' as the identity field,
246
185
  // a name change would be handled as drop + create by diffObjects()