@supabase/pg-delta 1.0.0-alpha.22 → 1.0.0-alpha.23

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 (220) hide show
  1. package/dist/core/catalog.model.js +1 -0
  2. package/dist/core/integrations/filter/flatten.js +13 -0
  3. package/dist/core/objects/aggregate/aggregate.diff.js +16 -0
  4. package/dist/core/objects/aggregate/aggregate.model.d.ts +10 -0
  5. package/dist/core/objects/aggregate/aggregate.model.js +19 -1
  6. package/dist/core/objects/aggregate/changes/aggregate.base.d.ts +1 -1
  7. package/dist/core/objects/aggregate/changes/aggregate.security-label.d.ts +28 -0
  8. package/dist/core/objects/aggregate/changes/aggregate.security-label.js +64 -0
  9. package/dist/core/objects/aggregate/changes/aggregate.types.d.ts +2 -1
  10. package/dist/core/objects/base.model.d.ts +8 -0
  11. package/dist/core/objects/base.model.js +2 -0
  12. package/dist/core/objects/domain/changes/domain.base.d.ts +1 -1
  13. package/dist/core/objects/domain/changes/domain.security-label.d.ts +28 -0
  14. package/dist/core/objects/domain/changes/domain.security-label.js +61 -0
  15. package/dist/core/objects/domain/changes/domain.types.d.ts +2 -1
  16. package/dist/core/objects/domain/domain.diff.js +16 -0
  17. package/dist/core/objects/domain/domain.model.d.ts +10 -0
  18. package/dist/core/objects/domain/domain.model.js +19 -1
  19. package/dist/core/objects/event-trigger/changes/event-trigger.base.d.ts +1 -1
  20. package/dist/core/objects/event-trigger/changes/event-trigger.security-label.d.ts +28 -0
  21. package/dist/core/objects/event-trigger/changes/event-trigger.security-label.js +61 -0
  22. package/dist/core/objects/event-trigger/changes/event-trigger.types.d.ts +2 -1
  23. package/dist/core/objects/event-trigger/event-trigger.diff.js +16 -0
  24. package/dist/core/objects/event-trigger/event-trigger.model.d.ts +10 -0
  25. package/dist/core/objects/event-trigger/event-trigger.model.js +19 -1
  26. package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.d.ts +1 -1
  27. package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.d.ts +28 -0
  28. package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.js +61 -0
  29. package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.d.ts +2 -1
  30. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.js +16 -0
  31. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.d.ts +22 -0
  32. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.js +20 -1
  33. package/dist/core/objects/materialized-view/changes/materialized-view.base.d.ts +1 -1
  34. package/dist/core/objects/materialized-view/changes/materialized-view.security-label.d.ts +28 -0
  35. package/dist/core/objects/materialized-view/changes/materialized-view.security-label.js +61 -0
  36. package/dist/core/objects/materialized-view/changes/materialized-view.types.d.ts +2 -1
  37. package/dist/core/objects/materialized-view/materialized-view.diff.js +18 -0
  38. package/dist/core/objects/materialized-view/materialized-view.model.d.ts +22 -0
  39. package/dist/core/objects/materialized-view/materialized-view.model.js +20 -1
  40. package/dist/core/objects/procedure/changes/procedure.base.d.ts +1 -1
  41. package/dist/core/objects/procedure/changes/procedure.security-label.d.ts +28 -0
  42. package/dist/core/objects/procedure/changes/procedure.security-label.js +69 -0
  43. package/dist/core/objects/procedure/changes/procedure.types.d.ts +2 -1
  44. package/dist/core/objects/procedure/procedure.diff.js +16 -0
  45. package/dist/core/objects/procedure/procedure.model.d.ts +10 -0
  46. package/dist/core/objects/procedure/procedure.model.js +19 -1
  47. package/dist/core/objects/publication/changes/publication.base.d.ts +1 -1
  48. package/dist/core/objects/publication/changes/publication.security-label.d.ts +28 -0
  49. package/dist/core/objects/publication/changes/publication.security-label.js +61 -0
  50. package/dist/core/objects/publication/changes/publication.types.d.ts +2 -1
  51. package/dist/core/objects/publication/publication.diff.js +16 -0
  52. package/dist/core/objects/publication/publication.model.d.ts +14 -0
  53. package/dist/core/objects/publication/publication.model.js +20 -1
  54. package/dist/core/objects/role/changes/role.base.d.ts +1 -1
  55. package/dist/core/objects/role/changes/role.security-label.d.ts +28 -0
  56. package/dist/core/objects/role/changes/role.security-label.js +61 -0
  57. package/dist/core/objects/role/changes/role.types.d.ts +2 -1
  58. package/dist/core/objects/role/role.diff.js +16 -0
  59. package/dist/core/objects/role/role.model.d.ts +10 -0
  60. package/dist/core/objects/role/role.model.js +29 -0
  61. package/dist/core/objects/schema/changes/schema.base.d.ts +1 -1
  62. package/dist/core/objects/schema/changes/schema.security-label.d.ts +28 -0
  63. package/dist/core/objects/schema/changes/schema.security-label.js +61 -0
  64. package/dist/core/objects/schema/changes/schema.types.d.ts +2 -1
  65. package/dist/core/objects/schema/schema.diff.js +24 -1
  66. package/dist/core/objects/schema/schema.model.d.ts +10 -0
  67. package/dist/core/objects/schema/schema.model.js +18 -1
  68. package/dist/core/objects/security-label.types.d.ts +20 -0
  69. package/dist/core/objects/security-label.types.js +46 -0
  70. package/dist/core/objects/sequence/changes/sequence.base.d.ts +1 -1
  71. package/dist/core/objects/sequence/changes/sequence.security-label.d.ts +28 -0
  72. package/dist/core/objects/sequence/changes/sequence.security-label.js +61 -0
  73. package/dist/core/objects/sequence/changes/sequence.types.d.ts +2 -1
  74. package/dist/core/objects/sequence/sequence.diff.js +16 -0
  75. package/dist/core/objects/sequence/sequence.model.d.ts +10 -0
  76. package/dist/core/objects/sequence/sequence.model.js +19 -1
  77. package/dist/core/objects/subscription/changes/subscription.base.d.ts +1 -1
  78. package/dist/core/objects/subscription/changes/subscription.security-label.d.ts +28 -0
  79. package/dist/core/objects/subscription/changes/subscription.security-label.js +61 -0
  80. package/dist/core/objects/subscription/changes/subscription.types.d.ts +2 -1
  81. package/dist/core/objects/subscription/subscription.diff.js +16 -0
  82. package/dist/core/objects/subscription/subscription.model.d.ts +10 -0
  83. package/dist/core/objects/subscription/subscription.model.js +19 -1
  84. package/dist/core/objects/table/changes/table.base.d.ts +1 -1
  85. package/dist/core/objects/table/changes/table.security-label.d.ts +63 -0
  86. package/dist/core/objects/table/changes/table.security-label.js +134 -0
  87. package/dist/core/objects/table/changes/table.types.d.ts +2 -1
  88. package/dist/core/objects/table/table.diff.js +49 -0
  89. package/dist/core/objects/table/table.model.d.ts +30 -0
  90. package/dist/core/objects/table/table.model.js +34 -2
  91. package/dist/core/objects/type/composite-type/changes/composite-type.base.d.ts +1 -1
  92. package/dist/core/objects/type/composite-type/changes/composite-type.security-label.d.ts +28 -0
  93. package/dist/core/objects/type/composite-type/changes/composite-type.security-label.js +61 -0
  94. package/dist/core/objects/type/composite-type/changes/composite-type.types.d.ts +2 -1
  95. package/dist/core/objects/type/composite-type/composite-type.diff.js +16 -0
  96. package/dist/core/objects/type/composite-type/composite-type.model.d.ts +22 -0
  97. package/dist/core/objects/type/composite-type/composite-type.model.js +22 -2
  98. package/dist/core/objects/type/enum/changes/enum.base.d.ts +1 -1
  99. package/dist/core/objects/type/enum/changes/enum.security-label.d.ts +28 -0
  100. package/dist/core/objects/type/enum/changes/enum.security-label.js +61 -0
  101. package/dist/core/objects/type/enum/changes/enum.types.d.ts +2 -1
  102. package/dist/core/objects/type/enum/enum.diff.js +16 -0
  103. package/dist/core/objects/type/enum/enum.model.d.ts +10 -0
  104. package/dist/core/objects/type/enum/enum.model.js +20 -1
  105. package/dist/core/objects/type/range/changes/range.base.d.ts +1 -1
  106. package/dist/core/objects/type/range/changes/range.security-label.d.ts +28 -0
  107. package/dist/core/objects/type/range/changes/range.security-label.js +61 -0
  108. package/dist/core/objects/type/range/changes/range.types.d.ts +2 -1
  109. package/dist/core/objects/type/range/range.diff.js +16 -0
  110. package/dist/core/objects/type/range/range.model.d.ts +10 -0
  111. package/dist/core/objects/type/range/range.model.js +19 -1
  112. package/dist/core/objects/utils.d.ts +1 -0
  113. package/dist/core/objects/utils.js +3 -0
  114. package/dist/core/objects/view/changes/view.base.d.ts +1 -1
  115. package/dist/core/objects/view/changes/view.security-label.d.ts +28 -0
  116. package/dist/core/objects/view/changes/view.security-label.js +61 -0
  117. package/dist/core/objects/view/changes/view.types.d.ts +2 -1
  118. package/dist/core/objects/view/view.diff.js +13 -0
  119. package/dist/core/objects/view/view.model.d.ts +26 -0
  120. package/dist/core/objects/view/view.model.js +20 -1
  121. package/dist/core/plan/sql-format/fixtures.js +1 -0
  122. package/package.json +1 -1
  123. package/src/core/catalog.model.ts +1 -0
  124. package/src/core/integrations/filter/dsl.test.ts +27 -0
  125. package/src/core/integrations/filter/flatten.ts +16 -0
  126. package/src/core/objects/aggregate/aggregate.diff.ts +33 -0
  127. package/src/core/objects/aggregate/aggregate.model.ts +22 -1
  128. package/src/core/objects/aggregate/changes/aggregate.base.ts +5 -1
  129. package/src/core/objects/aggregate/changes/aggregate.security-label.ts +99 -0
  130. package/src/core/objects/aggregate/changes/aggregate.types.ts +3 -1
  131. package/src/core/objects/base.model.ts +2 -0
  132. package/src/core/objects/domain/changes/domain.base.ts +5 -1
  133. package/src/core/objects/domain/changes/domain.security-label.test.ts +56 -0
  134. package/src/core/objects/domain/changes/domain.security-label.ts +77 -0
  135. package/src/core/objects/domain/changes/domain.types.ts +3 -1
  136. package/src/core/objects/domain/domain.diff.ts +33 -0
  137. package/src/core/objects/domain/domain.model.ts +22 -1
  138. package/src/core/objects/event-trigger/changes/event-trigger.base.ts +1 -1
  139. package/src/core/objects/event-trigger/changes/event-trigger.security-label.ts +95 -0
  140. package/src/core/objects/event-trigger/changes/event-trigger.types.ts +3 -1
  141. package/src/core/objects/event-trigger/event-trigger.diff.ts +33 -0
  142. package/src/core/objects/event-trigger/event-trigger.model.ts +22 -1
  143. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +5 -1
  144. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.ts +95 -0
  145. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +3 -1
  146. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +33 -0
  147. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +24 -1
  148. package/src/core/objects/materialized-view/changes/materialized-view.base.ts +5 -1
  149. package/src/core/objects/materialized-view/changes/materialized-view.security-label.test.ts +63 -0
  150. package/src/core/objects/materialized-view/changes/materialized-view.security-label.ts +95 -0
  151. package/src/core/objects/materialized-view/changes/materialized-view.types.ts +3 -1
  152. package/src/core/objects/materialized-view/materialized-view.diff.ts +37 -0
  153. package/src/core/objects/materialized-view/materialized-view.model.ts +25 -4
  154. package/src/core/objects/procedure/changes/procedure.base.ts +5 -1
  155. package/src/core/objects/procedure/changes/procedure.security-label.ts +105 -0
  156. package/src/core/objects/procedure/changes/procedure.types.ts +3 -1
  157. package/src/core/objects/procedure/procedure.diff.ts +33 -0
  158. package/src/core/objects/procedure/procedure.model.ts +23 -2
  159. package/src/core/objects/publication/changes/publication.base.ts +1 -1
  160. package/src/core/objects/publication/changes/publication.security-label.ts +95 -0
  161. package/src/core/objects/publication/changes/publication.types.ts +3 -1
  162. package/src/core/objects/publication/publication.diff.ts +33 -0
  163. package/src/core/objects/publication/publication.model.ts +24 -1
  164. package/src/core/objects/role/changes/role.base.ts +2 -1
  165. package/src/core/objects/role/changes/role.security-label.ts +77 -0
  166. package/src/core/objects/role/changes/role.types.ts +3 -1
  167. package/src/core/objects/role/role.diff.ts +33 -0
  168. package/src/core/objects/role/role.model.ts +32 -0
  169. package/src/core/objects/schema/changes/schema.alter.test.ts +1 -0
  170. package/src/core/objects/schema/changes/schema.base.ts +5 -1
  171. package/src/core/objects/schema/changes/schema.create.test.ts +1 -0
  172. package/src/core/objects/schema/changes/schema.drop.test.ts +1 -0
  173. package/src/core/objects/schema/changes/schema.security-label.test.ts +76 -0
  174. package/src/core/objects/schema/changes/schema.security-label.ts +77 -0
  175. package/src/core/objects/schema/changes/schema.types.ts +3 -1
  176. package/src/core/objects/schema/schema.diff.test.ts +1 -0
  177. package/src/core/objects/schema/schema.diff.ts +43 -1
  178. package/src/core/objects/schema/schema.model.ts +21 -1
  179. package/src/core/objects/security-label.types.test.ts +106 -0
  180. package/src/core/objects/security-label.types.ts +61 -0
  181. package/src/core/objects/sequence/changes/sequence.base.ts +5 -1
  182. package/src/core/objects/sequence/changes/sequence.security-label.test.ts +58 -0
  183. package/src/core/objects/sequence/changes/sequence.security-label.ts +92 -0
  184. package/src/core/objects/sequence/changes/sequence.types.ts +3 -1
  185. package/src/core/objects/sequence/sequence.diff.ts +33 -0
  186. package/src/core/objects/sequence/sequence.model.ts +22 -1
  187. package/src/core/objects/subscription/changes/subscription.base.ts +1 -1
  188. package/src/core/objects/subscription/changes/subscription.security-label.ts +95 -0
  189. package/src/core/objects/subscription/changes/subscription.types.ts +3 -1
  190. package/src/core/objects/subscription/subscription.diff.ts +33 -0
  191. package/src/core/objects/subscription/subscription.model.ts +22 -1
  192. package/src/core/objects/table/changes/table.base.ts +5 -1
  193. package/src/core/objects/table/changes/table.security-label.test.ts +140 -0
  194. package/src/core/objects/table/changes/table.security-label.ts +183 -0
  195. package/src/core/objects/table/changes/table.types.ts +3 -1
  196. package/src/core/objects/table/table.diff.ts +87 -0
  197. package/src/core/objects/table/table.model.ts +42 -2
  198. package/src/core/objects/type/composite-type/changes/composite-type.base.ts +5 -1
  199. package/src/core/objects/type/composite-type/changes/composite-type.security-label.ts +95 -0
  200. package/src/core/objects/type/composite-type/changes/composite-type.types.ts +3 -1
  201. package/src/core/objects/type/composite-type/composite-type.diff.ts +33 -0
  202. package/src/core/objects/type/composite-type/composite-type.model.ts +26 -2
  203. package/src/core/objects/type/enum/changes/enum.base.ts +5 -1
  204. package/src/core/objects/type/enum/changes/enum.security-label.ts +77 -0
  205. package/src/core/objects/type/enum/changes/enum.types.ts +3 -1
  206. package/src/core/objects/type/enum/enum.diff.ts +33 -0
  207. package/src/core/objects/type/enum/enum.model.ts +25 -1
  208. package/src/core/objects/type/range/changes/range.base.ts +5 -1
  209. package/src/core/objects/type/range/changes/range.security-label.ts +77 -0
  210. package/src/core/objects/type/range/changes/range.types.ts +3 -1
  211. package/src/core/objects/type/range/range.diff.ts +33 -0
  212. package/src/core/objects/type/range/range.model.ts +22 -1
  213. package/src/core/objects/utils.ts +3 -0
  214. package/src/core/objects/view/changes/view.base.ts +5 -1
  215. package/src/core/objects/view/changes/view.security-label.test.ts +64 -0
  216. package/src/core/objects/view/changes/view.security-label.ts +77 -0
  217. package/src/core/objects/view/changes/view.types.ts +3 -1
  218. package/src/core/objects/view/view.diff.ts +31 -0
  219. package/src/core/objects/view/view.model.ts +25 -2
  220. package/src/core/plan/sql-format/fixtures.ts +1 -0
