@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
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
emitColumnPrivilegeChanges,
|
|
5
5
|
} from "../base.privilege-diff.ts";
|
|
6
6
|
import type { ObjectDiffContext } from "../diff-context.ts";
|
|
7
|
+
import { diffSecurityLabels } from "../security-label.types.ts";
|
|
7
8
|
import { deepEqual } from "../utils.ts";
|
|
8
9
|
import {
|
|
9
10
|
AlterTableAddColumn,
|
|
@@ -47,6 +48,12 @@ import {
|
|
|
47
48
|
RevokeGrantOptionTablePrivileges,
|
|
48
49
|
RevokeTablePrivileges,
|
|
49
50
|
} from "./changes/table.privilege.ts";
|
|
51
|
+
import {
|
|
52
|
+
CreateSecurityLabelOnColumn,
|
|
53
|
+
CreateSecurityLabelOnTable,
|
|
54
|
+
DropSecurityLabelOnColumn,
|
|
55
|
+
DropSecurityLabelOnTable,
|
|
56
|
+
} from "./changes/table.security-label.ts";
|
|
50
57
|
import type { TableChange } from "./changes/table.types.ts";
|
|
51
58
|
import { Table } from "./table.model.ts";
|
|
52
59
|
|
|
@@ -245,15 +252,13 @@ export function diffTables(
|
|
|
245
252
|
|
|
246
253
|
// REPLICA IDENTITY: If non-default, emit ALTER TABLE ... REPLICA IDENTITY
|
|
247
254
|
if (branchTable.replica_identity !== "d") {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
);
|
|
256
|
-
}
|
|
255
|
+
changes.push(
|
|
256
|
+
new AlterTableSetReplicaIdentity({
|
|
257
|
+
table: branchTable,
|
|
258
|
+
mode: branchTable.replica_identity,
|
|
259
|
+
indexName: branchTable.replica_identity_index,
|
|
260
|
+
}),
|
|
261
|
+
);
|
|
257
262
|
}
|
|
258
263
|
|
|
259
264
|
changes.push(
|
|
@@ -281,6 +286,29 @@ export function diffTables(
|
|
|
281
286
|
}
|
|
282
287
|
}
|
|
283
288
|
|
|
289
|
+
// Table security labels on creation
|
|
290
|
+
for (const label of branchTable.security_labels) {
|
|
291
|
+
changes.push(
|
|
292
|
+
new CreateSecurityLabelOnTable({
|
|
293
|
+
table: branchTable,
|
|
294
|
+
securityLabel: label,
|
|
295
|
+
}),
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Column security labels on creation
|
|
300
|
+
for (const col of branchTable.columns) {
|
|
301
|
+
for (const label of col.security_labels ?? []) {
|
|
302
|
+
changes.push(
|
|
303
|
+
new CreateSecurityLabelOnColumn({
|
|
304
|
+
table: branchTable,
|
|
305
|
+
column: col,
|
|
306
|
+
securityLabel: label,
|
|
307
|
+
}),
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
284
312
|
// PRIVILEGES: For created objects, compare against default privileges state
|
|
285
313
|
// The migration script will run ALTER DEFAULT PRIVILEGES before CREATE (via constraint spec),
|
|
286
314
|
// so objects are created with the default privileges state in effect.
|
|
@@ -404,16 +432,23 @@ export function diffTables(
|
|
|
404
432
|
}
|
|
405
433
|
|
|
406
434
|
// REPLICA IDENTITY
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
435
|
+
// Re-emit when the mode changes, or when staying in 'i' mode but pointing
|
|
436
|
+
// at a different index. The index named on the branch must already exist
|
|
437
|
+
// before this ALTER runs; AlterTableSetReplicaIdentity declares that
|
|
438
|
+
// dependency in its `requires`.
|
|
439
|
+
const replicaIdentityChanged =
|
|
440
|
+
mainTable.replica_identity !== branchTable.replica_identity ||
|
|
441
|
+
(branchTable.replica_identity === "i" &&
|
|
442
|
+
mainTable.replica_identity_index !==
|
|
443
|
+
branchTable.replica_identity_index);
|
|
444
|
+
if (replicaIdentityChanged) {
|
|
445
|
+
changes.push(
|
|
446
|
+
new AlterTableSetReplicaIdentity({
|
|
447
|
+
table: mainTable,
|
|
448
|
+
mode: branchTable.replica_identity,
|
|
449
|
+
indexName: branchTable.replica_identity_index,
|
|
450
|
+
}),
|
|
451
|
+
);
|
|
417
452
|
}
|
|
418
453
|
|
|
419
454
|
// OWNER
|
|
@@ -435,6 +470,26 @@ export function diffTables(
|
|
|
435
470
|
}
|
|
436
471
|
}
|
|
437
472
|
|
|
473
|
+
// TABLE SECURITY LABELS
|
|
474
|
+
changes.push(
|
|
475
|
+
...diffSecurityLabels<
|
|
476
|
+
CreateSecurityLabelOnTable | DropSecurityLabelOnTable
|
|
477
|
+
>(
|
|
478
|
+
mainTable.security_labels,
|
|
479
|
+
branchTable.security_labels,
|
|
480
|
+
(securityLabel) =>
|
|
481
|
+
new CreateSecurityLabelOnTable({
|
|
482
|
+
table: branchTable,
|
|
483
|
+
securityLabel,
|
|
484
|
+
}),
|
|
485
|
+
(securityLabel) =>
|
|
486
|
+
new DropSecurityLabelOnTable({
|
|
487
|
+
table: mainTable,
|
|
488
|
+
securityLabel,
|
|
489
|
+
}),
|
|
490
|
+
),
|
|
491
|
+
);
|
|
492
|
+
|
|
438
493
|
// PARTITION ATTACH/DETACH
|
|
439
494
|
const mainIsPartition = Boolean(
|
|
440
495
|
mainTable.parent_schema && mainTable.parent_name,
|
|
@@ -881,6 +936,43 @@ export function diffTables(
|
|
|
881
936
|
);
|
|
882
937
|
}
|
|
883
938
|
}
|
|
939
|
+
|
|
940
|
+
// SECURITY LABELS on column
|
|
941
|
+
changes.push(
|
|
942
|
+
...diffSecurityLabels<
|
|
943
|
+
CreateSecurityLabelOnColumn | DropSecurityLabelOnColumn
|
|
944
|
+
>(
|
|
945
|
+
mainCol.security_labels ?? [],
|
|
946
|
+
branchCol.security_labels ?? [],
|
|
947
|
+
(securityLabel) =>
|
|
948
|
+
new CreateSecurityLabelOnColumn({
|
|
949
|
+
table: branchTable,
|
|
950
|
+
column: branchCol,
|
|
951
|
+
securityLabel,
|
|
952
|
+
}),
|
|
953
|
+
(securityLabel) =>
|
|
954
|
+
new DropSecurityLabelOnColumn({
|
|
955
|
+
table: mainTable,
|
|
956
|
+
column: mainCol,
|
|
957
|
+
securityLabel,
|
|
958
|
+
}),
|
|
959
|
+
),
|
|
960
|
+
);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
// Added columns with security labels (for created columns on existing tables)
|
|
964
|
+
for (const [name, col] of branchCols) {
|
|
965
|
+
if (!mainCols.has(name)) {
|
|
966
|
+
for (const label of col.security_labels ?? []) {
|
|
967
|
+
changes.push(
|
|
968
|
+
new CreateSecurityLabelOnColumn({
|
|
969
|
+
table: branchTable,
|
|
970
|
+
column: col,
|
|
971
|
+
securityLabel: label,
|
|
972
|
+
}),
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
884
976
|
}
|
|
885
977
|
|
|
886
978
|
// PRIVILEGES (unified object and column privileges)
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import type { Pool } from "pg";
|
|
3
|
+
import { extractTables, Table } from "./table.model.ts";
|
|
4
|
+
|
|
5
|
+
// Minimal fields required by tablePropsSchema; individual tests override the
|
|
6
|
+
// constraints array (and any other relevant fields).
|
|
7
|
+
const baseTableRow = {
|
|
8
|
+
schema: "public",
|
|
9
|
+
name: '"users"',
|
|
10
|
+
persistence: "p" as const,
|
|
11
|
+
row_security: false,
|
|
12
|
+
force_row_security: false,
|
|
13
|
+
has_indexes: false,
|
|
14
|
+
has_rules: false,
|
|
15
|
+
has_triggers: false,
|
|
16
|
+
has_subclasses: false,
|
|
17
|
+
is_populated: true,
|
|
18
|
+
replica_identity: "d" as const,
|
|
19
|
+
is_partition: false,
|
|
20
|
+
options: null,
|
|
21
|
+
partition_bound: null,
|
|
22
|
+
partition_by: null,
|
|
23
|
+
owner: "postgres",
|
|
24
|
+
comment: null,
|
|
25
|
+
parent_schema: null,
|
|
26
|
+
parent_name: null,
|
|
27
|
+
columns: [],
|
|
28
|
+
privileges: [],
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const baseConstraint = {
|
|
32
|
+
name: '"users_pkey"',
|
|
33
|
+
constraint_type: "p" as const,
|
|
34
|
+
deferrable: false,
|
|
35
|
+
initially_deferred: false,
|
|
36
|
+
validated: true,
|
|
37
|
+
is_local: true,
|
|
38
|
+
no_inherit: false,
|
|
39
|
+
is_temporal: false,
|
|
40
|
+
is_partition_clone: false,
|
|
41
|
+
parent_constraint_schema: null,
|
|
42
|
+
parent_constraint_name: null,
|
|
43
|
+
parent_table_schema: null,
|
|
44
|
+
parent_table_name: null,
|
|
45
|
+
key_columns: ['"id"'],
|
|
46
|
+
foreign_key_columns: null,
|
|
47
|
+
foreign_key_table: null,
|
|
48
|
+
foreign_key_schema: null,
|
|
49
|
+
foreign_key_table_is_partition: null,
|
|
50
|
+
foreign_key_parent_schema: null,
|
|
51
|
+
foreign_key_parent_table: null,
|
|
52
|
+
foreign_key_effective_schema: null,
|
|
53
|
+
foreign_key_effective_table: null,
|
|
54
|
+
on_update: null,
|
|
55
|
+
on_delete: null,
|
|
56
|
+
match_type: null,
|
|
57
|
+
check_expression: null,
|
|
58
|
+
owner: "postgres",
|
|
59
|
+
comment: null,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const mockPool = (rows: unknown[]): Pool =>
|
|
63
|
+
({ query: async () => ({ rows }) }) as unknown as Pool;
|
|
64
|
+
|
|
65
|
+
const mockPoolSequence = (...attempts: unknown[][]): Pool => {
|
|
66
|
+
let i = 0;
|
|
67
|
+
return {
|
|
68
|
+
query: async () => ({
|
|
69
|
+
rows: attempts[Math.min(i++, attempts.length - 1)],
|
|
70
|
+
}),
|
|
71
|
+
} as unknown as Pool;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const NO_BACKOFF = { backoffMs: 0 } as const;
|
|
75
|
+
|
|
76
|
+
describe("extractTables", () => {
|
|
77
|
+
test("skips constraints where pg_get_constraintdef returned NULL after exhausting retries", async () => {
|
|
78
|
+
const tables = await extractTables(
|
|
79
|
+
mockPool([
|
|
80
|
+
{
|
|
81
|
+
...baseTableRow,
|
|
82
|
+
constraints: [
|
|
83
|
+
{
|
|
84
|
+
...baseConstraint,
|
|
85
|
+
name: '"users_pkey"',
|
|
86
|
+
definition: "PRIMARY KEY (id)",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
...baseConstraint,
|
|
90
|
+
name: '"users_orphan_chk"',
|
|
91
|
+
constraint_type: "c",
|
|
92
|
+
key_columns: [],
|
|
93
|
+
definition: null,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
},
|
|
97
|
+
]),
|
|
98
|
+
NO_BACKOFF,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
expect(tables).toHaveLength(1);
|
|
102
|
+
expect(tables[0]).toBeInstanceOf(Table);
|
|
103
|
+
expect(tables[0]?.constraints).toHaveLength(1);
|
|
104
|
+
expect(tables[0]?.constraints[0]?.name).toBe('"users_pkey"');
|
|
105
|
+
expect(tables[0]?.constraints[0]?.definition).toBe("PRIMARY KEY (id)");
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test("does not throw ZodError when every constraint has a null definition", async () => {
|
|
109
|
+
const tables = await extractTables(
|
|
110
|
+
mockPool([
|
|
111
|
+
{
|
|
112
|
+
...baseTableRow,
|
|
113
|
+
constraints: [
|
|
114
|
+
{
|
|
115
|
+
...baseConstraint,
|
|
116
|
+
name: '"orphan_a"',
|
|
117
|
+
constraint_type: "c",
|
|
118
|
+
key_columns: [],
|
|
119
|
+
definition: null,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
...baseConstraint,
|
|
123
|
+
name: '"orphan_b"',
|
|
124
|
+
constraint_type: "c",
|
|
125
|
+
key_columns: [],
|
|
126
|
+
definition: null,
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
]),
|
|
131
|
+
NO_BACKOFF,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
expect(tables).toHaveLength(1);
|
|
135
|
+
expect(tables[0]?.constraints).toEqual([]);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test("returns all constraints when every definition is valid", async () => {
|
|
139
|
+
const tables = await extractTables(
|
|
140
|
+
mockPool([
|
|
141
|
+
{
|
|
142
|
+
...baseTableRow,
|
|
143
|
+
constraints: [
|
|
144
|
+
{
|
|
145
|
+
...baseConstraint,
|
|
146
|
+
name: '"users_pkey"',
|
|
147
|
+
definition: "PRIMARY KEY (id)",
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
...baseConstraint,
|
|
151
|
+
name: '"users_email_key"',
|
|
152
|
+
constraint_type: "u",
|
|
153
|
+
key_columns: ['"email"'],
|
|
154
|
+
definition: "UNIQUE (email)",
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
]),
|
|
159
|
+
NO_BACKOFF,
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
expect(tables[0]?.constraints.map((c) => c.name)).toEqual([
|
|
163
|
+
'"users_pkey"',
|
|
164
|
+
'"users_email_key"',
|
|
165
|
+
]);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test("recovers when pg_get_constraintdef is NULL on first attempt but resolved on retry", async () => {
|
|
169
|
+
const tables = await extractTables(
|
|
170
|
+
mockPoolSequence(
|
|
171
|
+
// attempt 1: one constraint has NULL definition
|
|
172
|
+
[
|
|
173
|
+
{
|
|
174
|
+
...baseTableRow,
|
|
175
|
+
constraints: [
|
|
176
|
+
{
|
|
177
|
+
...baseConstraint,
|
|
178
|
+
name: '"users_racy_chk"',
|
|
179
|
+
constraint_type: "c",
|
|
180
|
+
key_columns: [],
|
|
181
|
+
definition: null,
|
|
182
|
+
},
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
// attempt 2: constraint resolves on retry
|
|
187
|
+
[
|
|
188
|
+
{
|
|
189
|
+
...baseTableRow,
|
|
190
|
+
constraints: [
|
|
191
|
+
{
|
|
192
|
+
...baseConstraint,
|
|
193
|
+
name: '"users_racy_chk"',
|
|
194
|
+
constraint_type: "c",
|
|
195
|
+
key_columns: [],
|
|
196
|
+
definition: "CHECK (id > 0)",
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
),
|
|
202
|
+
{ retries: 2, backoffMs: 0 },
|
|
203
|
+
);
|
|
204
|
+
expect(tables).toHaveLength(1);
|
|
205
|
+
expect(tables[0]?.constraints).toHaveLength(1);
|
|
206
|
+
expect(tables[0]?.constraints[0]?.name).toBe('"users_racy_chk"');
|
|
207
|
+
expect(tables[0]?.constraints[0]?.definition).toBe("CHECK (id > 0)");
|
|
208
|
+
});
|
|
209
|
+
});
|
|
@@ -12,6 +12,15 @@ import {
|
|
|
12
12
|
type PrivilegeProps,
|
|
13
13
|
privilegePropsSchema,
|
|
14
14
|
} from "../base.privilege-diff.ts";
|
|
15
|
+
import {
|
|
16
|
+
type ExtractRetryOptions,
|
|
17
|
+
extractWithDefinitionRetry,
|
|
18
|
+
} from "../extract-with-retry.ts";
|
|
19
|
+
import {
|
|
20
|
+
normalizeSecurityLabels,
|
|
21
|
+
type SecurityLabelProps,
|
|
22
|
+
securityLabelPropsSchema,
|
|
23
|
+
} from "../security-label.types.ts";
|
|
15
24
|
|
|
16
25
|
const RelationPersistenceSchema = z.enum([
|
|
17
26
|
"p", // permanent
|
|
@@ -82,6 +91,15 @@ const tableConstraintPropsSchema = z.object({
|
|
|
82
91
|
|
|
83
92
|
export type TableConstraintProps = z.infer<typeof tableConstraintPropsSchema>;
|
|
84
93
|
|
|
94
|
+
// pg_get_constraintdef(oid, pretty) can return NULL under the same conditions
|
|
95
|
+
// as pg_get_indexdef: races with concurrent DDL, transient catalog
|
|
96
|
+
// inconsistencies, recovery edges. An unreadable constraint cannot be diffed,
|
|
97
|
+
// so we accept NULL here and filter the constraint out at extraction time
|
|
98
|
+
// rather than crashing the whole catalog parse with a ZodError.
|
|
99
|
+
const tableConstraintRowSchema = tableConstraintPropsSchema.extend({
|
|
100
|
+
definition: z.string().nullable(),
|
|
101
|
+
});
|
|
102
|
+
|
|
85
103
|
const tablePropsSchema = z.object({
|
|
86
104
|
schema: z.string(),
|
|
87
105
|
name: z.string(),
|
|
@@ -94,6 +112,7 @@ const tablePropsSchema = z.object({
|
|
|
94
112
|
has_subclasses: z.boolean(),
|
|
95
113
|
is_populated: z.boolean(),
|
|
96
114
|
replica_identity: ReplicaIdentitySchema,
|
|
115
|
+
replica_identity_index: z.string().nullable().optional(),
|
|
97
116
|
is_partition: z.boolean(),
|
|
98
117
|
options: z.array(z.string()).nullable(),
|
|
99
118
|
partition_bound: z.string().nullable(),
|
|
@@ -105,10 +124,20 @@ const tablePropsSchema = z.object({
|
|
|
105
124
|
columns: z.array(columnPropsSchema),
|
|
106
125
|
constraints: z.array(tableConstraintPropsSchema).optional(),
|
|
107
126
|
privileges: z.array(privilegePropsSchema),
|
|
127
|
+
security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const tableRowSchema = tablePropsSchema.extend({
|
|
131
|
+
constraints: z.array(tableConstraintRowSchema).optional(),
|
|
108
132
|
});
|
|
109
133
|
|
|
110
134
|
type TablePrivilegeProps = PrivilegeProps;
|
|
135
|
+
/**
|
|
136
|
+
* Table input props. `security_labels` is optional on direct construction
|
|
137
|
+
* (defaults to `[]`); extraction always produces it via the Zod default.
|
|
138
|
+
*/
|
|
111
139
|
export type TableProps = z.infer<typeof tablePropsSchema>;
|
|
140
|
+
type TableRow = z.infer<typeof tableRowSchema>;
|
|
112
141
|
|
|
113
142
|
export class Table extends BasePgModel implements TableLikeObject {
|
|
114
143
|
public readonly schema: TableProps["schema"];
|
|
@@ -122,6 +151,7 @@ export class Table extends BasePgModel implements TableLikeObject {
|
|
|
122
151
|
public readonly has_subclasses: TableProps["has_subclasses"];
|
|
123
152
|
public readonly is_populated: TableProps["is_populated"];
|
|
124
153
|
public readonly replica_identity: TableProps["replica_identity"];
|
|
154
|
+
public readonly replica_identity_index: TableProps["replica_identity_index"];
|
|
125
155
|
public readonly is_partition: TableProps["is_partition"];
|
|
126
156
|
public readonly options: TableProps["options"];
|
|
127
157
|
public readonly partition_bound: TableProps["partition_bound"];
|
|
@@ -133,6 +163,7 @@ export class Table extends BasePgModel implements TableLikeObject {
|
|
|
133
163
|
public readonly columns: TableProps["columns"];
|
|
134
164
|
public readonly constraints: TableConstraintProps[];
|
|
135
165
|
public readonly privileges: TablePrivilegeProps[];
|
|
166
|
+
public readonly security_labels: SecurityLabelProps[];
|
|
136
167
|
|
|
137
168
|
constructor(props: TableProps) {
|
|
138
169
|
super();
|
|
@@ -151,6 +182,7 @@ export class Table extends BasePgModel implements TableLikeObject {
|
|
|
151
182
|
this.has_subclasses = props.has_subclasses;
|
|
152
183
|
this.is_populated = props.is_populated;
|
|
153
184
|
this.replica_identity = props.replica_identity;
|
|
185
|
+
this.replica_identity_index = props.replica_identity_index ?? null;
|
|
154
186
|
this.is_partition = props.is_partition;
|
|
155
187
|
this.options = props.options;
|
|
156
188
|
this.partition_bound = props.partition_bound;
|
|
@@ -162,6 +194,7 @@ export class Table extends BasePgModel implements TableLikeObject {
|
|
|
162
194
|
this.columns = props.columns;
|
|
163
195
|
this.constraints = props.constraints ?? [];
|
|
164
196
|
this.privileges = props.privileges;
|
|
197
|
+
this.security_labels = props.security_labels ?? [];
|
|
165
198
|
}
|
|
166
199
|
|
|
167
200
|
get stableId(): `table:${string}` {
|
|
@@ -182,6 +215,7 @@ export class Table extends BasePgModel implements TableLikeObject {
|
|
|
182
215
|
row_security: this.row_security,
|
|
183
216
|
force_row_security: this.force_row_security,
|
|
184
217
|
replica_identity: this.replica_identity,
|
|
218
|
+
replica_identity_index: this.replica_identity_index,
|
|
185
219
|
options: this.options,
|
|
186
220
|
// Partition membership can be altered via ATTACH/DETACH
|
|
187
221
|
parent_schema: this.parent_schema,
|
|
@@ -192,6 +226,7 @@ export class Table extends BasePgModel implements TableLikeObject {
|
|
|
192
226
|
columns: this.columns,
|
|
193
227
|
constraints: this.constraints,
|
|
194
228
|
privileges: this.privileges,
|
|
229
|
+
security_labels: this.security_labels,
|
|
195
230
|
};
|
|
196
231
|
}
|
|
197
232
|
|
|
@@ -211,13 +246,23 @@ export class Table extends BasePgModel implements TableLikeObject {
|
|
|
211
246
|
options: this.options ? [...this.options].sort() : this.options,
|
|
212
247
|
constraints: normalizeConstraints(),
|
|
213
248
|
privileges: normalizePrivileges(this.privileges),
|
|
249
|
+
security_labels: normalizeSecurityLabels(this.security_labels),
|
|
214
250
|
},
|
|
215
251
|
};
|
|
216
252
|
}
|
|
217
253
|
}
|
|
218
254
|
|
|
219
|
-
export async function extractTables(
|
|
220
|
-
|
|
255
|
+
export async function extractTables(
|
|
256
|
+
pool: Pool,
|
|
257
|
+
options?: ExtractRetryOptions,
|
|
258
|
+
): Promise<Table[]> {
|
|
259
|
+
const tableRows = await extractWithDefinitionRetry({
|
|
260
|
+
label: "table constraints",
|
|
261
|
+
options,
|
|
262
|
+
hasNullDefinition: (row: TableRow) =>
|
|
263
|
+
row.constraints?.some((c) => c.definition === null) ?? false,
|
|
264
|
+
query: async () => {
|
|
265
|
+
const result = await pool.query<TableProps>(sql`
|
|
221
266
|
with extension_oids as (
|
|
222
267
|
select objid
|
|
223
268
|
from pg_depend d
|
|
@@ -236,6 +281,14 @@ with extension_oids as (
|
|
|
236
281
|
c.relhassubclass as has_subclasses,
|
|
237
282
|
c.relispopulated as is_populated,
|
|
238
283
|
c.relreplident as replica_identity,
|
|
284
|
+
(
|
|
285
|
+
select quote_ident(ri_class.relname)
|
|
286
|
+
from pg_index ri
|
|
287
|
+
join pg_class ri_class on ri_class.oid = ri.indexrelid
|
|
288
|
+
where ri.indrelid = c.oid
|
|
289
|
+
and ri.indisreplident is true
|
|
290
|
+
limit 1
|
|
291
|
+
) as replica_identity_index,
|
|
239
292
|
c.relispartition as is_partition,
|
|
240
293
|
c.reloptions as options,
|
|
241
294
|
pg_get_expr(c.relpartbound, c.oid) as partition_bound,
|
|
@@ -266,6 +319,7 @@ select
|
|
|
266
319
|
t.has_subclasses,
|
|
267
320
|
t.is_populated,
|
|
268
321
|
t.replica_identity,
|
|
322
|
+
t.replica_identity_index,
|
|
269
323
|
t.is_partition,
|
|
270
324
|
t.options,
|
|
271
325
|
t.partition_bound,
|
|
@@ -406,7 +460,20 @@ select
|
|
|
406
460
|
and a.attcollation <> t2.typcollation
|
|
407
461
|
),
|
|
408
462
|
'default', pg_get_expr(ad.adbin, ad.adrelid),
|
|
409
|
-
'comment', col_description(a.attrelid, a.attnum)
|
|
463
|
+
'comment', col_description(a.attrelid, a.attnum),
|
|
464
|
+
'security_labels', coalesce(
|
|
465
|
+
(
|
|
466
|
+
select json_agg(
|
|
467
|
+
json_build_object('provider', sl.provider, 'label', sl.label)
|
|
468
|
+
order by sl.provider
|
|
469
|
+
)
|
|
470
|
+
from pg_catalog.pg_seclabel sl
|
|
471
|
+
where sl.objoid = t.oid
|
|
472
|
+
and sl.classoid = 'pg_class'::regclass
|
|
473
|
+
and sl.objsubid = a.attnum
|
|
474
|
+
),
|
|
475
|
+
'[]'::json
|
|
476
|
+
)
|
|
410
477
|
)
|
|
411
478
|
end
|
|
412
479
|
order by a.attnum
|
|
@@ -446,20 +513,38 @@ select
|
|
|
446
513
|
join lateral aclexplode(src.acl) as x(grantor, grantee, privilege_type, is_grantable) on true
|
|
447
514
|
group by x.grantee, x.privilege_type
|
|
448
515
|
) as grp
|
|
449
|
-
), '[]') as privileges
|
|
516
|
+
), '[]') as privileges,
|
|
517
|
+
coalesce(
|
|
518
|
+
(
|
|
519
|
+
select json_agg(
|
|
520
|
+
json_build_object('provider', sl.provider, 'label', sl.label)
|
|
521
|
+
order by sl.provider
|
|
522
|
+
)
|
|
523
|
+
from pg_catalog.pg_seclabel sl
|
|
524
|
+
where sl.objoid = t.oid
|
|
525
|
+
and sl.classoid = 'pg_class'::regclass
|
|
526
|
+
and sl.objsubid = 0
|
|
527
|
+
),
|
|
528
|
+
'[]'::json
|
|
529
|
+
) as security_labels
|
|
450
530
|
from
|
|
451
531
|
tables t
|
|
452
532
|
left join pg_attribute a on a.attrelid = t.oid and a.attnum > 0 and not a.attisdropped
|
|
453
533
|
left join pg_attrdef ad on a.attrelid = ad.adrelid and a.attnum = ad.adnum
|
|
454
534
|
left join pg_type ty on ty.oid = a.atttypid
|
|
455
535
|
group by
|
|
456
|
-
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
|
|
536
|
+
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
|
|
457
537
|
order by
|
|
458
538
|
t.schema, t.name
|
|
459
539
|
`);
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
)
|
|
540
|
+
return result.rows.map((row: unknown) => tableRowSchema.parse(row));
|
|
541
|
+
},
|
|
542
|
+
});
|
|
543
|
+
const validatedRows = tableRows.map((row): TableProps => {
|
|
544
|
+
const filteredConstraints = row.constraints?.filter(
|
|
545
|
+
(c): c is TableConstraintProps => c.definition !== null,
|
|
546
|
+
);
|
|
547
|
+
return { ...row, constraints: filteredConstraints };
|
|
548
|
+
});
|
|
464
549
|
return validatedRows.map((row: TableProps) => new Table(row));
|
|
465
550
|
}
|