@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,134 @@
|
|
|
1
|
+
import { quoteLiteral } from "../../base.change.js";
|
|
2
|
+
import { stableId } from "../../utils.js";
|
|
3
|
+
import { CreateTableChange, DropTableChange } from "./table.base.js";
|
|
4
|
+
/**
|
|
5
|
+
* SECURITY LABEL FOR <provider> ON TABLE <schema>.<table> IS <literal>
|
|
6
|
+
*/
|
|
7
|
+
export class CreateSecurityLabelOnTable extends CreateTableChange {
|
|
8
|
+
table;
|
|
9
|
+
securityLabel;
|
|
10
|
+
scope = "security_label";
|
|
11
|
+
constructor(props) {
|
|
12
|
+
super();
|
|
13
|
+
this.table = props.table;
|
|
14
|
+
this.securityLabel = props.securityLabel;
|
|
15
|
+
}
|
|
16
|
+
get creates() {
|
|
17
|
+
return [
|
|
18
|
+
stableId.securityLabel(this.table.stableId, this.securityLabel.provider),
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
get requires() {
|
|
22
|
+
return [this.table.stableId];
|
|
23
|
+
}
|
|
24
|
+
serialize() {
|
|
25
|
+
return [
|
|
26
|
+
"SECURITY LABEL FOR",
|
|
27
|
+
this.securityLabel.provider,
|
|
28
|
+
"ON TABLE",
|
|
29
|
+
`${this.table.schema}.${this.table.name}`,
|
|
30
|
+
"IS",
|
|
31
|
+
quoteLiteral(this.securityLabel.label),
|
|
32
|
+
].join(" ");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class DropSecurityLabelOnTable extends DropTableChange {
|
|
36
|
+
table;
|
|
37
|
+
securityLabel;
|
|
38
|
+
scope = "security_label";
|
|
39
|
+
constructor(props) {
|
|
40
|
+
super();
|
|
41
|
+
this.table = props.table;
|
|
42
|
+
this.securityLabel = props.securityLabel;
|
|
43
|
+
}
|
|
44
|
+
get drops() {
|
|
45
|
+
return [
|
|
46
|
+
stableId.securityLabel(this.table.stableId, this.securityLabel.provider),
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
get requires() {
|
|
50
|
+
return [
|
|
51
|
+
stableId.securityLabel(this.table.stableId, this.securityLabel.provider),
|
|
52
|
+
this.table.stableId,
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
serialize() {
|
|
56
|
+
return [
|
|
57
|
+
"SECURITY LABEL FOR",
|
|
58
|
+
this.securityLabel.provider,
|
|
59
|
+
"ON TABLE",
|
|
60
|
+
`${this.table.schema}.${this.table.name}`,
|
|
61
|
+
"IS NULL",
|
|
62
|
+
].join(" ");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* SECURITY LABEL FOR <provider> ON COLUMN <schema>.<table>.<column> IS <literal>
|
|
67
|
+
*/
|
|
68
|
+
export class CreateSecurityLabelOnColumn extends CreateTableChange {
|
|
69
|
+
table;
|
|
70
|
+
column;
|
|
71
|
+
securityLabel;
|
|
72
|
+
scope = "security_label";
|
|
73
|
+
constructor(props) {
|
|
74
|
+
super();
|
|
75
|
+
this.table = props.table;
|
|
76
|
+
this.column = props.column;
|
|
77
|
+
this.securityLabel = props.securityLabel;
|
|
78
|
+
}
|
|
79
|
+
get creates() {
|
|
80
|
+
const columnStableId = stableId.column(this.table.schema, this.table.name, this.column.name);
|
|
81
|
+
return [
|
|
82
|
+
stableId.securityLabel(columnStableId, this.securityLabel.provider),
|
|
83
|
+
];
|
|
84
|
+
}
|
|
85
|
+
get requires() {
|
|
86
|
+
return [
|
|
87
|
+
stableId.column(this.table.schema, this.table.name, this.column.name),
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
serialize() {
|
|
91
|
+
return [
|
|
92
|
+
"SECURITY LABEL FOR",
|
|
93
|
+
this.securityLabel.provider,
|
|
94
|
+
"ON COLUMN",
|
|
95
|
+
`${this.table.schema}.${this.table.name}.${this.column.name}`,
|
|
96
|
+
"IS",
|
|
97
|
+
quoteLiteral(this.securityLabel.label),
|
|
98
|
+
].join(" ");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export class DropSecurityLabelOnColumn extends DropTableChange {
|
|
102
|
+
table;
|
|
103
|
+
column;
|
|
104
|
+
securityLabel;
|
|
105
|
+
scope = "security_label";
|
|
106
|
+
constructor(props) {
|
|
107
|
+
super();
|
|
108
|
+
this.table = props.table;
|
|
109
|
+
this.column = props.column;
|
|
110
|
+
this.securityLabel = props.securityLabel;
|
|
111
|
+
}
|
|
112
|
+
get drops() {
|
|
113
|
+
const columnStableId = stableId.column(this.table.schema, this.table.name, this.column.name);
|
|
114
|
+
return [
|
|
115
|
+
stableId.securityLabel(columnStableId, this.securityLabel.provider),
|
|
116
|
+
];
|
|
117
|
+
}
|
|
118
|
+
get requires() {
|
|
119
|
+
const columnStableId = stableId.column(this.table.schema, this.table.name, this.column.name);
|
|
120
|
+
return [
|
|
121
|
+
stableId.securityLabel(columnStableId, this.securityLabel.provider),
|
|
122
|
+
columnStableId,
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
serialize() {
|
|
126
|
+
return [
|
|
127
|
+
"SECURITY LABEL FOR",
|
|
128
|
+
this.securityLabel.provider,
|
|
129
|
+
"ON COLUMN",
|
|
130
|
+
`${this.table.schema}.${this.table.name}.${this.column.name}`,
|
|
131
|
+
"IS NULL",
|
|
132
|
+
].join(" ");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -3,5 +3,6 @@ import type { CommentTable } from "./table.comment.ts";
|
|
|
3
3
|
import type { CreateTable } from "./table.create.ts";
|
|
4
4
|
import type { DropTable } from "./table.drop.ts";
|
|
5
5
|
import type { TablePrivilege } from "./table.privilege.ts";
|
|
6
|
+
import type { SecurityLabelTable } from "./table.security-label.ts";
|
|
6
7
|
/** Union of all table-related change variants (`objectType: "table"`). @category Change Types */
|
|
7
|
-
export type TableChange = AlterTable | CommentTable | CreateTable | DropTable | TablePrivilege;
|
|
8
|
+
export type TableChange = AlterTable | CommentTable | CreateTable | DropTable | TablePrivilege | SecurityLabelTable;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { diffObjects } from "../base.diff.js";
|
|
2
2
|
import { diffPrivileges, emitColumnPrivilegeChanges, } from "../base.privilege-diff.js";
|
|
3
|
+
import { diffSecurityLabels } from "../security-label.types.js";
|
|
3
4
|
import { deepEqual } from "../utils.js";
|
|
4
5
|
import { AlterTableAddColumn, AlterTableAddConstraint, AlterTableAlterColumnAddIdentity, AlterTableAlterColumnDropDefault, AlterTableAlterColumnDropIdentity, AlterTableAlterColumnDropNotNull, AlterTableAlterColumnSetDefault, AlterTableAlterColumnSetGenerated, AlterTableAlterColumnSetNotNull, AlterTableAlterColumnType, AlterTableAttachPartition, AlterTableChangeOwner, AlterTableDetachPartition, AlterTableDisableRowLevelSecurity, AlterTableDropColumn, AlterTableDropConstraint, AlterTableEnableRowLevelSecurity, AlterTableForceRowLevelSecurity, AlterTableNoForceRowLevelSecurity, AlterTableResetStorageParams, AlterTableSetLogged, AlterTableSetReplicaIdentity, AlterTableSetStorageParams, AlterTableSetUnlogged, AlterTableValidateConstraint, } from "./changes/table.alter.js";
|
|
5
6
|
import { CreateCommentOnColumn, CreateCommentOnConstraint, CreateCommentOnTable, DropCommentOnColumn, DropCommentOnConstraint, DropCommentOnTable, } from "./changes/table.comment.js";
|
|
6
7
|
import { CreateTable } from "./changes/table.create.js";
|
|
7
8
|
import { DropTable } from "./changes/table.drop.js";
|
|
8
9
|
import { GrantTablePrivileges, RevokeGrantOptionTablePrivileges, RevokeTablePrivileges, } from "./changes/table.privilege.js";
|
|
10
|
+
import { CreateSecurityLabelOnColumn, CreateSecurityLabelOnTable, DropSecurityLabelOnColumn, DropSecurityLabelOnTable, } from "./changes/table.security-label.js";
|
|
9
11
|
import { Table } from "./table.model.js";
|
|
10
12
|
function createAlterConstraintChange(mainTable, branchTable) {
|
|
11
13
|
const changes = [];
|
|
@@ -152,13 +154,11 @@ export function diffTables(ctx, main, branch) {
|
|
|
152
154
|
}
|
|
153
155
|
// REPLICA IDENTITY: If non-default, emit ALTER TABLE ... REPLICA IDENTITY
|
|
154
156
|
if (branchTable.replica_identity !== "d") {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}));
|
|
161
|
-
}
|
|
157
|
+
changes.push(new AlterTableSetReplicaIdentity({
|
|
158
|
+
table: branchTable,
|
|
159
|
+
mode: branchTable.replica_identity,
|
|
160
|
+
indexName: branchTable.replica_identity_index,
|
|
161
|
+
}));
|
|
162
162
|
}
|
|
163
163
|
changes.push(...createAlterConstraintChange(
|
|
164
164
|
// Create a dummy table with no constraints do diff constraints against
|
|
@@ -176,6 +176,23 @@ export function diffTables(ctx, main, branch) {
|
|
|
176
176
|
changes.push(new CreateCommentOnColumn({ table: branchTable, column: col }));
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
|
+
// Table security labels on creation
|
|
180
|
+
for (const label of branchTable.security_labels) {
|
|
181
|
+
changes.push(new CreateSecurityLabelOnTable({
|
|
182
|
+
table: branchTable,
|
|
183
|
+
securityLabel: label,
|
|
184
|
+
}));
|
|
185
|
+
}
|
|
186
|
+
// Column security labels on creation
|
|
187
|
+
for (const col of branchTable.columns) {
|
|
188
|
+
for (const label of col.security_labels ?? []) {
|
|
189
|
+
changes.push(new CreateSecurityLabelOnColumn({
|
|
190
|
+
table: branchTable,
|
|
191
|
+
column: col,
|
|
192
|
+
securityLabel: label,
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
179
196
|
// PRIVILEGES: For created objects, compare against default privileges state
|
|
180
197
|
// The migration script will run ALTER DEFAULT PRIVILEGES before CREATE (via constraint spec),
|
|
181
198
|
// so objects are created with the default privileges state in effect.
|
|
@@ -261,14 +278,20 @@ export function diffTables(ctx, main, branch) {
|
|
|
261
278
|
}
|
|
262
279
|
}
|
|
263
280
|
// REPLICA IDENTITY
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
281
|
+
// Re-emit when the mode changes, or when staying in 'i' mode but pointing
|
|
282
|
+
// at a different index. The index named on the branch must already exist
|
|
283
|
+
// before this ALTER runs; AlterTableSetReplicaIdentity declares that
|
|
284
|
+
// dependency in its `requires`.
|
|
285
|
+
const replicaIdentityChanged = mainTable.replica_identity !== branchTable.replica_identity ||
|
|
286
|
+
(branchTable.replica_identity === "i" &&
|
|
287
|
+
mainTable.replica_identity_index !==
|
|
288
|
+
branchTable.replica_identity_index);
|
|
289
|
+
if (replicaIdentityChanged) {
|
|
290
|
+
changes.push(new AlterTableSetReplicaIdentity({
|
|
291
|
+
table: mainTable,
|
|
292
|
+
mode: branchTable.replica_identity,
|
|
293
|
+
indexName: branchTable.replica_identity_index,
|
|
294
|
+
}));
|
|
272
295
|
}
|
|
273
296
|
// OWNER
|
|
274
297
|
if (mainTable.owner !== branchTable.owner) {
|
|
@@ -286,6 +309,14 @@ export function diffTables(ctx, main, branch) {
|
|
|
286
309
|
changes.push(new CreateCommentOnTable({ table: branchTable }));
|
|
287
310
|
}
|
|
288
311
|
}
|
|
312
|
+
// TABLE SECURITY LABELS
|
|
313
|
+
changes.push(...diffSecurityLabels(mainTable.security_labels, branchTable.security_labels, (securityLabel) => new CreateSecurityLabelOnTable({
|
|
314
|
+
table: branchTable,
|
|
315
|
+
securityLabel,
|
|
316
|
+
}), (securityLabel) => new DropSecurityLabelOnTable({
|
|
317
|
+
table: mainTable,
|
|
318
|
+
securityLabel,
|
|
319
|
+
})));
|
|
289
320
|
// PARTITION ATTACH/DETACH
|
|
290
321
|
const mainIsPartition = Boolean(mainTable.parent_schema && mainTable.parent_name);
|
|
291
322
|
const branchIsPartition = Boolean(branchTable.parent_schema && branchTable.parent_name);
|
|
@@ -592,6 +623,28 @@ export function diffTables(ctx, main, branch) {
|
|
|
592
623
|
}));
|
|
593
624
|
}
|
|
594
625
|
}
|
|
626
|
+
// SECURITY LABELS on column
|
|
627
|
+
changes.push(...diffSecurityLabels(mainCol.security_labels ?? [], branchCol.security_labels ?? [], (securityLabel) => new CreateSecurityLabelOnColumn({
|
|
628
|
+
table: branchTable,
|
|
629
|
+
column: branchCol,
|
|
630
|
+
securityLabel,
|
|
631
|
+
}), (securityLabel) => new DropSecurityLabelOnColumn({
|
|
632
|
+
table: mainTable,
|
|
633
|
+
column: mainCol,
|
|
634
|
+
securityLabel,
|
|
635
|
+
})));
|
|
636
|
+
}
|
|
637
|
+
// Added columns with security labels (for created columns on existing tables)
|
|
638
|
+
for (const [name, col] of branchCols) {
|
|
639
|
+
if (!mainCols.has(name)) {
|
|
640
|
+
for (const label of col.security_labels ?? []) {
|
|
641
|
+
changes.push(new CreateSecurityLabelOnColumn({
|
|
642
|
+
table: branchTable,
|
|
643
|
+
column: col,
|
|
644
|
+
securityLabel: label,
|
|
645
|
+
}));
|
|
646
|
+
}
|
|
647
|
+
}
|
|
595
648
|
}
|
|
596
649
|
// PRIVILEGES (unified object and column privileges)
|
|
597
650
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
@@ -2,6 +2,8 @@ import type { Pool } from "pg";
|
|
|
2
2
|
import z from "zod";
|
|
3
3
|
import { BasePgModel, type TableLikeObject } from "../base.model.ts";
|
|
4
4
|
import { type PrivilegeProps } from "../base.privilege-diff.ts";
|
|
5
|
+
import { type ExtractRetryOptions } from "../extract-with-retry.ts";
|
|
6
|
+
import { type SecurityLabelProps } from "../security-label.types.ts";
|
|
5
7
|
export declare const ReplicaIdentitySchema: z.ZodEnum<{
|
|
6
8
|
n: "n";
|
|
7
9
|
i: "i";
|
|
@@ -85,6 +87,7 @@ declare const tablePropsSchema: z.ZodObject<{
|
|
|
85
87
|
d: "d";
|
|
86
88
|
f: "f";
|
|
87
89
|
}>;
|
|
90
|
+
replica_identity_index: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
88
91
|
is_partition: z.ZodBoolean;
|
|
89
92
|
options: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
90
93
|
partition_bound: z.ZodNullable<z.ZodString>;
|
|
@@ -110,6 +113,10 @@ declare const tablePropsSchema: z.ZodObject<{
|
|
|
110
113
|
collation: z.ZodNullable<z.ZodString>;
|
|
111
114
|
default: z.ZodNullable<z.ZodString>;
|
|
112
115
|
comment: z.ZodNullable<z.ZodString>;
|
|
116
|
+
security_labels: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
117
|
+
provider: z.ZodString;
|
|
118
|
+
label: z.ZodString;
|
|
119
|
+
}, z.z.core.$strip>>>;
|
|
113
120
|
}, z.z.core.$strip>>;
|
|
114
121
|
constraints: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
115
122
|
name: z.ZodString;
|
|
@@ -172,8 +179,16 @@ declare const tablePropsSchema: z.ZodObject<{
|
|
|
172
179
|
grantable: z.ZodBoolean;
|
|
173
180
|
columns: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
|
|
174
181
|
}, z.z.core.$strip>>;
|
|
182
|
+
security_labels: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
183
|
+
provider: z.ZodString;
|
|
184
|
+
label: z.ZodString;
|
|
185
|
+
}, z.z.core.$strip>>>>;
|
|
175
186
|
}, z.z.core.$strip>;
|
|
176
187
|
type TablePrivilegeProps = PrivilegeProps;
|
|
188
|
+
/**
|
|
189
|
+
* Table input props. `security_labels` is optional on direct construction
|
|
190
|
+
* (defaults to `[]`); extraction always produces it via the Zod default.
|
|
191
|
+
*/
|
|
177
192
|
export type TableProps = z.infer<typeof tablePropsSchema>;
|
|
178
193
|
export declare class Table extends BasePgModel implements TableLikeObject {
|
|
179
194
|
readonly schema: TableProps["schema"];
|
|
@@ -187,6 +202,7 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
187
202
|
readonly has_subclasses: TableProps["has_subclasses"];
|
|
188
203
|
readonly is_populated: TableProps["is_populated"];
|
|
189
204
|
readonly replica_identity: TableProps["replica_identity"];
|
|
205
|
+
readonly replica_identity_index: TableProps["replica_identity_index"];
|
|
190
206
|
readonly is_partition: TableProps["is_partition"];
|
|
191
207
|
readonly options: TableProps["options"];
|
|
192
208
|
readonly partition_bound: TableProps["partition_bound"];
|
|
@@ -198,6 +214,7 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
198
214
|
readonly columns: TableProps["columns"];
|
|
199
215
|
readonly constraints: TableConstraintProps[];
|
|
200
216
|
readonly privileges: TablePrivilegeProps[];
|
|
217
|
+
readonly security_labels: SecurityLabelProps[];
|
|
201
218
|
constructor(props: TableProps);
|
|
202
219
|
get stableId(): `table:${string}`;
|
|
203
220
|
get identityFields(): {
|
|
@@ -209,6 +226,7 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
209
226
|
row_security: boolean;
|
|
210
227
|
force_row_security: boolean;
|
|
211
228
|
replica_identity: "n" | "i" | "d" | "f";
|
|
229
|
+
replica_identity_index: string | null | undefined;
|
|
212
230
|
options: string[] | null;
|
|
213
231
|
parent_schema: string | null;
|
|
214
232
|
parent_name: string | null;
|
|
@@ -232,6 +250,10 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
232
250
|
collation: string | null;
|
|
233
251
|
default: string | null;
|
|
234
252
|
comment: string | null;
|
|
253
|
+
security_labels?: {
|
|
254
|
+
provider: string;
|
|
255
|
+
label: string;
|
|
256
|
+
}[] | undefined;
|
|
235
257
|
}[];
|
|
236
258
|
constraints: {
|
|
237
259
|
name: string;
|
|
@@ -270,6 +292,10 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
270
292
|
grantable: boolean;
|
|
271
293
|
columns?: string[] | null | undefined;
|
|
272
294
|
}[];
|
|
295
|
+
security_labels: {
|
|
296
|
+
provider: string;
|
|
297
|
+
label: string;
|
|
298
|
+
}[];
|
|
273
299
|
};
|
|
274
300
|
stableSnapshot(): {
|
|
275
301
|
identity: {
|
|
@@ -293,6 +319,10 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
293
319
|
collation: string | null;
|
|
294
320
|
default: string | null;
|
|
295
321
|
comment: string | null;
|
|
322
|
+
security_labels?: {
|
|
323
|
+
provider: string;
|
|
324
|
+
label: string;
|
|
325
|
+
}[] | undefined;
|
|
296
326
|
}[];
|
|
297
327
|
options: string[] | null;
|
|
298
328
|
constraints: {
|
|
@@ -332,10 +362,15 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
332
362
|
grantable: boolean;
|
|
333
363
|
columns: string[] | null | undefined;
|
|
334
364
|
}[];
|
|
365
|
+
security_labels: {
|
|
366
|
+
provider: string;
|
|
367
|
+
label: string;
|
|
368
|
+
}[];
|
|
335
369
|
persistence: "u" | "t" | "p";
|
|
336
370
|
row_security: boolean;
|
|
337
371
|
force_row_security: boolean;
|
|
338
372
|
replica_identity: "n" | "i" | "d" | "f";
|
|
373
|
+
replica_identity_index: string | null | undefined;
|
|
339
374
|
parent_schema: string | null;
|
|
340
375
|
parent_name: string | null;
|
|
341
376
|
partition_bound: string | null;
|
|
@@ -344,5 +379,5 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
344
379
|
};
|
|
345
380
|
};
|
|
346
381
|
}
|
|
347
|
-
export declare function extractTables(pool: Pool): Promise<Table[]>;
|
|
382
|
+
export declare function extractTables(pool: Pool, options?: ExtractRetryOptions): Promise<Table[]>;
|
|
348
383
|
export {};
|
|
@@ -3,6 +3,8 @@ import z from "zod";
|
|
|
3
3
|
import { BasePgModel, columnPropsSchema, normalizeColumns, } from "../base.model.js";
|
|
4
4
|
import { normalizePrivileges } from "../base.privilege.js";
|
|
5
5
|
import { privilegePropsSchema, } from "../base.privilege-diff.js";
|
|
6
|
+
import { extractWithDefinitionRetry, } from "../extract-with-retry.js";
|
|
7
|
+
import { normalizeSecurityLabels, securityLabelPropsSchema, } from "../security-label.types.js";
|
|
6
8
|
const RelationPersistenceSchema = z.enum([
|
|
7
9
|
"p", // permanent
|
|
8
10
|
"u", // unlogged
|
|
@@ -65,6 +67,14 @@ const tableConstraintPropsSchema = z.object({
|
|
|
65
67
|
definition: z.string(),
|
|
66
68
|
comment: z.string().nullable().optional(),
|
|
67
69
|
});
|
|
70
|
+
// pg_get_constraintdef(oid, pretty) can return NULL under the same conditions
|
|
71
|
+
// as pg_get_indexdef: races with concurrent DDL, transient catalog
|
|
72
|
+
// inconsistencies, recovery edges. An unreadable constraint cannot be diffed,
|
|
73
|
+
// so we accept NULL here and filter the constraint out at extraction time
|
|
74
|
+
// rather than crashing the whole catalog parse with a ZodError.
|
|
75
|
+
const tableConstraintRowSchema = tableConstraintPropsSchema.extend({
|
|
76
|
+
definition: z.string().nullable(),
|
|
77
|
+
});
|
|
68
78
|
const tablePropsSchema = z.object({
|
|
69
79
|
schema: z.string(),
|
|
70
80
|
name: z.string(),
|
|
@@ -77,6 +87,7 @@ const tablePropsSchema = z.object({
|
|
|
77
87
|
has_subclasses: z.boolean(),
|
|
78
88
|
is_populated: z.boolean(),
|
|
79
89
|
replica_identity: ReplicaIdentitySchema,
|
|
90
|
+
replica_identity_index: z.string().nullable().optional(),
|
|
80
91
|
is_partition: z.boolean(),
|
|
81
92
|
options: z.array(z.string()).nullable(),
|
|
82
93
|
partition_bound: z.string().nullable(),
|
|
@@ -88,6 +99,10 @@ const tablePropsSchema = z.object({
|
|
|
88
99
|
columns: z.array(columnPropsSchema),
|
|
89
100
|
constraints: z.array(tableConstraintPropsSchema).optional(),
|
|
90
101
|
privileges: z.array(privilegePropsSchema),
|
|
102
|
+
security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
|
|
103
|
+
});
|
|
104
|
+
const tableRowSchema = tablePropsSchema.extend({
|
|
105
|
+
constraints: z.array(tableConstraintRowSchema).optional(),
|
|
91
106
|
});
|
|
92
107
|
export class Table extends BasePgModel {
|
|
93
108
|
schema;
|
|
@@ -101,6 +116,7 @@ export class Table extends BasePgModel {
|
|
|
101
116
|
has_subclasses;
|
|
102
117
|
is_populated;
|
|
103
118
|
replica_identity;
|
|
119
|
+
replica_identity_index;
|
|
104
120
|
is_partition;
|
|
105
121
|
options;
|
|
106
122
|
partition_bound;
|
|
@@ -112,6 +128,7 @@ export class Table extends BasePgModel {
|
|
|
112
128
|
columns;
|
|
113
129
|
constraints;
|
|
114
130
|
privileges;
|
|
131
|
+
security_labels;
|
|
115
132
|
constructor(props) {
|
|
116
133
|
super();
|
|
117
134
|
// Identity fields
|
|
@@ -127,6 +144,7 @@ export class Table extends BasePgModel {
|
|
|
127
144
|
this.has_subclasses = props.has_subclasses;
|
|
128
145
|
this.is_populated = props.is_populated;
|
|
129
146
|
this.replica_identity = props.replica_identity;
|
|
147
|
+
this.replica_identity_index = props.replica_identity_index ?? null;
|
|
130
148
|
this.is_partition = props.is_partition;
|
|
131
149
|
this.options = props.options;
|
|
132
150
|
this.partition_bound = props.partition_bound;
|
|
@@ -138,6 +156,7 @@ export class Table extends BasePgModel {
|
|
|
138
156
|
this.columns = props.columns;
|
|
139
157
|
this.constraints = props.constraints ?? [];
|
|
140
158
|
this.privileges = props.privileges;
|
|
159
|
+
this.security_labels = props.security_labels ?? [];
|
|
141
160
|
}
|
|
142
161
|
get stableId() {
|
|
143
162
|
return `table:${this.schema}.${this.name}`;
|
|
@@ -155,6 +174,7 @@ export class Table extends BasePgModel {
|
|
|
155
174
|
row_security: this.row_security,
|
|
156
175
|
force_row_security: this.force_row_security,
|
|
157
176
|
replica_identity: this.replica_identity,
|
|
177
|
+
replica_identity_index: this.replica_identity_index,
|
|
158
178
|
options: this.options,
|
|
159
179
|
// Partition membership can be altered via ATTACH/DETACH
|
|
160
180
|
parent_schema: this.parent_schema,
|
|
@@ -165,6 +185,7 @@ export class Table extends BasePgModel {
|
|
|
165
185
|
columns: this.columns,
|
|
166
186
|
constraints: this.constraints,
|
|
167
187
|
privileges: this.privileges,
|
|
188
|
+
security_labels: this.security_labels,
|
|
168
189
|
};
|
|
169
190
|
}
|
|
170
191
|
stableSnapshot() {
|
|
@@ -181,12 +202,18 @@ export class Table extends BasePgModel {
|
|
|
181
202
|
options: this.options ? [...this.options].sort() : this.options,
|
|
182
203
|
constraints: normalizeConstraints(),
|
|
183
204
|
privileges: normalizePrivileges(this.privileges),
|
|
205
|
+
security_labels: normalizeSecurityLabels(this.security_labels),
|
|
184
206
|
},
|
|
185
207
|
};
|
|
186
208
|
}
|
|
187
209
|
}
|
|
188
|
-
export async function extractTables(pool) {
|
|
189
|
-
const
|
|
210
|
+
export async function extractTables(pool, options) {
|
|
211
|
+
const tableRows = await extractWithDefinitionRetry({
|
|
212
|
+
label: "table constraints",
|
|
213
|
+
options,
|
|
214
|
+
hasNullDefinition: (row) => row.constraints?.some((c) => c.definition === null) ?? false,
|
|
215
|
+
query: async () => {
|
|
216
|
+
const result = await pool.query(sql `
|
|
190
217
|
with extension_oids as (
|
|
191
218
|
select objid
|
|
192
219
|
from pg_depend d
|
|
@@ -205,6 +232,14 @@ with extension_oids as (
|
|
|
205
232
|
c.relhassubclass as has_subclasses,
|
|
206
233
|
c.relispopulated as is_populated,
|
|
207
234
|
c.relreplident as replica_identity,
|
|
235
|
+
(
|
|
236
|
+
select quote_ident(ri_class.relname)
|
|
237
|
+
from pg_index ri
|
|
238
|
+
join pg_class ri_class on ri_class.oid = ri.indexrelid
|
|
239
|
+
where ri.indrelid = c.oid
|
|
240
|
+
and ri.indisreplident is true
|
|
241
|
+
limit 1
|
|
242
|
+
) as replica_identity_index,
|
|
208
243
|
c.relispartition as is_partition,
|
|
209
244
|
c.reloptions as options,
|
|
210
245
|
pg_get_expr(c.relpartbound, c.oid) as partition_bound,
|
|
@@ -235,6 +270,7 @@ select
|
|
|
235
270
|
t.has_subclasses,
|
|
236
271
|
t.is_populated,
|
|
237
272
|
t.replica_identity,
|
|
273
|
+
t.replica_identity_index,
|
|
238
274
|
t.is_partition,
|
|
239
275
|
t.options,
|
|
240
276
|
t.partition_bound,
|
|
@@ -375,7 +411,20 @@ select
|
|
|
375
411
|
and a.attcollation <> t2.typcollation
|
|
376
412
|
),
|
|
377
413
|
'default', pg_get_expr(ad.adbin, ad.adrelid),
|
|
378
|
-
'comment', col_description(a.attrelid, a.attnum)
|
|
414
|
+
'comment', col_description(a.attrelid, a.attnum),
|
|
415
|
+
'security_labels', coalesce(
|
|
416
|
+
(
|
|
417
|
+
select json_agg(
|
|
418
|
+
json_build_object('provider', sl.provider, 'label', sl.label)
|
|
419
|
+
order by sl.provider
|
|
420
|
+
)
|
|
421
|
+
from pg_catalog.pg_seclabel sl
|
|
422
|
+
where sl.objoid = t.oid
|
|
423
|
+
and sl.classoid = 'pg_class'::regclass
|
|
424
|
+
and sl.objsubid = a.attnum
|
|
425
|
+
),
|
|
426
|
+
'[]'::json
|
|
427
|
+
)
|
|
379
428
|
)
|
|
380
429
|
end
|
|
381
430
|
order by a.attnum
|
|
@@ -415,18 +464,36 @@ select
|
|
|
415
464
|
join lateral aclexplode(src.acl) as x(grantor, grantee, privilege_type, is_grantable) on true
|
|
416
465
|
group by x.grantee, x.privilege_type
|
|
417
466
|
) as grp
|
|
418
|
-
), '[]') as privileges
|
|
467
|
+
), '[]') as privileges,
|
|
468
|
+
coalesce(
|
|
469
|
+
(
|
|
470
|
+
select json_agg(
|
|
471
|
+
json_build_object('provider', sl.provider, 'label', sl.label)
|
|
472
|
+
order by sl.provider
|
|
473
|
+
)
|
|
474
|
+
from pg_catalog.pg_seclabel sl
|
|
475
|
+
where sl.objoid = t.oid
|
|
476
|
+
and sl.classoid = 'pg_class'::regclass
|
|
477
|
+
and sl.objsubid = 0
|
|
478
|
+
),
|
|
479
|
+
'[]'::json
|
|
480
|
+
) as security_labels
|
|
419
481
|
from
|
|
420
482
|
tables t
|
|
421
483
|
left join pg_attribute a on a.attrelid = t.oid and a.attnum > 0 and not a.attisdropped
|
|
422
484
|
left join pg_attrdef ad on a.attrelid = ad.adrelid and a.attnum = ad.adnum
|
|
423
485
|
left join pg_type ty on ty.oid = a.atttypid
|
|
424
486
|
group by
|
|
425
|
-
t.oid, t.schema, t.name, t.persistence, t.row_security, t.force_row_security, t.has_indexes, t.has_rules, t.has_triggers, t.has_subclasses, t.is_populated, t.replica_identity, t.is_partition, t.options, t.partition_bound, t.partition_by, t.owner, t.parent_schema, t.parent_name
|
|
487
|
+
t.oid, t.schema, t.name, t.persistence, t.row_security, t.force_row_security, t.has_indexes, t.has_rules, t.has_triggers, t.has_subclasses, t.is_populated, t.replica_identity, t.replica_identity_index, t.is_partition, t.options, t.partition_bound, t.partition_by, t.owner, t.parent_schema, t.parent_name
|
|
426
488
|
order by
|
|
427
489
|
t.schema, t.name
|
|
428
490
|
`);
|
|
429
|
-
|
|
430
|
-
|
|
491
|
+
return result.rows.map((row) => tableRowSchema.parse(row));
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
const validatedRows = tableRows.map((row) => {
|
|
495
|
+
const filteredConstraints = row.constraints?.filter((c) => c.definition !== null);
|
|
496
|
+
return { ...row, constraints: filteredConstraints };
|
|
497
|
+
});
|
|
431
498
|
return validatedRows.map((row) => new Table(row));
|
|
432
499
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Pool } from "pg";
|
|
2
2
|
import z from "zod";
|
|
3
3
|
import { BasePgModel } from "../base.model.ts";
|
|
4
|
+
import { type ExtractRetryOptions } from "../extract-with-retry.ts";
|
|
4
5
|
declare const triggerPropsSchema: z.ZodObject<{
|
|
5
6
|
schema: z.ZodString;
|
|
6
7
|
name: z.ZodString;
|
|
@@ -97,5 +98,5 @@ export declare class Trigger extends BasePgModel {
|
|
|
97
98
|
comment: string | null;
|
|
98
99
|
};
|
|
99
100
|
}
|
|
100
|
-
export declare function extractTriggers(pool: Pool): Promise<Trigger[]>;
|
|
101
|
+
export declare function extractTriggers(pool: Pool, options?: ExtractRetryOptions): Promise<Trigger[]>;
|
|
101
102
|
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { sql } from "@ts-safeql/sql-tag";
|
|
2
2
|
import z from "zod";
|
|
3
3
|
import { BasePgModel } from "../base.model.js";
|
|
4
|
+
import { extractWithDefinitionRetry, } from "../extract-with-retry.js";
|
|
4
5
|
const TriggerEnabledSchema = z.enum([
|
|
5
6
|
"O", // ORIGIN - trigger fires in "origin" and "local" replica modes
|
|
6
7
|
"D", // DISABLED - trigger is disabled
|
|
@@ -41,6 +42,14 @@ const triggerPropsSchema = z.object({
|
|
|
41
42
|
definition: z.string(),
|
|
42
43
|
comment: z.string().nullable(),
|
|
43
44
|
});
|
|
45
|
+
// pg_get_triggerdef(oid, pretty) can return NULL when the trigger (its
|
|
46
|
+
// pg_trigger row) is dropped between catalog scan and resolution, or under
|
|
47
|
+
// transient catalog state. An unreadable trigger cannot be diffed, so we
|
|
48
|
+
// accept NULL here and filter the row out at extraction time rather than
|
|
49
|
+
// crashing the whole catalog parse with a ZodError.
|
|
50
|
+
const triggerRowSchema = triggerPropsSchema.extend({
|
|
51
|
+
definition: z.string().nullable(),
|
|
52
|
+
});
|
|
44
53
|
export class Trigger extends BasePgModel {
|
|
45
54
|
schema;
|
|
46
55
|
name;
|
|
@@ -139,8 +148,13 @@ export class Trigger extends BasePgModel {
|
|
|
139
148
|
};
|
|
140
149
|
}
|
|
141
150
|
}
|
|
142
|
-
export async function extractTriggers(pool) {
|
|
143
|
-
const
|
|
151
|
+
export async function extractTriggers(pool, options) {
|
|
152
|
+
const triggerRows = await extractWithDefinitionRetry({
|
|
153
|
+
label: "triggers",
|
|
154
|
+
options,
|
|
155
|
+
hasNullDefinition: (row) => row.definition === null,
|
|
156
|
+
query: async () => {
|
|
157
|
+
const result = await pool.query(sql `
|
|
144
158
|
with extension_trigger_oids as (
|
|
145
159
|
select objid
|
|
146
160
|
from pg_depend d
|
|
@@ -245,7 +259,9 @@ export async function extractTriggers(pool) {
|
|
|
245
259
|
|
|
246
260
|
order by 1, 2
|
|
247
261
|
`);
|
|
248
|
-
|
|
249
|
-
|
|
262
|
+
return result.rows.map((row) => triggerRowSchema.parse(row));
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
const validatedRows = triggerRows.filter((row) => row.definition !== null);
|
|
250
266
|
return validatedRows.map((row) => new Trigger(row));
|
|
251
267
|
}
|
|
@@ -2,7 +2,7 @@ import { BaseChange } from "../../../base.change.ts";
|
|
|
2
2
|
import type { CompositeType } from "../composite-type.model.ts";
|
|
3
3
|
declare abstract class BaseCompositeTypeChange extends BaseChange {
|
|
4
4
|
abstract readonly compositeType: CompositeType;
|
|
5
|
-
abstract readonly scope: "object" | "comment" | "privilege";
|
|
5
|
+
abstract readonly scope: "object" | "comment" | "privilege" | "security_label";
|
|
6
6
|
readonly objectType: "composite_type";
|
|
7
7
|
}
|
|
8
8
|
export declare abstract class CreateCompositeTypeChange extends BaseCompositeTypeChange {
|