@@ -0,0 +1,95 @@
1
+ import { quoteLiteral } from "../../base.change.ts";
2
+ import type { SecurityLabelProps } from "../../security-label.types.ts";
3
+ import { stableId } from "../../utils.ts";
4
+ import type { MaterializedView } from "../materialized-view.model.ts";
5
+ import {
6
+ CreateMaterializedViewChange,
7
+ DropMaterializedViewChange,
8
+ } from "./materialized-view.base.ts";
9
+
10
+ export type SecurityLabelMaterializedView =
11
+ | CreateSecurityLabelOnMaterializedView
12
+ | DropSecurityLabelOnMaterializedView;
13
+
14
+ export class CreateSecurityLabelOnMaterializedView extends CreateMaterializedViewChange {
15
+ public readonly materializedView: MaterializedView;
16
+ public readonly securityLabel: SecurityLabelProps;
17
+ public readonly scope = "security_label" as const;
18
+
19
+ constructor(props: {
20
+ materializedView: MaterializedView;
21
+ securityLabel: SecurityLabelProps;
22
+ }) {
23
+ super();
24
+ this.materializedView = props.materializedView;
25
+ this.securityLabel = props.securityLabel;
26
+ }
27
+
28
+ get creates() {
29
+ return [
30
+ stableId.securityLabel(
31
+ this.materializedView.stableId,
32
+ this.securityLabel.provider,
33
+ ),
34
+ ];
35
+ }
36
+
37
+ get requires() {
38
+ return [this.materializedView.stableId];
39
+ }
40
+
41
+ serialize(): string {
42
+ return [
43
+ "SECURITY LABEL FOR",
44
+ this.securityLabel.provider,
45
+ "ON MATERIALIZED VIEW",
46
+ `${this.materializedView.schema}.${this.materializedView.name}`,
47
+ "IS",
48
+ quoteLiteral(this.securityLabel.label),
49
+ ].join(" ");
50
+ }
51
+ }
52
+
53
+ export class DropSecurityLabelOnMaterializedView extends DropMaterializedViewChange {
54
+ public readonly materializedView: MaterializedView;
55
+ public readonly securityLabel: SecurityLabelProps;
56
+ public readonly scope = "security_label" as const;
57
+
58
+ constructor(props: {
59
+ materializedView: MaterializedView;
60
+ securityLabel: SecurityLabelProps;
61
+ }) {
62
+ super();
63
+ this.materializedView = props.materializedView;
64
+ this.securityLabel = props.securityLabel;
65
+ }
66
+
67
+ get drops() {
68
+ return [
69
+ stableId.securityLabel(
70
+ this.materializedView.stableId,
71
+ this.securityLabel.provider,
72
+ ),
73
+ ];
74
+ }
75
+
76
+ get requires() {
77
+ return [
78
+ stableId.securityLabel(
79
+ this.materializedView.stableId,
80
+ this.securityLabel.provider,
81
+ ),
82
+ this.materializedView.stableId,
83
+ ];
84
+ }
85
+
86
+ serialize(): string {
87
+ return [
88
+ "SECURITY LABEL FOR",
89
+ this.securityLabel.provider,
90
+ "ON MATERIALIZED VIEW",
91
+ `${this.materializedView.schema}.${this.materializedView.name}`,
92
+ "IS NULL",
93
+ ].join(" ");
94
+ }
95
+ }
@@ -3,6 +3,7 @@ import type { CommentMaterializedView } from "./materialized-view.comment.ts";
3
3
  import type { CreateMaterializedView } from "./materialized-view.create.ts";
