@supabase/pg-delta 1.0.0-alpha.2 → 1.0.0-alpha.4
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 +22 -0
- package/dist/cli/bin/cli.js +0 -0
- package/dist/cli/commands/plan.js +21 -0
- package/dist/cli/utils.d.ts +2 -0
- package/dist/cli/utils.js +1 -1
- package/dist/core/integrations/supabase.js +2 -0
- package/dist/core/objects/table/table.model.d.ts +4 -2
- package/dist/core/objects/table/table.model.js +3 -0
- package/dist/core/objects/trigger/changes/trigger.alter.js +23 -0
- package/dist/core/objects/trigger/changes/trigger.create.js +2 -1
- package/dist/core/objects/trigger/trigger.model.d.ts +1 -0
- package/dist/core/objects/trigger/trigger.model.js +3 -0
- package/dist/core/plan/apply.js +3 -3
- package/dist/core/plan/create.js +34 -15
- package/dist/core/plan/sql-format/constants.d.ts +2 -0
- package/dist/core/plan/sql-format/constants.js +11 -0
- package/dist/core/plan/sql-format/fixtures.d.ts +2 -0
- package/dist/core/plan/sql-format/fixtures.js +2449 -0
- package/dist/core/plan/sql-format/format-utils.d.ts +37 -0
- package/dist/core/plan/sql-format/format-utils.js +274 -0
- package/dist/core/plan/sql-format/formatters.d.ts +20 -0
- package/dist/core/plan/sql-format/formatters.js +737 -0
- package/dist/core/plan/sql-format/index.d.ts +2 -0
- package/dist/core/plan/sql-format/index.js +98 -0
- package/dist/core/plan/sql-format/keyword-case.d.ts +2 -0
- package/dist/core/plan/sql-format/keyword-case.js +868 -0
- package/dist/core/plan/sql-format/protect.d.ts +3 -0
- package/dist/core/plan/sql-format/protect.js +269 -0
- package/dist/core/plan/sql-format/sql-scanner.d.ts +59 -0
- package/dist/core/plan/sql-format/sql-scanner.js +202 -0
- package/dist/core/plan/sql-format/tokenizer.d.ts +22 -0
- package/dist/core/plan/sql-format/tokenizer.js +118 -0
- package/dist/core/plan/sql-format/types.d.ts +28 -0
- package/dist/core/plan/sql-format/types.js +1 -0
- package/dist/core/plan/sql-format/wrap.d.ts +2 -0
- package/dist/core/plan/sql-format/wrap.js +165 -0
- package/dist/core/plan/sql-format.d.ts +2 -0
- package/dist/core/plan/sql-format.js +1 -0
- package/dist/core/plan/statements.d.ts +2 -1
- package/dist/core/plan/statements.js +6 -2
- package/dist/core/postgres-config.d.ts +15 -0
- package/dist/core/postgres-config.js +30 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/package.json +37 -22
- package/src/cli/app.ts +28 -0
- package/src/cli/bin/cli.ts +9 -0
- package/src/cli/commands/apply.ts +101 -0
- package/src/cli/commands/plan.ts +195 -0
- package/src/cli/commands/sync.ts +185 -0
- package/src/cli/formatters/index.ts +5 -0
- package/src/cli/formatters/tree/tree-builder.ts +380 -0
- package/src/cli/formatters/tree/tree-renderer.ts +372 -0
- package/src/cli/formatters/tree/tree.ts +237 -0
- package/src/cli/utils/integrations.ts +42 -0
- package/src/cli/utils.ts +231 -0
- package/src/core/catalog.diff.ts +246 -0
- package/src/core/catalog.model.ts +384 -0
- package/src/core/change.types.ts +44 -0
- package/src/core/context.ts +26 -0
- package/src/core/depend.ts +1870 -0
- package/src/core/expand-replace-dependencies.ts +380 -0
- package/src/core/fingerprint.ts +204 -0
- package/src/core/integrations/filter/dsl.ts +204 -0
- package/src/core/integrations/filter/extractors.ts +145 -0
- package/src/core/integrations/filter/filter.types.ts +3 -0
- package/src/core/integrations/integration-dsl.ts +24 -0
- package/src/core/integrations/integration.types.ts +7 -0
- package/src/core/integrations/serialize/dsl.ts +77 -0
- package/src/core/integrations/serialize/serialize.types.ts +3 -0
- package/src/core/integrations/supabase.ts +121 -0
- package/src/core/objects/aggregate/aggregate.diff.test.ts +215 -0
- package/src/core/objects/aggregate/aggregate.diff.ts +278 -0
- package/src/core/objects/aggregate/aggregate.model.ts +317 -0
- package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +64 -0
- package/src/core/objects/aggregate/changes/aggregate.alter.ts +32 -0
- package/src/core/objects/aggregate/changes/aggregate.base.ts +20 -0
- package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +86 -0
- package/src/core/objects/aggregate/changes/aggregate.comment.ts +62 -0
- package/src/core/objects/aggregate/changes/aggregate.create.test.ts +101 -0
- package/src/core/objects/aggregate/changes/aggregate.create.ts +329 -0
- package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +78 -0
- package/src/core/objects/aggregate/changes/aggregate.drop.ts +32 -0
- package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +130 -0
- package/src/core/objects/aggregate/changes/aggregate.privilege.ts +146 -0
- package/src/core/objects/aggregate/changes/aggregate.types.ts +12 -0
- package/src/core/objects/base.change.ts +62 -0
- package/src/core/objects/base.default-privileges.ts +204 -0
- package/src/core/objects/base.diff.ts +20 -0
- package/src/core/objects/base.model.ts +82 -0
- package/src/core/objects/base.privilege-diff.ts +299 -0
- package/src/core/objects/base.privilege.ts +184 -0
- package/src/core/objects/collation/changes/collation.alter.test.ts +63 -0
- package/src/core/objects/collation/changes/collation.alter.ts +79 -0
- package/src/core/objects/collation/changes/collation.base.ts +20 -0
- package/src/core/objects/collation/changes/collation.comment.ts +68 -0
- package/src/core/objects/collation/changes/collation.create.test.ts +51 -0
- package/src/core/objects/collation/changes/collation.create.ts +106 -0
- package/src/core/objects/collation/changes/collation.drop.test.ts +28 -0
- package/src/core/objects/collation/changes/collation.drop.ts +37 -0
- package/src/core/objects/collation/changes/collation.types.ts +10 -0
- package/src/core/objects/collation/collation.diff.test.ts +100 -0
- package/src/core/objects/collation/collation.diff.ts +126 -0
- package/src/core/objects/collation/collation.model.ts +224 -0
- package/src/core/objects/domain/changes/domain.alter.test.ts +316 -0
- package/src/core/objects/domain/changes/domain.alter.ts +286 -0
- package/src/core/objects/domain/changes/domain.base.ts +20 -0
- package/src/core/objects/domain/changes/domain.comment.ts +59 -0
- package/src/core/objects/domain/changes/domain.create.test.ts +65 -0
- package/src/core/objects/domain/changes/domain.create.ts +118 -0
- package/src/core/objects/domain/changes/domain.drop.test.ts +30 -0
- package/src/core/objects/domain/changes/domain.drop.ts +34 -0
- package/src/core/objects/domain/changes/domain.privilege.ts +171 -0
- package/src/core/objects/domain/changes/domain.types.ts +12 -0
- package/src/core/objects/domain/domain.diff.test.ts +284 -0
- package/src/core/objects/domain/domain.diff.ts +358 -0
- package/src/core/objects/domain/domain.model.ts +190 -0
- package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +50 -0
- package/src/core/objects/event-trigger/changes/event-trigger.alter.ts +82 -0
- package/src/core/objects/event-trigger/changes/event-trigger.base.ts +20 -0
- package/src/core/objects/event-trigger/changes/event-trigger.comment.ts +66 -0
- package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +24 -0
- package/src/core/objects/event-trigger/changes/event-trigger.create.ts +72 -0
- package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +22 -0
- package/src/core/objects/event-trigger/changes/event-trigger.drop.ts +34 -0
- package/src/core/objects/event-trigger/changes/event-trigger.types.ts +10 -0
- package/src/core/objects/event-trigger/event-trigger.diff.test.ts +126 -0
- package/src/core/objects/event-trigger/event-trigger.diff.ts +126 -0
- package/src/core/objects/event-trigger/event-trigger.model.ts +106 -0
- package/src/core/objects/extension/changes/extension.alter.test.ts +58 -0
- package/src/core/objects/extension/changes/extension.alter.ts +78 -0
- package/src/core/objects/extension/changes/extension.base.ts +20 -0
- package/src/core/objects/extension/changes/extension.comment.ts +64 -0
- package/src/core/objects/extension/changes/extension.create.test.ts +25 -0
- package/src/core/objects/extension/changes/extension.create.ts +63 -0
- package/src/core/objects/extension/changes/extension.drop.test.ts +23 -0
- package/src/core/objects/extension/changes/extension.drop.ts +34 -0
- package/src/core/objects/extension/changes/extension.types.ts +10 -0
- package/src/core/objects/extension/extension.diff.test.ts +42 -0
- package/src/core/objects/extension/extension.diff.ts +90 -0
- package/src/core/objects/extension/extension.model.ts +280 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +125 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.ts +101 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.base.ts +20 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.comment.ts +72 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +125 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.ts +95 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +23 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.ts +36 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.privilege.ts +172 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.types.ts +12 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +179 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +341 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +149 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper.types.ts +10 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +309 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.ts +341 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +20 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.comment.ts +72 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +201 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.ts +81 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +43 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.ts +37 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.privilege.ts +181 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +12 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.test.ts +813 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +406 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +242 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +168 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.ts +126 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.base.ts +20 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.comment.ts +60 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +131 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.create.ts +81 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +24 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.ts +34 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.privilege.ts +164 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.types.ts +12 -0
- package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +167 -0
- package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +317 -0
- package/src/core/objects/foreign-data-wrapper/server/server.model.ts +133 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +82 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.ts +69 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.base.ts +20 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +85 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.ts +66 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +53 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.ts +40 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.types.ts +8 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.test.ts +77 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.ts +107 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.model.ts +96 -0
- package/src/core/objects/index/changes/index.alter.test.ts +200 -0
- package/src/core/objects/index/changes/index.alter.ts +144 -0
- package/src/core/objects/index/changes/index.base.ts +20 -0
- package/src/core/objects/index/changes/index.comment.ts +63 -0
- package/src/core/objects/index/changes/index.create.test.ts +66 -0
- package/src/core/objects/index/changes/index.create.ts +68 -0
- package/src/core/objects/index/changes/index.drop.test.ts +44 -0
- package/src/core/objects/index/changes/index.drop.ts +34 -0
- package/src/core/objects/index/changes/index.types.ts +6 -0
- package/src/core/objects/index/changes/utils.ts +16 -0
- package/src/core/objects/index/index.diff.test.ts +153 -0
- package/src/core/objects/index/index.diff.ts +243 -0
- package/src/core/objects/index/index.model.ts +370 -0
- package/src/core/objects/language/changes/language.alter.test.ts +33 -0
- package/src/core/objects/language/changes/language.alter.ts +53 -0
- package/src/core/objects/language/changes/language.base.ts +20 -0
- package/src/core/objects/language/changes/language.comment.ts +58 -0
- package/src/core/objects/language/changes/language.create.test.ts +27 -0
- package/src/core/objects/language/changes/language.create.ts +104 -0
- package/src/core/objects/language/changes/language.drop.test.ts +25 -0
- package/src/core/objects/language/changes/language.drop.ts +39 -0
- package/src/core/objects/language/changes/language.privilege.ts +172 -0
- package/src/core/objects/language/changes/language.types.ts +12 -0
- package/src/core/objects/language/language.diff.test.ts +53 -0
- package/src/core/objects/language/language.diff.ts +176 -0
- package/src/core/objects/language/language.model.ts +150 -0
- package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +123 -0
- package/src/core/objects/materialized-view/changes/materialized-view.alter.ts +113 -0
- package/src/core/objects/materialized-view/changes/materialized-view.base.ts +20 -0
- package/src/core/objects/materialized-view/changes/materialized-view.comment.ts +176 -0
- package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +64 -0
- package/src/core/objects/materialized-view/changes/materialized-view.create.ts +93 -0
- package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +34 -0
- package/src/core/objects/materialized-view/changes/materialized-view.drop.ts +60 -0
- package/src/core/objects/materialized-view/changes/materialized-view.privilege.ts +212 -0
- package/src/core/objects/materialized-view/changes/materialized-view.types.ts +12 -0
- package/src/core/objects/materialized-view/materialized-view.diff.test.ts +102 -0
- package/src/core/objects/materialized-view/materialized-view.diff.ts +451 -0
- package/src/core/objects/materialized-view/materialized-view.model.ts +258 -0
- package/src/core/objects/procedure/changes/procedure.alter.test.ts +1005 -0
- package/src/core/objects/procedure/changes/procedure.alter.ts +287 -0
- package/src/core/objects/procedure/changes/procedure.base.ts +20 -0
- package/src/core/objects/procedure/changes/procedure.comment.ts +70 -0
- package/src/core/objects/procedure/changes/procedure.create.test.ts +48 -0
- package/src/core/objects/procedure/changes/procedure.create.ts +92 -0
- package/src/core/objects/procedure/changes/procedure.drop.test.ts +85 -0
- package/src/core/objects/procedure/changes/procedure.drop.ts +49 -0
- package/src/core/objects/procedure/changes/procedure.privilege.ts +188 -0
- package/src/core/objects/procedure/changes/procedure.types.ts +12 -0
- package/src/core/objects/procedure/procedure.diff.test.ts +161 -0
- package/src/core/objects/procedure/procedure.diff.ts +404 -0
- package/src/core/objects/procedure/procedure.model.ts +264 -0
- package/src/core/objects/procedure/utils.ts +58 -0
- package/src/core/objects/publication/changes/publication.alter.test.ts +223 -0
- package/src/core/objects/publication/changes/publication.alter.ts +243 -0
- package/src/core/objects/publication/changes/publication.base.ts +20 -0
- package/src/core/objects/publication/changes/publication.comment.test.ts +70 -0
- package/src/core/objects/publication/changes/publication.comment.ts +64 -0
- package/src/core/objects/publication/changes/publication.create.test.ts +87 -0
- package/src/core/objects/publication/changes/publication.create.ts +82 -0
- package/src/core/objects/publication/changes/publication.drop.test.ts +46 -0
- package/src/core/objects/publication/changes/publication.drop.ts +29 -0
- package/src/core/objects/publication/changes/publication.types.ts +26 -0
- package/src/core/objects/publication/publication.diff.test.ts +292 -0
- package/src/core/objects/publication/publication.diff.ts +253 -0
- package/src/core/objects/publication/publication.model.ts +206 -0
- package/src/core/objects/publication/utils.ts +55 -0
- package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +250 -0
- package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +128 -0
- package/src/core/objects/rls-policy/changes/rls-policy.base.ts +20 -0
- package/src/core/objects/rls-policy/changes/rls-policy.comment.ts +69 -0
- package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +74 -0
- package/src/core/objects/rls-policy/changes/rls-policy.create.ts +100 -0
- package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +28 -0
- package/src/core/objects/rls-policy/changes/rls-policy.drop.ts +39 -0
- package/src/core/objects/rls-policy/changes/rls-policy.types.ts +10 -0
- package/src/core/objects/rls-policy/rls-policy.diff.test.ts +79 -0
- package/src/core/objects/rls-policy/rls-policy.diff.ts +121 -0
- package/src/core/objects/rls-policy/rls-policy.model.ts +140 -0
- package/src/core/objects/role/changes/role.alter.test.ts +346 -0
- package/src/core/objects/role/changes/role.alter.ts +110 -0
- package/src/core/objects/role/changes/role.base.ts +24 -0
- package/src/core/objects/role/changes/role.comment.ts +55 -0
- package/src/core/objects/role/changes/role.create.test.ts +52 -0
- package/src/core/objects/role/changes/role.create.ts +102 -0
- package/src/core/objects/role/changes/role.drop.test.ts +29 -0
- package/src/core/objects/role/changes/role.drop.ts +34 -0
- package/src/core/objects/role/changes/role.privilege.ts +376 -0
- package/src/core/objects/role/changes/role.types.ts +12 -0
- package/src/core/objects/role/role.diff.test.ts +44 -0
- package/src/core/objects/role/role.diff.ts +479 -0
- package/src/core/objects/role/role.model.ts +344 -0
- package/src/core/objects/rule/changes/rule.alter.test.ts +78 -0
- package/src/core/objects/rule/changes/rule.alter.ts +72 -0
- package/src/core/objects/rule/changes/rule.base.ts +20 -0
- package/src/core/objects/rule/changes/rule.comment.test.ts +55 -0
- package/src/core/objects/rule/changes/rule.comment.ts +62 -0
- package/src/core/objects/rule/changes/rule.create.test.ts +59 -0
- package/src/core/objects/rule/changes/rule.create.ts +42 -0
- package/src/core/objects/rule/changes/rule.drop.test.ts +38 -0
- package/src/core/objects/rule/changes/rule.drop.ts +29 -0
- package/src/core/objects/rule/changes/rule.types.ts +12 -0
- package/src/core/objects/rule/rule.diff.test.ts +132 -0
- package/src/core/objects/rule/rule.diff.ts +79 -0
- package/src/core/objects/rule/rule.model.ts +173 -0
- package/src/core/objects/schema/changes/schema.alter.test.ts +28 -0
- package/src/core/objects/schema/changes/schema.alter.ts +45 -0
- package/src/core/objects/schema/changes/schema.base.ts +20 -0
- package/src/core/objects/schema/changes/schema.comment.ts +56 -0
- package/src/core/objects/schema/changes/schema.create.test.ts +22 -0
- package/src/core/objects/schema/changes/schema.create.ts +47 -0
- package/src/core/objects/schema/changes/schema.drop.test.ts +20 -0
- package/src/core/objects/schema/changes/schema.drop.ts +34 -0
- package/src/core/objects/schema/changes/schema.privilege.ts +175 -0
- package/src/core/objects/schema/changes/schema.types.ts +12 -0
- package/src/core/objects/schema/schema.diff.test.ts +42 -0
- package/src/core/objects/schema/schema.diff.ts +209 -0
- package/src/core/objects/schema/schema.model.ts +107 -0
- package/src/core/objects/sequence/changes/sequence.alter.test.ts +151 -0
- package/src/core/objects/sequence/changes/sequence.alter.ts +115 -0
- package/src/core/objects/sequence/changes/sequence.base.ts +20 -0
- package/src/core/objects/sequence/changes/sequence.comment.ts +60 -0
- package/src/core/objects/sequence/changes/sequence.create.test.ts +84 -0
- package/src/core/objects/sequence/changes/sequence.create.ts +111 -0
- package/src/core/objects/sequence/changes/sequence.drop.test.ts +32 -0
- package/src/core/objects/sequence/changes/sequence.drop.ts +37 -0
- package/src/core/objects/sequence/changes/sequence.privilege.ts +179 -0
- package/src/core/objects/sequence/changes/sequence.types.ts +12 -0
- package/src/core/objects/sequence/sequence.diff.test.ts +141 -0
- package/src/core/objects/sequence/sequence.diff.ts +359 -0
- package/src/core/objects/sequence/sequence.model.ts +185 -0
- package/src/core/objects/subscription/changes/subscription.alter.test.ts +124 -0
- package/src/core/objects/subscription/changes/subscription.alter.ts +110 -0
- package/src/core/objects/subscription/changes/subscription.base.ts +20 -0
- package/src/core/objects/subscription/changes/subscription.comment.test.ts +67 -0
- package/src/core/objects/subscription/changes/subscription.comment.ts +64 -0
- package/src/core/objects/subscription/changes/subscription.create.test.ts +77 -0
- package/src/core/objects/subscription/changes/subscription.create.ts +69 -0
- package/src/core/objects/subscription/changes/subscription.drop.test.ts +46 -0
- package/src/core/objects/subscription/changes/subscription.drop.ts +20 -0
- package/src/core/objects/subscription/changes/subscription.types.ts +22 -0
- package/src/core/objects/subscription/subscription.diff.test.ts +232 -0
- package/src/core/objects/subscription/subscription.diff.ts +241 -0
- package/src/core/objects/subscription/subscription.model.ts +190 -0
- package/src/core/objects/subscription/utils.ts +156 -0
- package/src/core/objects/table/changes/table.alter.test.ts +823 -0
- package/src/core/objects/table/changes/table.alter.ts +806 -0
- package/src/core/objects/table/changes/table.base.ts +20 -0
- package/src/core/objects/table/changes/table.comment.ts +266 -0
- package/src/core/objects/table/changes/table.create.test.ts +150 -0
- package/src/core/objects/table/changes/table.create.ts +188 -0
- package/src/core/objects/table/changes/table.drop.test.ts +34 -0
- package/src/core/objects/table/changes/table.drop.ts +45 -0
- package/src/core/objects/table/changes/table.privilege.ts +200 -0
- package/src/core/objects/table/changes/table.types.ts +12 -0
- package/src/core/objects/table/table.diff.test.ts +711 -0
- package/src/core/objects/table/table.diff.ts +953 -0
- package/src/core/objects/table/table.model.ts +460 -0
- package/src/core/objects/trigger/changes/trigger.alter.test.ts +46 -0
- package/src/core/objects/trigger/changes/trigger.alter.ts +76 -0
- package/src/core/objects/trigger/changes/trigger.base.ts +20 -0
- package/src/core/objects/trigger/changes/trigger.comment.ts +64 -0
- package/src/core/objects/trigger/changes/trigger.create.test.ts +43 -0
- package/src/core/objects/trigger/changes/trigger.create.ts +85 -0
- package/src/core/objects/trigger/changes/trigger.drop.test.ts +43 -0
- package/src/core/objects/trigger/changes/trigger.drop.ts +39 -0
- package/src/core/objects/trigger/changes/trigger.types.ts +10 -0
- package/src/core/objects/trigger/trigger.diff.test.ts +83 -0
- package/src/core/objects/trigger/trigger.diff.ts +116 -0
- package/src/core/objects/trigger/trigger.model.ts +252 -0
- package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +202 -0
- package/src/core/objects/type/composite-type/changes/composite-type.alter.ts +174 -0
- package/src/core/objects/type/composite-type/changes/composite-type.base.ts +20 -0
- package/src/core/objects/type/composite-type/changes/composite-type.comment.ts +145 -0
- package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +101 -0
- package/src/core/objects/type/composite-type/changes/composite-type.create.ts +95 -0
- package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +33 -0
- package/src/core/objects/type/composite-type/changes/composite-type.drop.ts +37 -0
- package/src/core/objects/type/composite-type/changes/composite-type.privilege.ts +175 -0
- package/src/core/objects/type/composite-type/changes/composite-type.types.ts +12 -0
- package/src/core/objects/type/composite-type/composite-type.diff.test.ts +191 -0
- package/src/core/objects/type/composite-type/composite-type.diff.ts +372 -0
- package/src/core/objects/type/composite-type/composite-type.model.ts +252 -0
- package/src/core/objects/type/enum/changes/enum.alter.test.ts +104 -0
- package/src/core/objects/type/enum/changes/enum.alter.ts +91 -0
- package/src/core/objects/type/enum/changes/enum.base.ts +20 -0
- package/src/core/objects/type/enum/changes/enum.comment.ts +64 -0
- package/src/core/objects/type/enum/changes/enum.create.test.ts +28 -0
- package/src/core/objects/type/enum/changes/enum.create.ts +56 -0
- package/src/core/objects/type/enum/changes/enum.drop.test.ts +25 -0
- package/src/core/objects/type/enum/changes/enum.drop.ts +34 -0
- package/src/core/objects/type/enum/changes/enum.privilege.ts +175 -0
- package/src/core/objects/type/enum/changes/enum.types.ts +12 -0
- package/src/core/objects/type/enum/enum.diff.test.ts +191 -0
- package/src/core/objects/type/enum/enum.diff.ts +396 -0
- package/src/core/objects/type/enum/enum.model.ts +194 -0
- package/src/core/objects/type/range/changes/range.alter.test.ts +27 -0
- package/src/core/objects/type/range/changes/range.alter.ts +51 -0
- package/src/core/objects/type/range/changes/range.base.ts +20 -0
- package/src/core/objects/type/range/changes/range.comment.ts +64 -0
- package/src/core/objects/type/range/changes/range.create.test.ts +51 -0
- package/src/core/objects/type/range/changes/range.create.ts +151 -0
- package/src/core/objects/type/range/changes/range.drop.test.ts +26 -0
- package/src/core/objects/type/range/changes/range.drop.ts +34 -0
- package/src/core/objects/type/range/changes/range.privilege.ts +175 -0
- package/src/core/objects/type/range/changes/range.types.ts +12 -0
- package/src/core/objects/type/range/range.diff.test.ts +70 -0
- package/src/core/objects/type/range/range.diff.ts +259 -0
- package/src/core/objects/type/range/range.model.ts +187 -0
- package/src/core/objects/type/type.types.ts +5 -0
- package/src/core/objects/utils.ts +171 -0
- package/src/core/objects/view/changes/view.alter.test.ts +110 -0
- package/src/core/objects/view/changes/view.alter.ts +112 -0
- package/src/core/objects/view/changes/view.base.ts +20 -0
- package/src/core/objects/view/changes/view.comment.ts +59 -0
- package/src/core/objects/view/changes/view.create.test.ts +65 -0
- package/src/core/objects/view/changes/view.create.ts +73 -0
- package/src/core/objects/view/changes/view.drop.test.ts +34 -0
- package/src/core/objects/view/changes/view.drop.ts +40 -0
- package/src/core/objects/view/changes/view.privilege.ts +200 -0
- package/src/core/objects/view/changes/view.types.ts +12 -0
- package/src/core/objects/view/view.diff.test.ts +91 -0
- package/src/core/objects/view/view.diff.ts +365 -0
- package/src/core/objects/view/view.model.ts +276 -0
- package/src/core/plan/apply.ts +190 -0
- package/src/core/plan/create.ts +432 -0
- package/src/core/plan/hierarchy.ts +574 -0
- package/src/core/plan/index.ts +29 -0
- package/src/core/plan/io.ts +20 -0
- package/src/core/plan/risk.ts +48 -0
- package/src/core/plan/serialize.ts +195 -0
- package/src/core/plan/sql-format/constants.ts +13 -0
- package/src/core/plan/sql-format/fixtures.ts +2806 -0
- package/src/core/plan/sql-format/format-comment-literals.test.ts +96 -0
- package/src/core/plan/sql-format/format-functions.test.ts +127 -0
- package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +67 -0
- package/src/core/plan/sql-format/format-off.test.ts +809 -0
- package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +1056 -0
- package/src/core/plan/sql-format/format-pretty-narrow.test.ts +1283 -0
- package/src/core/plan/sql-format/format-pretty-preserve.test.ts +1052 -0
- package/src/core/plan/sql-format/format-pretty-upper.test.ts +1045 -0
- package/src/core/plan/sql-format/format-stress.test.ts +616 -0
- package/src/core/plan/sql-format/format-utils.test.ts +91 -0
- package/src/core/plan/sql-format/format-utils.ts +391 -0
- package/src/core/plan/sql-format/formatters.ts +921 -0
- package/src/core/plan/sql-format/index.ts +149 -0
- package/src/core/plan/sql-format/keyword-case.test.ts +118 -0
- package/src/core/plan/sql-format/keyword-case.ts +1085 -0
- package/src/core/plan/sql-format/protect.test.ts +127 -0
- package/src/core/plan/sql-format/protect.ts +337 -0
- package/src/core/plan/sql-format/sql-scanner.test.ts +240 -0
- package/src/core/plan/sql-format/sql-scanner.ts +252 -0
- package/src/core/plan/sql-format/tokenizer.test.ts +68 -0
- package/src/core/plan/sql-format/tokenizer.ts +152 -0
- package/src/core/plan/sql-format/types.ts +31 -0
- package/src/core/plan/sql-format/wrap.test.ts +119 -0
- package/src/core/plan/sql-format/wrap.ts +196 -0
- package/src/core/plan/sql-format.ts +2 -0
- package/src/core/plan/statements.ts +22 -0
- package/src/core/plan/types.ts +165 -0
- package/src/core/postgres-config.ts +169 -0
- package/src/core/sort/custom-constraints.ts +161 -0
- package/src/core/sort/debug-visualization.ts +239 -0
- package/src/core/sort/dependency-filter.ts +224 -0
- package/src/core/sort/graph-builder.ts +223 -0
- package/src/core/sort/graph-utils.ts +51 -0
- package/src/core/sort/logical-sort.ts +590 -0
- package/src/core/sort/sort-changes.ts +234 -0
- package/src/core/sort/topological-sort.ts +184 -0
- package/src/core/sort/types.ts +112 -0
- package/src/core/sort/utils.ts +69 -0
- package/src/index.ts +14 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import type { DefaultPrivilegeState } from "../../base.default-privileges.ts";
|
|
2
|
+
import { diffObjects } from "../../base.diff.ts";
|
|
3
|
+
import {
|
|
4
|
+
diffPrivileges,
|
|
5
|
+
filterPublicBuiltInDefaults,
|
|
6
|
+
groupPrivilegesByGrantable,
|
|
7
|
+
} from "../../base.privilege-diff.ts";
|
|
8
|
+
import type { Role } from "../../role/role.model.ts";
|
|
9
|
+
import { deepEqual, hasNonAlterableChanges } from "../../utils.ts";
|
|
10
|
+
import {
|
|
11
|
+
AlterCompositeTypeAddAttribute,
|
|
12
|
+
AlterCompositeTypeAlterAttributeType,
|
|
13
|
+
AlterCompositeTypeChangeOwner,
|
|
14
|
+
AlterCompositeTypeDropAttribute,
|
|
15
|
+
} from "./changes/composite-type.alter.ts";
|
|
16
|
+
import {
|
|
17
|
+
CreateCommentOnCompositeType,
|
|
18
|
+
CreateCommentOnCompositeTypeAttribute,
|
|
19
|
+
DropCommentOnCompositeType,
|
|
20
|
+
DropCommentOnCompositeTypeAttribute,
|
|
21
|
+
} from "./changes/composite-type.comment.ts";
|
|
22
|
+
import { CreateCompositeType } from "./changes/composite-type.create.ts";
|
|
23
|
+
import { DropCompositeType } from "./changes/composite-type.drop.ts";
|
|
24
|
+
import {
|
|
25
|
+
GrantCompositeTypePrivileges,
|
|
26
|
+
RevokeCompositeTypePrivileges,
|
|
27
|
+
RevokeGrantOptionCompositeTypePrivileges,
|
|
28
|
+
} from "./changes/composite-type.privilege.ts";
|
|
29
|
+
import type { CompositeTypeChange } from "./changes/composite-type.types.ts";
|
|
30
|
+
import type { CompositeType } from "./composite-type.model.ts";
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Diff two sets of composite types from main and branch catalogs.
|
|
34
|
+
*
|
|
35
|
+
* @param ctx - Context containing version, currentUser, and defaultPrivilegeState
|
|
36
|
+
* @param main - The composite types in the main catalog.
|
|
37
|
+
* @param branch - The composite types in the branch catalog.
|
|
38
|
+
* @returns A list of changes to apply to main to make it match branch.
|
|
39
|
+
*/
|
|
40
|
+
export function diffCompositeTypes(
|
|
41
|
+
ctx: {
|
|
42
|
+
version: number;
|
|
43
|
+
currentUser: string;
|
|
44
|
+
defaultPrivilegeState: DefaultPrivilegeState;
|
|
45
|
+
mainRoles: Record<string, Role>;
|
|
46
|
+
},
|
|
47
|
+
main: Record<string, CompositeType>,
|
|
48
|
+
branch: Record<string, CompositeType>,
|
|
49
|
+
): CompositeTypeChange[] {
|
|
50
|
+
const { created, dropped, altered } = diffObjects(main, branch);
|
|
51
|
+
|
|
52
|
+
const changes: CompositeTypeChange[] = [];
|
|
53
|
+
|
|
54
|
+
for (const compositeTypeId of created) {
|
|
55
|
+
const ct = branch[compositeTypeId];
|
|
56
|
+
changes.push(new CreateCompositeType({ compositeType: ct }));
|
|
57
|
+
|
|
58
|
+
// OWNER: If the composite type should be owned by someone other than the current user,
|
|
59
|
+
// emit ALTER TYPE ... OWNER TO after creation
|
|
60
|
+
if (ct.owner !== ctx.currentUser) {
|
|
61
|
+
changes.push(
|
|
62
|
+
new AlterCompositeTypeChangeOwner({
|
|
63
|
+
compositeType: ct,
|
|
64
|
+
owner: ct.owner,
|
|
65
|
+
}),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Type comment on creation
|
|
70
|
+
if (ct.comment !== null) {
|
|
71
|
+
changes.push(new CreateCommentOnCompositeType({ compositeType: ct }));
|
|
72
|
+
}
|
|
73
|
+
// Attribute comments on creation
|
|
74
|
+
for (const attr of ct.columns) {
|
|
75
|
+
if (attr.comment !== null) {
|
|
76
|
+
changes.push(
|
|
77
|
+
new CreateCommentOnCompositeTypeAttribute({
|
|
78
|
+
compositeType: ct,
|
|
79
|
+
attribute: attr,
|
|
80
|
+
}),
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// PRIVILEGES: For created objects, compare against default privileges state
|
|
86
|
+
// The migration script will run ALTER DEFAULT PRIVILEGES before CREATE (via constraint spec),
|
|
87
|
+
// so objects are created with the default privileges state in effect.
|
|
88
|
+
// We compare default privileges against desired privileges to generate REVOKE/GRANT statements
|
|
89
|
+
// needed to reach the final desired state.
|
|
90
|
+
const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(
|
|
91
|
+
ctx.currentUser,
|
|
92
|
+
"composite_type",
|
|
93
|
+
ct.schema ?? "",
|
|
94
|
+
);
|
|
95
|
+
// Filter out PUBLIC's built-in default USAGE privilege (PostgreSQL grants it automatically)
|
|
96
|
+
// Reference: https://www.postgresql.org/docs/17/ddl-priv.html Table 5.2
|
|
97
|
+
// This prevents generating unnecessary "GRANT USAGE TO PUBLIC" statements
|
|
98
|
+
const desiredPrivileges = filterPublicBuiltInDefaults(
|
|
99
|
+
"composite_type",
|
|
100
|
+
ct.privileges,
|
|
101
|
+
);
|
|
102
|
+
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
103
|
+
// and shouldn't be compared. Use the composite type owner as the reference.
|
|
104
|
+
const privilegeResults = diffPrivileges(
|
|
105
|
+
effectiveDefaults,
|
|
106
|
+
desiredPrivileges,
|
|
107
|
+
ct.owner,
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// Generate grant changes
|
|
111
|
+
for (const [grantee, result] of privilegeResults) {
|
|
112
|
+
if (result.grants.length > 0) {
|
|
113
|
+
const grantGroups = groupPrivilegesByGrantable(result.grants);
|
|
114
|
+
for (const [grantable, list] of grantGroups) {
|
|
115
|
+
void grantable;
|
|
116
|
+
changes.push(
|
|
117
|
+
new GrantCompositeTypePrivileges({
|
|
118
|
+
compositeType: ct,
|
|
119
|
+
grantee,
|
|
120
|
+
privileges: list,
|
|
121
|
+
version: ctx.version,
|
|
122
|
+
}),
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Generate revoke changes
|
|
128
|
+
if (result.revokes.length > 0) {
|
|
129
|
+
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
130
|
+
for (const [grantable, list] of revokeGroups) {
|
|
131
|
+
void grantable;
|
|
132
|
+
changes.push(
|
|
133
|
+
new RevokeCompositeTypePrivileges({
|
|
134
|
+
compositeType: ct,
|
|
135
|
+
grantee,
|
|
136
|
+
privileges: list,
|
|
137
|
+
version: ctx.version,
|
|
138
|
+
}),
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Generate revoke grant option changes
|
|
144
|
+
if (result.revokeGrantOption.length > 0) {
|
|
145
|
+
changes.push(
|
|
146
|
+
new RevokeGrantOptionCompositeTypePrivileges({
|
|
147
|
+
compositeType: ct,
|
|
148
|
+
grantee,
|
|
149
|
+
privilegeNames: result.revokeGrantOption,
|
|
150
|
+
version: ctx.version,
|
|
151
|
+
}),
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
for (const compositeTypeId of dropped) {
|
|
158
|
+
changes.push(
|
|
159
|
+
new DropCompositeType({ compositeType: main[compositeTypeId] }),
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
for (const compositeTypeId of altered) {
|
|
164
|
+
const mainCompositeType = main[compositeTypeId];
|
|
165
|
+
const branchCompositeType = branch[compositeTypeId];
|
|
166
|
+
|
|
167
|
+
// Check if non-alterable properties have changed
|
|
168
|
+
// These require dropping and recreating the composite type
|
|
169
|
+
const NON_ALTERABLE_FIELDS: Array<keyof CompositeType> = [
|
|
170
|
+
"row_security",
|
|
171
|
+
"force_row_security",
|
|
172
|
+
"has_indexes",
|
|
173
|
+
"has_rules",
|
|
174
|
+
"has_triggers",
|
|
175
|
+
"has_subclasses",
|
|
176
|
+
"is_populated",
|
|
177
|
+
"replica_identity",
|
|
178
|
+
"is_partition",
|
|
179
|
+
"options",
|
|
180
|
+
"partition_bound",
|
|
181
|
+
];
|
|
182
|
+
const nonAlterablePropsChanged = hasNonAlterableChanges(
|
|
183
|
+
mainCompositeType,
|
|
184
|
+
branchCompositeType,
|
|
185
|
+
NON_ALTERABLE_FIELDS,
|
|
186
|
+
{ options: deepEqual },
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
if (nonAlterablePropsChanged) {
|
|
190
|
+
// Replacement is not performed automatically for composite types
|
|
191
|
+
// to avoid destructive operations; keep changes minimal.
|
|
192
|
+
} else {
|
|
193
|
+
// Only alterable properties changed - check each one
|
|
194
|
+
|
|
195
|
+
// OWNER
|
|
196
|
+
if (mainCompositeType.owner !== branchCompositeType.owner) {
|
|
197
|
+
changes.push(
|
|
198
|
+
new AlterCompositeTypeChangeOwner({
|
|
199
|
+
compositeType: mainCompositeType,
|
|
200
|
+
owner: branchCompositeType.owner,
|
|
201
|
+
}),
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// TYPE COMMENT (create/drop when comment changes)
|
|
206
|
+
if (mainCompositeType.comment !== branchCompositeType.comment) {
|
|
207
|
+
if (branchCompositeType.comment === null) {
|
|
208
|
+
changes.push(
|
|
209
|
+
new DropCommentOnCompositeType({
|
|
210
|
+
compositeType: mainCompositeType,
|
|
211
|
+
}),
|
|
212
|
+
);
|
|
213
|
+
} else {
|
|
214
|
+
changes.push(
|
|
215
|
+
new CreateCommentOnCompositeType({
|
|
216
|
+
compositeType: branchCompositeType,
|
|
217
|
+
}),
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// ATTRIBUTE diffs
|
|
223
|
+
const mainAttrs = new Map(
|
|
224
|
+
mainCompositeType.columns.map((c) => [c.name, c]),
|
|
225
|
+
);
|
|
226
|
+
const branchAttrs = new Map(
|
|
227
|
+
branchCompositeType.columns.map((c) => [c.name, c]),
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
// Added attributes
|
|
231
|
+
for (const [name, attr] of branchAttrs) {
|
|
232
|
+
if (!mainAttrs.has(name)) {
|
|
233
|
+
changes.push(
|
|
234
|
+
new AlterCompositeTypeAddAttribute({
|
|
235
|
+
compositeType: branchCompositeType,
|
|
236
|
+
attribute: attr,
|
|
237
|
+
}),
|
|
238
|
+
);
|
|
239
|
+
if (attr.comment !== null) {
|
|
240
|
+
changes.push(
|
|
241
|
+
new CreateCommentOnCompositeTypeAttribute({
|
|
242
|
+
compositeType: branchCompositeType,
|
|
243
|
+
attribute: attr,
|
|
244
|
+
}),
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Dropped attributes
|
|
251
|
+
for (const [name, attr] of mainAttrs) {
|
|
252
|
+
if (!branchAttrs.has(name)) {
|
|
253
|
+
changes.push(
|
|
254
|
+
new AlterCompositeTypeDropAttribute({
|
|
255
|
+
compositeType: mainCompositeType,
|
|
256
|
+
attribute: attr,
|
|
257
|
+
}),
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Altered attribute type/collation
|
|
263
|
+
for (const [name, mainAttr] of mainAttrs) {
|
|
264
|
+
const branchAttr = branchAttrs.get(name);
|
|
265
|
+
if (!branchAttr) continue;
|
|
266
|
+
if (
|
|
267
|
+
mainAttr.data_type_str !== branchAttr.data_type_str ||
|
|
268
|
+
mainAttr.collation !== branchAttr.collation
|
|
269
|
+
) {
|
|
270
|
+
changes.push(
|
|
271
|
+
new AlterCompositeTypeAlterAttributeType({
|
|
272
|
+
compositeType: branchCompositeType,
|
|
273
|
+
attribute: branchAttr,
|
|
274
|
+
}),
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// COMMENT change on attribute
|
|
279
|
+
if (mainAttr.comment !== branchAttr.comment) {
|
|
280
|
+
if (branchAttr.comment === null) {
|
|
281
|
+
changes.push(
|
|
282
|
+
new DropCommentOnCompositeTypeAttribute({
|
|
283
|
+
compositeType: mainCompositeType,
|
|
284
|
+
attribute: mainAttr,
|
|
285
|
+
}),
|
|
286
|
+
);
|
|
287
|
+
} else {
|
|
288
|
+
changes.push(
|
|
289
|
+
new CreateCommentOnCompositeTypeAttribute({
|
|
290
|
+
compositeType: branchCompositeType,
|
|
291
|
+
attribute: branchAttr,
|
|
292
|
+
}),
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// PRIVILEGES
|
|
299
|
+
// Filter out PUBLIC's built-in default USAGE privilege from main catalog
|
|
300
|
+
// (PostgreSQL grants it automatically, so we shouldn't compare it)
|
|
301
|
+
const mainPrivilegesFiltered = filterPublicBuiltInDefaults(
|
|
302
|
+
"composite_type",
|
|
303
|
+
mainCompositeType.privileges,
|
|
304
|
+
);
|
|
305
|
+
// Filter out PUBLIC's built-in default USAGE privilege from branch catalog
|
|
306
|
+
const branchPrivilegesFiltered = filterPublicBuiltInDefaults(
|
|
307
|
+
"composite_type",
|
|
308
|
+
branchCompositeType.privileges,
|
|
309
|
+
);
|
|
310
|
+
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
311
|
+
// and shouldn't be compared. Use branch owner as the reference.
|
|
312
|
+
const privilegeResults = diffPrivileges(
|
|
313
|
+
mainPrivilegesFiltered,
|
|
314
|
+
branchPrivilegesFiltered,
|
|
315
|
+
branchCompositeType.owner,
|
|
316
|
+
ctx.mainRoles,
|
|
317
|
+
);
|
|
318
|
+
|
|
319
|
+
for (const [grantee, result] of privilegeResults) {
|
|
320
|
+
// Generate grant changes
|
|
321
|
+
if (result.grants.length > 0) {
|
|
322
|
+
const grantGroups = groupPrivilegesByGrantable(result.grants);
|
|
323
|
+
for (const [grantable, list] of grantGroups) {
|
|
324
|
+
void grantable;
|
|
325
|
+
changes.push(
|
|
326
|
+
new GrantCompositeTypePrivileges({
|
|
327
|
+
compositeType: branchCompositeType,
|
|
328
|
+
grantee,
|
|
329
|
+
privileges: list,
|
|
330
|
+
version: ctx.version,
|
|
331
|
+
}),
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Generate revoke changes
|
|
337
|
+
if (result.revokes.length > 0) {
|
|
338
|
+
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
339
|
+
for (const [grantable, list] of revokeGroups) {
|
|
340
|
+
void grantable;
|
|
341
|
+
changes.push(
|
|
342
|
+
new RevokeCompositeTypePrivileges({
|
|
343
|
+
compositeType: mainCompositeType,
|
|
344
|
+
grantee,
|
|
345
|
+
privileges: list,
|
|
346
|
+
version: ctx.version,
|
|
347
|
+
}),
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Generate revoke grant option changes
|
|
353
|
+
if (result.revokeGrantOption.length > 0) {
|
|
354
|
+
changes.push(
|
|
355
|
+
new RevokeGrantOptionCompositeTypePrivileges({
|
|
356
|
+
compositeType: mainCompositeType,
|
|
357
|
+
grantee,
|
|
358
|
+
privilegeNames: result.revokeGrantOption,
|
|
359
|
+
version: ctx.version,
|
|
360
|
+
}),
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Note: Composite type renaming would also use ALTER TYPE ... RENAME TO ...
|
|
366
|
+
// But since our CompositeType model uses 'name' as the identity field,
|
|
367
|
+
// a name change would be handled as drop + create by diffObjects()
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return changes;
|
|
372
|
+
}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { sql } from "@ts-safeql/sql-tag";
|
|
2
|
+
import type { Pool } from "pg";
|
|
3
|
+
import z from "zod";
|
|
4
|
+
import {
|
|
5
|
+
BasePgModel,
|
|
6
|
+
columnPropsSchema,
|
|
7
|
+
type TableLikeObject,
|
|
8
|
+
} from "../../base.model.ts";
|
|
9
|
+
import {
|
|
10
|
+
type PrivilegeProps,
|
|
11
|
+
privilegePropsSchema,
|
|
12
|
+
} from "../../base.privilege-diff.ts";
|
|
13
|
+
import { ReplicaIdentitySchema } from "../../table/table.model.ts";
|
|
14
|
+
|
|
15
|
+
const compositeTypePropsSchema = z.object({
|
|
16
|
+
schema: z.string(),
|
|
17
|
+
name: z.string(),
|
|
18
|
+
row_security: z.boolean(),
|
|
19
|
+
force_row_security: z.boolean(),
|
|
20
|
+
has_indexes: z.boolean(),
|
|
21
|
+
has_rules: z.boolean(),
|
|
22
|
+
has_triggers: z.boolean(),
|
|
23
|
+
has_subclasses: z.boolean(),
|
|
24
|
+
is_populated: z.boolean(),
|
|
25
|
+
replica_identity: ReplicaIdentitySchema,
|
|
26
|
+
is_partition: z.boolean(),
|
|
27
|
+
options: z.array(z.string()).nullable(),
|
|
28
|
+
partition_bound: z.string().nullable(),
|
|
29
|
+
owner: z.string(),
|
|
30
|
+
comment: z.string().nullable(),
|
|
31
|
+
columns: z.array(columnPropsSchema),
|
|
32
|
+
privileges: z.array(privilegePropsSchema),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
type CompositeTypePrivilegeProps = PrivilegeProps;
|
|
36
|
+
export type CompositeTypeProps = z.infer<typeof compositeTypePropsSchema>;
|
|
37
|
+
|
|
38
|
+
export class CompositeType extends BasePgModel implements TableLikeObject {
|
|
39
|
+
public readonly schema: CompositeTypeProps["schema"];
|
|
40
|
+
public readonly name: CompositeTypeProps["name"];
|
|
41
|
+
public readonly row_security: CompositeTypeProps["row_security"];
|
|
42
|
+
public readonly force_row_security: CompositeTypeProps["force_row_security"];
|
|
43
|
+
public readonly has_indexes: CompositeTypeProps["has_indexes"];
|
|
44
|
+
public readonly has_rules: CompositeTypeProps["has_rules"];
|
|
45
|
+
public readonly has_triggers: CompositeTypeProps["has_triggers"];
|
|
46
|
+
public readonly has_subclasses: CompositeTypeProps["has_subclasses"];
|
|
47
|
+
public readonly is_populated: CompositeTypeProps["is_populated"];
|
|
48
|
+
public readonly replica_identity: CompositeTypeProps["replica_identity"];
|
|
49
|
+
public readonly is_partition: CompositeTypeProps["is_partition"];
|
|
50
|
+
public readonly options: CompositeTypeProps["options"];
|
|
51
|
+
public readonly partition_bound: CompositeTypeProps["partition_bound"];
|
|
52
|
+
public readonly owner: CompositeTypeProps["owner"];
|
|
53
|
+
public readonly comment: CompositeTypeProps["comment"];
|
|
54
|
+
public readonly columns: CompositeTypeProps["columns"];
|
|
55
|
+
public readonly privileges: CompositeTypePrivilegeProps[];
|
|
56
|
+
|
|
57
|
+
constructor(props: CompositeTypeProps) {
|
|
58
|
+
super();
|
|
59
|
+
|
|
60
|
+
// Identity fields
|
|
61
|
+
this.schema = props.schema;
|
|
62
|
+
this.name = props.name;
|
|
63
|
+
|
|
64
|
+
// Data fields
|
|
65
|
+
this.row_security = props.row_security;
|
|
66
|
+
this.force_row_security = props.force_row_security;
|
|
67
|
+
this.has_indexes = props.has_indexes;
|
|
68
|
+
this.has_rules = props.has_rules;
|
|
69
|
+
this.has_triggers = props.has_triggers;
|
|
70
|
+
this.has_subclasses = props.has_subclasses;
|
|
71
|
+
this.is_populated = props.is_populated;
|
|
72
|
+
this.replica_identity = props.replica_identity;
|
|
73
|
+
this.is_partition = props.is_partition;
|
|
74
|
+
this.options = props.options;
|
|
75
|
+
this.partition_bound = props.partition_bound;
|
|
76
|
+
this.owner = props.owner;
|
|
77
|
+
this.comment = props.comment;
|
|
78
|
+
this.columns = props.columns;
|
|
79
|
+
this.privileges = props.privileges;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
get stableId(): `type:${string}` {
|
|
83
|
+
return `type:${this.schema}.${this.name}`;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
get identityFields() {
|
|
87
|
+
return {
|
|
88
|
+
schema: this.schema,
|
|
89
|
+
name: this.name,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get dataFields() {
|
|
94
|
+
return {
|
|
95
|
+
row_security: this.row_security,
|
|
96
|
+
force_row_security: this.force_row_security,
|
|
97
|
+
has_indexes: this.has_indexes,
|
|
98
|
+
has_rules: this.has_rules,
|
|
99
|
+
has_triggers: this.has_triggers,
|
|
100
|
+
has_subclasses: this.has_subclasses,
|
|
101
|
+
is_populated: this.is_populated,
|
|
102
|
+
replica_identity: this.replica_identity,
|
|
103
|
+
is_partition: this.is_partition,
|
|
104
|
+
options: this.options,
|
|
105
|
+
partition_bound: this.partition_bound,
|
|
106
|
+
owner: this.owner,
|
|
107
|
+
comment: this.comment,
|
|
108
|
+
columns: this.columns,
|
|
109
|
+
privileges: this.privileges,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
override stableSnapshot() {
|
|
114
|
+
const normalizeColumns = () =>
|
|
115
|
+
[...this.columns]
|
|
116
|
+
.map((col) => {
|
|
117
|
+
const { position: _pos, ...rest } = col as unknown as Record<
|
|
118
|
+
string,
|
|
119
|
+
unknown
|
|
120
|
+
>;
|
|
121
|
+
return rest;
|
|
122
|
+
})
|
|
123
|
+
.sort((a, b) => {
|
|
124
|
+
const nameA = (a.name as string | undefined) ?? "";
|
|
125
|
+
const nameB = (b.name as string | undefined) ?? "";
|
|
126
|
+
return nameA.localeCompare(nameB);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
identity: this.identityFields,
|
|
131
|
+
data: {
|
|
132
|
+
...this.dataFields,
|
|
133
|
+
columns: normalizeColumns(),
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export async function extractCompositeTypes(
|
|
140
|
+
pool: Pool,
|
|
141
|
+
): Promise<CompositeType[]> {
|
|
142
|
+
const { rows: compositeTypeRows } = await pool.query<CompositeTypeProps>(sql`
|
|
143
|
+
WITH extension_oids AS (
|
|
144
|
+
SELECT objid
|
|
145
|
+
FROM pg_depend d
|
|
146
|
+
WHERE d.refclassid = 'pg_extension'::regclass
|
|
147
|
+
AND d.classid = 'pg_type'::regclass
|
|
148
|
+
),
|
|
149
|
+
composite_types AS (
|
|
150
|
+
SELECT
|
|
151
|
+
c.relnamespace::regnamespace::text AS schema,
|
|
152
|
+
quote_ident(c.relname) AS name,
|
|
153
|
+
c.relrowsecurity AS row_security,
|
|
154
|
+
c.relforcerowsecurity AS force_row_security,
|
|
155
|
+
c.relhasindex AS has_indexes,
|
|
156
|
+
c.relhasrules AS has_rules,
|
|
157
|
+
c.relhastriggers AS has_triggers,
|
|
158
|
+
c.relhassubclass AS has_subclasses,
|
|
159
|
+
c.relispopulated AS is_populated,
|
|
160
|
+
c.relreplident AS replica_identity,
|
|
161
|
+
c.relispartition AS is_partition,
|
|
162
|
+
c.reloptions AS options,
|
|
163
|
+
pg_get_expr(c.relpartbound, c.oid) AS partition_bound,
|
|
164
|
+
c.relowner::regrole::text AS owner,
|
|
165
|
+
obj_description(c.reltype, 'pg_type') AS comment,
|
|
166
|
+
c.relacl AS relacl, -- used by privileges LATERAL
|
|
167
|
+
c.oid AS oid
|
|
168
|
+
FROM pg_catalog.pg_class c
|
|
169
|
+
LEFT JOIN extension_oids e ON c.reltype = e.objid
|
|
170
|
+
WHERE NOT c.relnamespace::regnamespace::text LIKE ANY (ARRAY['pg\\_%', 'information\\_schema'])
|
|
171
|
+
AND e.objid IS NULL
|
|
172
|
+
AND c.relkind = 'c'
|
|
173
|
+
)
|
|
174
|
+
SELECT
|
|
175
|
+
ct.schema,
|
|
176
|
+
ct.name,
|
|
177
|
+
ct.row_security,
|
|
178
|
+
ct.force_row_security,
|
|
179
|
+
ct.has_indexes,
|
|
180
|
+
ct.has_rules,
|
|
181
|
+
ct.has_triggers,
|
|
182
|
+
ct.has_subclasses,
|
|
183
|
+
ct.is_populated,
|
|
184
|
+
ct.replica_identity,
|
|
185
|
+
ct.is_partition,
|
|
186
|
+
ct.options,
|
|
187
|
+
ct.partition_bound,
|
|
188
|
+
ct.owner,
|
|
189
|
+
ct.comment,
|
|
190
|
+
COALESCE(priv.privileges, '[]') AS privileges,
|
|
191
|
+
COALESCE(cols.columns, '[]') AS columns
|
|
192
|
+
FROM composite_types ct
|
|
193
|
+
|
|
194
|
+
-- privileges as a per-row LATERAL subquery
|
|
195
|
+
LEFT JOIN LATERAL (
|
|
196
|
+
SELECT json_agg(
|
|
197
|
+
json_build_object(
|
|
198
|
+
'grantee', CASE WHEN x.grantee = 0 THEN 'PUBLIC' ELSE x.grantee::regrole::text END,
|
|
199
|
+
'privilege', x.privilege_type,
|
|
200
|
+
'grantable', x.is_grantable
|
|
201
|
+
)
|
|
202
|
+
ORDER BY x.grantee, x.privilege_type
|
|
203
|
+
) AS privileges
|
|
204
|
+
FROM LATERAL aclexplode(ct.relacl) AS x(grantor, grantee, privilege_type, is_grantable)
|
|
205
|
+
) priv ON TRUE
|
|
206
|
+
|
|
207
|
+
-- columns as a per-row LATERAL subquery (so no GROUP BY needed)
|
|
208
|
+
LEFT JOIN LATERAL (
|
|
209
|
+
SELECT json_agg(
|
|
210
|
+
json_build_object(
|
|
211
|
+
'name', quote_ident(a.attname),
|
|
212
|
+
'position', a.attnum,
|
|
213
|
+
'data_type', a.atttypid::regtype::text,
|
|
214
|
+
'data_type_str', format_type(a.atttypid, a.atttypmod),
|
|
215
|
+
'is_custom_type', ty.typnamespace::regnamespace::text NOT IN ('pg_catalog','information_schema'),
|
|
216
|
+
'custom_type_type', CASE WHEN ty.typnamespace::regnamespace::text NOT IN ('pg_catalog','information_schema') THEN ty.typtype ELSE NULL END,
|
|
217
|
+
'custom_type_category', CASE WHEN ty.typnamespace::regnamespace::text NOT IN ('pg_catalog','information_schema') THEN ty.typcategory ELSE NULL END,
|
|
218
|
+
'custom_type_schema', CASE WHEN ty.typnamespace::regnamespace::text NOT IN ('pg_catalog','information_schema') THEN ty.typnamespace::regnamespace ELSE NULL END,
|
|
219
|
+
'custom_type_name', CASE WHEN ty.typnamespace::regnamespace::text NOT IN ('pg_catalog','information_schema') THEN quote_ident(ty.typname) ELSE NULL END,
|
|
220
|
+
'not_null', a.attnotnull,
|
|
221
|
+
'is_identity', a.attidentity <> '',
|
|
222
|
+
'is_identity_always', a.attidentity = 'a',
|
|
223
|
+
'is_generated', a.attgenerated <> '',
|
|
224
|
+
'collation', (
|
|
225
|
+
SELECT quote_ident(c2.collname)
|
|
226
|
+
FROM pg_collation c2, pg_type t2
|
|
227
|
+
WHERE c2.oid = a.attcollation
|
|
228
|
+
AND t2.oid = a.atttypid
|
|
229
|
+
AND a.attcollation <> t2.typcollation
|
|
230
|
+
),
|
|
231
|
+
'default', pg_get_expr(ad.adbin, ad.adrelid),
|
|
232
|
+
'comment', col_description(a.attrelid, a.attnum)
|
|
233
|
+
)
|
|
234
|
+
ORDER BY a.attnum
|
|
235
|
+
) AS columns
|
|
236
|
+
FROM pg_attribute a
|
|
237
|
+
LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum
|
|
238
|
+
LEFT JOIN pg_type ty ON ty.oid = a.atttypid
|
|
239
|
+
WHERE a.attrelid = ct.oid
|
|
240
|
+
AND a.attnum > 0
|
|
241
|
+
AND NOT a.attisdropped
|
|
242
|
+
) cols ON TRUE
|
|
243
|
+
|
|
244
|
+
ORDER BY ct.schema, ct.name
|
|
245
|
+
`);
|
|
246
|
+
|
|
247
|
+
// Validate and parse each row using the Zod schema
|
|
248
|
+
const validatedRows = compositeTypeRows.map((row: unknown) =>
|
|
249
|
+
compositeTypePropsSchema.parse(row),
|
|
250
|
+
);
|
|
251
|
+
return validatedRows.map((row: CompositeTypeProps) => new CompositeType(row));
|
|
252
|
+
}
|