@supabase/pg-delta 1.0.0-alpha.4 → 1.0.0-alpha.6
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/README.md +40 -23
- package/dist/cli/app.js +26 -3
- package/dist/cli/bin/cli.js +5 -0
- package/dist/cli/commands/catalog-export.d.ts +5 -0
- package/dist/cli/commands/catalog-export.js +64 -0
- package/dist/cli/commands/declarative-apply.d.ts +6 -0
- package/dist/cli/commands/declarative-apply.js +288 -0
- package/dist/cli/commands/declarative-export.d.ts +5 -0
- package/dist/cli/commands/declarative-export.js +245 -0
- package/dist/cli/commands/plan.js +19 -6
- package/dist/cli/exit-code.d.ts +2 -0
- package/dist/cli/exit-code.js +7 -0
- package/dist/cli/formatters/tree/tree.js +3 -2
- package/dist/cli/utils/apply-display.d.ts +52 -0
- package/dist/cli/utils/apply-display.js +183 -0
- package/dist/cli/utils/export-display.d.ts +43 -0
- package/dist/cli/utils/export-display.js +202 -0
- package/dist/cli/utils/resolve-input.d.ts +7 -0
- package/dist/cli/utils/resolve-input.js +13 -0
- package/dist/core/catalog-export/index.d.ts +11 -0
- package/dist/core/catalog-export/index.js +10 -0
- package/dist/core/catalog.diff.d.ts +1 -0
- package/dist/core/catalog.diff.js +64 -48
- package/dist/core/catalog.model.d.ts +14 -1
- package/dist/core/catalog.model.js +103 -1
- package/dist/core/catalog.snapshot.d.ts +66 -0
- package/dist/core/catalog.snapshot.js +206 -0
- package/dist/core/declarative-apply/discover-sql.d.ts +18 -0
- package/dist/core/declarative-apply/discover-sql.js +86 -0
- package/dist/core/declarative-apply/extract-catalog-providers.d.ts +23 -0
- package/dist/core/declarative-apply/extract-catalog-providers.js +159 -0
- package/dist/core/declarative-apply/index.d.ts +49 -0
- package/dist/core/declarative-apply/index.js +134 -0
- package/dist/core/declarative-apply/round-apply.d.ts +100 -0
- package/dist/core/declarative-apply/round-apply.js +378 -0
- package/dist/core/export/file-mapper.d.ts +71 -0
- package/dist/core/export/file-mapper.js +474 -0
- package/dist/core/export/grouper.d.ts +13 -0
- package/dist/core/export/grouper.js +76 -0
- package/dist/core/export/index.d.ts +45 -0
- package/dist/core/export/index.js +63 -0
- package/dist/core/export/types.d.ts +84 -0
- package/dist/core/export/types.js +25 -0
- package/dist/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
- package/dist/core/integrations/filter/dsl.d.ts +38 -1
- package/dist/core/integrations/filter/dsl.js +20 -2
- package/dist/core/integrations/filter/extractors.js +42 -0
- package/dist/core/integrations/integration-dsl.d.ts +10 -0
- package/dist/core/integrations/supabase.d.ts +8 -0
- package/dist/core/integrations/supabase.js +9 -0
- package/dist/core/objects/aggregate/aggregate.diff.d.ts +2 -8
- package/dist/core/objects/aggregate/aggregate.diff.js +16 -70
- package/dist/core/objects/aggregate/aggregate.model.d.ts +8 -8
- package/dist/core/objects/aggregate/aggregate.model.js +1 -1
- package/dist/core/objects/aggregate/changes/aggregate.create.js +1 -1
- package/dist/core/objects/aggregate/changes/aggregate.drop.js +1 -1
- package/dist/core/objects/base.privilege-diff.d.ts +38 -13
- package/dist/core/objects/base.privilege-diff.js +104 -22
- package/dist/core/objects/base.privilege.d.ts +1 -0
- package/dist/core/objects/base.privilege.js +9 -2
- package/dist/core/objects/collation/collation.diff.d.ts +2 -3
- package/dist/core/objects/diff-context.d.ts +15 -0
- package/dist/core/objects/diff-context.js +1 -0
- package/dist/core/objects/domain/changes/domain.create.js +4 -2
- package/dist/core/objects/domain/domain.diff.d.ts +2 -8
- package/dist/core/objects/domain/domain.diff.js +16 -77
- package/dist/core/objects/domain/domain.model.js +1 -1
- package/dist/core/objects/event-trigger/event-trigger.diff.d.ts +2 -3
- package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.d.ts +2 -8
- package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.js +13 -77
- package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.js +2 -2
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.d.ts +2 -8
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.js +16 -77
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.js +1 -1
- package/dist/core/objects/foreign-data-wrapper/server/server.diff.d.ts +2 -8
- package/dist/core/objects/foreign-data-wrapper/server/server.diff.js +13 -77
- package/dist/core/objects/language/language.diff.d.ts +2 -5
- package/dist/core/objects/language/language.diff.js +7 -39
- package/dist/core/objects/materialized-view/materialized-view.diff.d.ts +2 -8
- package/dist/core/objects/materialized-view/materialized-view.diff.js +16 -158
- package/dist/core/objects/materialized-view/materialized-view.model.d.ts +3 -3
- package/dist/core/objects/materialized-view/materialized-view.model.js +1 -1
- package/dist/core/objects/procedure/changes/procedure.alter.js +12 -12
- package/dist/core/objects/procedure/procedure.diff.d.ts +2 -8
- package/dist/core/objects/procedure/procedure.diff.js +16 -77
- package/dist/core/objects/procedure/procedure.model.d.ts +9 -9
- package/dist/core/objects/procedure/procedure.model.js +1 -1
- package/dist/core/objects/publication/changes/publication.alter.d.ts +0 -9
- package/dist/core/objects/publication/changes/publication.alter.js +0 -14
- package/dist/core/objects/publication/changes/publication.types.d.ts +2 -2
- package/dist/core/objects/publication/publication.diff.d.ts +2 -3
- package/dist/core/objects/publication/publication.diff.js +8 -13
- package/dist/core/objects/rls-policy/changes/rls-policy.alter.js +3 -3
- package/dist/core/objects/rls-policy/rls-policy.model.d.ts +2 -2
- package/dist/core/objects/role/role.diff.js +22 -1
- package/dist/core/objects/role/role.model.d.ts +4 -3
- package/dist/core/objects/role/role.model.js +118 -12
- package/dist/core/objects/rule/rule.model.d.ts +1 -1
- package/dist/core/objects/schema/schema.diff.d.ts +2 -8
- package/dist/core/objects/schema/schema.diff.js +16 -77
- package/dist/core/objects/schema/schema.model.js +1 -1
- package/dist/core/objects/sequence/sequence.diff.d.ts +2 -8
- package/dist/core/objects/sequence/sequence.diff.js +16 -79
- package/dist/core/objects/sequence/sequence.model.js +1 -1
- package/dist/core/objects/subscription/subscription.diff.d.ts +2 -3
- package/dist/core/objects/table/changes/table.create.js +3 -0
- package/dist/core/objects/table/table.diff.d.ts +2 -8
- package/dist/core/objects/table/table.diff.js +26 -157
- package/dist/core/objects/table/table.model.d.ts +23 -22
- package/dist/core/objects/table/table.model.js +1 -1
- package/dist/core/objects/trigger/changes/trigger.create.js +2 -4
- package/dist/core/objects/trigger/trigger.model.d.ts +8 -0
- package/dist/core/objects/trigger/trigger.model.js +11 -0
- package/dist/core/objects/type/composite-type/composite-type.diff.d.ts +2 -8
- package/dist/core/objects/type/composite-type/composite-type.diff.js +16 -77
- package/dist/core/objects/type/composite-type/composite-type.model.d.ts +3 -3
- package/dist/core/objects/type/composite-type/composite-type.model.js +2 -1
- package/dist/core/objects/type/enum/enum.diff.d.ts +2 -8
- package/dist/core/objects/type/enum/enum.diff.js +25 -112
- package/dist/core/objects/type/enum/enum.model.js +1 -1
- package/dist/core/objects/type/range/changes/range.create.js +6 -3
- package/dist/core/objects/type/range/range.diff.d.ts +2 -8
- package/dist/core/objects/type/range/range.diff.js +16 -77
- package/dist/core/objects/type/range/range.model.js +1 -1
- package/dist/core/objects/view/view.diff.d.ts +2 -8
- package/dist/core/objects/view/view.diff.js +16 -158
- package/dist/core/objects/view/view.model.d.ts +18 -4
- package/dist/core/objects/view/view.model.js +3 -13
- package/dist/core/plan/apply.js +9 -26
- package/dist/core/plan/create.d.ts +19 -6
- package/dist/core/plan/create.js +134 -174
- package/dist/core/plan/serialize.js +16 -4
- package/dist/core/plan/sql-format/fixtures.js +3 -5
- package/dist/core/plan/sql-format/keyword-case.js +26 -1
- package/dist/core/plan/ssl-config.d.ts +32 -0
- package/dist/core/plan/ssl-config.js +115 -0
- package/dist/core/plan/types.d.ts +6 -0
- package/dist/core/postgres-config.d.ts +14 -0
- package/dist/core/postgres-config.js +53 -2
- package/dist/core/sort/graph-builder.js +10 -0
- package/dist/core/sort/logical-sort.js +31 -23
- package/dist/core/test-utils/assert-valid-sql.d.ts +10 -0
- package/dist/core/test-utils/assert-valid-sql.js +19 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -1
- package/package.json +21 -4
- package/src/cli/app.ts +27 -3
- package/src/cli/bin/cli.ts +6 -0
- package/src/cli/commands/catalog-export.ts +78 -0
- package/src/cli/commands/declarative-apply.diagnostics.test.ts +77 -0
- package/src/cli/commands/declarative-apply.ts +380 -0
- package/src/cli/commands/declarative-export.ts +330 -0
- package/src/cli/commands/plan.ts +28 -7
- package/src/cli/exit-code.test.ts +19 -0
- package/src/cli/exit-code.ts +7 -0
- package/src/cli/formatters/tree/tree.ts +3 -2
- package/src/cli/utils/apply-display.test.ts +348 -0
- package/src/cli/utils/apply-display.ts +238 -0
- package/src/cli/utils/export-display.test.ts +103 -0
- package/src/cli/utils/export-display.ts +275 -0
- package/src/cli/utils/integrations.test.ts +44 -0
- package/src/cli/utils/resolve-input.test.ts +38 -0
- package/src/cli/utils/resolve-input.ts +17 -0
- package/src/core/catalog-export/index.ts +20 -0
- package/src/core/catalog.diff.ts +79 -78
- package/src/core/catalog.model.test.ts +122 -0
- package/src/core/catalog.model.ts +127 -1
- package/src/core/catalog.snapshot.test.ts +464 -0
- package/src/core/catalog.snapshot.ts +289 -0
- package/src/core/declarative-apply/discover-sql.test.ts +103 -0
- package/src/core/declarative-apply/discover-sql.ts +107 -0
- package/src/core/declarative-apply/extract-catalog-providers.ts +220 -0
- package/src/core/declarative-apply/index.test.ts +67 -0
- package/src/core/declarative-apply/index.ts +205 -0
- package/src/core/declarative-apply/round-apply.test.ts +504 -0
- package/src/core/declarative-apply/round-apply.ts +562 -0
- package/src/core/expand-replace-dependencies.test.ts +70 -0
- package/src/core/export/file-mapper.test.ts +816 -0
- package/src/core/export/file-mapper.ts +574 -0
- package/src/core/export/grouper.ts +108 -0
- package/src/core/export/index.ts +129 -0
- package/src/core/export/types.ts +104 -0
- package/src/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
- package/src/core/integrations/filter/dsl.test.ts +211 -0
- package/src/core/integrations/filter/dsl.ts +65 -3
- package/src/core/integrations/filter/extractors.test.ts +244 -0
- package/src/core/integrations/filter/extractors.ts +42 -0
- package/src/core/integrations/integration-dsl.ts +10 -0
- package/src/core/integrations/serialize/dsl.test.ts +91 -0
- package/src/core/integrations/supabase.ts +9 -0
- package/src/core/objects/aggregate/aggregate.diff.ts +39 -95
- package/src/core/objects/aggregate/aggregate.model.ts +1 -1
- package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +3 -1
- package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +5 -2
- package/src/core/objects/aggregate/changes/aggregate.create.test.ts +6 -3
- package/src/core/objects/aggregate/changes/aggregate.create.ts +1 -1
- package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +7 -3
- package/src/core/objects/aggregate/changes/aggregate.drop.ts +1 -1
- package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +9 -3
- package/src/core/objects/base.privilege-diff.ts +178 -30
- package/src/core/objects/base.privilege.ts +9 -2
- package/src/core/objects/collation/changes/collation.alter.test.ts +7 -2
- package/src/core/objects/collation/changes/collation.create.test.ts +7 -2
- package/src/core/objects/collation/changes/collation.drop.test.ts +4 -1
- package/src/core/objects/collation/collation.diff.test.ts +9 -12
- package/src/core/objects/collation/collation.diff.ts +2 -1
- package/src/core/objects/diff-context.ts +16 -0
- package/src/core/objects/domain/changes/domain.alter.test.ts +28 -9
- package/src/core/objects/domain/changes/domain.create.test.ts +32 -2
- package/src/core/objects/domain/changes/domain.create.ts +7 -1
- package/src/core/objects/domain/changes/domain.drop.test.ts +4 -1
- package/src/core/objects/domain/domain.diff.ts +39 -102
- package/src/core/objects/domain/domain.model.ts +1 -1
- package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +10 -3
- package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +4 -1
- package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +4 -1
- package/src/core/objects/event-trigger/event-trigger.diff.test.ts +12 -7
- package/src/core/objects/event-trigger/event-trigger.diff.ts +2 -1
- package/src/core/objects/extension/changes/extension.alter.test.ts +7 -2
- package/src/core/objects/extension/changes/extension.create.test.ts +4 -1
- package/src/core/objects/extension/changes/extension.drop.test.ts +4 -1
- package/src/core/objects/extension/extension.model.test.ts +98 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +16 -5
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +51 -16
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +4 -1
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +111 -4
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +31 -101
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +2 -2
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +46 -15
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +13 -4
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +4 -1
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +39 -102
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +1 -1
- package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +22 -7
- package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +19 -6
- package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +4 -1
- package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +95 -0
- package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +31 -101
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +13 -4
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +16 -5
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +10 -3
- package/src/core/objects/index/changes/index.alter.test.ts +13 -4
- package/src/core/objects/index/changes/index.create.test.ts +4 -1
- package/src/core/objects/index/changes/index.drop.test.ts +4 -1
- package/src/core/objects/language/changes/language.alter.test.ts +4 -1
- package/src/core/objects/language/changes/language.create.test.ts +4 -1
- package/src/core/objects/language/changes/language.drop.test.ts +4 -1
- package/src/core/objects/language/language.diff.test.ts +86 -4
- package/src/core/objects/language/language.diff.ts +17 -49
- package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +10 -3
- package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +7 -2
- package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +4 -1
- package/src/core/objects/materialized-view/materialized-view.diff.test.ts +162 -0
- package/src/core/objects/materialized-view/materialized-view.diff.ts +41 -191
- package/src/core/objects/materialized-view/materialized-view.model.ts +1 -1
- package/src/core/objects/procedure/changes/procedure.alter.test.ts +121 -49
- package/src/core/objects/procedure/changes/procedure.alter.ts +15 -12
- package/src/core/objects/procedure/changes/procedure.create.test.ts +4 -1
- package/src/core/objects/procedure/changes/procedure.drop.test.ts +7 -2
- package/src/core/objects/procedure/procedure.diff.ts +39 -102
- package/src/core/objects/procedure/procedure.model.ts +1 -1
- package/src/core/objects/publication/changes/publication.alter.test.ts +15 -21
- package/src/core/objects/publication/changes/publication.alter.ts +0 -18
- package/src/core/objects/publication/changes/publication.comment.test.ts +5 -2
- package/src/core/objects/publication/changes/publication.create.test.ts +5 -2
- package/src/core/objects/publication/changes/publication.drop.test.ts +3 -1
- package/src/core/objects/publication/changes/publication.types.ts +0 -2
- package/src/core/objects/publication/publication.diff.test.ts +24 -19
- package/src/core/objects/publication/publication.diff.ts +9 -15
- package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +31 -14
- package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +3 -3
- package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +10 -3
- package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +4 -1
- package/src/core/objects/role/changes/role.alter.test.ts +31 -15
- package/src/core/objects/role/changes/role.create.test.ts +6 -2
- package/src/core/objects/role/changes/role.drop.test.ts +4 -1
- package/src/core/objects/role/role.diff.test.ts +235 -0
- package/src/core/objects/role/role.diff.ts +21 -1
- package/src/core/objects/role/role.model.ts +122 -14
- package/src/core/objects/rule/changes/rule.alter.test.ts +7 -3
- package/src/core/objects/rule/changes/rule.comment.test.ts +5 -2
- package/src/core/objects/rule/changes/rule.create.test.ts +6 -2
- package/src/core/objects/rule/changes/rule.drop.test.ts +3 -1
- package/src/core/objects/schema/changes/schema.alter.test.ts +4 -1
- package/src/core/objects/schema/changes/schema.create.test.ts +4 -1
- package/src/core/objects/schema/changes/schema.drop.test.ts +4 -1
- package/src/core/objects/schema/schema.diff.ts +39 -102
- package/src/core/objects/schema/schema.model.ts +1 -1
- package/src/core/objects/sequence/changes/sequence.alter.test.ts +11 -5
- package/src/core/objects/sequence/changes/sequence.create.test.ts +8 -3
- package/src/core/objects/sequence/changes/sequence.drop.test.ts +4 -1
- package/src/core/objects/sequence/sequence.diff.test.ts +114 -0
- package/src/core/objects/sequence/sequence.diff.ts +39 -104
- package/src/core/objects/sequence/sequence.model.ts +1 -1
- package/src/core/objects/subscription/changes/subscription.alter.test.ts +15 -5
- package/src/core/objects/subscription/changes/subscription.comment.test.ts +5 -2
- package/src/core/objects/subscription/changes/subscription.create.test.ts +5 -2
- package/src/core/objects/subscription/changes/subscription.drop.test.ts +3 -1
- package/src/core/objects/subscription/subscription.diff.test.ts +16 -11
- package/src/core/objects/subscription/subscription.diff.ts +2 -1
- package/src/core/objects/table/changes/table.alter.test.ts +38 -15
- package/src/core/objects/table/changes/table.create.test.ts +41 -3
- package/src/core/objects/table/changes/table.create.ts +4 -0
- package/src/core/objects/table/changes/table.drop.test.ts +3 -1
- package/src/core/objects/table/table.diff.test.ts +157 -0
- package/src/core/objects/table/table.diff.ts +54 -190
- package/src/core/objects/table/table.model.ts +1 -1
- package/src/core/objects/trigger/changes/trigger.alter.test.ts +8 -4
- package/src/core/objects/trigger/changes/trigger.create.test.ts +5 -1
- package/src/core/objects/trigger/changes/trigger.create.ts +7 -4
- package/src/core/objects/trigger/changes/trigger.drop.test.ts +5 -1
- package/src/core/objects/trigger/trigger.diff.test.ts +1 -0
- package/src/core/objects/trigger/trigger.model.ts +12 -0
- package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +10 -4
- package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +7 -2
- package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +4 -1
- package/src/core/objects/type/composite-type/composite-type.diff.test.ts +78 -0
- package/src/core/objects/type/composite-type/composite-type.diff.ts +39 -101
- package/src/core/objects/type/composite-type/composite-type.model.ts +2 -1
- package/src/core/objects/type/enum/changes/enum.alter.test.ts +14 -5
- package/src/core/objects/type/enum/changes/enum.create.test.ts +4 -1
- package/src/core/objects/type/enum/changes/enum.drop.test.ts +4 -1
- package/src/core/objects/type/enum/enum.diff.test.ts +181 -0
- package/src/core/objects/type/enum/enum.diff.ts +58 -146
- package/src/core/objects/type/enum/enum.model.ts +1 -1
- package/src/core/objects/type/range/changes/range.alter.test.ts +3 -1
- package/src/core/objects/type/range/changes/range.create.test.ts +5 -2
- package/src/core/objects/type/range/changes/range.create.ts +6 -2
- package/src/core/objects/type/range/changes/range.drop.test.ts +3 -1
- package/src/core/objects/type/range/range.diff.test.ts +77 -0
- package/src/core/objects/type/range/range.diff.ts +39 -101
- package/src/core/objects/type/range/range.model.ts +1 -1
- package/src/core/objects/view/changes/view.alter.test.ts +8 -3
- package/src/core/objects/view/changes/view.create.test.ts +7 -2
- package/src/core/objects/view/changes/view.drop.test.ts +4 -1
- package/src/core/objects/view/view.diff.test.ts +82 -0
- package/src/core/objects/view/view.diff.ts +41 -191
- package/src/core/objects/view/view.model.ts +3 -17
- package/src/core/plan/apply.ts +9 -27
- package/src/core/plan/create.ts +173 -237
- package/src/core/plan/serialize.test.ts +317 -0
- package/src/core/plan/serialize.ts +18 -4
- package/src/core/plan/sql-format/fixtures.ts +2 -5
- package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +52 -0
- package/src/core/plan/sql-format/format-off.test.ts +14 -17
- package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +27 -22
- package/src/core/plan/sql-format/format-pretty-narrow.test.ts +17 -21
- package/src/core/plan/sql-format/format-pretty-preserve.test.ts +25 -20
- package/src/core/plan/sql-format/format-pretty-upper.test.ts +23 -20
- package/src/core/plan/sql-format/keyword-case.ts +36 -1
- package/src/core/plan/ssl-config.ts +172 -0
- package/src/core/plan/types.ts +6 -0
- package/src/core/postgres-config.ts +71 -2
- package/src/core/sort/graph-builder.ts +12 -0
- package/src/core/sort/logical-sort.test.ts +371 -0
- package/src/core/sort/logical-sort.ts +32 -25
- package/src/core/sort/topological-sort.test.ts +275 -0
- package/src/core/test-utils/assert-valid-sql.ts +20 -0
- package/src/index.ts +26 -2
|
@@ -64,6 +64,9 @@ export class CreateTable extends CreateTableChange {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
+
// Function dependencies from DEFAULT expressions are handled by pg_depend
|
|
68
|
+
// catalog constraints in the sort pipeline, which provides exact argument
|
|
69
|
+
// types and covers all expression contexts (not just column defaults).
|
|
67
70
|
}
|
|
68
71
|
return Array.from(dependencies);
|
|
69
72
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { Role } from "../role/role.model.ts";
|
|
1
|
+
import type { ObjectDiffContext } from "../diff-context.ts";
|
|
3
2
|
import type { TableChange } from "./changes/table.types.ts";
|
|
4
3
|
import { Table } from "./table.model.ts";
|
|
5
4
|
/**
|
|
@@ -10,9 +9,4 @@ import { Table } from "./table.model.ts";
|
|
|
10
9
|
* @param branch - The tables in the branch catalog.
|
|
11
10
|
* @returns A list of changes to apply to main to make it match branch.
|
|
12
11
|
*/
|
|
13
|
-
export declare function diffTables(ctx:
|
|
14
|
-
version: number;
|
|
15
|
-
currentUser: string;
|
|
16
|
-
defaultPrivilegeState: DefaultPrivilegeState;
|
|
17
|
-
mainRoles: Record<string, Role>;
|
|
18
|
-
}, main: Record<string, Table>, branch: Record<string, Table>): TableChange[];
|
|
12
|
+
export declare function diffTables(ctx: Pick<ObjectDiffContext, "version" | "currentUser" | "defaultPrivilegeState">, main: Record<string, Table>, branch: Record<string, Table>): TableChange[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { diffObjects } from "../base.diff.js";
|
|
2
|
-
import { diffPrivileges,
|
|
2
|
+
import { diffPrivileges, emitColumnPrivilegeChanges, } from "../base.privilege-diff.js";
|
|
3
3
|
import { deepEqual } from "../utils.js";
|
|
4
4
|
import { AlterTableAddColumn, AlterTableAddConstraint, AlterTableAlterColumnDropDefault, AlterTableAlterColumnDropNotNull, AlterTableAlterColumnSetDefault, AlterTableAlterColumnSetNotNull, AlterTableAlterColumnType, AlterTableAttachPartition, AlterTableChangeOwner, AlterTableDetachPartition, AlterTableDisableRowLevelSecurity, AlterTableDropColumn, AlterTableDropConstraint, AlterTableEnableRowLevelSecurity, AlterTableForceRowLevelSecurity, AlterTableNoForceRowLevelSecurity, AlterTableResetStorageParams, AlterTableSetLogged, AlterTableSetReplicaIdentity, AlterTableSetStorageParams, AlterTableSetUnlogged, AlterTableValidateConstraint, } from "./changes/table.alter.js";
|
|
5
5
|
import { CreateCommentOnColumn, CreateCommentOnConstraint, CreateCommentOnTable, DropCommentOnColumn, DropCommentOnConstraint, DropCommentOnTable, } from "./changes/table.comment.js";
|
|
@@ -149,6 +149,16 @@ export function diffTables(ctx, main, branch) {
|
|
|
149
149
|
if (branchTable.force_row_security) {
|
|
150
150
|
changes.push(new AlterTableForceRowLevelSecurity({ table: branchTable }));
|
|
151
151
|
}
|
|
152
|
+
// REPLICA IDENTITY: If non-default, emit ALTER TABLE ... REPLICA IDENTITY
|
|
153
|
+
if (branchTable.replica_identity !== "d") {
|
|
154
|
+
// Skip 'i' (USING INDEX) — handled by index changes
|
|
155
|
+
if (branchTable.replica_identity !== "i") {
|
|
156
|
+
changes.push(new AlterTableSetReplicaIdentity({
|
|
157
|
+
table: branchTable,
|
|
158
|
+
mode: branchTable.replica_identity,
|
|
159
|
+
}));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
152
162
|
changes.push(...createAlterConstraintChange(
|
|
153
163
|
// Create a dummy table with no constraints do diff constraints against
|
|
154
164
|
new Table({
|
|
@@ -171,86 +181,18 @@ export function diffTables(ctx, main, branch) {
|
|
|
171
181
|
// We compare default privileges against desired privileges to generate REVOKE/GRANT statements
|
|
172
182
|
// needed to reach the final desired state.
|
|
173
183
|
const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(ctx.currentUser, "table", branchTable.schema ?? "");
|
|
184
|
+
const creatorFilteredDefaults = branchTable.owner !== ctx.currentUser
|
|
185
|
+
? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
|
|
186
|
+
: effectiveDefaults;
|
|
174
187
|
const desiredPrivileges = branchTable.privileges;
|
|
175
188
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
176
189
|
// and shouldn't be compared. Use the table owner as the reference.
|
|
177
|
-
const privilegeResults = diffPrivileges(
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
for (const [grantable, privSet] of group.byGrant) {
|
|
184
|
-
const privileges = Array.from(privSet).map((priv) => ({
|
|
185
|
-
privilege: priv,
|
|
186
|
-
grantable,
|
|
187
|
-
}));
|
|
188
|
-
changes.push(new GrantTablePrivileges({
|
|
189
|
-
table: branchTable,
|
|
190
|
-
grantee,
|
|
191
|
-
privileges,
|
|
192
|
-
columns: group.columns,
|
|
193
|
-
version: ctx.version,
|
|
194
|
-
}));
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
// Generate revoke changes
|
|
199
|
-
if (result.revokes.length > 0) {
|
|
200
|
-
const revokeGroups = groupPrivilegesByColumns(result.revokes);
|
|
201
|
-
for (const [, group] of revokeGroups) {
|
|
202
|
-
const allPrivileges = new Set();
|
|
203
|
-
for (const [, privSet] of group.byGrant) {
|
|
204
|
-
for (const priv of privSet) {
|
|
205
|
-
allPrivileges.add(priv);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
const privileges = Array.from(allPrivileges).map((priv) => ({
|
|
209
|
-
privilege: priv,
|
|
210
|
-
grantable: false,
|
|
211
|
-
}));
|
|
212
|
-
changes.push(new RevokeTablePrivileges({
|
|
213
|
-
table: branchTable,
|
|
214
|
-
grantee,
|
|
215
|
-
privileges,
|
|
216
|
-
columns: group.columns,
|
|
217
|
-
version: ctx.version,
|
|
218
|
-
}));
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
// Generate revoke grant option changes
|
|
222
|
-
if (result.revokeGrantOption.length > 0) {
|
|
223
|
-
const revokeGrantGroups = new Map();
|
|
224
|
-
for (const r of result.revokeGrantOption) {
|
|
225
|
-
const originalPriv = effectiveDefaults.find((p) => p.grantee === grantee && p.privilege === r);
|
|
226
|
-
const key = originalPriv?.columns
|
|
227
|
-
? originalPriv.columns.sort().join(",")
|
|
228
|
-
: "";
|
|
229
|
-
if (!revokeGrantGroups.has(key)) {
|
|
230
|
-
revokeGrantGroups.set(key, {
|
|
231
|
-
columns: originalPriv?.columns
|
|
232
|
-
? [...originalPriv.columns]
|
|
233
|
-
: undefined,
|
|
234
|
-
privileges: new Set(),
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
const group = revokeGrantGroups.get(key);
|
|
238
|
-
if (!group)
|
|
239
|
-
continue;
|
|
240
|
-
group.privileges.add(r);
|
|
241
|
-
}
|
|
242
|
-
for (const [, group] of revokeGrantGroups) {
|
|
243
|
-
const privilegeNames = Array.from(group.privileges);
|
|
244
|
-
changes.push(new RevokeGrantOptionTablePrivileges({
|
|
245
|
-
table: branchTable,
|
|
246
|
-
grantee,
|
|
247
|
-
privilegeNames,
|
|
248
|
-
columns: group.columns,
|
|
249
|
-
version: ctx.version,
|
|
250
|
-
}));
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
190
|
+
const privilegeResults = diffPrivileges(creatorFilteredDefaults, desiredPrivileges, branchTable.owner);
|
|
191
|
+
changes.push(...emitColumnPrivilegeChanges(privilegeResults, branchTable, branchTable, "table", {
|
|
192
|
+
Grant: GrantTablePrivileges,
|
|
193
|
+
Revoke: RevokeTablePrivileges,
|
|
194
|
+
RevokeGrantOption: RevokeGrantOptionTablePrivileges,
|
|
195
|
+
}, effectiveDefaults, ctx.version));
|
|
254
196
|
}
|
|
255
197
|
for (const tableId of dropped) {
|
|
256
198
|
changes.push(new DropTable({ table: main[tableId] }));
|
|
@@ -584,85 +526,12 @@ export function diffTables(ctx, main, branch) {
|
|
|
584
526
|
// PRIVILEGES (unified object and column privileges)
|
|
585
527
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
586
528
|
// and shouldn't be compared. Use branch owner as the reference.
|
|
587
|
-
const privilegeResults = diffPrivileges(mainTable.privileges, branchTable.privileges, branchTable.owner
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
for (const [grantable, privSet] of group.byGrant) {
|
|
594
|
-
const privileges = Array.from(privSet).map((priv) => ({
|
|
595
|
-
privilege: priv,
|
|
596
|
-
grantable,
|
|
597
|
-
}));
|
|
598
|
-
changes.push(new GrantTablePrivileges({
|
|
599
|
-
table: branchTable,
|
|
600
|
-
grantee,
|
|
601
|
-
privileges,
|
|
602
|
-
columns: group.columns,
|
|
603
|
-
version: ctx.version,
|
|
604
|
-
}));
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
// Generate revoke changes
|
|
609
|
-
if (result.revokes.length > 0) {
|
|
610
|
-
const revokeGroups = groupPrivilegesByColumns(result.revokes);
|
|
611
|
-
for (const [, group] of revokeGroups) {
|
|
612
|
-
// Collapse all grantable groups into a single revoke (grantable: false)
|
|
613
|
-
const allPrivileges = new Set();
|
|
614
|
-
for (const [, privSet] of group.byGrant) {
|
|
615
|
-
for (const priv of privSet) {
|
|
616
|
-
allPrivileges.add(priv);
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
const privileges = Array.from(allPrivileges).map((priv) => ({
|
|
620
|
-
privilege: priv,
|
|
621
|
-
grantable: false,
|
|
622
|
-
}));
|
|
623
|
-
changes.push(new RevokeTablePrivileges({
|
|
624
|
-
table: mainTable,
|
|
625
|
-
grantee,
|
|
626
|
-
privileges,
|
|
627
|
-
columns: group.columns,
|
|
628
|
-
version: ctx.version,
|
|
629
|
-
}));
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
// Generate revoke grant option changes
|
|
633
|
-
if (result.revokeGrantOption.length > 0) {
|
|
634
|
-
const revokeGrantGroups = new Map();
|
|
635
|
-
for (const r of result.revokeGrantOption) {
|
|
636
|
-
// For revoke grant option, we need to find the columns from the original privilege
|
|
637
|
-
const originalPriv = mainTable.privileges.find((p) => p.grantee === grantee && p.privilege === r);
|
|
638
|
-
const key = originalPriv?.columns
|
|
639
|
-
? originalPriv.columns.sort().join(",")
|
|
640
|
-
: "";
|
|
641
|
-
if (!revokeGrantGroups.has(key)) {
|
|
642
|
-
revokeGrantGroups.set(key, {
|
|
643
|
-
columns: originalPriv?.columns
|
|
644
|
-
? [...originalPriv.columns]
|
|
645
|
-
: undefined,
|
|
646
|
-
privileges: new Set(),
|
|
647
|
-
});
|
|
648
|
-
}
|
|
649
|
-
const group = revokeGrantGroups.get(key);
|
|
650
|
-
if (!group)
|
|
651
|
-
continue;
|
|
652
|
-
group.privileges.add(r);
|
|
653
|
-
}
|
|
654
|
-
for (const [, group] of revokeGrantGroups) {
|
|
655
|
-
const privilegeNames = Array.from(group.privileges);
|
|
656
|
-
changes.push(new RevokeGrantOptionTablePrivileges({
|
|
657
|
-
table: mainTable,
|
|
658
|
-
grantee,
|
|
659
|
-
privilegeNames,
|
|
660
|
-
columns: group.columns,
|
|
661
|
-
version: ctx.version,
|
|
662
|
-
}));
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
}
|
|
529
|
+
const privilegeResults = diffPrivileges(mainTable.privileges, branchTable.privileges, branchTable.owner);
|
|
530
|
+
changes.push(...emitColumnPrivilegeChanges(privilegeResults, branchTable, mainTable, "table", {
|
|
531
|
+
Grant: GrantTablePrivileges,
|
|
532
|
+
Revoke: RevokeTablePrivileges,
|
|
533
|
+
RevokeGrantOption: RevokeGrantOptionTablePrivileges,
|
|
534
|
+
}, mainTable.privileges, ctx.version));
|
|
666
535
|
}
|
|
667
536
|
return changes;
|
|
668
537
|
}
|
|
@@ -3,19 +3,19 @@ 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
5
|
export declare const ReplicaIdentitySchema: z.ZodEnum<{
|
|
6
|
-
f: "f";
|
|
7
6
|
n: "n";
|
|
8
7
|
i: "i";
|
|
9
8
|
d: "d";
|
|
9
|
+
f: "f";
|
|
10
10
|
}>;
|
|
11
11
|
declare const tableConstraintPropsSchema: z.ZodObject<{
|
|
12
12
|
name: z.ZodString;
|
|
13
13
|
constraint_type: z.ZodEnum<{
|
|
14
|
-
f: "f";
|
|
15
14
|
u: "u";
|
|
16
15
|
t: "t";
|
|
17
|
-
p: "p";
|
|
18
16
|
c: "c";
|
|
17
|
+
p: "p";
|
|
18
|
+
f: "f";
|
|
19
19
|
x: "x";
|
|
20
20
|
}>;
|
|
21
21
|
deferrable: z.ZodBoolean;
|
|
@@ -38,24 +38,24 @@ declare const tableConstraintPropsSchema: z.ZodObject<{
|
|
|
38
38
|
foreign_key_effective_schema: z.ZodNullable<z.ZodString>;
|
|
39
39
|
foreign_key_effective_table: z.ZodNullable<z.ZodString>;
|
|
40
40
|
on_update: z.ZodNullable<z.ZodEnum<{
|
|
41
|
-
r: "r";
|
|
42
41
|
n: "n";
|
|
43
42
|
a: "a";
|
|
43
|
+
r: "r";
|
|
44
44
|
d: "d";
|
|
45
45
|
c: "c";
|
|
46
46
|
}>>;
|
|
47
47
|
on_delete: z.ZodNullable<z.ZodEnum<{
|
|
48
|
-
r: "r";
|
|
49
48
|
n: "n";
|
|
50
49
|
a: "a";
|
|
50
|
+
r: "r";
|
|
51
51
|
d: "d";
|
|
52
52
|
c: "c";
|
|
53
53
|
}>>;
|
|
54
54
|
match_type: z.ZodNullable<z.ZodEnum<{
|
|
55
|
-
f: "f";
|
|
56
55
|
u: "u";
|
|
57
56
|
s: "s";
|
|
58
57
|
p: "p";
|
|
58
|
+
f: "f";
|
|
59
59
|
}>>;
|
|
60
60
|
check_expression: z.ZodNullable<z.ZodString>;
|
|
61
61
|
owner: z.ZodString;
|
|
@@ -79,10 +79,10 @@ declare const tablePropsSchema: z.ZodObject<{
|
|
|
79
79
|
has_subclasses: z.ZodBoolean;
|
|
80
80
|
is_populated: z.ZodBoolean;
|
|
81
81
|
replica_identity: z.ZodEnum<{
|
|
82
|
-
f: "f";
|
|
83
82
|
n: "n";
|
|
84
83
|
i: "i";
|
|
85
84
|
d: "d";
|
|
85
|
+
f: "f";
|
|
86
86
|
}>;
|
|
87
87
|
is_partition: z.ZodBoolean;
|
|
88
88
|
options: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
@@ -113,11 +113,11 @@ declare const tablePropsSchema: z.ZodObject<{
|
|
|
113
113
|
constraints: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
114
114
|
name: z.ZodString;
|
|
115
115
|
constraint_type: z.ZodEnum<{
|
|
116
|
-
f: "f";
|
|
117
116
|
u: "u";
|
|
118
117
|
t: "t";
|
|
119
|
-
p: "p";
|
|
120
118
|
c: "c";
|
|
119
|
+
p: "p";
|
|
120
|
+
f: "f";
|
|
121
121
|
x: "x";
|
|
122
122
|
}>;
|
|
123
123
|
deferrable: z.ZodBoolean;
|
|
@@ -140,24 +140,24 @@ declare const tablePropsSchema: z.ZodObject<{
|
|
|
140
140
|
foreign_key_effective_schema: z.ZodNullable<z.ZodString>;
|
|
141
141
|
foreign_key_effective_table: z.ZodNullable<z.ZodString>;
|
|
142
142
|
on_update: z.ZodNullable<z.ZodEnum<{
|
|
143
|
-
r: "r";
|
|
144
143
|
n: "n";
|
|
145
144
|
a: "a";
|
|
145
|
+
r: "r";
|
|
146
146
|
d: "d";
|
|
147
147
|
c: "c";
|
|
148
148
|
}>>;
|
|
149
149
|
on_delete: z.ZodNullable<z.ZodEnum<{
|
|
150
|
-
r: "r";
|
|
151
150
|
n: "n";
|
|
152
151
|
a: "a";
|
|
152
|
+
r: "r";
|
|
153
153
|
d: "d";
|
|
154
154
|
c: "c";
|
|
155
155
|
}>>;
|
|
156
156
|
match_type: z.ZodNullable<z.ZodEnum<{
|
|
157
|
-
f: "f";
|
|
158
157
|
u: "u";
|
|
159
158
|
s: "s";
|
|
160
159
|
p: "p";
|
|
160
|
+
f: "f";
|
|
161
161
|
}>>;
|
|
162
162
|
check_expression: z.ZodNullable<z.ZodString>;
|
|
163
163
|
owner: z.ZodString;
|
|
@@ -206,7 +206,7 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
206
206
|
persistence: "u" | "t" | "p";
|
|
207
207
|
row_security: boolean;
|
|
208
208
|
force_row_security: boolean;
|
|
209
|
-
replica_identity: "
|
|
209
|
+
replica_identity: "n" | "i" | "d" | "f";
|
|
210
210
|
options: string[] | null;
|
|
211
211
|
parent_schema: string | null;
|
|
212
212
|
parent_name: string | null;
|
|
@@ -233,7 +233,7 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
233
233
|
}[];
|
|
234
234
|
constraints: {
|
|
235
235
|
name: string;
|
|
236
|
-
constraint_type: "
|
|
236
|
+
constraint_type: "u" | "t" | "c" | "p" | "f" | "x";
|
|
237
237
|
deferrable: boolean;
|
|
238
238
|
initially_deferred: boolean;
|
|
239
239
|
validated: boolean;
|
|
@@ -253,9 +253,9 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
253
253
|
foreign_key_parent_table: string | null;
|
|
254
254
|
foreign_key_effective_schema: string | null;
|
|
255
255
|
foreign_key_effective_table: string | null;
|
|
256
|
-
on_update: "
|
|
257
|
-
on_delete: "
|
|
258
|
-
match_type: "
|
|
256
|
+
on_update: "n" | "a" | "r" | "d" | "c" | null;
|
|
257
|
+
on_delete: "n" | "a" | "r" | "d" | "c" | null;
|
|
258
|
+
match_type: "u" | "s" | "p" | "f" | null;
|
|
259
259
|
check_expression: string | null;
|
|
260
260
|
owner: string;
|
|
261
261
|
definition: string;
|
|
@@ -294,7 +294,7 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
294
294
|
options: string[] | null;
|
|
295
295
|
constraints: {
|
|
296
296
|
name: string;
|
|
297
|
-
constraint_type: "
|
|
297
|
+
constraint_type: "u" | "t" | "c" | "p" | "f" | "x";
|
|
298
298
|
deferrable: boolean;
|
|
299
299
|
initially_deferred: boolean;
|
|
300
300
|
validated: boolean;
|
|
@@ -314,9 +314,9 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
314
314
|
foreign_key_parent_table: string | null;
|
|
315
315
|
foreign_key_effective_schema: string | null;
|
|
316
316
|
foreign_key_effective_table: string | null;
|
|
317
|
-
on_update: "
|
|
318
|
-
on_delete: "
|
|
319
|
-
match_type: "
|
|
317
|
+
on_update: "n" | "a" | "r" | "d" | "c" | null;
|
|
318
|
+
on_delete: "n" | "a" | "r" | "d" | "c" | null;
|
|
319
|
+
match_type: "u" | "s" | "p" | "f" | null;
|
|
320
320
|
check_expression: string | null;
|
|
321
321
|
owner: string;
|
|
322
322
|
definition: string;
|
|
@@ -326,11 +326,12 @@ export declare class Table extends BasePgModel implements TableLikeObject {
|
|
|
326
326
|
grantee: string;
|
|
327
327
|
privilege: string;
|
|
328
328
|
grantable: boolean;
|
|
329
|
+
columns: string[] | null | undefined;
|
|
329
330
|
}[];
|
|
330
331
|
persistence: "u" | "t" | "p";
|
|
331
332
|
row_security: boolean;
|
|
332
333
|
force_row_security: boolean;
|
|
333
|
-
replica_identity: "
|
|
334
|
+
replica_identity: "n" | "i" | "d" | "f";
|
|
334
335
|
parent_schema: string | null;
|
|
335
336
|
parent_name: string | null;
|
|
336
337
|
partition_bound: string | null;
|
|
@@ -397,7 +397,7 @@ select
|
|
|
397
397
|
from (
|
|
398
398
|
-- one row for object ACL + one row per column ACL
|
|
399
399
|
select null::name as attname, t.oid as relacl_oid, (
|
|
400
|
-
select c_rel.relacl from pg_class c_rel where c_rel.oid = t.oid
|
|
400
|
+
select COALESCE(c_rel.relacl, acldefault('r', c_rel.relowner)) from pg_class c_rel where c_rel.oid = t.oid
|
|
401
401
|
) as acl
|
|
402
402
|
union all
|
|
403
403
|
select a2.attname, t.oid as relacl_oid, a2.attacl
|
|
@@ -45,10 +45,8 @@ export class CreateTrigger extends CreateTriggerChange {
|
|
|
45
45
|
// Table dependency
|
|
46
46
|
dependencies.add(stableId.table(this.trigger.schema, this.trigger.table_name));
|
|
47
47
|
// Function dependency
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
// For now, we rely on pg_depend extraction for procedure dependencies.
|
|
51
|
-
// If needed, we could parse the trigger definition to extract the full function signature.
|
|
48
|
+
// Trigger functions always have signature () RETURNS trigger, so no arguments.
|
|
49
|
+
dependencies.add(stableId.procedure(this.trigger.function_schema, this.trigger.function_name));
|
|
52
50
|
// Owner dependency
|
|
53
51
|
dependencies.add(stableId.role(this.trigger.owner));
|
|
54
52
|
return Array.from(dependencies);
|
|
@@ -5,6 +5,13 @@ declare const triggerPropsSchema: z.ZodObject<{
|
|
|
5
5
|
schema: z.ZodString;
|
|
6
6
|
name: z.ZodString;
|
|
7
7
|
table_name: z.ZodString;
|
|
8
|
+
table_relkind: z.ZodEnum<{
|
|
9
|
+
r: "r";
|
|
10
|
+
v: "v";
|
|
11
|
+
m: "m";
|
|
12
|
+
p: "p";
|
|
13
|
+
f: "f";
|
|
14
|
+
}>;
|
|
8
15
|
function_schema: z.ZodString;
|
|
9
16
|
function_name: z.ZodString;
|
|
10
17
|
trigger_type: z.ZodNumber;
|
|
@@ -37,6 +44,7 @@ export declare class Trigger extends BasePgModel {
|
|
|
37
44
|
readonly schema: TriggerProps["schema"];
|
|
38
45
|
readonly name: TriggerProps["name"];
|
|
39
46
|
readonly table_name: TriggerProps["table_name"];
|
|
47
|
+
readonly table_relkind: TriggerProps["table_relkind"];
|
|
40
48
|
readonly function_schema: TriggerProps["function_schema"];
|
|
41
49
|
readonly function_name: TriggerProps["function_name"];
|
|
42
50
|
readonly trigger_type: TriggerProps["trigger_type"];
|
|
@@ -7,10 +7,18 @@ const TriggerEnabledSchema = z.enum([
|
|
|
7
7
|
"R", // REPLICA - trigger fires only in "replica" mode
|
|
8
8
|
"A", // ALWAYS - trigger fires regardless of replication mode
|
|
9
9
|
]);
|
|
10
|
+
const TriggerTableRelkindSchema = z.enum([
|
|
11
|
+
"r", // ordinary table
|
|
12
|
+
"p", // partitioned table
|
|
13
|
+
"f", // foreign table
|
|
14
|
+
"v", // view
|
|
15
|
+
"m", // materialized view
|
|
16
|
+
]);
|
|
10
17
|
const triggerPropsSchema = z.object({
|
|
11
18
|
schema: z.string(),
|
|
12
19
|
name: z.string(),
|
|
13
20
|
table_name: z.string(),
|
|
21
|
+
table_relkind: TriggerTableRelkindSchema,
|
|
14
22
|
function_schema: z.string(),
|
|
15
23
|
function_name: z.string(),
|
|
16
24
|
trigger_type: z.number(),
|
|
@@ -37,6 +45,7 @@ export class Trigger extends BasePgModel {
|
|
|
37
45
|
schema;
|
|
38
46
|
name;
|
|
39
47
|
table_name;
|
|
48
|
+
table_relkind;
|
|
40
49
|
function_schema;
|
|
41
50
|
function_name;
|
|
42
51
|
trigger_type;
|
|
@@ -64,6 +73,7 @@ export class Trigger extends BasePgModel {
|
|
|
64
73
|
this.schema = props.schema;
|
|
65
74
|
this.name = props.name;
|
|
66
75
|
this.table_name = props.table_name;
|
|
76
|
+
this.table_relkind = props.table_relkind;
|
|
67
77
|
// Data fields
|
|
68
78
|
this.function_schema = props.function_schema;
|
|
69
79
|
this.function_name = props.function_name;
|
|
@@ -150,6 +160,7 @@ export async function extractTriggers(pool) {
|
|
|
150
160
|
tc.relnamespace::regnamespace::text as schema,
|
|
151
161
|
quote_ident(t.tgname) as name,
|
|
152
162
|
quote_ident(tc.relname) as table_name,
|
|
163
|
+
tc.relkind as table_relkind,
|
|
153
164
|
|
|
154
165
|
fc.pronamespace::regnamespace::text as function_schema,
|
|
155
166
|
quote_ident(fc.proname) as function_name,
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { Role } from "../../role/role.model.ts";
|
|
1
|
+
import type { ObjectDiffContext } from "../../diff-context.ts";
|
|
3
2
|
import type { CompositeTypeChange } from "./changes/composite-type.types.ts";
|
|
4
3
|
import type { CompositeType } from "./composite-type.model.ts";
|
|
5
4
|
/**
|
|
@@ -10,9 +9,4 @@ import type { CompositeType } from "./composite-type.model.ts";
|
|
|
10
9
|
* @param branch - The composite types in the branch catalog.
|
|
11
10
|
* @returns A list of changes to apply to main to make it match branch.
|
|
12
11
|
*/
|
|
13
|
-
export declare function diffCompositeTypes(ctx:
|
|
14
|
-
version: number;
|
|
15
|
-
currentUser: string;
|
|
16
|
-
defaultPrivilegeState: DefaultPrivilegeState;
|
|
17
|
-
mainRoles: Record<string, Role>;
|
|
18
|
-
}, main: Record<string, CompositeType>, branch: Record<string, CompositeType>): CompositeTypeChange[];
|
|
12
|
+
export declare function diffCompositeTypes(ctx: Pick<ObjectDiffContext, "version" | "currentUser" | "defaultPrivilegeState">, main: Record<string, CompositeType>, branch: Record<string, CompositeType>): CompositeTypeChange[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { diffObjects } from "../../base.diff.js";
|
|
2
|
-
import { diffPrivileges,
|
|
2
|
+
import { diffPrivileges, emitObjectPrivilegeChanges, filterPublicBuiltInDefaults, } from "../../base.privilege-diff.js";
|
|
3
3
|
import { deepEqual, hasNonAlterableChanges } from "../../utils.js";
|
|
4
4
|
import { AlterCompositeTypeAddAttribute, AlterCompositeTypeAlterAttributeType, AlterCompositeTypeChangeOwner, AlterCompositeTypeDropAttribute, } from "./changes/composite-type.alter.js";
|
|
5
5
|
import { CreateCommentOnCompositeType, CreateCommentOnCompositeTypeAttribute, DropCommentOnCompositeType, DropCommentOnCompositeTypeAttribute, } from "./changes/composite-type.comment.js";
|
|
@@ -47,50 +47,21 @@ export function diffCompositeTypes(ctx, main, branch) {
|
|
|
47
47
|
// We compare default privileges against desired privileges to generate REVOKE/GRANT statements
|
|
48
48
|
// needed to reach the final desired state.
|
|
49
49
|
const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(ctx.currentUser, "composite_type", ct.schema ?? "");
|
|
50
|
+
const creatorFilteredDefaults = ct.owner !== ctx.currentUser
|
|
51
|
+
? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
|
|
52
|
+
: effectiveDefaults;
|
|
50
53
|
// Filter out PUBLIC's built-in default USAGE privilege (PostgreSQL grants it automatically)
|
|
51
54
|
// Reference: https://www.postgresql.org/docs/17/ddl-priv.html Table 5.2
|
|
52
55
|
// This prevents generating unnecessary "GRANT USAGE TO PUBLIC" statements
|
|
53
56
|
const desiredPrivileges = filterPublicBuiltInDefaults("composite_type", ct.privileges);
|
|
54
57
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
55
58
|
// and shouldn't be compared. Use the composite type owner as the reference.
|
|
56
|
-
const privilegeResults = diffPrivileges(
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
void grantable;
|
|
63
|
-
changes.push(new GrantCompositeTypePrivileges({
|
|
64
|
-
compositeType: ct,
|
|
65
|
-
grantee,
|
|
66
|
-
privileges: list,
|
|
67
|
-
version: ctx.version,
|
|
68
|
-
}));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// Generate revoke changes
|
|
72
|
-
if (result.revokes.length > 0) {
|
|
73
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
74
|
-
for (const [grantable, list] of revokeGroups) {
|
|
75
|
-
void grantable;
|
|
76
|
-
changes.push(new RevokeCompositeTypePrivileges({
|
|
77
|
-
compositeType: ct,
|
|
78
|
-
grantee,
|
|
79
|
-
privileges: list,
|
|
80
|
-
version: ctx.version,
|
|
81
|
-
}));
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
// Generate revoke grant option changes
|
|
85
|
-
if (result.revokeGrantOption.length > 0) {
|
|
86
|
-
changes.push(new RevokeGrantOptionCompositeTypePrivileges({
|
|
87
|
-
compositeType: ct,
|
|
88
|
-
grantee,
|
|
89
|
-
privilegeNames: result.revokeGrantOption,
|
|
90
|
-
version: ctx.version,
|
|
91
|
-
}));
|
|
92
|
-
}
|
|
93
|
-
}
|
|
59
|
+
const privilegeResults = diffPrivileges(filterPublicBuiltInDefaults("composite_type", creatorFilteredDefaults), desiredPrivileges, ct.owner);
|
|
60
|
+
changes.push(...emitObjectPrivilegeChanges(privilegeResults, ct, ct, "compositeType", {
|
|
61
|
+
Grant: GrantCompositeTypePrivileges,
|
|
62
|
+
Revoke: RevokeCompositeTypePrivileges,
|
|
63
|
+
RevokeGrantOption: RevokeGrantOptionCompositeTypePrivileges,
|
|
64
|
+
}, ctx.version));
|
|
94
65
|
}
|
|
95
66
|
for (const compositeTypeId of dropped) {
|
|
96
67
|
changes.push(new DropCompositeType({ compositeType: main[compositeTypeId] }));
|
|
@@ -203,44 +174,12 @@ export function diffCompositeTypes(ctx, main, branch) {
|
|
|
203
174
|
const branchPrivilegesFiltered = filterPublicBuiltInDefaults("composite_type", branchCompositeType.privileges);
|
|
204
175
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
205
176
|
// and shouldn't be compared. Use branch owner as the reference.
|
|
206
|
-
const privilegeResults = diffPrivileges(mainPrivilegesFiltered, branchPrivilegesFiltered, branchCompositeType.owner
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
void grantable;
|
|
213
|
-
changes.push(new GrantCompositeTypePrivileges({
|
|
214
|
-
compositeType: branchCompositeType,
|
|
215
|
-
grantee,
|
|
216
|
-
privileges: list,
|
|
217
|
-
version: ctx.version,
|
|
218
|
-
}));
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
// Generate revoke changes
|
|
222
|
-
if (result.revokes.length > 0) {
|
|
223
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
224
|
-
for (const [grantable, list] of revokeGroups) {
|
|
225
|
-
void grantable;
|
|
226
|
-
changes.push(new RevokeCompositeTypePrivileges({
|
|
227
|
-
compositeType: mainCompositeType,
|
|
228
|
-
grantee,
|
|
229
|
-
privileges: list,
|
|
230
|
-
version: ctx.version,
|
|
231
|
-
}));
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
// Generate revoke grant option changes
|
|
235
|
-
if (result.revokeGrantOption.length > 0) {
|
|
236
|
-
changes.push(new RevokeGrantOptionCompositeTypePrivileges({
|
|
237
|
-
compositeType: mainCompositeType,
|
|
238
|
-
grantee,
|
|
239
|
-
privilegeNames: result.revokeGrantOption,
|
|
240
|
-
version: ctx.version,
|
|
241
|
-
}));
|
|
242
|
-
}
|
|
243
|
-
}
|
|
177
|
+
const privilegeResults = diffPrivileges(mainPrivilegesFiltered, branchPrivilegesFiltered, branchCompositeType.owner);
|
|
178
|
+
changes.push(...emitObjectPrivilegeChanges(privilegeResults, branchCompositeType, mainCompositeType, "compositeType", {
|
|
179
|
+
Grant: GrantCompositeTypePrivileges,
|
|
180
|
+
Revoke: RevokeCompositeTypePrivileges,
|
|
181
|
+
RevokeGrantOption: RevokeGrantOptionCompositeTypePrivileges,
|
|
182
|
+
}, ctx.version));
|
|
244
183
|
// Note: Composite type renaming would also use ALTER TYPE ... RENAME TO ...
|
|
245
184
|
// But since our CompositeType model uses 'name' as the identity field,
|
|
246
185
|
// a name change would be handled as drop + create by diffObjects()
|