4
4
  import type { DropMaterializedView } from "./materialized-view.drop.ts";
5
5
  import type { MaterializedViewPrivilege } from "./materialized-view.privilege.ts";
6
+ import type { SecurityLabelMaterializedView } from "./materialized-view.security-label.ts";
6
7
 
7
8
  /** Union of all materialized-view-related change variants (`objectType: "materialized_view"`). @category Change Types */
8
9
  export type MaterializedViewChange =
@@ -10,4 +11,5 @@ export type MaterializedViewChange =
10
11
  | CommentMaterializedView
11
12
  | CreateMaterializedView
12
13
  | DropMaterializedView
13
- | MaterializedViewPrivilege;
14
+ | MaterializedViewPrivilege
15
+ | SecurityLabelMaterializedView;
@@ -4,6 +4,7 @@ import {
4
4
  emitColumnPrivilegeChanges,
5
5
  } from "../base.privilege-diff.ts";
6
6
  import type { ObjectDiffContext } from "../diff-context.ts";
7
+ import { diffSecurityLabels } from "../security-label.types.ts";
7
8
  import { deepEqual, hasNonAlterableChanges } from "../utils.ts";
8
9
  import {
9
10
  AlterMaterializedViewChangeOwner,
@@ -22,6 +23,10 @@ import {
22
23
  RevokeGrantOptionMaterializedViewPrivileges,
23
24
  RevokeMaterializedViewPrivileges,
24
25
  } from "./changes/materialized-view.privilege.ts";
26
+ import {
27
+ CreateSecurityLabelOnMaterializedView,
28
+ DropSecurityLabelOnMaterializedView,
29
+ } from "./changes/materialized-view.security-label.ts";
25
30
  import type { MaterializedViewChange } from "./changes/materialized-view.types.ts";
26
31
  import type { MaterializedView } from "./materialized-view.model.ts";
27
32
 
@@ -88,6 +93,17 @@ export function diffMaterializedViews(
88
93
  }
89
94
  }
