@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.
- package/dist/core/catalog.model.js +1 -0
- package/dist/core/integrations/filter/flatten.js +13 -0
- package/dist/core/objects/aggregate/aggregate.diff.js +16 -0
- package/dist/core/objects/aggregate/aggregate.model.d.ts +10 -0
- package/dist/core/objects/aggregate/aggregate.model.js +19 -1
- package/dist/core/objects/aggregate/changes/aggregate.base.d.ts +1 -1
- package/dist/core/objects/aggregate/changes/aggregate.security-label.d.ts +28 -0
- package/dist/core/objects/aggregate/changes/aggregate.security-label.js +64 -0
- package/dist/core/objects/aggregate/changes/aggregate.types.d.ts +2 -1
- package/dist/core/objects/base.model.d.ts +8 -0
- package/dist/core/objects/base.model.js +2 -0
- package/dist/core/objects/domain/changes/domain.base.d.ts +1 -1
- package/dist/core/objects/domain/changes/domain.security-label.d.ts +28 -0
- package/dist/core/objects/domain/changes/domain.security-label.js +61 -0
- package/dist/core/objects/domain/changes/domain.types.d.ts +2 -1
- package/dist/core/objects/domain/domain.diff.js +16 -0
- package/dist/core/objects/domain/domain.model.d.ts +10 -0
- package/dist/core/objects/domain/domain.model.js +19 -1
- package/dist/core/objects/event-trigger/changes/event-trigger.base.d.ts +1 -1
- package/dist/core/objects/event-trigger/changes/event-trigger.security-label.d.ts +28 -0
- package/dist/core/objects/event-trigger/changes/event-trigger.security-label.js +61 -0
- package/dist/core/objects/event-trigger/changes/event-trigger.types.d.ts +2 -1
- package/dist/core/objects/event-trigger/event-trigger.diff.js +16 -0
- package/dist/core/objects/event-trigger/event-trigger.model.d.ts +10 -0
- package/dist/core/objects/event-trigger/event-trigger.model.js +19 -1
- package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.d.ts +1 -1
- package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.d.ts +28 -0
- package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.js +61 -0
- package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.d.ts +2 -1
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.js +16 -0
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.d.ts +22 -0
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.js +20 -1
- package/dist/core/objects/materialized-view/changes/materialized-view.base.d.ts +1 -1
- package/dist/core/objects/materialized-view/changes/materialized-view.security-label.d.ts +28 -0
- package/dist/core/objects/materialized-view/changes/materialized-view.security-label.js +61 -0
- package/dist/core/objects/materialized-view/changes/materialized-view.types.d.ts +2 -1
- package/dist/core/objects/materialized-view/materialized-view.diff.js +18 -0
- package/dist/core/objects/materialized-view/materialized-view.model.d.ts +22 -0
- package/dist/core/objects/materialized-view/materialized-view.model.js +20 -1
- package/dist/core/objects/procedure/changes/procedure.base.d.ts +1 -1
- package/dist/core/objects/procedure/changes/procedure.security-label.d.ts +28 -0
- package/dist/core/objects/procedure/changes/procedure.security-label.js +69 -0
- package/dist/core/objects/procedure/changes/procedure.types.d.ts +2 -1
- package/dist/core/objects/procedure/procedure.diff.js +16 -0
- package/dist/core/objects/procedure/procedure.model.d.ts +10 -0
- package/dist/core/objects/procedure/procedure.model.js +19 -1
- package/dist/core/objects/publication/changes/publication.base.d.ts +1 -1
- package/dist/core/objects/publication/changes/publication.security-label.d.ts +28 -0
- package/dist/core/objects/publication/changes/publication.security-label.js +61 -0
- package/dist/core/objects/publication/changes/publication.types.d.ts +2 -1
- package/dist/core/objects/publication/publication.diff.js +16 -0
- package/dist/core/objects/publication/publication.model.d.ts +14 -0
- package/dist/core/objects/publication/publication.model.js +20 -1
- package/dist/core/objects/role/changes/role.base.d.ts +1 -1
- package/dist/core/objects/role/changes/role.security-label.d.ts +28 -0
- package/dist/core/objects/role/changes/role.security-label.js +61 -0
- package/dist/core/objects/role/changes/role.types.d.ts +2 -1
- package/dist/core/objects/role/role.diff.js +16 -0
- package/dist/core/objects/role/role.model.d.ts +10 -0
- package/dist/core/objects/role/role.model.js +29 -0
- package/dist/core/objects/schema/changes/schema.base.d.ts +1 -1
- package/dist/core/objects/schema/changes/schema.security-label.d.ts +28 -0
- package/dist/core/objects/schema/changes/schema.security-label.js +61 -0
- package/dist/core/objects/schema/changes/schema.types.d.ts +2 -1
- package/dist/core/objects/schema/schema.diff.js +24 -1
- package/dist/core/objects/schema/schema.model.d.ts +10 -0
- package/dist/core/objects/schema/schema.model.js +18 -1
- package/dist/core/objects/security-label.types.d.ts +20 -0
- package/dist/core/objects/security-label.types.js +46 -0
- package/dist/core/objects/sequence/changes/sequence.base.d.ts +1 -1
- package/dist/core/objects/sequence/changes/sequence.security-label.d.ts +28 -0
- package/dist/core/objects/sequence/changes/sequence.security-label.js +61 -0
- package/dist/core/objects/sequence/changes/sequence.types.d.ts +2 -1
- package/dist/core/objects/sequence/sequence.diff.js +16 -0
- package/dist/core/objects/sequence/sequence.model.d.ts +10 -0
- package/dist/core/objects/sequence/sequence.model.js +19 -1
- package/dist/core/objects/subscription/changes/subscription.base.d.ts +1 -1
- package/dist/core/objects/subscription/changes/subscription.security-label.d.ts +28 -0
- package/dist/core/objects/subscription/changes/subscription.security-label.js +61 -0
- package/dist/core/objects/subscription/changes/subscription.types.d.ts +2 -1
- package/dist/core/objects/subscription/subscription.diff.js +16 -0
- package/dist/core/objects/subscription/subscription.model.d.ts +10 -0
- package/dist/core/objects/subscription/subscription.model.js +19 -1
- package/dist/core/objects/table/changes/table.base.d.ts +1 -1
- package/dist/core/objects/table/changes/table.security-label.d.ts +63 -0
- package/dist/core/objects/table/changes/table.security-label.js +134 -0
- package/dist/core/objects/table/changes/table.types.d.ts +2 -1
- package/dist/core/objects/table/table.diff.js +49 -0
- package/dist/core/objects/table/table.model.d.ts +30 -0
- package/dist/core/objects/table/table.model.js +34 -2
- package/dist/core/objects/type/composite-type/changes/composite-type.base.d.ts +1 -1
- package/dist/core/objects/type/composite-type/changes/composite-type.security-label.d.ts +28 -0
- package/dist/core/objects/type/composite-type/changes/composite-type.security-label.js +61 -0
- package/dist/core/objects/type/composite-type/changes/composite-type.types.d.ts +2 -1
- package/dist/core/objects/type/composite-type/composite-type.diff.js +16 -0
- package/dist/core/objects/type/composite-type/composite-type.model.d.ts +22 -0
- package/dist/core/objects/type/composite-type/composite-type.model.js +22 -2
- package/dist/core/objects/type/enum/changes/enum.base.d.ts +1 -1
- package/dist/core/objects/type/enum/changes/enum.security-label.d.ts +28 -0
- package/dist/core/objects/type/enum/changes/enum.security-label.js +61 -0
- package/dist/core/objects/type/enum/changes/enum.types.d.ts +2 -1
- package/dist/core/objects/type/enum/enum.diff.js +16 -0
- package/dist/core/objects/type/enum/enum.model.d.ts +10 -0
- package/dist/core/objects/type/enum/enum.model.js +20 -1
- package/dist/core/objects/type/range/changes/range.base.d.ts +1 -1
- package/dist/core/objects/type/range/changes/range.security-label.d.ts +28 -0
- package/dist/core/objects/type/range/changes/range.security-label.js +61 -0
- package/dist/core/objects/type/range/changes/range.types.d.ts +2 -1
- package/dist/core/objects/type/range/range.diff.js +16 -0
- package/dist/core/objects/type/range/range.model.d.ts +10 -0
- package/dist/core/objects/type/range/range.model.js +19 -1
- package/dist/core/objects/utils.d.ts +1 -0
- package/dist/core/objects/utils.js +3 -0
- package/dist/core/objects/view/changes/view.base.d.ts +1 -1
- package/dist/core/objects/view/changes/view.security-label.d.ts +28 -0
- package/dist/core/objects/view/changes/view.security-label.js +61 -0
- package/dist/core/objects/view/changes/view.types.d.ts +2 -1
- package/dist/core/objects/view/view.diff.js +13 -0
- package/dist/core/objects/view/view.model.d.ts +26 -0
- package/dist/core/objects/view/view.model.js +20 -1
- package/dist/core/plan/sql-format/fixtures.js +1 -0
- package/package.json +1 -1
- package/src/core/catalog.model.ts +1 -0
- package/src/core/integrations/filter/dsl.test.ts +27 -0
- package/src/core/integrations/filter/flatten.ts +16 -0
- package/src/core/objects/aggregate/aggregate.diff.ts +33 -0
- package/src/core/objects/aggregate/aggregate.model.ts +22 -1
- package/src/core/objects/aggregate/changes/aggregate.base.ts +5 -1
- package/src/core/objects/aggregate/changes/aggregate.security-label.ts +99 -0
- package/src/core/objects/aggregate/changes/aggregate.types.ts +3 -1
- package/src/core/objects/base.model.ts +2 -0
- package/src/core/objects/domain/changes/domain.base.ts +5 -1
- package/src/core/objects/domain/changes/domain.security-label.test.ts +56 -0
- package/src/core/objects/domain/changes/domain.security-label.ts +77 -0
- package/src/core/objects/domain/changes/domain.types.ts +3 -1
- package/src/core/objects/domain/domain.diff.ts +33 -0
- package/src/core/objects/domain/domain.model.ts +22 -1
- package/src/core/objects/event-trigger/changes/event-trigger.base.ts +1 -1
- package/src/core/objects/event-trigger/changes/event-trigger.security-label.ts +95 -0
- package/src/core/objects/event-trigger/changes/event-trigger.types.ts +3 -1
- package/src/core/objects/event-trigger/event-trigger.diff.ts +33 -0
- package/src/core/objects/event-trigger/event-trigger.model.ts +22 -1
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +5 -1
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.ts +95 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +3 -1
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +33 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +24 -1
- package/src/core/objects/materialized-view/changes/materialized-view.base.ts +5 -1
- package/src/core/objects/materialized-view/changes/materialized-view.security-label.test.ts +63 -0
- package/src/core/objects/materialized-view/changes/materialized-view.security-label.ts +95 -0
- package/src/core/objects/materialized-view/changes/materialized-view.types.ts +3 -1
- package/src/core/objects/materialized-view/materialized-view.diff.ts +37 -0
- package/src/core/objects/materialized-view/materialized-view.model.ts +25 -4
- package/src/core/objects/procedure/changes/procedure.base.ts +5 -1
- package/src/core/objects/procedure/changes/procedure.security-label.ts +105 -0
- package/src/core/objects/procedure/changes/procedure.types.ts +3 -1
- package/src/core/objects/procedure/procedure.diff.ts +33 -0
- package/src/core/objects/procedure/procedure.model.ts +23 -2
- package/src/core/objects/publication/changes/publication.base.ts +1 -1
- package/src/core/objects/publication/changes/publication.security-label.ts +95 -0
- package/src/core/objects/publication/changes/publication.types.ts +3 -1
- package/src/core/objects/publication/publication.diff.ts +33 -0
- package/src/core/objects/publication/publication.model.ts +24 -1
- package/src/core/objects/role/changes/role.base.ts +2 -1
- package/src/core/objects/role/changes/role.security-label.ts +77 -0
- package/src/core/objects/role/changes/role.types.ts +3 -1
- package/src/core/objects/role/role.diff.ts +33 -0
- package/src/core/objects/role/role.model.ts +32 -0
- package/src/core/objects/schema/changes/schema.alter.test.ts +1 -0
- package/src/core/objects/schema/changes/schema.base.ts +5 -1
- package/src/core/objects/schema/changes/schema.create.test.ts +1 -0
- package/src/core/objects/schema/changes/schema.drop.test.ts +1 -0
- package/src/core/objects/schema/changes/schema.security-label.test.ts +76 -0
- package/src/core/objects/schema/changes/schema.security-label.ts +77 -0
- package/src/core/objects/schema/changes/schema.types.ts +3 -1
- package/src/core/objects/schema/schema.diff.test.ts +1 -0
- package/src/core/objects/schema/schema.diff.ts +43 -1
- package/src/core/objects/schema/schema.model.ts +21 -1
- package/src/core/objects/security-label.types.test.ts +106 -0
- package/src/core/objects/security-label.types.ts +61 -0
- package/src/core/objects/sequence/changes/sequence.base.ts +5 -1
- package/src/core/objects/sequence/changes/sequence.security-label.test.ts +58 -0
- package/src/core/objects/sequence/changes/sequence.security-label.ts +92 -0
- package/src/core/objects/sequence/changes/sequence.types.ts +3 -1
- package/src/core/objects/sequence/sequence.diff.ts +33 -0
- package/src/core/objects/sequence/sequence.model.ts +22 -1
- package/src/core/objects/subscription/changes/subscription.base.ts +1 -1
- package/src/core/objects/subscription/changes/subscription.security-label.ts +95 -0
- package/src/core/objects/subscription/changes/subscription.types.ts +3 -1
- package/src/core/objects/subscription/subscription.diff.ts +33 -0
- package/src/core/objects/subscription/subscription.model.ts +22 -1
- package/src/core/objects/table/changes/table.base.ts +5 -1
- package/src/core/objects/table/changes/table.security-label.test.ts +140 -0
- package/src/core/objects/table/changes/table.security-label.ts +183 -0
- package/src/core/objects/table/changes/table.types.ts +3 -1
- package/src/core/objects/table/table.diff.ts +87 -0
- package/src/core/objects/table/table.model.ts +42 -2
- package/src/core/objects/type/composite-type/changes/composite-type.base.ts +5 -1
- package/src/core/objects/type/composite-type/changes/composite-type.security-label.ts +95 -0
- package/src/core/objects/type/composite-type/changes/composite-type.types.ts +3 -1
- package/src/core/objects/type/composite-type/composite-type.diff.ts +33 -0
- package/src/core/objects/type/composite-type/composite-type.model.ts +26 -2
- package/src/core/objects/type/enum/changes/enum.base.ts +5 -1
- package/src/core/objects/type/enum/changes/enum.security-label.ts +77 -0
- package/src/core/objects/type/enum/changes/enum.types.ts +3 -1
- package/src/core/objects/type/enum/enum.diff.ts +33 -0
- package/src/core/objects/type/enum/enum.model.ts +25 -1
- package/src/core/objects/type/range/changes/range.base.ts +5 -1
- package/src/core/objects/type/range/changes/range.security-label.ts +77 -0
- package/src/core/objects/type/range/changes/range.types.ts +3 -1
- package/src/core/objects/type/range/range.diff.ts +33 -0
- package/src/core/objects/type/range/range.model.ts +22 -1
- package/src/core/objects/utils.ts +3 -0
- package/src/core/objects/view/changes/view.base.ts +5 -1
- package/src/core/objects/view/changes/view.security-label.test.ts +64 -0
- package/src/core/objects/view/changes/view.security-label.ts +77 -0
- package/src/core/objects/view/changes/view.types.ts +3 -1
- package/src/core/objects/view/view.diff.ts +31 -0
- package/src/core/objects/view/view.model.ts +25 -2
- package/src/core/plan/sql-format/fixtures.ts +1 -0
|
@@ -3,6 +3,7 @@ import z from "zod";
|
|
|
3
3
|
import { BasePgModel, columnPropsSchema, normalizeColumns, } from "../base.model.js";
|
|
4
4
|
import { privilegePropsSchema, } from "../base.privilege-diff.js";
|
|
5
5
|
import { extractWithDefinitionRetry, } from "../extract-with-retry.js";
|
|
6
|
+
import { normalizeSecurityLabels, securityLabelPropsSchema, } from "../security-label.types.js";
|
|
6
7
|
import { ReplicaIdentitySchema } from "../table/table.model.js";
|
|
7
8
|
const viewPropsSchema = z.object({
|
|
8
9
|
schema: z.string(),
|
|
@@ -23,6 +24,7 @@ const viewPropsSchema = z.object({
|
|
|
23
24
|
comment: z.string().nullable(),
|
|
24
25
|
columns: z.array(columnPropsSchema),
|
|
25
26
|
privileges: z.array(privilegePropsSchema),
|
|
27
|
+
security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
|
|
26
28
|
});
|
|
27
29
|
// pg_get_viewdef(oid) can return NULL when the underlying view (or its
|
|
28
30
|
// pg_rewrite row) is dropped between catalog scan and resolution, or under
|
|
@@ -51,6 +53,7 @@ export class View extends BasePgModel {
|
|
|
51
53
|
comment;
|
|
52
54
|
columns;
|
|
53
55
|
privileges;
|
|
56
|
+
security_labels;
|
|
54
57
|
constructor(props) {
|
|
55
58
|
super();
|
|
56
59
|
// Identity fields
|
|
@@ -73,6 +76,7 @@ export class View extends BasePgModel {
|
|
|
73
76
|
this.comment = props.comment;
|
|
74
77
|
this.columns = props.columns;
|
|
75
78
|
this.privileges = props.privileges;
|
|
79
|
+
this.security_labels = props.security_labels ?? [];
|
|
76
80
|
}
|
|
77
81
|
get stableId() {
|
|
78
82
|
return `view:${this.schema}.${this.name}`;
|
|
@@ -101,6 +105,7 @@ export class View extends BasePgModel {
|
|
|
101
105
|
comment: this.comment,
|
|
102
106
|
columns: this.columns,
|
|
103
107
|
privileges: this.privileges,
|
|
108
|
+
security_labels: this.security_labels,
|
|
104
109
|
};
|
|
105
110
|
}
|
|
106
111
|
stableSnapshot() {
|
|
@@ -109,6 +114,7 @@ export class View extends BasePgModel {
|
|
|
109
114
|
data: {
|
|
110
115
|
...this.dataFields,
|
|
111
116
|
columns: normalizeColumns(this.columns),
|
|
117
|
+
security_labels: normalizeSecurityLabels(this.security_labels),
|
|
112
118
|
},
|
|
113
119
|
};
|
|
114
120
|
}
|
|
@@ -235,7 +241,20 @@ select
|
|
|
235
241
|
join lateral aclexplode(src.acl) as x(grantor, grantee, privilege_type, is_grantable) on true
|
|
236
242
|
group by x.grantee, x.privilege_type
|
|
237
243
|
) as grp
|
|
238
|
-
), '[]') as privileges
|
|
244
|
+
), '[]') as privileges,
|
|
245
|
+
coalesce(
|
|
246
|
+
(
|
|
247
|
+
select json_agg(
|
|
248
|
+
json_build_object('provider', sl.provider, 'label', sl.label)
|
|
249
|
+
order by sl.provider
|
|
250
|
+
)
|
|
251
|
+
from pg_catalog.pg_seclabel sl
|
|
252
|
+
where sl.objoid = v.oid
|
|
253
|
+
and sl.classoid = 'pg_class'::regclass
|
|
254
|
+
and sl.objsubid = 0
|
|
255
|
+
),
|
|
256
|
+
'[]'::json
|
|
257
|
+
) as security_labels
|
|
239
258
|
from
|
|
240
259
|
views v
|
|
241
260
|
left join pg_attribute a on a.attrelid = v.oid and a.attnum > 0 and not a.attisdropped
|
package/package.json
CHANGED
|
@@ -41,6 +41,16 @@ const membershipChange = {
|
|
|
41
41
|
requires: [],
|
|
42
42
|
} as unknown as Change;
|
|
43
43
|
|
|
44
|
+
const securityLabelChange = {
|
|
45
|
+
objectType: "schema",
|
|
46
|
+
operation: "create",
|
|
47
|
+
scope: "security_label",
|
|
48
|
+
schema: { name: "labeled" },
|
|
49
|
+
securityLabel: { provider: "dummy", label: "classified" },
|
|
50
|
+
requires: ["schema:labeled"],
|
|
51
|
+
creates: ["security_label:schema:labeled:dummy"],
|
|
52
|
+
} as unknown as Change;
|
|
53
|
+
|
|
44
54
|
describe("evaluatePattern", () => {
|
|
45
55
|
describe("bare key matching (top-level properties)", () => {
|
|
46
56
|
test("objectType match", () => {
|
|
@@ -242,6 +252,23 @@ describe("evaluatePattern", () => {
|
|
|
242
252
|
});
|
|
243
253
|
});
|
|
244
254
|
|
|
255
|
+
describe("security label matching", () => {
|
|
256
|
+
test("provider matches security label changes", () => {
|
|
257
|
+
expect(
|
|
258
|
+
evaluatePattern(
|
|
259
|
+
{ scope: "security_label", provider: "dummy" },
|
|
260
|
+
securityLabelChange,
|
|
261
|
+
),
|
|
262
|
+
).toBe(true);
|
|
263
|
+
expect(
|
|
264
|
+
evaluatePattern(
|
|
265
|
+
{ scope: "security_label", provider: "other" },
|
|
266
|
+
securityLabelChange,
|
|
267
|
+
),
|
|
268
|
+
).toBe(false);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
|
|
245
272
|
describe("composition patterns", () => {
|
|
246
273
|
test("not negates a pattern", () => {
|
|
247
274
|
expect(
|
|
@@ -105,6 +105,22 @@ export function flattenChange(change: Change): Record<string, FlatValue> {
|
|
|
105
105
|
flat[`${prefix}/${subKey}`] = flatVal;
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
+
} else if (
|
|
109
|
+
key === "securityLabel" &&
|
|
110
|
+
value &&
|
|
111
|
+
typeof value === "object" &&
|
|
112
|
+
!Array.isArray(value)
|
|
113
|
+
) {
|
|
114
|
+
// Security labels are change-level metadata, so expose provider/label as
|
|
115
|
+
// bare keys for filters like { scope: "security_label", provider: "..." }.
|
|
116
|
+
for (const [subKey, subValue] of Object.entries(
|
|
117
|
+
value as Record<string, unknown>,
|
|
118
|
+
)) {
|
|
119
|
+
const flatVal = toFlatValue(subValue);
|
|
120
|
+
if (flatVal !== undefined) {
|
|
121
|
+
flat[subKey] = flatVal;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
108
124
|
} else {
|
|
109
125
|
const flatVal = toFlatValue(value);
|
|
110
126
|
if (flatVal !== undefined) {
|
|
@@ -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 type { Aggregate } from "./aggregate.model.ts";
|
|
10
11
|
import { AlterAggregateChangeOwner } from "./changes/aggregate.alter.ts";
|
|
@@ -19,6 +20,10 @@ import {
|
|
|
19
20
|
RevokeAggregatePrivileges,
|
|
20
21
|
RevokeGrantOptionAggregatePrivileges,
|
|
21
22
|
} from "./changes/aggregate.privilege.ts";
|
|
23
|
+
import {
|
|
24
|
+
CreateSecurityLabelOnAggregate,
|
|
25
|
+
DropSecurityLabelOnAggregate,
|
|
26
|
+
} from "./changes/aggregate.security-label.ts";
|
|
22
27
|
import type { AggregateChange } from "./changes/aggregate.types.ts";
|
|
23
28
|
|
|
24
29
|
export function diffAggregates(
|
|
@@ -51,6 +56,14 @@ export function diffAggregates(
|
|
|
51
56
|
if (aggregate.comment !== null) {
|
|
52
57
|
changes.push(new CreateCommentOnAggregate({ aggregate }));
|
|
53
58
|
}
|
|
59
|
+
for (const label of aggregate.security_labels) {
|
|
60
|
+
changes.push(
|
|
61
|
+
new CreateSecurityLabelOnAggregate({
|
|
62
|
+
aggregate,
|
|
63
|
+
securityLabel: label,
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
66
|
+
}
|
|
54
67
|
|
|
55
68
|
// PRIVILEGES: For created objects, compare against default privileges state
|
|
56
69
|
// The migration script will run ALTER DEFAULT PRIVILEGES before CREATE (via constraint spec),
|
|
@@ -182,6 +195,26 @@ export function diffAggregates(
|
|
|
182
195
|
}
|
|
183
196
|
}
|
|
184
197
|
|
|
198
|
+
// SECURITY LABELS
|
|
199
|
+
changes.push(
|
|
200
|
+
...diffSecurityLabels<
|
|
201
|
+
CreateSecurityLabelOnAggregate | DropSecurityLabelOnAggregate
|
|
202
|
+
>(
|
|
203
|
+
mainAggregate.security_labels,
|
|
204
|
+
branchAggregate.security_labels,
|
|
205
|
+
(securityLabel) =>
|
|
206
|
+
new CreateSecurityLabelOnAggregate({
|
|
207
|
+
aggregate: branchAggregate,
|
|
208
|
+
securityLabel,
|
|
209
|
+
}),
|
|
210
|
+
(securityLabel) =>
|
|
211
|
+
new DropSecurityLabelOnAggregate({
|
|
212
|
+
aggregate: mainAggregate,
|
|
213
|
+
securityLabel,
|
|
214
|
+
}),
|
|
215
|
+
),
|
|
216
|
+
);
|
|
217
|
+
|
|
185
218
|
// PRIVILEGES
|
|
186
219
|
// Filter out PUBLIC's built-in default EXECUTE privilege from main catalog
|
|
187
220
|
// (PostgreSQL grants it automatically, so we shouldn't compare it)
|
|
@@ -6,6 +6,10 @@ import {
|
|
|
6
6
|
type PrivilegeProps,
|
|
7
7
|
privilegePropsSchema,
|
|
8
8
|
} from "../base.privilege-diff.ts";
|
|
9
|
+
import {
|
|
10
|
+
type SecurityLabelProps,
|
|
11
|
+
securityLabelPropsSchema,
|
|
12
|
+
} from "../security-label.types.ts";
|
|
9
13
|
|
|
10
14
|
const AggregateKindSchema = z.enum([
|
|
11
15
|
"n", // normal aggregate
|
|
@@ -75,6 +79,7 @@ const aggregatePropsSchema = z.object({
|
|
|
75
79
|
owner: z.string(),
|
|
76
80
|
comment: z.string().nullable(),
|
|
77
81
|
privileges: z.array(privilegePropsSchema),
|
|
82
|
+
security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
|
|
78
83
|
});
|
|
79
84
|
|
|
80
85
|
type AggregatePrivilegeProps = PrivilegeProps;
|
|
@@ -122,6 +127,7 @@ export class Aggregate extends BasePgModel {
|
|
|
122
127
|
public readonly owner: AggregateProps["owner"];
|
|
123
128
|
public readonly comment: AggregateProps["comment"];
|
|
124
129
|
public readonly privileges: AggregatePrivilegeProps[];
|
|
130
|
+
public readonly security_labels: SecurityLabelProps[];
|
|
125
131
|
|
|
126
132
|
constructor(props: AggregateProps) {
|
|
127
133
|
super();
|
|
@@ -168,6 +174,7 @@ export class Aggregate extends BasePgModel {
|
|
|
168
174
|
this.owner = props.owner;
|
|
169
175
|
this.comment = props.comment;
|
|
170
176
|
this.privileges = props.privileges;
|
|
177
|
+
this.security_labels = props.security_labels ?? [];
|
|
171
178
|
}
|
|
172
179
|
|
|
173
180
|
get stableId(): `aggregate:${string}` {
|
|
@@ -224,6 +231,7 @@ export class Aggregate extends BasePgModel {
|
|
|
224
231
|
owner: this.owner,
|
|
225
232
|
comment: this.comment,
|
|
226
233
|
privileges: this.privileges,
|
|
234
|
+
security_labels: this.security_labels,
|
|
227
235
|
};
|
|
228
236
|
}
|
|
229
237
|
}
|
|
@@ -294,7 +302,20 @@ select
|
|
|
294
302
|
)
|
|
295
303
|
from lateral aclexplode(COALESCE(p.proacl, acldefault('f', p.proowner))) as x(grantor, grantee, privilege_type, is_grantable)
|
|
296
304
|
), '[]'
|
|
297
|
-
) as privileges
|
|
305
|
+
) as privileges,
|
|
306
|
+
coalesce(
|
|
307
|
+
(
|
|
308
|
+
select json_agg(
|
|
309
|
+
json_build_object('provider', sl.provider, 'label', sl.label)
|
|
310
|
+
order by sl.provider
|
|
311
|
+
)
|
|
312
|
+
from pg_catalog.pg_seclabel sl
|
|
313
|
+
where sl.objoid = p.oid
|
|
314
|
+
and sl.classoid = 'pg_proc'::regclass
|
|
315
|
+
and sl.objsubid = 0
|
|
316
|
+
),
|
|
317
|
+
'[]'::json
|
|
318
|
+
) as security_labels
|
|
298
319
|
from
|
|
299
320
|
pg_catalog.pg_proc p
|
|
300
321
|
inner join pg_catalog.pg_aggregate a on a.aggfnoid = p.oid
|
|
@@ -3,7 +3,11 @@ import type { Aggregate } from "../aggregate.model.ts";
|
|
|
3
3
|
|
|
4
4
|
abstract class BaseAggregateChange extends BaseChange {
|
|
5
5
|
abstract readonly aggregate: Aggregate;
|
|
6
|
-
abstract readonly scope:
|
|
6
|
+
abstract readonly scope:
|
|
7
|
+
| "object"
|
|
8
|
+
| "comment"
|
|
9
|
+
| "privilege"
|
|
10
|
+
| "security_label";
|
|
7
11
|
readonly objectType: "aggregate" = "aggregate";
|
|
8
12
|
}
|
|
9
13
|
|
|
@@ -0,0 +1,99 @@
|
|
|
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 { Aggregate } from "../aggregate.model.ts";
|
|
5
|
+
import {
|
|
6
|
+
CreateAggregateChange,
|
|
7
|
+
DropAggregateChange,
|
|
8
|
+
} from "./aggregate.base.ts";
|
|
9
|
+
|
|
10
|
+
export type SecurityLabelAggregate =
|
|
11
|
+
| CreateSecurityLabelOnAggregate
|
|
12
|
+
| DropSecurityLabelOnAggregate;
|
|
13
|
+
|
|
14
|
+
function aggregateIdentity(a: Aggregate): string {
|
|
15
|
+
return `${a.schema}.${a.name}(${a.identityArguments})`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class CreateSecurityLabelOnAggregate extends CreateAggregateChange {
|
|
19
|
+
public readonly aggregate: Aggregate;
|
|
20
|
+
public readonly securityLabel: SecurityLabelProps;
|
|
21
|
+
public readonly scope = "security_label" as const;
|
|
22
|
+
|
|
23
|
+
constructor(props: {
|
|
24
|
+
aggregate: Aggregate;
|
|
25
|
+
securityLabel: SecurityLabelProps;
|
|
26
|
+
}) {
|
|
27
|
+
super();
|
|
28
|
+
this.aggregate = props.aggregate;
|
|
29
|
+
this.securityLabel = props.securityLabel;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get creates() {
|
|
33
|
+
return [
|
|
34
|
+
stableId.securityLabel(
|
|
35
|
+
this.aggregate.stableId,
|
|
36
|
+
this.securityLabel.provider,
|
|
37
|
+
),
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get requires() {
|
|
42
|
+
return [this.aggregate.stableId];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
serialize(): string {
|
|
46
|
+
return [
|
|
47
|
+
"SECURITY LABEL FOR",
|
|
48
|
+
this.securityLabel.provider,
|
|
49
|
+
"ON AGGREGATE",
|
|
50
|
+
aggregateIdentity(this.aggregate),
|
|
51
|
+
"IS",
|
|
52
|
+
quoteLiteral(this.securityLabel.label),
|
|
53
|
+
].join(" ");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export class DropSecurityLabelOnAggregate extends DropAggregateChange {
|
|
58
|
+
public readonly aggregate: Aggregate;
|
|
59
|
+
public readonly securityLabel: SecurityLabelProps;
|
|
60
|
+
public readonly scope = "security_label" as const;
|
|
61
|
+
|
|
62
|
+
constructor(props: {
|
|
63
|
+
aggregate: Aggregate;
|
|
64
|
+
securityLabel: SecurityLabelProps;
|
|
65
|
+
}) {
|
|
66
|
+
super();
|
|
67
|
+
this.aggregate = props.aggregate;
|
|
68
|
+
this.securityLabel = props.securityLabel;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
get drops() {
|
|
72
|
+
return [
|
|
73
|
+
stableId.securityLabel(
|
|
74
|
+
this.aggregate.stableId,
|
|
75
|
+
this.securityLabel.provider,
|
|
76
|
+
),
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
get requires() {
|
|
81
|
+
return [
|
|
82
|
+
stableId.securityLabel(
|
|
83
|
+
this.aggregate.stableId,
|
|
84
|
+
this.securityLabel.provider,
|
|
85
|
+
),
|
|
86
|
+
this.aggregate.stableId,
|
|
87
|
+
];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
serialize(): string {
|
|
91
|
+
return [
|
|
92
|
+
"SECURITY LABEL FOR",
|
|
93
|
+
this.securityLabel.provider,
|
|
94
|
+
"ON AGGREGATE",
|
|
95
|
+
aggregateIdentity(this.aggregate),
|
|
96
|
+
"IS NULL",
|
|
97
|
+
].join(" ");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -3,6 +3,7 @@ import type { CommentAggregate } from "./aggregate.comment.ts";
|
|
|
3
3
|
import type { CreateAggregate } from "./aggregate.create.ts";
|
|
4
4
|
import type { DropAggregate } from "./aggregate.drop.ts";
|
|
5
5
|
import type { AggregatePrivilege } from "./aggregate.privilege.ts";
|
|
6
|
+
import type { SecurityLabelAggregate } from "./aggregate.security-label.ts";
|
|
6
7
|
|
|
7
8
|
/** Union of all aggregate-related change variants (`objectType: "aggregate"`). @category Change Types */
|
|
8
9
|
export type AggregateChange =
|
|
@@ -10,4 +11,5 @@ export type AggregateChange =
|
|
|
10
11
|
| CommentAggregate
|
|
11
12
|
| CreateAggregate
|
|
12
13
|
| DropAggregate
|
|
13
|
-
| AggregatePrivilege
|
|
14
|
+
| AggregatePrivilege
|
|
15
|
+
| SecurityLabelAggregate;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import z from "zod";
|
|
2
|
+
import { securityLabelPropsSchema } from "./security-label.types.ts";
|
|
2
3
|
import { deepEqual } from "./utils.ts";
|
|
3
4
|
|
|
4
5
|
export const columnPropsSchema = z.object({
|
|
@@ -18,6 +19,7 @@ export const columnPropsSchema = z.object({
|
|
|
18
19
|
collation: z.string().nullable(),
|
|
19
20
|
default: z.string().nullable(),
|
|
20
21
|
comment: z.string().nullable(),
|
|
22
|
+
security_labels: z.array(securityLabelPropsSchema).optional(),
|
|
21
23
|
});
|
|
22
24
|
|
|
23
25
|
export type ColumnProps = z.infer<typeof columnPropsSchema>;
|
|
@@ -3,7 +3,11 @@ import type { Domain } from "../domain.model.ts";
|
|
|
3
3
|
|
|
4
4
|
abstract class BaseDomainChange extends BaseChange {
|
|
5
5
|
abstract readonly domain: Domain;
|
|
6
|
-
abstract readonly scope:
|
|
6
|
+
abstract readonly scope:
|
|
7
|
+
| "object"
|
|
8
|
+
| "comment"
|
|
9
|
+
| "privilege"
|
|
10
|
+
| "security_label";
|
|
7
11
|
readonly objectType: "domain" = "domain";
|
|
8
12
|
}
|
|
9
13
|
|
|
@@ -0,0 +1,56 @@
|
|
|
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 { Domain, type DomainProps } from "../domain.model.ts";
|
|
5
|
+
import {
|
|
6
|
+
CreateSecurityLabelOnDomain,
|
|
7
|
+
DropSecurityLabelOnDomain,
|
|
8
|
+
} from "./domain.security-label.ts";
|
|
9
|
+
|
|
10
|
+
const makeDomain = (): Domain =>
|
|
11
|
+
new Domain({
|
|
12
|
+
schema: "public",
|
|
13
|
+
name: "email_t",
|
|
14
|
+
base_type: "text",
|
|
15
|
+
base_type_schema: "pg_catalog",
|
|
16
|
+
not_null: false,
|
|
17
|
+
type_modifier: -1,
|
|
18
|
+
array_dimensions: 0,
|
|
19
|
+
collation: null,
|
|
20
|
+
default_bin: null,
|
|
21
|
+
default_value: null,
|
|
22
|
+
owner: "postgres",
|
|
23
|
+
comment: null,
|
|
24
|
+
constraints: [],
|
|
25
|
+
privileges: [],
|
|
26
|
+
} as DomainProps);
|
|
27
|
+
|
|
28
|
+
describe("domain.security-label", () => {
|
|
29
|
+
test("create serializes", async () => {
|
|
30
|
+
const domain = makeDomain();
|
|
31
|
+
const change = new CreateSecurityLabelOnDomain({
|
|
32
|
+
domain,
|
|
33
|
+
securityLabel: { provider: "dummy", label: "classified" },
|
|
34
|
+
});
|
|
35
|
+
expect(change.scope).toBe("security_label");
|
|
36
|
+
expect(change.creates).toEqual([
|
|
37
|
+
stableId.securityLabel(domain.stableId, "dummy"),
|
|
38
|
+
]);
|
|
39
|
+
await assertValidSql(change.serialize());
|
|
40
|
+
expect(change.serialize()).toBe(
|
|
41
|
+
"SECURITY LABEL FOR dummy ON DOMAIN public.email_t IS 'classified'",
|
|
42
|
+
);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("drop serializes to IS NULL", async () => {
|
|
46
|
+
const domain = makeDomain();
|
|
47
|
+
const change = new DropSecurityLabelOnDomain({
|
|
48
|
+
domain,
|
|
49
|
+
securityLabel: { provider: "dummy", label: "x" },
|
|
50
|
+
});
|
|
51
|
+
await assertValidSql(change.serialize());
|
|
52
|
+
expect(change.serialize()).toBe(
|
|
53
|
+
"SECURITY LABEL FOR dummy ON DOMAIN public.email_t IS NULL",
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -0,0 +1,77 @@
|
|
|
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 { Domain } from "../domain.model.ts";
|
|
5
|
+
import { CreateDomainChange, DropDomainChange } from "./domain.base.ts";
|
|
6
|
+
|
|
7
|
+
export type SecurityLabelDomain =
|
|
8
|
+
| CreateSecurityLabelOnDomain
|
|
9
|
+
| DropSecurityLabelOnDomain;
|
|
10
|
+
|
|
11
|
+
export class CreateSecurityLabelOnDomain extends CreateDomainChange {
|
|
12
|
+
public readonly domain: Domain;
|
|
13
|
+
public readonly securityLabel: SecurityLabelProps;
|
|
14
|
+
public readonly scope = "security_label" as const;
|
|
15
|
+
|
|
16
|
+
constructor(props: { domain: Domain; securityLabel: SecurityLabelProps }) {
|
|
17
|
+
super();
|
|
18
|
+
this.domain = props.domain;
|
|
19
|
+
this.securityLabel = props.securityLabel;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
get creates() {
|
|
23
|
+
return [
|
|
24
|
+
stableId.securityLabel(this.domain.stableId, this.securityLabel.provider),
|
|
25
|
+
];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get requires() {
|
|
29
|
+
return [this.domain.stableId];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
serialize(): string {
|
|
33
|
+
return [
|
|
34
|
+
"SECURITY LABEL FOR",
|
|
35
|
+
this.securityLabel.provider,
|
|
36
|
+
"ON DOMAIN",
|
|
37
|
+
`${this.domain.schema}.${this.domain.name}`,
|
|
38
|
+
"IS",
|
|
39
|
+
quoteLiteral(this.securityLabel.label),
|
|
40
|
+
].join(" ");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class DropSecurityLabelOnDomain extends DropDomainChange {
|
|
45
|
+
public readonly domain: Domain;
|
|
46
|
+
public readonly securityLabel: SecurityLabelProps;
|
|
47
|
+
public readonly scope = "security_label" as const;
|
|
48
|
+
|
|
49
|
+
constructor(props: { domain: Domain; securityLabel: SecurityLabelProps }) {
|
|
50
|
+
super();
|
|
51
|
+
this.domain = props.domain;
|
|
52
|
+
this.securityLabel = props.securityLabel;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get drops() {
|
|
56
|
+
return [
|
|
57
|
+
stableId.securityLabel(this.domain.stableId, this.securityLabel.provider),
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get requires() {
|
|
62
|
+
return [
|
|
63
|
+
stableId.securityLabel(this.domain.stableId, this.securityLabel.provider),
|
|
64
|
+
this.domain.stableId,
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
serialize(): string {
|
|
69
|
+
return [
|
|
70
|
+
"SECURITY LABEL FOR",
|
|
71
|
+
this.securityLabel.provider,
|
|
72
|
+
"ON DOMAIN",
|
|
73
|
+
`${this.domain.schema}.${this.domain.name}`,
|
|
74
|
+
"IS NULL",
|
|
75
|
+
].join(" ");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -3,6 +3,7 @@ import type { CommentDomain } from "./domain.comment.ts";
|
|
|
3
3
|
import type { CreateDomain } from "./domain.create.ts";
|
|
4
4
|
import type { DropDomain } from "./domain.drop.ts";
|
|
5
5
|
import type { DomainPrivilege } from "./domain.privilege.ts";
|
|
6
|
+
import type { SecurityLabelDomain } from "./domain.security-label.ts";
|
|
6
7
|
|
|
7
8
|
/** Union of all domain-related change variants (`objectType: "domain"`). @category Change Types */
|
|
8
9
|
export type DomainChange =
|
|
@@ -10,4 +11,5 @@ export type DomainChange =
|
|
|
10
11
|
| CommentDomain
|
|
11
12
|
| CreateDomain
|
|
12
13
|
| DropDomain
|
|
13
|
-
| DomainPrivilege
|
|
14
|
+
| DomainPrivilege
|
|
15
|
+
| SecurityLabelDomain;
|
|
@@ -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 {
|
|
9
10
|
AlterDomainAddConstraint,
|
|
10
11
|
AlterDomainChangeOwner,
|
|
@@ -26,6 +27,10 @@ import {
|
|
|
26
27
|
RevokeDomainPrivileges,
|
|
27
28
|
RevokeGrantOptionDomainPrivileges,
|
|
28
29
|
} from "./changes/domain.privilege.ts";
|
|
30
|
+
import {
|
|
31
|
+
CreateSecurityLabelOnDomain,
|
|
32
|
+
DropSecurityLabelOnDomain,
|
|
33
|
+
} from "./changes/domain.security-label.ts";
|
|
29
34
|
import type { DomainChange } from "./changes/domain.types.ts";
|
|
30
35
|
import type { Domain } from "./domain.model.ts";
|
|
31
36
|
|
|
@@ -67,6 +72,14 @@ export function diffDomains(
|
|
|
67
72
|
if (newDomain.comment !== null) {
|
|
68
73
|
changes.push(new CreateCommentOnDomain({ domain: newDomain }));
|
|
69
74
|
}
|
|
75
|
+
for (const label of newDomain.security_labels) {
|
|
76
|
+
changes.push(
|
|
77
|
+
new CreateSecurityLabelOnDomain({
|
|
78
|
+
domain: newDomain,
|
|
79
|
+
securityLabel: label,
|
|
80
|
+
}),
|
|
81
|
+
);
|
|
82
|
+
}
|
|
70
83
|
// For unvalidated constraints, CREATE DOMAIN cannot specify NOT VALID.
|
|
71
84
|
// Add them after creation and validate to match branch state semantics.
|
|
72
85
|
// For already validated constraints, they are emitted inline in CREATE DOMAIN.
|
|
@@ -255,6 +268,26 @@ export function diffDomains(
|
|
|
255
268
|
}
|
|
256
269
|
}
|
|
257
270
|
|
|
271
|
+
// SECURITY LABELS
|
|
272
|
+
changes.push(
|
|
273
|
+
...diffSecurityLabels<
|
|
274
|
+
CreateSecurityLabelOnDomain | DropSecurityLabelOnDomain
|
|
275
|
+
>(
|
|
276
|
+
mainDomain.security_labels,
|
|
277
|
+
branchDomain.security_labels,
|
|
278
|
+
(securityLabel) =>
|
|
279
|
+
new CreateSecurityLabelOnDomain({
|
|
280
|
+
domain: branchDomain,
|
|
281
|
+
securityLabel,
|
|
282
|
+
}),
|
|
283
|
+
(securityLabel) =>
|
|
284
|
+
new DropSecurityLabelOnDomain({
|
|
285
|
+
domain: mainDomain,
|
|
286
|
+
securityLabel,
|
|
287
|
+
}),
|
|
288
|
+
),
|
|
289
|
+
);
|
|
290
|
+
|
|
258
291
|
// PRIVILEGES
|
|
259
292
|
// Filter out PUBLIC's built-in default USAGE privilege from main catalog
|
|
260
293
|
// (PostgreSQL grants it automatically, so we shouldn't compare it)
|