@supabase/pg-delta 1.0.0-alpha.21 → 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.diff.js +4 -3
- package/dist/core/catalog.model.d.ts +8 -1
- package/dist/core/catalog.model.js +10 -8
- package/dist/core/expand-replace-dependencies.js +23 -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/extract-with-retry.d.ts +36 -0
- package/dist/core/objects/extract-with-retry.js +51 -0
- 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/index/index.diff.js +0 -1
- package/dist/core/objects/index/index.model.d.ts +2 -3
- package/dist/core/objects/index/index.model.js +17 -6
- 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 +24 -1
- package/dist/core/objects/materialized-view/materialized-view.model.js +40 -5
- 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 +12 -1
- package/dist/core/objects/procedure/procedure.model.js +39 -5
- 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/rls-policy/rls-policy.diff.js +13 -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/rule/rule.model.d.ts +2 -1
- package/dist/core/objects/rule/rule.model.js +20 -3
- 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.d.ts +2 -1
- package/dist/core/objects/sequence/sequence.diff.js +44 -4
- 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.alter.d.ts +12 -1
- package/dist/core/objects/table/changes/table.alter.js +20 -2
- 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 +68 -15
- package/dist/core/objects/table/table.model.d.ts +36 -1
- package/dist/core/objects/table/table.model.js +74 -7
- package/dist/core/objects/trigger/trigger.model.d.ts +2 -1
- package/dist/core/objects/trigger/trigger.model.js +20 -4
- 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 +2 -0
- package/dist/core/objects/utils.js +6 -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 +28 -1
- package/dist/core/objects/view/view.model.js +40 -5
- package/dist/core/plan/create.js +3 -1
- package/dist/core/plan/sql-format/fixtures.js +1 -0
- package/dist/core/plan/types.d.ts +8 -0
- package/dist/core/{post-diff-cycle-breaking.d.ts → post-diff-normalization.d.ts} +8 -1
- package/dist/core/post-diff-normalization.js +202 -0
- package/dist/core/sort/cycle-breakers.js +1 -1
- package/dist/core/sort/utils.d.ts +10 -0
- package/dist/core/sort/utils.js +28 -0
- package/package.json +1 -1
- package/src/core/catalog.diff.ts +4 -2
- package/src/core/catalog.model.ts +21 -8
- package/src/core/expand-replace-dependencies.test.ts +131 -0
- package/src/core/expand-replace-dependencies.ts +24 -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/extract-with-retry.test.ts +143 -0
- package/src/core/objects/extract-with-retry.ts +87 -0
- 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/index/index.diff.ts +0 -1
- package/src/core/objects/index/index.model.test.ts +37 -1
- package/src/core/objects/index/index.model.ts +25 -6
- 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.test.ts +93 -0
- package/src/core/objects/materialized-view/materialized-view.model.ts +52 -8
- 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.test.ts +117 -0
- package/src/core/objects/procedure/procedure.model.ts +51 -7
- 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/rls-policy/rls-policy.diff.ts +19 -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/rule/rule.model.test.ts +99 -0
- package/src/core/objects/rule/rule.model.ts +28 -4
- 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.test.ts +87 -0
- package/src/core/objects/sequence/sequence.diff.ts +64 -6
- 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.alter.test.ts +13 -21
- package/src/core/objects/table/changes/table.alter.ts +30 -3
- 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 +111 -19
- package/src/core/objects/table/table.model.test.ts +209 -0
- package/src/core/objects/table/table.model.ts +94 -9
- package/src/core/objects/trigger/trigger.model.test.ts +113 -0
- package/src/core/objects/trigger/trigger.model.ts +28 -5
- 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 +6 -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.test.ts +90 -0
- package/src/core/objects/view/view.model.ts +53 -7
- package/src/core/plan/create.ts +3 -1
- package/src/core/plan/sql-format/fixtures.ts +1 -0
- package/src/core/plan/types.ts +8 -0
- package/src/core/{post-diff-cycle-breaking.test.ts → post-diff-normalization.test.ts} +168 -4
- package/src/core/post-diff-normalization.ts +260 -0
- package/src/core/sort/cycle-breakers.ts +1 -1
- package/src/core/sort/utils.ts +38 -0
- package/dist/core/post-diff-cycle-breaking.js +0 -100
- package/src/core/post-diff-cycle-breaking.ts +0 -138
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import {
|
|
3
|
+
diffSecurityLabels,
|
|
4
|
+
type SecurityLabelProps,
|
|
5
|
+
securityLabelPropsSchema,
|
|
6
|
+
} from "./security-label.types.ts";
|
|
7
|
+
|
|
8
|
+
describe("securityLabelPropsSchema", () => {
|
|
9
|
+
test("parses valid props", () => {
|
|
10
|
+
const parsed = securityLabelPropsSchema.parse({
|
|
11
|
+
provider: "p",
|
|
12
|
+
label: "l",
|
|
13
|
+
});
|
|
14
|
+
expect(parsed).toEqual({ provider: "p", label: "l" });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("rejects null provider", () => {
|
|
18
|
+
expect(() =>
|
|
19
|
+
securityLabelPropsSchema.parse({ provider: null, label: "l" }),
|
|
20
|
+
).toThrow();
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("rejects null label", () => {
|
|
24
|
+
expect(() =>
|
|
25
|
+
securityLabelPropsSchema.parse({ provider: "p", label: null }),
|
|
26
|
+
).toThrow();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
describe("diffSecurityLabels", () => {
|
|
31
|
+
type Change = { kind: "create" | "drop" } & SecurityLabelProps;
|
|
32
|
+
const makeCreate = (p: SecurityLabelProps): Change => ({
|
|
33
|
+
kind: "create",
|
|
34
|
+
...p,
|
|
35
|
+
});
|
|
36
|
+
const makeDrop = (p: SecurityLabelProps): Change => ({
|
|
37
|
+
kind: "drop",
|
|
38
|
+
...p,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("both empty → no changes", () => {
|
|
42
|
+
expect(diffSecurityLabels([], [], makeCreate, makeDrop)).toEqual([]);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("added providers emit create", () => {
|
|
46
|
+
expect(
|
|
47
|
+
diffSecurityLabels(
|
|
48
|
+
[],
|
|
49
|
+
[{ provider: "a", label: "x" }],
|
|
50
|
+
makeCreate,
|
|
51
|
+
makeDrop,
|
|
52
|
+
),
|
|
53
|
+
).toEqual([{ kind: "create", provider: "a", label: "x" }]);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("removed providers emit drop", () => {
|
|
57
|
+
expect(
|
|
58
|
+
diffSecurityLabels(
|
|
59
|
+
[{ provider: "a", label: "x" }],
|
|
60
|
+
[],
|
|
61
|
+
makeCreate,
|
|
62
|
+
makeDrop,
|
|
63
|
+
),
|
|
64
|
+
).toEqual([{ kind: "drop", provider: "a", label: "x" }]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("changed label emits create (overwrite semantics)", () => {
|
|
68
|
+
expect(
|
|
69
|
+
diffSecurityLabels(
|
|
70
|
+
[{ provider: "a", label: "old" }],
|
|
71
|
+
[{ provider: "a", label: "new" }],
|
|
72
|
+
makeCreate,
|
|
73
|
+
makeDrop,
|
|
74
|
+
),
|
|
75
|
+
).toEqual([{ kind: "create", provider: "a", label: "new" }]);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
test("unchanged label emits nothing", () => {
|
|
79
|
+
expect(
|
|
80
|
+
diffSecurityLabels(
|
|
81
|
+
[{ provider: "a", label: "x" }],
|
|
82
|
+
[{ provider: "a", label: "x" }],
|
|
83
|
+
makeCreate,
|
|
84
|
+
makeDrop,
|
|
85
|
+
),
|
|
86
|
+
).toEqual([]);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("mixed add/remove/change/unchanged across providers, sorted by provider", () => {
|
|
90
|
+
const main = [
|
|
91
|
+
{ provider: "a", label: "stay" },
|
|
92
|
+
{ provider: "b", label: "old" },
|
|
93
|
+
{ provider: "c", label: "remove" },
|
|
94
|
+
];
|
|
95
|
+
const branch = [
|
|
96
|
+
{ provider: "a", label: "stay" },
|
|
97
|
+
{ provider: "b", label: "new" },
|
|
98
|
+
{ provider: "d", label: "add" },
|
|
99
|
+
];
|
|
100
|
+
expect(diffSecurityLabels(main, branch, makeCreate, makeDrop)).toEqual([
|
|
101
|
+
{ kind: "create", provider: "b", label: "new" },
|
|
102
|
+
{ kind: "drop", provider: "c", label: "remove" },
|
|
103
|
+
{ kind: "create", provider: "d", label: "add" },
|
|
104
|
+
]);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const securityLabelPropsSchema = z.object({
|
|
4
|
+
provider: z.string(),
|
|
5
|
+
label: z.string(),
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export type SecurityLabelProps = z.infer<typeof securityLabelPropsSchema>;
|
|
9
|
+
|
|
10
|
+
export function normalizeSecurityLabels(
|
|
11
|
+
labels: readonly SecurityLabelProps[],
|
|
12
|
+
): SecurityLabelProps[] {
|
|
13
|
+
return [...labels].sort((a, b) => a.provider.localeCompare(b.provider));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Pure helper: compares two arrays of security labels keyed by provider and
|
|
18
|
+
* returns a deterministic list of create/drop changes.
|
|
19
|
+
*
|
|
20
|
+
* - Labels present only on `branch` → emit create (via makeCreate).
|
|
21
|
+
* - Labels present only on `main` → emit drop (via makeDrop).
|
|
22
|
+
* - Labels with differing `label` under the same provider → emit create
|
|
23
|
+
* (PostgreSQL's SECURITY LABEL … IS '…' overwrites, so no separate alter).
|
|
24
|
+
* - Unchanged labels → nothing.
|
|
25
|
+
*
|
|
26
|
+
* Output order: by provider ascending.
|
|
27
|
+
*/
|
|
28
|
+
export function diffSecurityLabels<C>(
|
|
29
|
+
main: readonly SecurityLabelProps[],
|
|
30
|
+
branch: readonly SecurityLabelProps[],
|
|
31
|
+
makeCreate: (props: SecurityLabelProps) => C,
|
|
32
|
+
makeDrop: (props: SecurityLabelProps) => C,
|
|
33
|
+
): C[] {
|
|
34
|
+
const mainByProvider = new Map(main.map((l) => [l.provider, l.label]));
|
|
35
|
+
const branchByProvider = new Map(branch.map((l) => [l.provider, l.label]));
|
|
36
|
+
|
|
37
|
+
const providers = new Set<string>([
|
|
38
|
+
...mainByProvider.keys(),
|
|
39
|
+
...branchByProvider.keys(),
|
|
40
|
+
]);
|
|
41
|
+
const sortedProviders = [...providers].sort();
|
|
42
|
+
|
|
43
|
+
const out: C[] = [];
|
|
44
|
+
for (const provider of sortedProviders) {
|
|
45
|
+
const mainLabel = mainByProvider.get(provider);
|
|
46
|
+
const branchLabel = branchByProvider.get(provider);
|
|
47
|
+
|
|
48
|
+
if (mainLabel === undefined && branchLabel !== undefined) {
|
|
49
|
+
out.push(makeCreate({ provider, label: branchLabel }));
|
|
50
|
+
} else if (mainLabel !== undefined && branchLabel === undefined) {
|
|
51
|
+
out.push(makeDrop({ provider, label: mainLabel }));
|
|
52
|
+
} else if (
|
|
53
|
+
mainLabel !== undefined &&
|
|
54
|
+
branchLabel !== undefined &&
|
|
55
|
+
mainLabel !== branchLabel
|
|
56
|
+
) {
|
|
57
|
+
out.push(makeCreate({ provider, label: branchLabel }));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
@@ -3,7 +3,11 @@ import type { Sequence } from "../sequence.model.ts";
|
|
|
3
3
|
|
|
4
4
|
abstract class BaseSequenceChange extends BaseChange {
|
|
5
5
|
abstract readonly sequence: Sequence;
|
|
6
|
-
abstract readonly scope:
|
|
6
|
+
abstract readonly scope:
|
|
7
|
+
| "object"
|
|
8
|
+
| "comment"
|
|
9
|
+
| "privilege"
|
|
10
|
+
| "security_label";
|
|
7
11
|
readonly objectType: "sequence" = "sequence";
|
|
8
12
|
}
|
|
9
13
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
|
|
3
|
+
import { stableId } from "../../utils.ts";
|
|
4
|
+
import { Sequence, type SequenceProps } from "../sequence.model.ts";
|
|
5
|
+
import {
|
|
6
|
+
CreateSecurityLabelOnSequence,
|
|
7
|
+
DropSecurityLabelOnSequence,
|
|
8
|
+
} from "./sequence.security-label.ts";
|
|
9
|
+
|
|
10
|
+
const makeSequence = (): Sequence =>
|
|
11
|
+
new Sequence({
|
|
12
|
+
schema: "public",
|
|
13
|
+
name: "s1",
|
|
14
|
+
data_type: "bigint",
|
|
15
|
+
start_value: 1,
|
|
16
|
+
minimum_value: BigInt(1),
|
|
17
|
+
maximum_value: BigInt("9223372036854775807"),
|
|
18
|
+
increment: 1,
|
|
19
|
+
cycle_option: false,
|
|
20
|
+
cache_size: 1,
|
|
21
|
+
persistence: "p",
|
|
22
|
+
owned_by_schema: null,
|
|
23
|
+
owned_by_table: null,
|
|
24
|
+
owned_by_column: null,
|
|
25
|
+
comment: null,
|
|
26
|
+
privileges: [],
|
|
27
|
+
owner: "postgres",
|
|
28
|
+
} as SequenceProps);
|
|
29
|
+
|
|
30
|
+
describe("sequence.security-label", () => {
|
|
31
|
+
test("create serializes", async () => {
|
|
32
|
+
const sequence = makeSequence();
|
|
33
|
+
const change = new CreateSecurityLabelOnSequence({
|
|
34
|
+
sequence,
|
|
35
|
+
securityLabel: { provider: "dummy", label: "classified" },
|
|
36
|
+
});
|
|
37
|
+
expect(change.scope).toBe("security_label");
|
|
38
|
+
expect(change.creates).toEqual([
|
|
39
|
+
stableId.securityLabel(sequence.stableId, "dummy"),
|
|
40
|
+
]);
|
|
41
|
+
await assertValidSql(change.serialize());
|
|
42
|
+
expect(change.serialize()).toBe(
|
|
43
|
+
"SECURITY LABEL FOR dummy ON SEQUENCE public.s1 IS 'classified'",
|
|
44
|
+
);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("drop serializes to IS NULL", async () => {
|
|
48
|
+
const sequence = makeSequence();
|
|
49
|
+
const change = new DropSecurityLabelOnSequence({
|
|
50
|
+
sequence,
|
|
51
|
+
securityLabel: { provider: "dummy", label: "x" },
|
|
52
|
+
});
|
|
53
|
+
await assertValidSql(change.serialize());
|
|
54
|
+
expect(change.serialize()).toBe(
|
|
55
|
+
"SECURITY LABEL FOR dummy ON SEQUENCE public.s1 IS NULL",
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
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 { Sequence } from "../sequence.model.ts";
|
|
5
|
+
import { CreateSequenceChange, DropSequenceChange } from "./sequence.base.ts";
|
|
6
|
+
|
|
7
|
+
export type SecurityLabelSequence =
|
|
8
|
+
| CreateSecurityLabelOnSequence
|
|
9
|
+
| DropSecurityLabelOnSequence;
|
|
10
|
+
|
|
11
|
+
export class CreateSecurityLabelOnSequence extends CreateSequenceChange {
|
|
12
|
+
public readonly sequence: Sequence;
|
|
13
|
+
public readonly securityLabel: SecurityLabelProps;
|
|
14
|
+
public readonly scope = "security_label" as const;
|
|
15
|
+
|
|
16
|
+
constructor(props: {
|
|
17
|
+
sequence: Sequence;
|
|
18
|
+
securityLabel: SecurityLabelProps;
|
|
19
|
+
}) {
|
|
20
|
+
super();
|
|
21
|
+
this.sequence = props.sequence;
|
|
22
|
+
this.securityLabel = props.securityLabel;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
get creates() {
|
|
26
|
+
return [
|
|
27
|
+
stableId.securityLabel(
|
|
28
|
+
this.sequence.stableId,
|
|
29
|
+
this.securityLabel.provider,
|
|
30
|
+
),
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get requires() {
|
|
35
|
+
return [this.sequence.stableId];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
serialize(): string {
|
|
39
|
+
return [
|
|
40
|
+
"SECURITY LABEL FOR",
|
|
41
|
+
this.securityLabel.provider,
|
|
42
|
+
"ON SEQUENCE",
|
|
43
|
+
`${this.sequence.schema}.${this.sequence.name}`,
|
|
44
|
+
"IS",
|
|
45
|
+
quoteLiteral(this.securityLabel.label),
|
|
46
|
+
].join(" ");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class DropSecurityLabelOnSequence extends DropSequenceChange {
|
|
51
|
+
public readonly sequence: Sequence;
|
|
52
|
+
public readonly securityLabel: SecurityLabelProps;
|
|
53
|
+
public readonly scope = "security_label" as const;
|
|
54
|
+
|
|
55
|
+
constructor(props: {
|
|
56
|
+
sequence: Sequence;
|
|
57
|
+
securityLabel: SecurityLabelProps;
|
|
58
|
+
}) {
|
|
59
|
+
super();
|
|
60
|
+
this.sequence = props.sequence;
|
|
61
|
+
this.securityLabel = props.securityLabel;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get drops() {
|
|
65
|
+
return [
|
|
66
|
+
stableId.securityLabel(
|
|
67
|
+
this.sequence.stableId,
|
|
68
|
+
this.securityLabel.provider,
|
|
69
|
+
),
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get requires() {
|
|
74
|
+
return [
|
|
75
|
+
stableId.securityLabel(
|
|
76
|
+
this.sequence.stableId,
|
|
77
|
+
this.securityLabel.provider,
|
|
78
|
+
),
|
|
79
|
+
this.sequence.stableId,
|
|
80
|
+
];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
serialize(): string {
|
|
84
|
+
return [
|
|
85
|
+
"SECURITY LABEL FOR",
|
|
86
|
+
this.securityLabel.provider,
|
|
87
|
+
"ON SEQUENCE",
|
|
88
|
+
`${this.sequence.schema}.${this.sequence.name}`,
|
|
89
|
+
"IS NULL",
|
|
90
|
+
].join(" ");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -3,6 +3,7 @@ import type { CommentSequence } from "./sequence.comment.ts";
|
|
|
3
3
|
import type { CreateSequence } from "./sequence.create.ts";
|
|
4
4
|
import type { DropSequence } from "./sequence.drop.ts";
|
|
5
5
|
import type { SequencePrivilege } from "./sequence.privilege.ts";
|
|
6
|
+
import type { SecurityLabelSequence } from "./sequence.security-label.ts";
|
|
6
7
|
|
|
7
8
|
/** Union of all sequence-related change variants (`objectType: "sequence"`). @category Change Types */
|
|
8
9
|
export type SequenceChange =
|
|
@@ -10,4 +11,5 @@ export type SequenceChange =
|
|
|
10
11
|
| CommentSequence
|
|
11
12
|
| CreateSequence
|
|
12
13
|
| DropSequence
|
|
13
|
-
| SequencePrivilege
|
|
14
|
+
| SequencePrivilege
|
|
15
|
+
| SecurityLabelSequence;
|
|
@@ -327,6 +327,93 @@ describe.concurrent("sequence.diff", () => {
|
|
|
327
327
|
expect(changes).toHaveLength(0);
|
|
328
328
|
});
|
|
329
329
|
|
|
330
|
+
test("recreate same-name sequence when owning table is renamed away", () => {
|
|
331
|
+
// Reproduces issue #228 case 1: a SERIAL column's table is renamed
|
|
332
|
+
// (`old_table` → `new_table`). The sequence keeps the same name
|
|
333
|
+
// (`old_table_id_seq`) but its OWNED BY now points at `new_table.id`.
|
|
334
|
+
// PostgreSQL cascade-drops the sequence with the old table, so a later
|
|
335
|
+
// CREATE TABLE that references `old_table_id_seq` fails. The diff must
|
|
336
|
+
// emit CreateSequence (and skip the explicit DropSequence to avoid an
|
|
337
|
+
// unbreakable cycle with the DropTable).
|
|
338
|
+
const tableColumn = {
|
|
339
|
+
name: "id",
|
|
340
|
+
position: 1,
|
|
341
|
+
data_type: "integer",
|
|
342
|
+
data_type_str: "integer",
|
|
343
|
+
is_custom_type: false,
|
|
344
|
+
custom_type_type: null,
|
|
345
|
+
custom_type_category: null,
|
|
346
|
+
custom_type_schema: null,
|
|
347
|
+
custom_type_name: null,
|
|
348
|
+
not_null: true,
|
|
349
|
+
is_identity: false,
|
|
350
|
+
is_identity_always: false,
|
|
351
|
+
is_generated: false,
|
|
352
|
+
collation: null,
|
|
353
|
+
default: "nextval('public.old_table_id_seq'::regclass)",
|
|
354
|
+
comment: null,
|
|
355
|
+
};
|
|
356
|
+
const tableBaseProps = {
|
|
357
|
+
schema: "public",
|
|
358
|
+
persistence: "p" as const,
|
|
359
|
+
row_security: false,
|
|
360
|
+
force_row_security: false,
|
|
361
|
+
has_indexes: false,
|
|
362
|
+
has_rules: false,
|
|
363
|
+
has_triggers: false,
|
|
364
|
+
has_subclasses: false,
|
|
365
|
+
is_populated: true,
|
|
366
|
+
replica_identity: "d" as const,
|
|
367
|
+
is_partition: false,
|
|
368
|
+
options: null,
|
|
369
|
+
partition_bound: null,
|
|
370
|
+
partition_by: null,
|
|
371
|
+
owner: "test",
|
|
372
|
+
comment: null,
|
|
373
|
+
parent_schema: null,
|
|
374
|
+
parent_name: null,
|
|
375
|
+
privileges: [],
|
|
376
|
+
};
|
|
377
|
+
const oldTable = new Table({
|
|
378
|
+
...tableBaseProps,
|
|
379
|
+
name: "old_table",
|
|
380
|
+
columns: [tableColumn],
|
|
381
|
+
});
|
|
382
|
+
const newTable = new Table({
|
|
383
|
+
...tableBaseProps,
|
|
384
|
+
name: "new_table",
|
|
385
|
+
columns: [tableColumn],
|
|
386
|
+
});
|
|
387
|
+
const mainSequence = new Sequence({
|
|
388
|
+
...base,
|
|
389
|
+
name: "old_table_id_seq",
|
|
390
|
+
owned_by_schema: "public",
|
|
391
|
+
owned_by_table: "old_table",
|
|
392
|
+
owned_by_column: "id",
|
|
393
|
+
});
|
|
394
|
+
const branchSequence = new Sequence({
|
|
395
|
+
...base,
|
|
396
|
+
name: "old_table_id_seq",
|
|
397
|
+
owned_by_schema: "public",
|
|
398
|
+
owned_by_table: "new_table",
|
|
399
|
+
owned_by_column: "id",
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
const changes = diffSequences(
|
|
403
|
+
testContext,
|
|
404
|
+
{ [mainSequence.stableId]: mainSequence },
|
|
405
|
+
{ [branchSequence.stableId]: branchSequence },
|
|
406
|
+
{ [newTable.stableId]: newTable },
|
|
407
|
+
{ [oldTable.stableId]: oldTable },
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
expect(changes.some((c) => c instanceof DropSequence)).toBe(false);
|
|
411
|
+
expect(changes.some((c) => c instanceof CreateSequence)).toBe(true);
|
|
412
|
+
expect(changes.some((c) => c instanceof AlterSequenceSetOwnedBy)).toBe(
|
|
413
|
+
true,
|
|
414
|
+
);
|
|
415
|
+
});
|
|
416
|
+
|
|
330
417
|
test("create with comment emits CreateCommentOnSequence", () => {
|
|
331
418
|
const s = new Sequence({ ...base, comment: "my seq" });
|
|
332
419
|
const changes = diffSequences(testContext, {}, { [s.stableId]: s });
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
emitObjectPrivilegeChanges,
|
|
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 { AlterTableAlterColumnSetDefault } from "../table/changes/table.alter.ts";
|
|
8
9
|
import type { Table } from "../table/table.model.ts";
|
|
9
10
|
import { hasNonAlterableChanges } from "../utils.ts";
|
|
@@ -22,6 +23,10 @@ import {
|
|
|
22
23
|
RevokeGrantOptionSequencePrivileges,
|
|
23
24
|
RevokeSequencePrivileges,
|
|
24
25
|
} from "./changes/sequence.privilege.ts";
|
|
26
|
+
import {
|
|
27
|
+
CreateSecurityLabelOnSequence,
|
|
28
|
+
DropSecurityLabelOnSequence,
|
|
29
|
+
} from "./changes/sequence.security-label.ts";
|
|
25
30
|
import type { SequenceChange } from "./changes/sequence.types.ts";
|
|
26
31
|
import type { Sequence } from "./sequence.model.ts";
|
|
27
32
|
|
|
@@ -36,6 +41,7 @@ type SequenceOrColumnSetDefaultChange =
|
|
|
36
41
|
* @param main - The sequences in the main catalog.
|
|
37
42
|
* @param branch - The sequences in the branch catalog.
|
|
38
43
|
* @param branchTables - The tables in the branch catalog (used to check if owning tables are being dropped).
|
|
44
|
+
* @param mainTables - The tables in the main catalog (used to detect when a same-name sequence will be cascade-dropped because its main-side owning table is going away).
|
|
39
45
|
* @returns A list of changes to apply to main to make it match branch.
|
|
40
46
|
*/
|
|
41
47
|
export function diffSequences(
|
|
@@ -46,6 +52,7 @@ export function diffSequences(
|
|
|
46
52
|
main: Record<string, Sequence>,
|
|
47
53
|
branch: Record<string, Sequence>,
|
|
48
54
|
branchTables: Record<string, Table> = {},
|
|
55
|
+
mainTables: Record<string, Table> = {},
|
|
49
56
|
): SequenceOrColumnSetDefaultChange[] {
|
|
50
57
|
const { created, dropped, altered } = diffObjects(main, branch);
|
|
51
58
|
|
|
@@ -57,6 +64,14 @@ export function diffSequences(
|
|
|
57
64
|
if (createdSeq.comment !== null) {
|
|
58
65
|
changes.push(new CreateCommentOnSequence({ sequence: createdSeq }));
|
|
59
66
|
}
|
|
67
|
+
for (const label of createdSeq.security_labels) {
|
|
68
|
+
changes.push(
|
|
69
|
+
new CreateSecurityLabelOnSequence({
|
|
70
|
+
sequence: createdSeq,
|
|
71
|
+
securityLabel: label,
|
|
72
|
+
}),
|
|
73
|
+
);
|
|
74
|
+
}
|
|
60
75
|
// If the created sequence is OWNED BY a column, emit an ALTER to set it
|
|
61
76
|
if (
|
|
62
77
|
createdSeq.owned_by_schema !== null &&
|
|
@@ -157,12 +172,35 @@ export function diffSequences(
|
|
|
157
172
|
NON_ALTERABLE_FIELDS,
|
|
158
173
|
);
|
|
159
174
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
175
|
+
// A sequence kept the same name (so it's "altered" in catalog terms),
|
|
176
|
+
// but its main-side owning table is going away from the plan (renamed
|
|
177
|
+
// away or simply dropped). PostgreSQL will cascade-drop the sequence
|
|
178
|
+
// alongside the table, leaving any later CREATE TABLE / column-default
|
|
179
|
+
// that depends on the sequence name pointing at nothing. Treat this
|
|
180
|
+
// like a non-alterable change so we recreate the sequence after the
|
|
181
|
+
// owning table is dropped.
|
|
182
|
+
const mainOwnedByTableId =
|
|
183
|
+
mainSequence.owned_by_schema && mainSequence.owned_by_table
|
|
184
|
+
? `table:${mainSequence.owned_by_schema}.${mainSequence.owned_by_table}`
|
|
185
|
+
: null;
|
|
186
|
+
const cascadeOrphanedByOwningTable =
|
|
187
|
+
mainOwnedByTableId !== null &&
|
|
188
|
+
mainTables[mainOwnedByTableId] !== undefined &&
|
|
189
|
+
branchTables[mainOwnedByTableId] === undefined;
|
|
190
|
+
|
|
191
|
+
if (nonAlterablePropsChanged || cascadeOrphanedByOwningTable) {
|
|
192
|
+
// When the owning table is going away in this plan, PostgreSQL will
|
|
193
|
+
// cascade-drop the sequence as part of the DROP TABLE. Emitting an
|
|
194
|
+
// explicit DROP SEQUENCE here would (a) introduce an unbreakable
|
|
195
|
+
// DropSequence ↔ DropTable cycle on the catalog edges between the
|
|
196
|
+
// sequence and the dropped column, and (b) be redundant with the
|
|
197
|
+
// cascade. The CreateSequence below restores the sequence under its
|
|
198
|
+
// original name so any same-name reference in a later CREATE TABLE
|
|
199
|
+
// resolves correctly.
|
|
200
|
+
if (!cascadeOrphanedByOwningTable) {
|
|
201
|
+
changes.push(new DropSequence({ sequence: mainSequence }));
|
|
202
|
+
}
|
|
203
|
+
changes.push(new CreateSequence({ sequence: branchSequence }));
|
|
166
204
|
// Re-apply OWNED BY if present on branch
|
|
167
205
|
if (
|
|
168
206
|
branchSequence.owned_by_schema !== null &&
|
|
@@ -300,6 +338,26 @@ export function diffSequences(
|
|
|
300
338
|
}
|
|
301
339
|
}
|
|
302
340
|
|
|
341
|
+
// SECURITY LABELS
|
|
342
|
+
changes.push(
|
|
343
|
+
...diffSecurityLabels<
|
|
344
|
+
CreateSecurityLabelOnSequence | DropSecurityLabelOnSequence
|
|
345
|
+
>(
|
|
346
|
+
mainSequence.security_labels,
|
|
347
|
+
branchSequence.security_labels,
|
|
348
|
+
(securityLabel) =>
|
|
349
|
+
new CreateSecurityLabelOnSequence({
|
|
350
|
+
sequence: branchSequence,
|
|
351
|
+
securityLabel,
|
|
352
|
+
}),
|
|
353
|
+
(securityLabel) =>
|
|
354
|
+
new DropSecurityLabelOnSequence({
|
|
355
|
+
sequence: mainSequence,
|
|
356
|
+
securityLabel,
|
|
357
|
+
}),
|
|
358
|
+
),
|
|
359
|
+
);
|
|
360
|
+
|
|
303
361
|
// PRIVILEGES
|
|
304
362
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
305
363
|
// and shouldn't be compared. Use branch owner as the reference.
|
|
@@ -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 sequencePropsSchema = z.object({
|
|
11
15
|
schema: z.string(),
|
|
@@ -24,6 +28,7 @@ const sequencePropsSchema = z.object({
|
|
|
24
28
|
comment: z.string().nullable(),
|
|
25
29
|
privileges: z.array(privilegePropsSchema),
|
|
26
30
|
owner: z.string(),
|
|
31
|
+
security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
|
|
27
32
|
});
|
|
28
33
|
|
|
29
34
|
type SequencePrivilegeProps = PrivilegeProps;
|
|
@@ -46,6 +51,7 @@ export class Sequence extends BasePgModel {
|
|
|
46
51
|
public readonly comment: SequenceProps["comment"];
|
|
47
52
|
public readonly privileges: SequencePrivilegeProps[];
|
|
48
53
|
public readonly owner: SequenceProps["owner"];
|
|
54
|
+
public readonly security_labels: SecurityLabelProps[];
|
|
49
55
|
|
|
50
56
|
constructor(props: SequenceProps) {
|
|
51
57
|
super();
|
|
@@ -69,6 +75,7 @@ export class Sequence extends BasePgModel {
|
|
|
69
75
|
this.comment = props.comment;
|
|
70
76
|
this.privileges = props.privileges;
|
|
71
77
|
this.owner = props.owner;
|
|
78
|
+
this.security_labels = props.security_labels ?? [];
|
|
72
79
|
}
|
|
73
80
|
|
|
74
81
|
get stableId(): `sequence:${string}` {
|
|
@@ -98,6 +105,7 @@ export class Sequence extends BasePgModel {
|
|
|
98
105
|
comment: this.comment,
|
|
99
106
|
privileges: this.privileges,
|
|
100
107
|
owner: this.owner,
|
|
108
|
+
security_labels: this.security_labels,
|
|
101
109
|
};
|
|
102
110
|
}
|
|
103
111
|
}
|
|
@@ -151,7 +159,20 @@ select
|
|
|
151
159
|
from lateral aclexplode(COALESCE(c.relacl, acldefault('S', c.relowner))) as x(grantor, grantee, privilege_type, is_grantable)
|
|
152
160
|
), '[]'
|
|
153
161
|
) as privileges,
|
|
154
|
-
c.relowner::regrole::text as owner
|
|
162
|
+
c.relowner::regrole::text as owner,
|
|
163
|
+
coalesce(
|
|
164
|
+
(
|
|
165
|
+
select json_agg(
|
|
166
|
+
json_build_object('provider', sl.provider, 'label', sl.label)
|
|
167
|
+
order by sl.provider
|
|
168
|
+
)
|
|
169
|
+
from pg_catalog.pg_seclabel sl
|
|
170
|
+
where sl.objoid = c.oid
|
|
171
|
+
and sl.classoid = 'pg_class'::regclass
|
|
172
|
+
and sl.objsubid = 0
|
|
173
|
+
),
|
|
174
|
+
'[]'::json
|
|
175
|
+
) as security_labels
|
|
155
176
|
from
|
|
156
177
|
pg_catalog.pg_class c
|
|
157
178
|
inner join pg_catalog.pg_sequence s on s.seqrelid = c.oid
|
|
@@ -3,7 +3,7 @@ import type { Subscription } from "../subscription.model.ts";
|
|
|
3
3
|
|
|
4
4
|
abstract class BaseSubscriptionChange extends BaseChange {
|
|
5
5
|
abstract readonly subscription: Subscription;
|
|
6
|
-
abstract readonly scope: "object" | "comment";
|
|
6
|
+
abstract readonly scope: "object" | "comment" | "security_label";
|
|
7
7
|
readonly objectType = "subscription" as const;
|
|
8
8
|
}
|
|
9
9
|
|