90
95
 
96
+ // Security labels on the matview itself (columns of matviews are not
97
+ // supported targets of SECURITY LABEL, so we only label the relation).
98
+ for (const label of mv.security_labels) {
99
+ changes.push(
100
+ new CreateSecurityLabelOnMaterializedView({
101
+ materializedView: mv,
102
+ securityLabel: label,
103
+ }),
104
+ );
105
+ }
106
+
91
107
  // PRIVILEGES: For created objects, compare against default privileges state
92
108
  // The migration script will run ALTER DEFAULT PRIVILEGES before CREATE (via constraint spec),
93
109
  // so objects are created with the default privileges state in effect.
@@ -241,6 +257,27 @@ export function diffMaterializedViews(
241
257
  );
242
258
  }
243
259
  }
260
+
261
+ // SECURITY LABELS
262
+ changes.push(
263
+ ...diffSecurityLabels<
264
+ | CreateSecurityLabelOnMaterializedView
265
+ | DropSecurityLabelOnMaterializedView
266
+ >(
267
+ mainMaterializedView.security_labels,
268
+ branchMaterializedView.security_labels,
269
+ (securityLabel) =>
270
+ new CreateSecurityLabelOnMaterializedView({
271
+ materializedView: branchMaterializedView,
272
+ securityLabel,
273
+ }),
274
+ (securityLabel) =>
275
+ new DropSecurityLabelOnMaterializedView({
276
+ materializedView: mainMaterializedView,
277
+ securityLabel,
278
+ }),
279
+ ),
280
+ );
244
281
  // COMMENT changes on columns
