@supabase/pg-delta 1.0.0-alpha.4 → 1.0.0-alpha.5
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
|
@@ -84,6 +84,10 @@ export class CreateTable extends CreateTableChange {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
+
|
|
88
|
+
// Function dependencies from DEFAULT expressions are handled by pg_depend
|
|
89
|
+
// catalog constraints in the sort pipeline, which provides exact argument
|
|
90
|
+
// types and covers all expression contexts (not just column defaults).
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
return Array.from(dependencies);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
|
|
2
3
|
import { Table, type TableProps } from "../table.model.ts";
|
|
3
4
|
import { DropTable } from "./table.drop.ts";
|
|
4
5
|
|
|
@@ -26,9 +27,10 @@ const base: TableProps = {
|
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
describe.concurrent("table.drop", () => {
|
|
29
|
-
test("drop table basic", () => {
|
|
30
|
+
test("drop table basic", async () => {
|
|
30
31
|
const t = new Table(base);
|
|
31
32
|
const change = new DropTable({ table: t });
|
|
33
|
+
await assertValidSql(change.serialize());
|
|
32
34
|
expect(change.serialize()).toBe("DROP TABLE public.t");
|
|
33
35
|
});
|
|
34
36
|
});
|
|
@@ -24,6 +24,11 @@ import {
|
|
|
24
24
|
} from "./changes/table.alter.ts";
|
|
25
25
|
import { CreateTable } from "./changes/table.create.ts";
|
|
26
26
|
import { DropTable } from "./changes/table.drop.ts";
|
|
27
|
+
import {
|
|
28
|
+
GrantTablePrivileges,
|
|
29
|
+
RevokeGrantOptionTablePrivileges,
|
|
30
|
+
RevokeTablePrivileges,
|
|
31
|
+
} from "./changes/table.privilege.ts";
|
|
27
32
|
import { diffTables } from "./table.diff.ts";
|
|
28
33
|
import { Table, type TableProps } from "./table.model.ts";
|
|
29
34
|
|
|
@@ -708,4 +713,156 @@ describe.concurrent("table.diff", () => {
|
|
|
708
713
|
notNullDropped.some((c) => c instanceof AlterTableAlterColumnDropNotNull),
|
|
709
714
|
).toBe(true);
|
|
710
715
|
});
|
|
716
|
+
|
|
717
|
+
test("created table with privileges emits grant changes", () => {
|
|
718
|
+
const t = new Table({
|
|
719
|
+
...base,
|
|
720
|
+
privileges: [
|
|
721
|
+
{ grantee: "role_sel", privilege: "SELECT", grantable: false },
|
|
722
|
+
{ grantee: "role_ins", privilege: "INSERT", grantable: true },
|
|
723
|
+
],
|
|
724
|
+
});
|
|
725
|
+
const changes = diffTables(testContext, {}, { [t.stableId]: t });
|
|
726
|
+
expect(changes[0]).toBeInstanceOf(CreateTable);
|
|
727
|
+
expect(changes.some((c) => c instanceof GrantTablePrivileges)).toBe(true);
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
test("created table with default privilege revoke grant option", () => {
|
|
731
|
+
const defaultPrivilegeState = new DefaultPrivilegeState({});
|
|
732
|
+
defaultPrivilegeState.applyGrant("postgres", "r", "public", "role_a", [
|
|
733
|
+
{ privilege: "SELECT", grantable: true },
|
|
734
|
+
]);
|
|
735
|
+
const ctx = {
|
|
736
|
+
...testContext,
|
|
737
|
+
defaultPrivilegeState,
|
|
738
|
+
};
|
|
739
|
+
const t = new Table({
|
|
740
|
+
...base,
|
|
741
|
+
owner: "postgres",
|
|
742
|
+
privileges: [
|
|
743
|
+
{ grantee: "role_a", privilege: "SELECT", grantable: false },
|
|
744
|
+
],
|
|
745
|
+
});
|
|
746
|
+
const changes = diffTables(ctx, {}, { [t.stableId]: t });
|
|
747
|
+
expect(changes[0]).toBeInstanceOf(CreateTable);
|
|
748
|
+
expect(
|
|
749
|
+
changes.some((c) => c instanceof RevokeGrantOptionTablePrivileges),
|
|
750
|
+
).toBe(true);
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
test("altered table privileges emit grant, revoke, and revoke grant option", () => {
|
|
754
|
+
const main = new Table({
|
|
755
|
+
...base,
|
|
756
|
+
privileges: [
|
|
757
|
+
{ grantee: "role_sel", privilege: "SELECT", grantable: false },
|
|
758
|
+
{ grantee: "role_with_option", privilege: "SELECT", grantable: true },
|
|
759
|
+
{ grantee: "role_removed", privilege: "SELECT", grantable: false },
|
|
760
|
+
],
|
|
761
|
+
});
|
|
762
|
+
const branch = new Table({
|
|
763
|
+
...base,
|
|
764
|
+
privileges: [
|
|
765
|
+
{ grantee: "role_sel", privilege: "SELECT", grantable: true },
|
|
766
|
+
{ grantee: "role_with_option", privilege: "SELECT", grantable: false },
|
|
767
|
+
{ grantee: "role_new", privilege: "SELECT", grantable: false },
|
|
768
|
+
],
|
|
769
|
+
});
|
|
770
|
+
const changes = diffTables(
|
|
771
|
+
testContext,
|
|
772
|
+
{ [main.stableId]: main },
|
|
773
|
+
{ [branch.stableId]: branch },
|
|
774
|
+
);
|
|
775
|
+
expect(changes.some((c) => c instanceof GrantTablePrivileges)).toBe(true);
|
|
776
|
+
expect(changes.some((c) => c instanceof RevokeTablePrivileges)).toBe(true);
|
|
777
|
+
expect(
|
|
778
|
+
changes.some((c) => c instanceof RevokeGrantOptionTablePrivileges),
|
|
779
|
+
).toBe(true);
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
test("altered table privileges emit revokes before grants", () => {
|
|
783
|
+
const main = new Table({
|
|
784
|
+
...base,
|
|
785
|
+
privileges: [
|
|
786
|
+
{ grantee: "authenticated", privilege: "INSERT", grantable: false },
|
|
787
|
+
{ grantee: "authenticated", privilege: "UPDATE", grantable: false },
|
|
788
|
+
],
|
|
789
|
+
});
|
|
790
|
+
const branch = new Table({
|
|
791
|
+
...base,
|
|
792
|
+
privileges: [
|
|
793
|
+
{
|
|
794
|
+
grantee: "authenticated",
|
|
795
|
+
privilege: "INSERT",
|
|
796
|
+
grantable: false,
|
|
797
|
+
columns: ["org_id", "name"],
|
|
798
|
+
},
|
|
799
|
+
{
|
|
800
|
+
grantee: "authenticated",
|
|
801
|
+
privilege: "UPDATE",
|
|
802
|
+
grantable: false,
|
|
803
|
+
columns: ["name"],
|
|
804
|
+
},
|
|
805
|
+
],
|
|
806
|
+
});
|
|
807
|
+
const changes = diffTables(
|
|
808
|
+
testContext,
|
|
809
|
+
{ [main.stableId]: main },
|
|
810
|
+
{ [branch.stableId]: branch },
|
|
811
|
+
);
|
|
812
|
+
const privilegeChanges = changes.filter(
|
|
813
|
+
(c) =>
|
|
814
|
+
c instanceof GrantTablePrivileges ||
|
|
815
|
+
c instanceof RevokeTablePrivileges ||
|
|
816
|
+
c instanceof RevokeGrantOptionTablePrivileges,
|
|
817
|
+
);
|
|
818
|
+
expect(privilegeChanges.length).toBeGreaterThan(1);
|
|
819
|
+
|
|
820
|
+
const firstRevokeIndex = privilegeChanges.findIndex(
|
|
821
|
+
(c) => c instanceof RevokeTablePrivileges,
|
|
822
|
+
);
|
|
823
|
+
const firstGrantIndex = privilegeChanges.findIndex(
|
|
824
|
+
(c) => c instanceof GrantTablePrivileges,
|
|
825
|
+
);
|
|
826
|
+
expect(firstRevokeIndex).not.toBe(-1);
|
|
827
|
+
expect(firstGrantIndex).not.toBe(-1);
|
|
828
|
+
expect(firstRevokeIndex).toBeLessThan(firstGrantIndex);
|
|
829
|
+
});
|
|
830
|
+
|
|
831
|
+
test("storage params: set when added from null", () => {
|
|
832
|
+
const main = new Table(base);
|
|
833
|
+
const branch = new Table({
|
|
834
|
+
...base,
|
|
835
|
+
options: ["autovacuum_enabled=false"],
|
|
836
|
+
});
|
|
837
|
+
const changes = diffTables(
|
|
838
|
+
testContext,
|
|
839
|
+
{ [main.stableId]: main },
|
|
840
|
+
{ [branch.stableId]: branch },
|
|
841
|
+
);
|
|
842
|
+
expect(changes.some((c) => c instanceof AlterTableSetStorageParams)).toBe(
|
|
843
|
+
true,
|
|
844
|
+
);
|
|
845
|
+
expect(changes.some((c) => c instanceof AlterTableResetStorageParams)).toBe(
|
|
846
|
+
false,
|
|
847
|
+
);
|
|
848
|
+
});
|
|
849
|
+
|
|
850
|
+
test("storage params: reset when removed to null", () => {
|
|
851
|
+
const main = new Table({
|
|
852
|
+
...base,
|
|
853
|
+
options: ["fillfactor=90"],
|
|
854
|
+
});
|
|
855
|
+
const branch = new Table(base);
|
|
856
|
+
const changes = diffTables(
|
|
857
|
+
testContext,
|
|
858
|
+
{ [main.stableId]: main },
|
|
859
|
+
{ [branch.stableId]: branch },
|
|
860
|
+
);
|
|
861
|
+
expect(changes.some((c) => c instanceof AlterTableResetStorageParams)).toBe(
|
|
862
|
+
true,
|
|
863
|
+
);
|
|
864
|
+
expect(changes.some((c) => c instanceof AlterTableSetStorageParams)).toBe(
|
|
865
|
+
false,
|
|
866
|
+
);
|
|
867
|
+
});
|
|
711
868
|
});
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import type { DefaultPrivilegeState } from "../base.default-privileges.ts";
|
|
2
1
|
import { diffObjects } from "../base.diff.ts";
|
|
3
2
|
import {
|
|
4
3
|
diffPrivileges,
|
|
5
|
-
|
|
4
|
+
emitColumnPrivilegeChanges,
|
|
6
5
|
} from "../base.privilege-diff.ts";
|
|
7
|
-
import type {
|
|
6
|
+
import type { ObjectDiffContext } from "../diff-context.ts";
|
|
8
7
|
import { deepEqual } from "../utils.ts";
|
|
9
8
|
import {
|
|
10
9
|
AlterTableAddColumn,
|
|
@@ -202,12 +201,10 @@ function createAlterConstraintChange(mainTable: Table, branchTable: Table) {
|
|
|
202
201
|
* @returns A list of changes to apply to main to make it match branch.
|
|
203
202
|
*/
|
|
204
203
|
export function diffTables(
|
|
205
|
-
ctx:
|
|
206
|
-
|
|
207
|
-
currentUser
|
|
208
|
-
|
|
209
|
-
mainRoles: Record<string, Role>;
|
|
210
|
-
},
|
|
204
|
+
ctx: Pick<
|
|
205
|
+
ObjectDiffContext,
|
|
206
|
+
"version" | "currentUser" | "defaultPrivilegeState"
|
|
207
|
+
>,
|
|
211
208
|
main: Record<string, Table>,
|
|
212
209
|
branch: Record<string, Table>,
|
|
213
210
|
): TableChange[] {
|
|
@@ -242,6 +239,19 @@ export function diffTables(
|
|
|
242
239
|
changes.push(new AlterTableForceRowLevelSecurity({ table: branchTable }));
|
|
243
240
|
}
|
|
244
241
|
|
|
242
|
+
// REPLICA IDENTITY: If non-default, emit ALTER TABLE ... REPLICA IDENTITY
|
|
243
|
+
if (branchTable.replica_identity !== "d") {
|
|
244
|
+
// Skip 'i' (USING INDEX) — handled by index changes
|
|
245
|
+
if (branchTable.replica_identity !== "i") {
|
|
246
|
+
changes.push(
|
|
247
|
+
new AlterTableSetReplicaIdentity({
|
|
248
|
+
table: branchTable,
|
|
249
|
+
mode: branchTable.replica_identity,
|
|
250
|
+
}),
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
245
255
|
changes.push(
|
|
246
256
|
...createAlterConstraintChange(
|
|
247
257
|
// Create a dummy table with no constraints do diff constraints against
|
|
@@ -277,104 +287,34 @@ export function diffTables(
|
|
|
277
287
|
"table",
|
|
278
288
|
branchTable.schema ?? "",
|
|
279
289
|
);
|
|
290
|
+
const creatorFilteredDefaults =
|
|
291
|
+
branchTable.owner !== ctx.currentUser
|
|
292
|
+
? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
|
|
293
|
+
: effectiveDefaults;
|
|
280
294
|
const desiredPrivileges = branchTable.privileges;
|
|
281
295
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
282
296
|
// and shouldn't be compared. Use the table owner as the reference.
|
|
283
297
|
const privilegeResults = diffPrivileges(
|
|
284
|
-
|
|
298
|
+
creatorFilteredDefaults,
|
|
285
299
|
desiredPrivileges,
|
|
286
300
|
branchTable.owner,
|
|
287
|
-
ctx.mainRoles,
|
|
288
301
|
);
|
|
289
302
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
columns: group.columns,
|
|
306
|
-
version: ctx.version,
|
|
307
|
-
}),
|
|
308
|
-
);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// Generate revoke changes
|
|
314
|
-
if (result.revokes.length > 0) {
|
|
315
|
-
const revokeGroups = groupPrivilegesByColumns(result.revokes);
|
|
316
|
-
for (const [, group] of revokeGroups) {
|
|
317
|
-
const allPrivileges = new Set<string>();
|
|
318
|
-
for (const [, privSet] of group.byGrant) {
|
|
319
|
-
for (const priv of privSet) {
|
|
320
|
-
allPrivileges.add(priv);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
const privileges = Array.from(allPrivileges).map((priv) => ({
|
|
324
|
-
privilege: priv,
|
|
325
|
-
grantable: false,
|
|
326
|
-
}));
|
|
327
|
-
changes.push(
|
|
328
|
-
new RevokeTablePrivileges({
|
|
329
|
-
table: branchTable,
|
|
330
|
-
grantee,
|
|
331
|
-
privileges,
|
|
332
|
-
columns: group.columns,
|
|
333
|
-
version: ctx.version,
|
|
334
|
-
}),
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Generate revoke grant option changes
|
|
340
|
-
if (result.revokeGrantOption.length > 0) {
|
|
341
|
-
const revokeGrantGroups = new Map<
|
|
342
|
-
string,
|
|
343
|
-
{ columns?: string[]; privileges: Set<string> }
|
|
344
|
-
>();
|
|
345
|
-
for (const r of result.revokeGrantOption) {
|
|
346
|
-
const originalPriv = effectiveDefaults.find(
|
|
347
|
-
(p) => p.grantee === grantee && p.privilege === r,
|
|
348
|
-
);
|
|
349
|
-
const key = originalPriv?.columns
|
|
350
|
-
? originalPriv.columns.sort().join(",")
|
|
351
|
-
: "";
|
|
352
|
-
if (!revokeGrantGroups.has(key)) {
|
|
353
|
-
revokeGrantGroups.set(key, {
|
|
354
|
-
columns: originalPriv?.columns
|
|
355
|
-
? [...originalPriv.columns]
|
|
356
|
-
: undefined,
|
|
357
|
-
privileges: new Set(),
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
const group = revokeGrantGroups.get(key);
|
|
361
|
-
if (!group) continue;
|
|
362
|
-
group.privileges.add(r);
|
|
363
|
-
}
|
|
364
|
-
for (const [, group] of revokeGrantGroups) {
|
|
365
|
-
const privilegeNames = Array.from(group.privileges);
|
|
366
|
-
changes.push(
|
|
367
|
-
new RevokeGrantOptionTablePrivileges({
|
|
368
|
-
table: branchTable,
|
|
369
|
-
grantee,
|
|
370
|
-
privilegeNames,
|
|
371
|
-
columns: group.columns,
|
|
372
|
-
version: ctx.version,
|
|
373
|
-
}),
|
|
374
|
-
);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
303
|
+
changes.push(
|
|
304
|
+
...(emitColumnPrivilegeChanges(
|
|
305
|
+
privilegeResults,
|
|
306
|
+
branchTable,
|
|
307
|
+
branchTable,
|
|
308
|
+
"table",
|
|
309
|
+
{
|
|
310
|
+
Grant: GrantTablePrivileges,
|
|
311
|
+
Revoke: RevokeTablePrivileges,
|
|
312
|
+
RevokeGrantOption: RevokeGrantOptionTablePrivileges,
|
|
313
|
+
},
|
|
314
|
+
effectiveDefaults,
|
|
315
|
+
ctx.version,
|
|
316
|
+
) as TableChange[]),
|
|
317
|
+
);
|
|
378
318
|
}
|
|
379
319
|
|
|
380
320
|
for (const tableId of dropped) {
|
|
@@ -854,99 +794,23 @@ export function diffTables(
|
|
|
854
794
|
mainTable.privileges,
|
|
855
795
|
branchTable.privileges,
|
|
856
796
|
branchTable.owner,
|
|
857
|
-
ctx.mainRoles,
|
|
858
797
|
);
|
|
859
798
|
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
columns: group.columns,
|
|
876
|
-
version: ctx.version,
|
|
877
|
-
}),
|
|
878
|
-
);
|
|
879
|
-
}
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
// Generate revoke changes
|
|
884
|
-
if (result.revokes.length > 0) {
|
|
885
|
-
const revokeGroups = groupPrivilegesByColumns(result.revokes);
|
|
886
|
-
for (const [, group] of revokeGroups) {
|
|
887
|
-
// Collapse all grantable groups into a single revoke (grantable: false)
|
|
888
|
-
const allPrivileges = new Set<string>();
|
|
889
|
-
for (const [, privSet] of group.byGrant) {
|
|
890
|
-
for (const priv of privSet) {
|
|
891
|
-
allPrivileges.add(priv);
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
const privileges = Array.from(allPrivileges).map((priv) => ({
|
|
895
|
-
privilege: priv,
|
|
896
|
-
grantable: false,
|
|
897
|
-
}));
|
|
898
|
-
changes.push(
|
|
899
|
-
new RevokeTablePrivileges({
|
|
900
|
-
table: mainTable,
|
|
901
|
-
grantee,
|
|
902
|
-
privileges,
|
|
903
|
-
columns: group.columns,
|
|
904
|
-
version: ctx.version,
|
|
905
|
-
}),
|
|
906
|
-
);
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
// Generate revoke grant option changes
|
|
911
|
-
if (result.revokeGrantOption.length > 0) {
|
|
912
|
-
const revokeGrantGroups = new Map<
|
|
913
|
-
string,
|
|
914
|
-
{ columns?: string[]; privileges: Set<string> }
|
|
915
|
-
>();
|
|
916
|
-
for (const r of result.revokeGrantOption) {
|
|
917
|
-
// For revoke grant option, we need to find the columns from the original privilege
|
|
918
|
-
const originalPriv = mainTable.privileges.find(
|
|
919
|
-
(p) => p.grantee === grantee && p.privilege === r,
|
|
920
|
-
);
|
|
921
|
-
const key = originalPriv?.columns
|
|
922
|
-
? originalPriv.columns.sort().join(",")
|
|
923
|
-
: "";
|
|
924
|
-
if (!revokeGrantGroups.has(key)) {
|
|
925
|
-
revokeGrantGroups.set(key, {
|
|
926
|
-
columns: originalPriv?.columns
|
|
927
|
-
? [...originalPriv.columns]
|
|
928
|
-
: undefined,
|
|
929
|
-
privileges: new Set(),
|
|
930
|
-
});
|
|
931
|
-
}
|
|
932
|
-
const group = revokeGrantGroups.get(key);
|
|
933
|
-
if (!group) continue;
|
|
934
|
-
group.privileges.add(r);
|
|
935
|
-
}
|
|
936
|
-
for (const [, group] of revokeGrantGroups) {
|
|
937
|
-
const privilegeNames = Array.from(group.privileges);
|
|
938
|
-
changes.push(
|
|
939
|
-
new RevokeGrantOptionTablePrivileges({
|
|
940
|
-
table: mainTable,
|
|
941
|
-
grantee,
|
|
942
|
-
privilegeNames,
|
|
943
|
-
columns: group.columns,
|
|
944
|
-
version: ctx.version,
|
|
945
|
-
}),
|
|
946
|
-
);
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
}
|
|
799
|
+
changes.push(
|
|
800
|
+
...(emitColumnPrivilegeChanges(
|
|
801
|
+
privilegeResults,
|
|
802
|
+
branchTable,
|
|
803
|
+
mainTable,
|
|
804
|
+
"table",
|
|
805
|
+
{
|
|
806
|
+
Grant: GrantTablePrivileges,
|
|
807
|
+
Revoke: RevokeTablePrivileges,
|
|
808
|
+
RevokeGrantOption: RevokeGrantOptionTablePrivileges,
|
|
809
|
+
},
|
|
810
|
+
mainTable.privileges,
|
|
811
|
+
ctx.version,
|
|
812
|
+
) as TableChange[]),
|
|
813
|
+
);
|
|
950
814
|
}
|
|
951
815
|
|
|
952
816
|
return changes;
|
|
@@ -428,7 +428,7 @@ select
|
|
|
428
428
|
from (
|
|
429
429
|
-- one row for object ACL + one row per column ACL
|
|
430
430
|
select null::name as attname, t.oid as relacl_oid, (
|
|
431
|
-
select c_rel.relacl from pg_class c_rel where c_rel.oid = t.oid
|
|
431
|
+
select COALESCE(c_rel.relacl, acldefault('r', c_rel.relowner)) from pg_class c_rel where c_rel.oid = t.oid
|
|
432
432
|
) as acl
|
|
433
433
|
union all
|
|
434
434
|
select a2.attname, t.oid as relacl_oid, a2.attacl
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
|
|
2
3
|
import { Trigger, type TriggerProps } from "../trigger.model.ts";
|
|
3
4
|
import { ReplaceTrigger } from "./trigger.alter.ts";
|
|
4
5
|
|
|
5
6
|
describe.concurrent("trigger", () => {
|
|
6
7
|
describe("alter", () => {
|
|
7
|
-
test("replace trigger", () => {
|
|
8
|
+
test("replace trigger", async () => {
|
|
8
9
|
const props: Omit<TriggerProps, "enabled"> = {
|
|
9
10
|
schema: "public",
|
|
10
11
|
name: "test_trigger",
|
|
11
12
|
table_name: "test_table",
|
|
13
|
+
table_relkind: "r",
|
|
12
14
|
function_schema: "public",
|
|
13
15
|
function_name: "test_function",
|
|
14
16
|
trigger_type: 1 << 4, // UPDATE (1<<4) = 16, AFTER is default (0), STATEMENT is default (0)
|
|
15
17
|
is_internal: false,
|
|
16
|
-
deferrable:
|
|
18
|
+
deferrable: false,
|
|
17
19
|
initially_deferred: false,
|
|
18
20
|
argument_count: 0,
|
|
19
21
|
column_numbers: null,
|
|
@@ -28,7 +30,7 @@ describe.concurrent("trigger", () => {
|
|
|
28
30
|
is_on_partitioned_table: false,
|
|
29
31
|
owner: "test",
|
|
30
32
|
definition:
|
|
31
|
-
"CREATE TRIGGER test_trigger AFTER UPDATE ON public.test_table
|
|
33
|
+
"CREATE TRIGGER test_trigger AFTER UPDATE ON public.test_table EXECUTE FUNCTION public.test_function()",
|
|
32
34
|
comment: null,
|
|
33
35
|
};
|
|
34
36
|
const branch = new Trigger({
|
|
@@ -38,8 +40,10 @@ describe.concurrent("trigger", () => {
|
|
|
38
40
|
|
|
39
41
|
const change = new ReplaceTrigger({ trigger: branch });
|
|
40
42
|
|
|
43
|
+
await assertValidSql(change.serialize());
|
|
44
|
+
|
|
41
45
|
expect(change.serialize()).toBe(
|
|
42
|
-
"CREATE OR REPLACE TRIGGER test_trigger AFTER UPDATE ON public.test_table
|
|
46
|
+
"CREATE OR REPLACE TRIGGER test_trigger AFTER UPDATE ON public.test_table EXECUTE FUNCTION public.test_function()",
|
|
43
47
|
);
|
|
44
48
|
});
|
|
45
49
|
});
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
|
|
2
3
|
import { Trigger } from "../trigger.model.ts";
|
|
3
4
|
import { CreateTrigger } from "./trigger.create.ts";
|
|
4
5
|
|
|
5
6
|
describe("trigger", () => {
|
|
6
|
-
test("create", () => {
|
|
7
|
+
test("create", async () => {
|
|
7
8
|
const trigger = new Trigger({
|
|
8
9
|
schema: "public",
|
|
9
10
|
name: "test_trigger",
|
|
10
11
|
table_name: "test_table",
|
|
12
|
+
table_relkind: "r",
|
|
11
13
|
function_schema: "public",
|
|
12
14
|
function_name: "test_function",
|
|
13
15
|
trigger_type: (1 << 1) | (1 << 2) | (1 << 0), // BEFORE (1<<1) | INSERT (1<<2) | ROW (1<<0) = 7
|
|
@@ -36,6 +38,8 @@ describe("trigger", () => {
|
|
|
36
38
|
trigger,
|
|
37
39
|
});
|
|
38
40
|
|
|
41
|
+
await assertValidSql(change.serialize());
|
|
42
|
+
|
|
39
43
|
expect(change.serialize()).toBe(
|
|
40
44
|
"CREATE TRIGGER test_trigger BEFORE INSERT ON public.test_table FOR EACH ROW EXECUTE FUNCTION public.test_function()",
|
|
41
45
|
);
|
|
@@ -60,10 +60,13 @@ export class CreateTrigger extends CreateTriggerChange {
|
|
|
60
60
|
);
|
|
61
61
|
|
|
62
62
|
// Function dependency
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
// Trigger functions always have signature () RETURNS trigger, so no arguments.
|
|
64
|
+
dependencies.add(
|
|
65
|
+
stableId.procedure(
|
|
66
|
+
this.trigger.function_schema,
|
|
67
|
+
this.trigger.function_name,
|
|
68
|
+
),
|
|
69
|
+
);
|
|
67
70
|
|
|
68
71
|
// Owner dependency
|
|
69
72
|
dependencies.add(stableId.role(this.trigger.owner));
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
|
|
2
3
|
import { Trigger } from "../trigger.model.ts";
|
|
3
4
|
import { DropTrigger } from "./trigger.drop.ts";
|
|
4
5
|
|
|
5
6
|
describe("trigger", () => {
|
|
6
|
-
test("drop", () => {
|
|
7
|
+
test("drop", async () => {
|
|
7
8
|
const trigger = new Trigger({
|
|
8
9
|
schema: "public",
|
|
9
10
|
name: "test_trigger",
|
|
10
11
|
table_name: "test_table",
|
|
12
|
+
table_relkind: "r",
|
|
11
13
|
function_schema: "public",
|
|
12
14
|
function_name: "test_function",
|
|
13
15
|
trigger_type: 66,
|
|
@@ -36,6 +38,8 @@ describe("trigger", () => {
|
|
|
36
38
|
trigger,
|
|
37
39
|
});
|
|
38
40
|
|
|
41
|
+
await assertValidSql(change.serialize());
|
|
42
|
+
|
|
39
43
|
expect(change.serialize()).toBe(
|
|
40
44
|
"DROP TRIGGER test_trigger ON public.test_table",
|
|
41
45
|
);
|
|
@@ -10,10 +10,19 @@ const TriggerEnabledSchema = z.enum([
|
|
|
10
10
|
"A", // ALWAYS - trigger fires regardless of replication mode
|
|
11
11
|
]);
|
|
12
12
|
|
|
13
|
+
const TriggerTableRelkindSchema = z.enum([
|
|
14
|
+
"r", // ordinary table
|
|
15
|
+
"p", // partitioned table
|
|
16
|
+
"f", // foreign table
|
|
17
|
+
"v", // view
|
|
18
|
+
"m", // materialized view
|
|
19
|
+
]);
|
|
20
|
+
|
|
13
21
|
const triggerPropsSchema = z.object({
|
|
14
22
|
schema: z.string(),
|
|
15
23
|
name: z.string(),
|
|
16
24
|
table_name: z.string(),
|
|
25
|
+
table_relkind: TriggerTableRelkindSchema,
|
|
17
26
|
function_schema: z.string(),
|
|
18
27
|
function_name: z.string(),
|
|
19
28
|
trigger_type: z.number(),
|
|
@@ -43,6 +52,7 @@ export class Trigger extends BasePgModel {
|
|
|
43
52
|
public readonly schema: TriggerProps["schema"];
|
|
44
53
|
public readonly name: TriggerProps["name"];
|
|
45
54
|
public readonly table_name: TriggerProps["table_name"];
|
|
55
|
+
public readonly table_relkind: TriggerProps["table_relkind"];
|
|
46
56
|
public readonly function_schema: TriggerProps["function_schema"];
|
|
47
57
|
public readonly function_name: TriggerProps["function_name"];
|
|
48
58
|
public readonly trigger_type: TriggerProps["trigger_type"];
|
|
@@ -72,6 +82,7 @@ export class Trigger extends BasePgModel {
|
|
|
72
82
|
this.schema = props.schema;
|
|
73
83
|
this.name = props.name;
|
|
74
84
|
this.table_name = props.table_name;
|
|
85
|
+
this.table_relkind = props.table_relkind;
|
|
75
86
|
|
|
76
87
|
// Data fields
|
|
77
88
|
this.function_schema = props.function_schema;
|
|
@@ -164,6 +175,7 @@ export async function extractTriggers(pool: Pool): Promise<Trigger[]> {
|
|
|
164
175
|
tc.relnamespace::regnamespace::text as schema,
|
|
165
176
|
quote_ident(t.tgname) as name,
|
|
166
177
|
quote_ident(tc.relname) as table_name,
|
|
178
|
+
tc.relkind as table_relkind,
|
|
167
179
|
|
|
168
180
|
fc.pronamespace::regnamespace::text as function_schema,
|
|
169
181
|
quote_ident(fc.proname) as function_name,
|