@supabase/pg-delta 1.0.0-alpha.22 → 1.0.0-alpha.24
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/dist/core/post-diff-normalization.d.ts +7 -0
- package/dist/core/post-diff-normalization.js +33 -4
- package/dist/core/sort/cycle-breakers.js +139 -17
- 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
- package/src/core/post-diff-normalization.test.ts +123 -0
- package/src/core/post-diff-normalization.ts +40 -4
- package/src/core/sort/cycle-breakers.test.ts +236 -2
- package/src/core/sort/cycle-breakers.ts +184 -24
- package/src/core/sort/sort-changes.test.ts +317 -0
|
@@ -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
|
AlterForeignTableAddColumn,
|
|
10
11
|
AlterForeignTableAlterColumnDropDefault,
|
|
@@ -27,6 +28,10 @@ import {
|
|
|
27
28
|
RevokeForeignTablePrivileges,
|
|
28
29
|
RevokeGrantOptionForeignTablePrivileges,
|
|
29
30
|
} from "./changes/foreign-table.privilege.ts";
|
|
31
|
+
import {
|
|
32
|
+
CreateSecurityLabelOnForeignTable,
|
|
33
|
+
DropSecurityLabelOnForeignTable,
|
|
34
|
+
} from "./changes/foreign-table.security-label.ts";
|
|
30
35
|
import type { ForeignTableChange } from "./changes/foreign-table.types.ts";
|
|
31
36
|
import type { ForeignTable } from "./foreign-table.model.ts";
|
|
32
37
|
|
|
@@ -70,6 +75,14 @@ export function diffForeignTables(
|
|
|
70
75
|
new CreateCommentOnForeignTable({ foreignTable: createdTable }),
|
|
71
76
|
);
|
|
72
77
|
}
|
|
78
|
+
for (const label of createdTable.security_labels) {
|
|
79
|
+
changes.push(
|
|
80
|
+
new CreateSecurityLabelOnForeignTable({
|
|
81
|
+
foreignTable: createdTable,
|
|
82
|
+
securityLabel: label,
|
|
83
|
+
}),
|
|
84
|
+
);
|
|
85
|
+
}
|
|
73
86
|
|
|
74
87
|
// PRIVILEGES: For created objects, compare against default privileges state
|
|
75
88
|
const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(
|
|
@@ -249,6 +262,26 @@ export function diffForeignTables(
|
|
|
249
262
|
}
|
|
250
263
|
}
|
|
251
264
|
|
|
265
|
+
// SECURITY LABELS
|
|
266
|
+
changes.push(
|
|
267
|
+
...diffSecurityLabels<
|
|
268
|
+
CreateSecurityLabelOnForeignTable | DropSecurityLabelOnForeignTable
|
|
269
|
+
>(
|
|
270
|
+
mainTable.security_labels,
|
|
271
|
+
branchTable.security_labels,
|
|
272
|
+
(securityLabel) =>
|
|
273
|
+
new CreateSecurityLabelOnForeignTable({
|
|
274
|
+
foreignTable: branchTable,
|
|
275
|
+
securityLabel,
|
|
276
|
+
}),
|
|
277
|
+
(securityLabel) =>
|
|
278
|
+
new DropSecurityLabelOnForeignTable({
|
|
279
|
+
foreignTable: mainTable,
|
|
280
|
+
securityLabel,
|
|
281
|
+
}),
|
|
282
|
+
),
|
|
283
|
+
);
|
|
284
|
+
|
|
252
285
|
// PRIVILEGES
|
|
253
286
|
const mainPrivilegesFiltered = filterPublicBuiltInDefaults(
|
|
254
287
|
"foreign_table",
|
|
@@ -10,6 +10,11 @@ import {
|
|
|
10
10
|
type PrivilegeProps,
|
|
11
11
|
privilegePropsSchema,
|
|
12
12
|
} from "../../base.privilege-diff.ts";
|
|
13
|
+
import {
|
|
14
|
+
normalizeSecurityLabels,
|
|
15
|
+
type SecurityLabelProps,
|
|
16
|
+
securityLabelPropsSchema,
|
|
17
|
+
} from "../../security-label.types.ts";
|
|
13
18
|
|
|
14
19
|
/**
|
|
15
20
|
* All properties exposed by CREATE FOREIGN TABLE statement are included in diff output.
|
|
@@ -30,6 +35,7 @@ const foreignTablePropsSchema = z.object({
|
|
|
30
35
|
comment: z.string().nullable(),
|
|
31
36
|
columns: z.array(columnPropsSchema),
|
|
32
37
|
privileges: z.array(privilegePropsSchema),
|
|
38
|
+
security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
|
|
33
39
|
});
|
|
34
40
|
|
|
35
41
|
type ForeignTablePrivilegeProps = PrivilegeProps;
|
|
@@ -44,6 +50,7 @@ export class ForeignTable extends BasePgModel implements TableLikeObject {
|
|
|
44
50
|
public readonly comment: ForeignTableProps["comment"];
|
|
45
51
|
public readonly columns: ForeignTableProps["columns"];
|
|
46
52
|
public readonly privileges: ForeignTablePrivilegeProps[];
|
|
53
|
+
public readonly security_labels: SecurityLabelProps[];
|
|
47
54
|
|
|
48
55
|
constructor(props: ForeignTableProps) {
|
|
49
56
|
super();
|
|
@@ -59,6 +66,7 @@ export class ForeignTable extends BasePgModel implements TableLikeObject {
|
|
|
59
66
|
this.comment = props.comment;
|
|
60
67
|
this.columns = props.columns;
|
|
61
68
|
this.privileges = props.privileges;
|
|
69
|
+
this.security_labels = props.security_labels ?? [];
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
get stableId(): `foreignTable:${string}` {
|
|
@@ -80,6 +88,7 @@ export class ForeignTable extends BasePgModel implements TableLikeObject {
|
|
|
80
88
|
comment: this.comment,
|
|
81
89
|
columns: this.columns,
|
|
82
90
|
privileges: this.privileges,
|
|
91
|
+
security_labels: this.security_labels,
|
|
83
92
|
};
|
|
84
93
|
}
|
|
85
94
|
|
|
@@ -104,6 +113,7 @@ export class ForeignTable extends BasePgModel implements TableLikeObject {
|
|
|
104
113
|
data: {
|
|
105
114
|
...this.dataFields,
|
|
106
115
|
columns: normalizeColumns(),
|
|
116
|
+
security_labels: normalizeSecurityLabels(this.security_labels),
|
|
107
117
|
},
|
|
108
118
|
};
|
|
109
119
|
}
|
|
@@ -209,7 +219,20 @@ export async function extractForeignTables(
|
|
|
209
219
|
join lateral aclexplode(src.acl) as x(grantor, grantee, privilege_type, is_grantable) on true
|
|
210
220
|
group by x.grantee, x.privilege_type
|
|
211
221
|
) as grp
|
|
212
|
-
), '[]') as privileges
|
|
222
|
+
), '[]') as privileges,
|
|
223
|
+
coalesce(
|
|
224
|
+
(
|
|
225
|
+
select json_agg(
|
|
226
|
+
json_build_object('provider', sl.provider, 'label', sl.label)
|
|
227
|
+
order by sl.provider
|
|
228
|
+
)
|
|
229
|
+
from pg_catalog.pg_seclabel sl
|
|
230
|
+
where sl.objoid = ft.oid
|
|
231
|
+
and sl.classoid = 'pg_class'::regclass
|
|
232
|
+
and sl.objsubid = 0
|
|
233
|
+
),
|
|
234
|
+
'[]'::json
|
|
235
|
+
) as security_labels
|
|
213
236
|
from
|
|
214
237
|
foreign_tables ft
|
|
215
238
|
left join pg_attribute a on a.attrelid = ft.oid and a.attnum > 0 and not a.attisdropped
|
|
@@ -3,7 +3,11 @@ import type { MaterializedView } from "../materialized-view.model.ts";
|
|
|
3
3
|
|
|
4
4
|
abstract class BaseMaterializedViewChange extends BaseChange {
|
|
5
5
|
abstract readonly materializedView: MaterializedView;
|
|
6
|
-
abstract readonly scope:
|
|
6
|
+
abstract readonly scope:
|
|
7
|
+
| "object"
|
|
8
|
+
| "comment"
|
|
9
|
+
| "privilege"
|
|
10
|
+
| "security_label";
|
|
7
11
|
readonly objectType: "materialized_view" = "materialized_view";
|
|
8
12
|
}
|
|
9
13
|
|
|
@@ -0,0 +1,63 @@
|
|
|
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 {
|
|
5
|
+
MaterializedView,
|
|
6
|
+
type MaterializedViewProps,
|
|
7
|
+
} from "../materialized-view.model.ts";
|
|
8
|
+
import {
|
|
9
|
+
CreateSecurityLabelOnMaterializedView,
|
|
10
|
+
DropSecurityLabelOnMaterializedView,
|
|
11
|
+
} from "./materialized-view.security-label.ts";
|
|
12
|
+
|
|
13
|
+
const makeMV = (): MaterializedView =>
|
|
14
|
+
new MaterializedView({
|
|
15
|
+
schema: "public",
|
|
16
|
+
name: "mv",
|
|
17
|
+
definition: "SELECT 1",
|
|
18
|
+
row_security: false,
|
|
19
|
+
force_row_security: false,
|
|
20
|
+
has_indexes: false,
|
|
21
|
+
has_rules: false,
|
|
22
|
+
has_triggers: false,
|
|
23
|
+
has_subclasses: false,
|
|
24
|
+
is_populated: true,
|
|
25
|
+
replica_identity: "d",
|
|
26
|
+
is_partition: false,
|
|
27
|
+
options: null,
|
|
28
|
+
partition_bound: null,
|
|
29
|
+
owner: "postgres",
|
|
30
|
+
comment: null,
|
|
31
|
+
columns: [],
|
|
32
|
+
privileges: [],
|
|
33
|
+
} as MaterializedViewProps);
|
|
34
|
+
|
|
35
|
+
describe("materialized-view.security-label", () => {
|
|
36
|
+
test("create serializes", async () => {
|
|
37
|
+
const mv = makeMV();
|
|
38
|
+
const change = new CreateSecurityLabelOnMaterializedView({
|
|
39
|
+
materializedView: mv,
|
|
40
|
+
securityLabel: { provider: "dummy", label: "classified" },
|
|
41
|
+
});
|
|
42
|
+
expect(change.scope).toBe("security_label");
|
|
43
|
+
expect(change.creates).toEqual([
|
|
44
|
+
stableId.securityLabel(mv.stableId, "dummy"),
|
|
45
|
+
]);
|
|
46
|
+
await assertValidSql(change.serialize());
|
|
47
|
+
expect(change.serialize()).toBe(
|
|
48
|
+
"SECURITY LABEL FOR dummy ON MATERIALIZED VIEW public.mv IS 'classified'",
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("drop serializes to IS NULL", async () => {
|
|
53
|
+
const mv = makeMV();
|
|
54
|
+
const change = new DropSecurityLabelOnMaterializedView({
|
|
55
|
+
materializedView: mv,
|
|
56
|
+
securityLabel: { provider: "dummy", label: "x" },
|
|
57
|
+
});
|
|
58
|
+
await assertValidSql(change.serialize());
|
|
59
|
+
expect(change.serialize()).toBe(
|
|
60
|
+
"SECURITY LABEL FOR dummy ON MATERIALIZED VIEW public.mv IS NULL",
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
@@ -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:
|
|
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(
|