245
282
  const mainCols = new Map(
246
283
  mainMaterializedView.columns.map((c) => [c.name, c]),
@@ -14,6 +14,11 @@ import {
14
14
  type ExtractRetryOptions,
15
15
  extractWithDefinitionRetry,
16
16
  } from "../extract-with-retry.ts";
17
+ import {
18
+ normalizeSecurityLabels,
19
+ type SecurityLabelProps,
20
+ securityLabelPropsSchema,
21
+ } from "../security-label.types.ts";
17
22
  import { ReplicaIdentitySchema } from "../table/table.model.ts";
18
23
 
19
24
  const materializedViewPropsSchema = z.object({
@@ -35,6 +40,7 @@ const materializedViewPropsSchema = z.object({
35
40
  comment: z.string().nullable(),
36
41
  columns: z.array(columnPropsSchema),
37
42
  privileges: z.array(privilegePropsSchema),
43
+ security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
38
44
  });
39
45
 
40
46
  // pg_get_viewdef(oid) can return NULL when the underlying matview (or its
@@ -68,6 +74,7 @@ export class MaterializedView extends BasePgModel implements TableLikeObject {
68
74
  public readonly comment: MaterializedViewProps["comment"];
69
75
  public readonly columns: MaterializedViewProps["columns"];
70
76
  public readonly privileges: MaterializedViewPrivilegeProps[];
77
+ public readonly security_labels: SecurityLabelProps[];
71
78
 
72
79
  constructor(props: MaterializedViewProps) {
73
80
  super();
@@ -93,6 +100,7 @@ export class MaterializedView extends BasePgModel implements TableLikeObject {
93
100
  this.comment = props.comment;
94
101
  this.columns = props.columns;
95
102
  this.privileges = props.privileges;
103
+ this.security_labels = props.security_labels ?? [];
96
104
  }
97
105
 
98
106
  get stableId(): `materializedView:${string}` {
@@ -124,6 +132,7 @@ export class MaterializedView extends BasePgModel implements TableLikeObject {
124
132
  comment: this.comment,
125
133
  columns: this.columns,
126
134
  privileges: this.privileges,
135
+ security_labels: this.security_labels,
127
136
  };
128
137
  }
129
138
 
@@ -148,6 +157,7 @@ export class MaterializedView extends BasePgModel implements TableLikeObject {
148
157
  data: {
149
158
  ...this.dataFields,
150
159
  columns: normalizeColumns(),
160
+ security_labels: normalizeSecurityLabels(this.security_labels),
151
161
  },
152
162
  };
153
163
  }
@@ -252,7 +262,20 @@ select
252
262
  join lateral aclexplode(src.acl) as x(grantor, grantee, privilege_type, is_grantable) on true
253
263
  group by x.grantee, x.privilege_type
254
264
  ) as grp
255
- ), '[]') as privileges
265
+ ), '[]') as privileges,
266
+ coalesce(
267
+ (
268
+ select json_agg(
269
+ json_build_object('provider', sl.provider, 'label', sl.label)
270
+ order by sl.provider
271
+ )
272
+ from pg_catalog.pg_seclabel sl
273
+ where sl.objoid = c.oid
274
+ and sl.classoid = 'pg_class'::regclass
275
+ and sl.objsubid = 0
276
+ ),
277
+ '[]'::json
278
+ ) as security_labels
256
279
  from
257
280
  pg_catalog.pg_class c
258
281
  left outer join extension_oids e on c.oid = e.objid
@@ -275,7 +298,5 @@ order by
275
298
  const validatedRows = mvRows.filter(
276
299
  (row): row is MaterializedViewProps => row.definition !== null,
277
300
  );
278
- return validatedRows.map(
279
- (row: MaterializedViewProps) => new MaterializedView(row),
280
- );
301
+ return validatedRows.map((row) => new MaterializedView(row));
281
302
  }
@@ -3,7 +3,11 @@ import type { Procedure } from "../procedure.model.ts";
3
3
 
4
4
  abstract class BaseProcedureChange extends BaseChange {
5
5
  abstract readonly procedure: Procedure;
6
- abstract readonly scope: "object" | "comment" | "privilege";
6
+ abstract readonly scope:
7
+ | "object"
8
+ | "comment"
9
+ | "privilege"
10
+ | "security_label";
7
11
  readonly objectType: "procedure" = "procedure";
8
12
  }
9
13
 
@@ -0,0 +1,105 @@
1
+ import { quoteLiteral } from "../../base.change.ts";
2
+ import type { SecurityLabelProps } from "../../security-label.types.ts";
3
+ import { stableId } from "../../utils.ts";
4
+ import type { Procedure } from "../procedure.model.ts";
5
+ import {
6
+ CreateProcedureChange,
7
+ DropProcedureChange,
8
+ } from "./procedure.base.ts";
9
+
10
+ export type SecurityLabelProcedure =
11
+ | CreateSecurityLabelOnProcedure
12
+ | DropSecurityLabelOnProcedure;
13
+
14
+ function targetKeyword(p: Procedure): "FUNCTION" | "PROCEDURE" {
15
+ return p.kind === "p" ? "PROCEDURE" : "FUNCTION";
16
+ }
17
+
18
+ function procedureIdentity(p: Procedure): string {
19
+ return `${p.schema}.${p.name}(${(p.argument_types ?? []).join(",")})`;
20
+ }
21
+
22
+ export class CreateSecurityLabelOnProcedure extends CreateProcedureChange {
23
+ public readonly procedure: Procedure;
24
+ public readonly securityLabel: SecurityLabelProps;
25
+ public readonly scope = "security_label" as const;
26
+
27
+ constructor(props: {
28
+ procedure: Procedure;
29
+ securityLabel: SecurityLabelProps;
30
+ }) {
31
+ super();
32
+ this.procedure = props.procedure;
33
+ this.securityLabel = props.securityLabel;
34
+ }
35
+
36
+ get creates() {
37
+ return [
38
+ stableId.securityLabel(
39
+ this.procedure.stableId,
40
+ this.securityLabel.provider,
41
+ ),
42
+ ];
43
+ }
44
+
45
+ get requires() {
46
+ return [this.procedure.stableId];
47
+ }
48
+
49
+ serialize(): string {
50
+ return [
51
+ "SECURITY LABEL FOR",
52
+ this.securityLabel.provider,
53
+ "ON",
54
+ targetKeyword(this.procedure),
55
+ procedureIdentity(this.procedure),
56
+ "IS",
57
+ quoteLiteral(this.securityLabel.label),
58
+ ].join(" ");
59
+ }
60
+ }
61
+
62
+ export class DropSecurityLabelOnProcedure extends DropProcedureChange {
63
+ public readonly procedure: Procedure;
64
+ public readonly securityLabel: SecurityLabelProps;
65
+ public readonly scope = "security_label" as const;
66
+
67
+ constructor(props: {
68
+ procedure: Procedure;
69
+ securityLabel: SecurityLabelProps;
70
+ }) {
71
+ super();
72
+ this.procedure = props.procedure;
73
+ this.securityLabel = props.securityLabel;
74
+ }
75
+
76
+ get drops() {
77
+ return [
78
+ stableId.securityLabel(
79
+ this.procedure.stableId,
80
+ this.securityLabel.provider,
81
+ ),
82
+ ];
83
+ }
84
+
85
+ get requires() {
86
+ return [
87
+ stableId.securityLabel(
88
+ this.procedure.stableId,
89
+ this.securityLabel.provider,
90
+ ),
91
+ this.procedure.stableId,
92
+ ];
93
+ }
94
+
95
+ serialize(): string {
96
+ return [
97
+ "SECURITY LABEL FOR",
98
+ this.securityLabel.provider,
99
+ "ON",
100
+ targetKeyword(this.procedure),
101
+ procedureIdentity(this.procedure),
102
+ "IS NULL",
103
+ ].join(" ");
104
+ }
105
+ }
@@ -3,6 +3,7 @@ import type { CommentProcedure } from "./procedure.comment.ts";
3
3
  import type { CreateProcedure } from "./procedure.create.ts";
4
4
  import type { DropProcedure } from "./procedure.drop.ts";
5
5
  import type { ProcedurePrivilege } from "./procedure.privilege.ts";
6
+ import type { SecurityLabelProcedure } from "./procedure.security-label.ts";
6
7
 
7
8
  /** Union of all procedure-related change variants (`objectType: "procedure"`). @category Change Types */
8
9
  export type ProcedureChange =
@@ -10,4 +11,5 @@ export type ProcedureChange =
10
11
  | CommentProcedure
11
12
  | CreateProcedure
12
13
  | DropProcedure
13
- | ProcedurePrivilege;
14
+ | ProcedurePrivilege
15
+ | SecurityLabelProcedure;
@@ -5,6 +5,7 @@ import {
5
5
  filterPublicBuiltInDefaults,
6
6
  } from "../base.privilege-diff.ts";
7
7
  import type { ObjectDiffContext } from "../diff-context.ts";
8
+ import { diffSecurityLabels } from "../security-label.types.ts";
8
9
  import { deepEqual, hasNonAlterableChanges } from "../utils.ts";
9
10
  import {
10
11
  AlterProcedureChangeOwner,
@@ -26,6 +27,10 @@ import {
26
27
  RevokeGrantOptionProcedurePrivileges,
27
28
  RevokeProcedurePrivileges,
28
29
  } from "./changes/procedure.privilege.ts";
30
+ import {
31
+ CreateSecurityLabelOnProcedure,
32
+ DropSecurityLabelOnProcedure,
33
+ } from "./changes/procedure.security-label.ts";
29
34
  import type { ProcedureChange } from "./changes/procedure.types.ts";
30
35
  import type { Procedure } from "./procedure.model.ts";
31
36
 
@@ -66,6 +71,14 @@ export function diffProcedures(
66
71
  if (proc.comment !== null) {
67
72
  changes.push(new CreateCommentOnProcedure({ procedure: proc }));
68
73
  }
74
+ for (const label of proc.security_labels) {
75
+ changes.push(
76
+ new CreateSecurityLabelOnProcedure({
77
+ procedure: proc,
78
+ securityLabel: label,
79
+ }),
80
+ );
81
+ }
69
82
 
70
83
  // PRIVILEGES: For created objects, compare against default privileges state
71
84
  // The migration script will run ALTER DEFAULT PRIVILEGES before CREATE (via constraint spec),
@@ -225,6 +238,26 @@ export function diffProcedures(
225
238
  }
226
239
  }
227
240
 
241
+ // SECURITY LABELS
242
+ changes.push(
243
+ ...diffSecurityLabels<
244
+ CreateSecurityLabelOnProcedure | DropSecurityLabelOnProcedure
245
+ >(
246
+ mainProcedure.security_labels,
247
+ branchProcedure.security_labels,
248
+ (securityLabel) =>
249
+ new CreateSecurityLabelOnProcedure({
250
+ procedure: branchProcedure,
251
+ securityLabel,
252
+ }),
253
+ (securityLabel) =>
254
+ new DropSecurityLabelOnProcedure({
255
+ procedure: mainProcedure,
256
+ securityLabel,
257
+ }),
258
+ ),
259
+ );
260
+
228
261
  // SECURITY DEFINER/INVOKER
229
262
  if (mainProcedure.security_definer !== branchProcedure.security_definer) {
230
263
  changes.push(
@@ -10,6 +10,10 @@ import {
10
10
  type ExtractRetryOptions,
11
11
  extractWithDefinitionRetry,
12
12
  } from "../extract-with-retry.ts";
13
+ import {
14
+ type SecurityLabelProps,
15
+ securityLabelPropsSchema,
16
+ } from "../security-label.types.ts";
13
17
 
14
18
  const FunctionKindSchema = z.enum([
15
19
  "f", // function
@@ -68,6 +72,7 @@ const procedurePropsSchema = z.object({
68
72
  owner: z.string(),
69
73
  comment: z.string().nullable(),
70
74
  privileges: z.array(privilegePropsSchema),
75
+ security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
71
76
  });
72
77
 
73
78
  // pg_get_functiondef(oid) can return NULL when the function (its pg_proc
@@ -112,6 +117,7 @@ export class Procedure extends BasePgModel {
112
117
  public readonly owner: ProcedureProps["owner"];
113
118
  public readonly comment: ProcedureProps["comment"];
114
119
  public readonly privileges: ProcedurePrivilegeProps[];
120
+ public readonly security_labels: SecurityLabelProps[];
115
121
 
116
122
  constructor(props: ProcedureProps) {
117
123
  super();
@@ -148,6 +154,7 @@ export class Procedure extends BasePgModel {
148
154
  this.owner = props.owner;
149
155
  this.comment = props.comment;
150
156
  this.privileges = props.privileges;
157
+ this.security_labels = props.security_labels ?? [];
151
158
  }
152
159
 
153
160
  get stableId(): `procedure:${string}` {
@@ -192,6 +199,7 @@ export class Procedure extends BasePgModel {
192
199
  owner: this.owner,
193
200
  comment: this.comment,
194
201
  privileges: this.privileges,
202
+ security_labels: this.security_labels,
195
203
  };
196
204
  }
197
205
  }
@@ -265,7 +273,20 @@ select
265
273
  )
266
274
  from lateral aclexplode(COALESCE(p.proacl, acldefault('f', p.proowner))) as x(grantor, grantee, privilege_type, is_grantable)
267
275
  ), '[]'
268
- ) as privileges
276
+ ) as privileges,
277
+ coalesce(
278
+ (
279
+ select json_agg(
280
+ json_build_object('provider', sl.provider, 'label', sl.label)
281
+ order by sl.provider
282
+ )
283
+ from pg_catalog.pg_seclabel sl
284
+ where sl.objoid = p.oid
285
+ and sl.classoid = 'pg_proc'::regclass
286
+ and sl.objsubid = 0
287
+ ),
288
+ '[]'::json
289
+ ) as security_labels
269
290
  from
270
291
  pg_catalog.pg_proc p
271
292
  inner join pg_catalog.pg_language l on l.oid = p.prolang
@@ -283,5 +304,5 @@ order by
283
304
  const validatedRows = procedureRows.filter(
284
305
  (row): row is ProcedureProps => row.definition !== null,
285
306
  );
286
- return validatedRows.map((row: ProcedureProps) => new Procedure(row));
307
+ return validatedRows.map((row) => new Procedure(row));
287
308
  }
@@ -3,7 +3,7 @@ import type { Publication } from "../publication.model.ts";
3
3
 
4
4
  abstract class BasePublicationChange extends BaseChange {
5
5
  abstract readonly publication: Publication;
6
- abstract readonly scope: "object" | "comment";
6
+ abstract readonly scope: "object" | "comment" | "security_label";
7
7
  readonly objectType = "publication" as const;
8
8
  }
9
9
 
@@ -0,0 +1,95 @@
1
+ import { quoteLiteral } from "../../base.change.ts";
2
+ import type { SecurityLabelProps } from "../../security-label.types.ts";
3
+ import { stableId } from "../../utils.ts";
4
+ import type { Publication } from "../publication.model.ts";
5
+ import {
6
+ CreatePublicationChange,
7
+ DropPublicationChange,
8
+ } from "./publication.base.ts";
9
+
10
+ export type SecurityLabelPublication =
11
+ | CreateSecurityLabelOnPublication
12
+ | DropSecurityLabelOnPublication;
13
+
14
+ export class CreateSecurityLabelOnPublication extends CreatePublicationChange {
15
+ public readonly publication: Publication;
16
+ public readonly securityLabel: SecurityLabelProps;
17
+ public readonly scope = "security_label" as const;
18
+
19
+ constructor(props: {
20
+ publication: Publication;
21
+ securityLabel: SecurityLabelProps;
22
+ }) {
23
+ super();
24
+ this.publication = props.publication;
25
+ this.securityLabel = props.securityLabel;
26
+ }
27
+
28
+ get creates() {
29
+ return [
30
+ stableId.securityLabel(
31
+ this.publication.stableId,
32
+ this.securityLabel.provider,
33
+ ),
34
+ ];
35
+ }
36
+
37
+ get requires() {
38
+ return [this.publication.stableId];
39
+ }
40
+
41
+ serialize(): string {
42
+ return [
43
+ "SECURITY LABEL FOR",
44
+ this.securityLabel.provider,
45
+ "ON PUBLICATION",
46
+ this.publication.name,
47
+ "IS",
48
+ quoteLiteral(this.securityLabel.label),
49
+ ].join(" ");
50
+ }
51
+ }
52
+
53
+ export class DropSecurityLabelOnPublication extends DropPublicationChange {
54
+ public readonly publication: Publication;
55
+ public readonly securityLabel: SecurityLabelProps;
56
+ public readonly scope = "security_label" as const;
57
+
58
+ constructor(props: {
59
+ publication: Publication;
60
+ securityLabel: SecurityLabelProps;
61
+ }) {
62
+ super();
63
+ this.publication = props.publication;
64
+ this.securityLabel = props.securityLabel;
65
+ }
66
+
67
+ get drops() {
68
+ return [
69
+ stableId.securityLabel(
70
+ this.publication.stableId,
71
+ this.securityLabel.provider,
72
+ ),
73
+ ];
74
+ }
75
+
76
+ get requires() {
77
+ return [
78
+ stableId.securityLabel(
79
+ this.publication.stableId,
80
+ this.securityLabel.provider,
81
+ ),
82
+ this.publication.stableId,
83
+ ];
84
+ }
85
+
86
+ serialize(): string {
87
+ return [
88
+ "SECURITY LABEL FOR",
89
+ this.securityLabel.provider,
90
+ "ON PUBLICATION",
91
+ this.publication.name,
92
+ "IS NULL",
93
+ ].join(" ");
94
+ }
95
+ }
@@ -10,6 +10,7 @@ import type {
10
10
  import type { CommentPublication } from "./publication.comment.ts";
11
11
  import type { CreatePublication } from "./publication.create.ts";
12
12
  import type { DropPublication } from "./publication.drop.ts";
13
+ import type { SecurityLabelPublication } from "./publication.security-label.ts";
13
14
 
14
15
  /** Union of all publication-related change variants (`objectType: "publication"`). @category Change Types */
15
16
  export type PublicationChange =
@@ -22,4 +23,5 @@ export type PublicationChange =
22
23
  | AlterPublicationSetOwner
23
24
  | CommentPublication
24
25
  | CreatePublication
25
- | DropPublication;
26
+ | DropPublication
27
+ | SecurityLabelPublication;