@supabase/pg-delta 1.0.0-alpha.4 → 1.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -23
- package/dist/cli/app.js +26 -3
- package/dist/cli/bin/cli.js +5 -0
- package/dist/cli/commands/catalog-export.d.ts +5 -0
- package/dist/cli/commands/catalog-export.js +64 -0
- package/dist/cli/commands/declarative-apply.d.ts +6 -0
- package/dist/cli/commands/declarative-apply.js +288 -0
- package/dist/cli/commands/declarative-export.d.ts +5 -0
- package/dist/cli/commands/declarative-export.js +245 -0
- package/dist/cli/commands/plan.js +19 -6
- package/dist/cli/exit-code.d.ts +2 -0
- package/dist/cli/exit-code.js +7 -0
- package/dist/cli/formatters/tree/tree.js +3 -2
- package/dist/cli/utils/apply-display.d.ts +52 -0
- package/dist/cli/utils/apply-display.js +183 -0
- package/dist/cli/utils/export-display.d.ts +43 -0
- package/dist/cli/utils/export-display.js +202 -0
- package/dist/cli/utils/resolve-input.d.ts +7 -0
- package/dist/cli/utils/resolve-input.js +13 -0
- package/dist/core/catalog-export/index.d.ts +11 -0
- package/dist/core/catalog-export/index.js +10 -0
- package/dist/core/catalog.diff.d.ts +1 -0
- package/dist/core/catalog.diff.js +64 -48
- package/dist/core/catalog.model.d.ts +14 -1
- package/dist/core/catalog.model.js +103 -1
- package/dist/core/catalog.snapshot.d.ts +66 -0
- package/dist/core/catalog.snapshot.js +206 -0
- package/dist/core/declarative-apply/discover-sql.d.ts +18 -0
- package/dist/core/declarative-apply/discover-sql.js +86 -0
- package/dist/core/declarative-apply/extract-catalog-providers.d.ts +23 -0
- package/dist/core/declarative-apply/extract-catalog-providers.js +159 -0
- package/dist/core/declarative-apply/index.d.ts +49 -0
- package/dist/core/declarative-apply/index.js +134 -0
- package/dist/core/declarative-apply/round-apply.d.ts +100 -0
- package/dist/core/declarative-apply/round-apply.js +378 -0
- package/dist/core/export/file-mapper.d.ts +71 -0
- package/dist/core/export/file-mapper.js +474 -0
- package/dist/core/export/grouper.d.ts +13 -0
- package/dist/core/export/grouper.js +76 -0
- package/dist/core/export/index.d.ts +45 -0
- package/dist/core/export/index.js +63 -0
- package/dist/core/export/types.d.ts +84 -0
- package/dist/core/export/types.js +25 -0
- package/dist/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
- package/dist/core/integrations/filter/dsl.d.ts +38 -1
- package/dist/core/integrations/filter/dsl.js +20 -2
- package/dist/core/integrations/filter/extractors.js +42 -0
- package/dist/core/integrations/integration-dsl.d.ts +10 -0
- package/dist/core/integrations/supabase.d.ts +8 -0
- package/dist/core/integrations/supabase.js +9 -0
- package/dist/core/objects/aggregate/aggregate.diff.d.ts +2 -8
- package/dist/core/objects/aggregate/aggregate.diff.js +16 -70
- package/dist/core/objects/aggregate/aggregate.model.d.ts +8 -8
- package/dist/core/objects/aggregate/aggregate.model.js +1 -1
- package/dist/core/objects/aggregate/changes/aggregate.create.js +1 -1
- package/dist/core/objects/aggregate/changes/aggregate.drop.js +1 -1
- package/dist/core/objects/base.privilege-diff.d.ts +38 -13
- package/dist/core/objects/base.privilege-diff.js +104 -22
- package/dist/core/objects/base.privilege.d.ts +1 -0
- package/dist/core/objects/base.privilege.js +9 -2
- package/dist/core/objects/collation/collation.diff.d.ts +2 -3
- package/dist/core/objects/diff-context.d.ts +15 -0
- package/dist/core/objects/diff-context.js +1 -0
- package/dist/core/objects/domain/changes/domain.create.js +4 -2
- package/dist/core/objects/domain/domain.diff.d.ts +2 -8
- package/dist/core/objects/domain/domain.diff.js +16 -77
- package/dist/core/objects/domain/domain.model.js +1 -1
- package/dist/core/objects/event-trigger/event-trigger.diff.d.ts +2 -3
- package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.d.ts +2 -8
- package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.js +13 -77
- package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.js +2 -2
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.d.ts +2 -8
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.js +16 -77
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.js +1 -1
- package/dist/core/objects/foreign-data-wrapper/server/server.diff.d.ts +2 -8
- package/dist/core/objects/foreign-data-wrapper/server/server.diff.js +13 -77
- package/dist/core/objects/language/language.diff.d.ts +2 -5
- package/dist/core/objects/language/language.diff.js +7 -39
- package/dist/core/objects/materialized-view/materialized-view.diff.d.ts +2 -8
- package/dist/core/objects/materialized-view/materialized-view.diff.js +16 -158
- package/dist/core/objects/materialized-view/materialized-view.model.d.ts +3 -3
- package/dist/core/objects/materialized-view/materialized-view.model.js +1 -1
- package/dist/core/objects/procedure/changes/procedure.alter.js +12 -12
- package/dist/core/objects/procedure/procedure.diff.d.ts +2 -8
- package/dist/core/objects/procedure/procedure.diff.js +16 -77
- package/dist/core/objects/procedure/procedure.model.d.ts +9 -9
- package/dist/core/objects/procedure/procedure.model.js +1 -1
- package/dist/core/objects/publication/changes/publication.alter.d.ts +0 -9
- package/dist/core/objects/publication/changes/publication.alter.js +0 -14
- package/dist/core/objects/publication/changes/publication.types.d.ts +2 -2
- package/dist/core/objects/publication/publication.diff.d.ts +2 -3
- package/dist/core/objects/publication/publication.diff.js +8 -13
- package/dist/core/objects/rls-policy/changes/rls-policy.alter.js +3 -3
- package/dist/core/objects/rls-policy/rls-policy.model.d.ts +2 -2
- package/dist/core/objects/role/role.diff.js +22 -1
- package/dist/core/objects/role/role.model.d.ts +4 -3
- package/dist/core/objects/role/role.model.js +118 -12
- package/dist/core/objects/rule/rule.model.d.ts +1 -1
- package/dist/core/objects/schema/schema.diff.d.ts +2 -8
- package/dist/core/objects/schema/schema.diff.js +16 -77
- package/dist/core/objects/schema/schema.model.js +1 -1
- package/dist/core/objects/sequence/sequence.diff.d.ts +2 -8
- package/dist/core/objects/sequence/sequence.diff.js +16 -79
- package/dist/core/objects/sequence/sequence.model.js +1 -1
- package/dist/core/objects/subscription/subscription.diff.d.ts +2 -3
- package/dist/core/objects/table/changes/table.create.js +3 -0
- package/dist/core/objects/table/table.diff.d.ts +2 -8
- package/dist/core/objects/table/table.diff.js +26 -157
- package/dist/core/objects/table/table.model.d.ts +23 -22
- package/dist/core/objects/table/table.model.js +1 -1
- package/dist/core/objects/trigger/changes/trigger.create.js +2 -4
- package/dist/core/objects/trigger/trigger.model.d.ts +8 -0
- package/dist/core/objects/trigger/trigger.model.js +11 -0
- package/dist/core/objects/type/composite-type/composite-type.diff.d.ts +2 -8
- package/dist/core/objects/type/composite-type/composite-type.diff.js +16 -77
- package/dist/core/objects/type/composite-type/composite-type.model.d.ts +3 -3
- package/dist/core/objects/type/composite-type/composite-type.model.js +2 -1
- package/dist/core/objects/type/enum/enum.diff.d.ts +2 -8
- package/dist/core/objects/type/enum/enum.diff.js +25 -112
- package/dist/core/objects/type/enum/enum.model.js +1 -1
- package/dist/core/objects/type/range/changes/range.create.js +6 -3
- package/dist/core/objects/type/range/range.diff.d.ts +2 -8
- package/dist/core/objects/type/range/range.diff.js +16 -77
- package/dist/core/objects/type/range/range.model.js +1 -1
- package/dist/core/objects/view/view.diff.d.ts +2 -8
- package/dist/core/objects/view/view.diff.js +16 -158
- package/dist/core/objects/view/view.model.d.ts +18 -4
- package/dist/core/objects/view/view.model.js +3 -13
- package/dist/core/plan/apply.js +9 -26
- package/dist/core/plan/create.d.ts +19 -6
- package/dist/core/plan/create.js +134 -174
- package/dist/core/plan/serialize.js +16 -4
- package/dist/core/plan/sql-format/fixtures.js +3 -5
- package/dist/core/plan/sql-format/keyword-case.js +26 -1
- package/dist/core/plan/ssl-config.d.ts +32 -0
- package/dist/core/plan/ssl-config.js +115 -0
- package/dist/core/plan/types.d.ts +6 -0
- package/dist/core/postgres-config.d.ts +14 -0
- package/dist/core/postgres-config.js +53 -2
- package/dist/core/sort/graph-builder.js +10 -0
- package/dist/core/sort/logical-sort.js +31 -23
- package/dist/core/test-utils/assert-valid-sql.d.ts +10 -0
- package/dist/core/test-utils/assert-valid-sql.js +19 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -1
- package/package.json +21 -4
- package/src/cli/app.ts +27 -3
- package/src/cli/bin/cli.ts +6 -0
- package/src/cli/commands/catalog-export.ts +78 -0
- package/src/cli/commands/declarative-apply.diagnostics.test.ts +77 -0
- package/src/cli/commands/declarative-apply.ts +380 -0
- package/src/cli/commands/declarative-export.ts +330 -0
- package/src/cli/commands/plan.ts +28 -7
- package/src/cli/exit-code.test.ts +19 -0
- package/src/cli/exit-code.ts +7 -0
- package/src/cli/formatters/tree/tree.ts +3 -2
- package/src/cli/utils/apply-display.test.ts +348 -0
- package/src/cli/utils/apply-display.ts +238 -0
- package/src/cli/utils/export-display.test.ts +103 -0
- package/src/cli/utils/export-display.ts +275 -0
- package/src/cli/utils/integrations.test.ts +44 -0
- package/src/cli/utils/resolve-input.test.ts +38 -0
- package/src/cli/utils/resolve-input.ts +17 -0
- package/src/core/catalog-export/index.ts +20 -0
- package/src/core/catalog.diff.ts +79 -78
- package/src/core/catalog.model.test.ts +122 -0
- package/src/core/catalog.model.ts +127 -1
- package/src/core/catalog.snapshot.test.ts +464 -0
- package/src/core/catalog.snapshot.ts +289 -0
- package/src/core/declarative-apply/discover-sql.test.ts +103 -0
- package/src/core/declarative-apply/discover-sql.ts +107 -0
- package/src/core/declarative-apply/extract-catalog-providers.ts +220 -0
- package/src/core/declarative-apply/index.test.ts +67 -0
- package/src/core/declarative-apply/index.ts +205 -0
- package/src/core/declarative-apply/round-apply.test.ts +504 -0
- package/src/core/declarative-apply/round-apply.ts +562 -0
- package/src/core/expand-replace-dependencies.test.ts +70 -0
- package/src/core/export/file-mapper.test.ts +816 -0
- package/src/core/export/file-mapper.ts +574 -0
- package/src/core/export/grouper.ts +108 -0
- package/src/core/export/index.ts +129 -0
- package/src/core/export/types.ts +104 -0
- package/src/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
- package/src/core/integrations/filter/dsl.test.ts +211 -0
- package/src/core/integrations/filter/dsl.ts +65 -3
- package/src/core/integrations/filter/extractors.test.ts +244 -0
- package/src/core/integrations/filter/extractors.ts +42 -0
- package/src/core/integrations/integration-dsl.ts +10 -0
- package/src/core/integrations/serialize/dsl.test.ts +91 -0
- package/src/core/integrations/supabase.ts +9 -0
- package/src/core/objects/aggregate/aggregate.diff.ts +39 -95
- package/src/core/objects/aggregate/aggregate.model.ts +1 -1
- package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +3 -1
- package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +5 -2
- package/src/core/objects/aggregate/changes/aggregate.create.test.ts +6 -3
- package/src/core/objects/aggregate/changes/aggregate.create.ts +1 -1
- package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +7 -3
- package/src/core/objects/aggregate/changes/aggregate.drop.ts +1 -1
- package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +9 -3
- package/src/core/objects/base.privilege-diff.ts +178 -30
- package/src/core/objects/base.privilege.ts +9 -2
- package/src/core/objects/collation/changes/collation.alter.test.ts +7 -2
- package/src/core/objects/collation/changes/collation.create.test.ts +7 -2
- package/src/core/objects/collation/changes/collation.drop.test.ts +4 -1
- package/src/core/objects/collation/collation.diff.test.ts +9 -12
- package/src/core/objects/collation/collation.diff.ts +2 -1
- package/src/core/objects/diff-context.ts +16 -0
- package/src/core/objects/domain/changes/domain.alter.test.ts +28 -9
- package/src/core/objects/domain/changes/domain.create.test.ts +32 -2
- package/src/core/objects/domain/changes/domain.create.ts +7 -1
- package/src/core/objects/domain/changes/domain.drop.test.ts +4 -1
- package/src/core/objects/domain/domain.diff.ts +39 -102
- package/src/core/objects/domain/domain.model.ts +1 -1
- package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +10 -3
- package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +4 -1
- package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +4 -1
- package/src/core/objects/event-trigger/event-trigger.diff.test.ts +12 -7
- package/src/core/objects/event-trigger/event-trigger.diff.ts +2 -1
- package/src/core/objects/extension/changes/extension.alter.test.ts +7 -2
- package/src/core/objects/extension/changes/extension.create.test.ts +4 -1
- package/src/core/objects/extension/changes/extension.drop.test.ts +4 -1
- package/src/core/objects/extension/extension.model.test.ts +98 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +16 -5
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +51 -16
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +4 -1
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +111 -4
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +31 -101
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +2 -2
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +46 -15
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +13 -4
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +4 -1
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +39 -102
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +1 -1
- package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +22 -7
- package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +19 -6
- package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +4 -1
- package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +95 -0
- package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +31 -101
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +13 -4
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +16 -5
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +10 -3
- package/src/core/objects/index/changes/index.alter.test.ts +13 -4
- package/src/core/objects/index/changes/index.create.test.ts +4 -1
- package/src/core/objects/index/changes/index.drop.test.ts +4 -1
- package/src/core/objects/language/changes/language.alter.test.ts +4 -1
- package/src/core/objects/language/changes/language.create.test.ts +4 -1
- package/src/core/objects/language/changes/language.drop.test.ts +4 -1
- package/src/core/objects/language/language.diff.test.ts +86 -4
- package/src/core/objects/language/language.diff.ts +17 -49
- package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +10 -3
- package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +7 -2
- package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +4 -1
- package/src/core/objects/materialized-view/materialized-view.diff.test.ts +162 -0
- package/src/core/objects/materialized-view/materialized-view.diff.ts +41 -191
- package/src/core/objects/materialized-view/materialized-view.model.ts +1 -1
- package/src/core/objects/procedure/changes/procedure.alter.test.ts +121 -49
- package/src/core/objects/procedure/changes/procedure.alter.ts +15 -12
- package/src/core/objects/procedure/changes/procedure.create.test.ts +4 -1
- package/src/core/objects/procedure/changes/procedure.drop.test.ts +7 -2
- package/src/core/objects/procedure/procedure.diff.ts +39 -102
- package/src/core/objects/procedure/procedure.model.ts +1 -1
- package/src/core/objects/publication/changes/publication.alter.test.ts +15 -21
- package/src/core/objects/publication/changes/publication.alter.ts +0 -18
- package/src/core/objects/publication/changes/publication.comment.test.ts +5 -2
- package/src/core/objects/publication/changes/publication.create.test.ts +5 -2
- package/src/core/objects/publication/changes/publication.drop.test.ts +3 -1
- package/src/core/objects/publication/changes/publication.types.ts +0 -2
- package/src/core/objects/publication/publication.diff.test.ts +24 -19
- package/src/core/objects/publication/publication.diff.ts +9 -15
- package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +31 -14
- package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +3 -3
- package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +10 -3
- package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +4 -1
- package/src/core/objects/role/changes/role.alter.test.ts +31 -15
- package/src/core/objects/role/changes/role.create.test.ts +6 -2
- package/src/core/objects/role/changes/role.drop.test.ts +4 -1
- package/src/core/objects/role/role.diff.test.ts +235 -0
- package/src/core/objects/role/role.diff.ts +21 -1
- package/src/core/objects/role/role.model.ts +122 -14
- package/src/core/objects/rule/changes/rule.alter.test.ts +7 -3
- package/src/core/objects/rule/changes/rule.comment.test.ts +5 -2
- package/src/core/objects/rule/changes/rule.create.test.ts +6 -2
- package/src/core/objects/rule/changes/rule.drop.test.ts +3 -1
- package/src/core/objects/schema/changes/schema.alter.test.ts +4 -1
- package/src/core/objects/schema/changes/schema.create.test.ts +4 -1
- package/src/core/objects/schema/changes/schema.drop.test.ts +4 -1
- package/src/core/objects/schema/schema.diff.ts +39 -102
- package/src/core/objects/schema/schema.model.ts +1 -1
- package/src/core/objects/sequence/changes/sequence.alter.test.ts +11 -5
- package/src/core/objects/sequence/changes/sequence.create.test.ts +8 -3
- package/src/core/objects/sequence/changes/sequence.drop.test.ts +4 -1
- package/src/core/objects/sequence/sequence.diff.test.ts +114 -0
- package/src/core/objects/sequence/sequence.diff.ts +39 -104
- package/src/core/objects/sequence/sequence.model.ts +1 -1
- package/src/core/objects/subscription/changes/subscription.alter.test.ts +15 -5
- package/src/core/objects/subscription/changes/subscription.comment.test.ts +5 -2
- package/src/core/objects/subscription/changes/subscription.create.test.ts +5 -2
- package/src/core/objects/subscription/changes/subscription.drop.test.ts +3 -1
- package/src/core/objects/subscription/subscription.diff.test.ts +16 -11
- package/src/core/objects/subscription/subscription.diff.ts +2 -1
- package/src/core/objects/table/changes/table.alter.test.ts +38 -15
- package/src/core/objects/table/changes/table.create.test.ts +41 -3
- package/src/core/objects/table/changes/table.create.ts +4 -0
- package/src/core/objects/table/changes/table.drop.test.ts +3 -1
- package/src/core/objects/table/table.diff.test.ts +157 -0
- package/src/core/objects/table/table.diff.ts +54 -190
- package/src/core/objects/table/table.model.ts +1 -1
- package/src/core/objects/trigger/changes/trigger.alter.test.ts +8 -4
- package/src/core/objects/trigger/changes/trigger.create.test.ts +5 -1
- package/src/core/objects/trigger/changes/trigger.create.ts +7 -4
- package/src/core/objects/trigger/changes/trigger.drop.test.ts +5 -1
- package/src/core/objects/trigger/trigger.diff.test.ts +1 -0
- package/src/core/objects/trigger/trigger.model.ts +12 -0
- package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +10 -4
- package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +7 -2
- package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +4 -1
- package/src/core/objects/type/composite-type/composite-type.diff.test.ts +78 -0
- package/src/core/objects/type/composite-type/composite-type.diff.ts +39 -101
- package/src/core/objects/type/composite-type/composite-type.model.ts +2 -1
- package/src/core/objects/type/enum/changes/enum.alter.test.ts +14 -5
- package/src/core/objects/type/enum/changes/enum.create.test.ts +4 -1
- package/src/core/objects/type/enum/changes/enum.drop.test.ts +4 -1
- package/src/core/objects/type/enum/enum.diff.test.ts +181 -0
- package/src/core/objects/type/enum/enum.diff.ts +58 -146
- package/src/core/objects/type/enum/enum.model.ts +1 -1
- package/src/core/objects/type/range/changes/range.alter.test.ts +3 -1
- package/src/core/objects/type/range/changes/range.create.test.ts +5 -2
- package/src/core/objects/type/range/changes/range.create.ts +6 -2
- package/src/core/objects/type/range/changes/range.drop.test.ts +3 -1
- package/src/core/objects/type/range/range.diff.test.ts +77 -0
- package/src/core/objects/type/range/range.diff.ts +39 -101
- package/src/core/objects/type/range/range.model.ts +1 -1
- package/src/core/objects/view/changes/view.alter.test.ts +8 -3
- package/src/core/objects/view/changes/view.create.test.ts +7 -2
- package/src/core/objects/view/changes/view.drop.test.ts +4 -1
- package/src/core/objects/view/view.diff.test.ts +82 -0
- package/src/core/objects/view/view.diff.ts +41 -191
- package/src/core/objects/view/view.model.ts +3 -17
- package/src/core/plan/apply.ts +9 -27
- package/src/core/plan/create.ts +173 -237
- package/src/core/plan/serialize.test.ts +317 -0
- package/src/core/plan/serialize.ts +18 -4
- package/src/core/plan/sql-format/fixtures.ts +2 -5
- package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +52 -0
- package/src/core/plan/sql-format/format-off.test.ts +14 -17
- package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +27 -22
- package/src/core/plan/sql-format/format-pretty-narrow.test.ts +17 -21
- package/src/core/plan/sql-format/format-pretty-preserve.test.ts +25 -20
- package/src/core/plan/sql-format/format-pretty-upper.test.ts +23 -20
- package/src/core/plan/sql-format/keyword-case.ts +36 -1
- package/src/core/plan/ssl-config.ts +172 -0
- package/src/core/plan/types.ts +6 -0
- package/src/core/postgres-config.ts +71 -2
- package/src/core/sort/graph-builder.ts +12 -0
- package/src/core/sort/logical-sort.test.ts +371 -0
- package/src/core/sort/logical-sort.ts +32 -25
- package/src/core/sort/topological-sort.test.ts +275 -0
- package/src/core/test-utils/assert-valid-sql.ts +20 -0
- package/src/index.ts +26 -2
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import type { Change } from "../../change.types.ts";
|
|
3
|
+
import { compileSerializeDSL } from "./dsl.ts";
|
|
4
|
+
|
|
5
|
+
function makeChange(
|
|
6
|
+
type: string,
|
|
7
|
+
operation: string,
|
|
8
|
+
serializeFn: (opts?: Record<string, unknown>) => string,
|
|
9
|
+
): Change {
|
|
10
|
+
return {
|
|
11
|
+
objectType: type,
|
|
12
|
+
operation,
|
|
13
|
+
scope: "object",
|
|
14
|
+
schema: { name: "test" },
|
|
15
|
+
serialize: serializeFn,
|
|
16
|
+
} as unknown as Change;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe("compileSerializeDSL", () => {
|
|
20
|
+
test("matching rule applies its options", () => {
|
|
21
|
+
const serializer = compileSerializeDSL([
|
|
22
|
+
{
|
|
23
|
+
when: { type: "schema" as const, operation: "create" as const },
|
|
24
|
+
options: { skipAuthorization: true },
|
|
25
|
+
},
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
const change = makeChange("schema", "create", (opts) =>
|
|
29
|
+
opts?.skipAuthorization
|
|
30
|
+
? "CREATE SCHEMA test"
|
|
31
|
+
: "CREATE SCHEMA test AUTHORIZATION owner",
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
expect(serializer(change)).toBe("CREATE SCHEMA test");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("no matching rule uses default serialization", () => {
|
|
38
|
+
const serializer = compileSerializeDSL([
|
|
39
|
+
{
|
|
40
|
+
when: { type: "table" as const },
|
|
41
|
+
options: { skipAuthorization: true },
|
|
42
|
+
},
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
const change = makeChange("schema", "create", (opts) =>
|
|
46
|
+
opts?.skipAuthorization
|
|
47
|
+
? "CREATE SCHEMA test"
|
|
48
|
+
: "CREATE SCHEMA test AUTHORIZATION owner",
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
expect(serializer(change)).toBe("CREATE SCHEMA test AUTHORIZATION owner");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("first matching rule wins", () => {
|
|
55
|
+
const serializer = compileSerializeDSL([
|
|
56
|
+
{
|
|
57
|
+
when: { type: "schema" as const },
|
|
58
|
+
options: { skipAuthorization: true },
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
when: { type: "schema" as const },
|
|
62
|
+
options: { skipAuthorization: false },
|
|
63
|
+
},
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
const change = makeChange("schema", "create", (opts) =>
|
|
67
|
+
opts?.skipAuthorization ? "WITHOUT AUTH" : "WITH AUTH",
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
expect(serializer(change)).toBe("WITHOUT AUTH");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("skips non-matching first rule and applies second", () => {
|
|
74
|
+
const serializer = compileSerializeDSL([
|
|
75
|
+
{
|
|
76
|
+
when: { type: "table" as const },
|
|
77
|
+
options: { skipAuthorization: true },
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
when: { type: "schema" as const },
|
|
81
|
+
options: { skipAuthorization: false },
|
|
82
|
+
},
|
|
83
|
+
]);
|
|
84
|
+
|
|
85
|
+
const change = makeChange("schema", "create", (opts) =>
|
|
86
|
+
opts?.skipAuthorization ? "WITHOUT AUTH" : "WITH AUTH",
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
expect(serializer(change)).toBe("WITH AUTH");
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -58,7 +58,16 @@ const SUPABASE_SYSTEM_ROLES = [
|
|
|
58
58
|
"supabase_superuser",
|
|
59
59
|
] as const;
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* To generate the emptyCatalog snapshot, run catalog-export against a fresh
|
|
63
|
+
* supabase/postgres container:
|
|
64
|
+
*
|
|
65
|
+
* pgdelta catalog-export --target postgres://postgres:postgres@localhost:54322/postgres --output supabase-baseline.json
|
|
66
|
+
*
|
|
67
|
+
* Then import and assign the JSON content to the emptyCatalog field below.
|
|
68
|
+
*/
|
|
61
69
|
export const supabase: IntegrationDSL = {
|
|
70
|
+
// TODO: emptyCatalog: undefined -- populate by running catalog-export on a clean Supabase container
|
|
62
71
|
filter: {
|
|
63
72
|
or: [
|
|
64
73
|
{
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import type { DefaultPrivilegeState } from "../base.default-privileges.ts";
|
|
2
1
|
import { diffObjects } from "../base.diff.ts";
|
|
3
2
|
import {
|
|
4
3
|
diffPrivileges,
|
|
4
|
+
emitObjectPrivilegeChanges,
|
|
5
5
|
filterPublicBuiltInDefaults,
|
|
6
|
-
groupPrivilegesByGrantable,
|
|
7
6
|
} from "../base.privilege-diff.ts";
|
|
8
|
-
import type {
|
|
7
|
+
import type { ObjectDiffContext } from "../diff-context.ts";
|
|
9
8
|
import { deepEqual, hasNonAlterableChanges } from "../utils.ts";
|
|
10
9
|
import type { Aggregate } from "./aggregate.model.ts";
|
|
11
10
|
import { AlterAggregateChangeOwner } from "./changes/aggregate.alter.ts";
|
|
@@ -23,12 +22,10 @@ import {
|
|
|
23
22
|
import type { AggregateChange } from "./changes/aggregate.types.ts";
|
|
24
23
|
|
|
25
24
|
export function diffAggregates(
|
|
26
|
-
ctx:
|
|
27
|
-
|
|
28
|
-
currentUser
|
|
29
|
-
|
|
30
|
-
mainRoles: Record<string, Role>;
|
|
31
|
-
},
|
|
25
|
+
ctx: Pick<
|
|
26
|
+
ObjectDiffContext,
|
|
27
|
+
"version" | "currentUser" | "defaultPrivilegeState"
|
|
28
|
+
>,
|
|
32
29
|
main: Record<string, Aggregate>,
|
|
33
30
|
branch: Record<string, Aggregate>,
|
|
34
31
|
): AggregateChange[] {
|
|
@@ -65,6 +62,10 @@ export function diffAggregates(
|
|
|
65
62
|
"aggregate",
|
|
66
63
|
aggregate.schema ?? "",
|
|
67
64
|
);
|
|
65
|
+
const creatorFilteredDefaults =
|
|
66
|
+
aggregate.owner !== ctx.currentUser
|
|
67
|
+
? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
|
|
68
|
+
: effectiveDefaults;
|
|
68
69
|
// Filter out PUBLIC's built-in default EXECUTE privilege (PostgreSQL grants it automatically)
|
|
69
70
|
// Reference: https://www.postgresql.org/docs/17/ddl-priv.html Table 5.2
|
|
70
71
|
// This prevents generating unnecessary "GRANT EXECUTE TO PUBLIC" statements
|
|
@@ -75,55 +76,25 @@ export function diffAggregates(
|
|
|
75
76
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
76
77
|
// and shouldn't be compared. Use the aggregate owner as the reference.
|
|
77
78
|
const privilegeResults = diffPrivileges(
|
|
78
|
-
|
|
79
|
+
filterPublicBuiltInDefaults("aggregate", creatorFilteredDefaults),
|
|
79
80
|
desiredPrivileges,
|
|
80
81
|
aggregate.owner,
|
|
81
|
-
ctx.mainRoles,
|
|
82
82
|
);
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Generate revoke changes
|
|
101
|
-
if (result.revokes.length > 0) {
|
|
102
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
103
|
-
for (const [, list] of revokeGroups) {
|
|
104
|
-
changes.push(
|
|
105
|
-
new RevokeAggregatePrivileges({
|
|
106
|
-
aggregate,
|
|
107
|
-
grantee,
|
|
108
|
-
privileges: list,
|
|
109
|
-
version: ctx.version,
|
|
110
|
-
}),
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Generate revoke grant option changes
|
|
116
|
-
if (result.revokeGrantOption.length > 0) {
|
|
117
|
-
changes.push(
|
|
118
|
-
new RevokeGrantOptionAggregatePrivileges({
|
|
119
|
-
aggregate,
|
|
120
|
-
grantee,
|
|
121
|
-
privilegeNames: result.revokeGrantOption,
|
|
122
|
-
version: ctx.version,
|
|
123
|
-
}),
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
84
|
+
changes.push(
|
|
85
|
+
...(emitObjectPrivilegeChanges(
|
|
86
|
+
privilegeResults,
|
|
87
|
+
aggregate,
|
|
88
|
+
aggregate,
|
|
89
|
+
"aggregate",
|
|
90
|
+
{
|
|
91
|
+
Grant: GrantAggregatePrivileges,
|
|
92
|
+
Revoke: RevokeAggregatePrivileges,
|
|
93
|
+
RevokeGrantOption: RevokeGrantOptionAggregatePrivileges,
|
|
94
|
+
},
|
|
95
|
+
ctx.version,
|
|
96
|
+
) as AggregateChange[]),
|
|
97
|
+
);
|
|
127
98
|
}
|
|
128
99
|
|
|
129
100
|
for (const aggregateId of dropped) {
|
|
@@ -229,49 +200,22 @@ export function diffAggregates(
|
|
|
229
200
|
mainPrivilegesFiltered,
|
|
230
201
|
branchPrivilegesFiltered,
|
|
231
202
|
branchAggregate.owner,
|
|
232
|
-
ctx.mainRoles,
|
|
233
203
|
);
|
|
234
204
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (result.revokes.length > 0) {
|
|
251
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
252
|
-
for (const [, list] of revokeGroups) {
|
|
253
|
-
changes.push(
|
|
254
|
-
new RevokeAggregatePrivileges({
|
|
255
|
-
aggregate: mainAggregate,
|
|
256
|
-
grantee,
|
|
257
|
-
privileges: list,
|
|
258
|
-
version: ctx.version,
|
|
259
|
-
}),
|
|
260
|
-
);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (result.revokeGrantOption.length > 0) {
|
|
265
|
-
changes.push(
|
|
266
|
-
new RevokeGrantOptionAggregatePrivileges({
|
|
267
|
-
aggregate: mainAggregate,
|
|
268
|
-
grantee,
|
|
269
|
-
privilegeNames: result.revokeGrantOption,
|
|
270
|
-
version: ctx.version,
|
|
271
|
-
}),
|
|
272
|
-
);
|
|
273
|
-
}
|
|
274
|
-
}
|
|
205
|
+
changes.push(
|
|
206
|
+
...(emitObjectPrivilegeChanges(
|
|
207
|
+
privilegeResults,
|
|
208
|
+
branchAggregate,
|
|
209
|
+
mainAggregate,
|
|
210
|
+
"aggregate",
|
|
211
|
+
{
|
|
212
|
+
Grant: GrantAggregatePrivileges,
|
|
213
|
+
Revoke: RevokeAggregatePrivileges,
|
|
214
|
+
RevokeGrantOption: RevokeGrantOptionAggregatePrivileges,
|
|
215
|
+
},
|
|
216
|
+
ctx.version,
|
|
217
|
+
) as AggregateChange[]),
|
|
218
|
+
);
|
|
275
219
|
}
|
|
276
220
|
|
|
277
221
|
return changes;
|
|
@@ -292,7 +292,7 @@ select
|
|
|
292
292
|
)
|
|
293
293
|
order by x.grantee, x.privilege_type
|
|
294
294
|
)
|
|
295
|
-
from lateral aclexplode(p.proacl) as x(grantor, grantee, privilege_type, is_grantable)
|
|
295
|
+
from lateral aclexplode(COALESCE(p.proacl, acldefault('f', p.proowner))) as x(grantor, grantee, privilege_type, is_grantable)
|
|
296
296
|
), '[]'
|
|
297
297
|
) as privileges
|
|
298
298
|
from
|
|
@@ -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 { Aggregate } from "../aggregate.model.ts";
|
|
3
4
|
import { AlterAggregateChangeOwner } from "./aggregate.alter.ts";
|
|
4
5
|
|
|
@@ -49,7 +50,7 @@ const base: AggregateProps = {
|
|
|
49
50
|
};
|
|
50
51
|
|
|
51
52
|
describe("aggregate.alter", () => {
|
|
52
|
-
test("serialize owner change", () => {
|
|
53
|
+
test("serialize owner change", async () => {
|
|
53
54
|
const aggregate = new Aggregate(base);
|
|
54
55
|
const change = new AlterAggregateChangeOwner({
|
|
55
56
|
aggregate,
|
|
@@ -57,6 +58,7 @@ describe("aggregate.alter", () => {
|
|
|
57
58
|
});
|
|
58
59
|
|
|
59
60
|
expect(change.requires).toEqual([aggregate.stableId]);
|
|
61
|
+
await assertValidSql(change.serialize());
|
|
60
62
|
expect(change.serialize()).toBe(
|
|
61
63
|
"ALTER AGGREGATE public.agg_sum(integer) OWNER TO owner2",
|
|
62
64
|
);
|
|
@@ -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 { stableId } from "../../utils.ts";
|
|
3
4
|
import { Aggregate } from "../aggregate.model.ts";
|
|
4
5
|
import {
|
|
@@ -59,18 +60,19 @@ const makeAggregate = (override: Partial<AggregateProps> = {}) =>
|
|
|
59
60
|
});
|
|
60
61
|
|
|
61
62
|
describe("aggregate.comment", () => {
|
|
62
|
-
test("create comment serializes and tracks dependencies", () => {
|
|
63
|
+
test("create comment serializes and tracks dependencies", async () => {
|
|
63
64
|
const aggregate = makeAggregate({ comment: "aggregate's total" });
|
|
64
65
|
const change = new CreateCommentOnAggregate({ aggregate });
|
|
65
66
|
|
|
66
67
|
expect(change.creates).toEqual([stableId.comment(aggregate.stableId)]);
|
|
67
68
|
expect(change.requires).toEqual([aggregate.stableId]);
|
|
69
|
+
await assertValidSql(change.serialize());
|
|
68
70
|
expect(change.serialize()).toBe(
|
|
69
71
|
"COMMENT ON AGGREGATE public.agg_sum(integer) IS 'aggregate''s total'",
|
|
70
72
|
);
|
|
71
73
|
});
|
|
72
74
|
|
|
73
|
-
test("drop comment serializes and tracks dependencies", () => {
|
|
75
|
+
test("drop comment serializes and tracks dependencies", async () => {
|
|
74
76
|
const aggregate = makeAggregate({ comment: "some comment" });
|
|
75
77
|
const change = new DropCommentOnAggregate({ aggregate });
|
|
76
78
|
|
|
@@ -79,6 +81,7 @@ describe("aggregate.comment", () => {
|
|
|
79
81
|
stableId.comment(aggregate.stableId),
|
|
80
82
|
aggregate.stableId,
|
|
81
83
|
]);
|
|
84
|
+
await assertValidSql(change.serialize());
|
|
82
85
|
expect(change.serialize()).toBe(
|
|
83
86
|
"COMMENT ON AGGREGATE public.agg_sum(integer) IS NULL",
|
|
84
87
|
);
|
|
@@ -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 { Aggregate } from "../aggregate.model.ts";
|
|
3
4
|
import { CreateAggregate } from "./aggregate.create.ts";
|
|
4
5
|
|
|
@@ -55,17 +56,18 @@ const makeAggregate = (override: Partial<AggregateProps> = {}) =>
|
|
|
55
56
|
});
|
|
56
57
|
|
|
57
58
|
describe("aggregate.create", () => {
|
|
58
|
-
test("serialize minimal aggregate", () => {
|
|
59
|
+
test("serialize minimal aggregate", async () => {
|
|
59
60
|
const aggregate = makeAggregate();
|
|
60
61
|
const change = new CreateAggregate({ aggregate });
|
|
61
62
|
|
|
62
63
|
expect(change.creates).toEqual([aggregate.stableId]);
|
|
64
|
+
await assertValidSql(change.serialize());
|
|
63
65
|
expect(change.serialize()).toMatchInlineSnapshot(
|
|
64
66
|
`"CREATE AGGREGATE public.agg_sum(integer) (SFUNC = pg_catalog.int4pl, STYPE = integer)"`,
|
|
65
67
|
);
|
|
66
68
|
});
|
|
67
69
|
|
|
68
|
-
test("serialize aggregate with optional clauses and or replace", () => {
|
|
70
|
+
test("serialize aggregate with optional clauses and or replace", async () => {
|
|
69
71
|
const aggregate = makeAggregate({
|
|
70
72
|
name: "agg_full",
|
|
71
73
|
transition_function: "public.sum_int8(bigint,bigint)",
|
|
@@ -94,8 +96,9 @@ describe("aggregate.create", () => {
|
|
|
94
96
|
|
|
95
97
|
const change = new CreateAggregate({ aggregate, orReplace: true });
|
|
96
98
|
|
|
99
|
+
await assertValidSql(change.serialize());
|
|
97
100
|
expect(change.serialize()).toMatchInlineSnapshot(
|
|
98
|
-
`"CREATE OR REPLACE AGGREGATE public.agg_full(integer) (SFUNC = public.sum_int8, STYPE = bigint, SSPACE = 8, FINALFUNC = public.finalize, FINALFUNC_EXTRA, FINALFUNC_MODIFY = READ_WRITE, COMBINEFUNC = public.combine, SERIALFUNC = public.serialize_state, DESERIALFUNC = public.deserialize_state, INITCOND = '0', MSFUNC = public.msum, MINVFUNC = public.minv, MSTYPE = pg_catalog.bigint, MSSPACE = 16, MFINALFUNC = public.mfinal, MFINALFUNC_EXTRA, MFINALFUNC_MODIFY = SHAREABLE, MINITCOND = '0', SORTOP = OPERATOR(pg_catalog.<), PARALLEL SAFE, STRICT, HYPOTHETICAL)"`,
|
|
101
|
+
`"CREATE OR REPLACE AGGREGATE public.agg_full(integer) (SFUNC = public.sum_int8, STYPE = bigint, SSPACE = 8, FINALFUNC = public.finalize, FINALFUNC_EXTRA, FINALFUNC_MODIFY = READ_WRITE, COMBINEFUNC = public.combine, SERIALFUNC = public.serialize_state, DESERIALFUNC = public.deserialize_state, INITCOND = '0', MSFUNC = public.msum, MINVFUNC = public.minv, MSTYPE = pg_catalog.bigint, MSSPACE = 16, MFINALFUNC = public.mfinal, MFINALFUNC_EXTRA, MFINALFUNC_MODIFY = SHAREABLE, MINITCOND = '0', SORTOP = OPERATOR(pg_catalog.<), PARALLEL = SAFE, STRICT, HYPOTHETICAL)"`,
|
|
99
102
|
);
|
|
100
103
|
});
|
|
101
104
|
});
|
|
@@ -275,7 +275,7 @@ export class CreateAggregate extends CreateAggregateChange {
|
|
|
275
275
|
|
|
276
276
|
if (this.aggregate.parallel_safety !== "u") {
|
|
277
277
|
clauses.push(
|
|
278
|
-
`PARALLEL ${formatParallel(this.aggregate.parallel_safety)}`,
|
|
278
|
+
`PARALLEL = ${formatParallel(this.aggregate.parallel_safety)}`,
|
|
279
279
|
);
|
|
280
280
|
}
|
|
281
281
|
|
|
@@ -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 { Aggregate } from "../aggregate.model.ts";
|
|
3
4
|
import { DropAggregate } from "./aggregate.drop.ts";
|
|
4
5
|
|
|
@@ -55,16 +56,17 @@ const makeAggregate = (override: Partial<AggregateProps> = {}) =>
|
|
|
55
56
|
});
|
|
56
57
|
|
|
57
58
|
describe("aggregate.drop", () => {
|
|
58
|
-
test("serialize drop for aggregate with arguments", () => {
|
|
59
|
+
test("serialize drop for aggregate with arguments", async () => {
|
|
59
60
|
const aggregate = makeAggregate();
|
|
60
61
|
const change = new DropAggregate({ aggregate });
|
|
61
62
|
|
|
62
63
|
expect(change.drops).toEqual([aggregate.stableId]);
|
|
63
64
|
expect(change.requires).toEqual([aggregate.stableId]);
|
|
65
|
+
await assertValidSql(change.serialize());
|
|
64
66
|
expect(change.serialize()).toBe("DROP AGGREGATE public.agg_sum(integer)");
|
|
65
67
|
});
|
|
66
68
|
|
|
67
|
-
test("serialize drop for aggregate without arguments", () => {
|
|
69
|
+
test("serialize drop for aggregate without arguments", async () => {
|
|
68
70
|
const aggregate = makeAggregate({
|
|
69
71
|
name: "agg_no_args",
|
|
70
72
|
identity_arguments: "",
|
|
@@ -73,6 +75,8 @@ describe("aggregate.drop", () => {
|
|
|
73
75
|
});
|
|
74
76
|
const change = new DropAggregate({ aggregate });
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
await assertValidSql(change.serialize());
|
|
79
|
+
|
|
80
|
+
expect(change.serialize()).toBe("DROP AGGREGATE public.agg_no_args(*)");
|
|
77
81
|
});
|
|
78
82
|
});
|
|
@@ -26,7 +26,7 @@ export class DropAggregate extends DropAggregateChange {
|
|
|
26
26
|
serialize(): string {
|
|
27
27
|
const signature = this.aggregate.identityArguments;
|
|
28
28
|
const qualifiedName = `${this.aggregate.schema}.${this.aggregate.name}`;
|
|
29
|
-
const withArgs = signature.length > 0 ? `(${signature})` : "()";
|
|
29
|
+
const withArgs = signature.length > 0 ? `(${signature})` : "(*)";
|
|
30
30
|
return `DROP AGGREGATE ${qualifiedName}${withArgs}`;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -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 { stableId } from "../../utils.ts";
|
|
3
4
|
import { Aggregate } from "../aggregate.model.ts";
|
|
4
5
|
import {
|
|
@@ -54,7 +55,7 @@ const base: AggregateProps = {
|
|
|
54
55
|
};
|
|
55
56
|
|
|
56
57
|
describe("aggregate.privilege", () => {
|
|
57
|
-
test("grant privileges without grant option", () => {
|
|
58
|
+
test("grant privileges without grant option", async () => {
|
|
58
59
|
const aggregate = new Aggregate(base);
|
|
59
60
|
const change = new GrantAggregatePrivileges({
|
|
60
61
|
aggregate,
|
|
@@ -70,12 +71,13 @@ describe("aggregate.privilege", () => {
|
|
|
70
71
|
aggregate.stableId,
|
|
71
72
|
stableId.role("role_exec"),
|
|
72
73
|
]);
|
|
74
|
+
await assertValidSql(change.serialize());
|
|
73
75
|
expect(change.serialize()).toBe(
|
|
74
76
|
"GRANT ALL ON FUNCTION public.agg_sum(integer) TO role_exec",
|
|
75
77
|
);
|
|
76
78
|
});
|
|
77
79
|
|
|
78
|
-
test("grant privileges with grant option", () => {
|
|
80
|
+
test("grant privileges with grant option", async () => {
|
|
79
81
|
const aggregate = new Aggregate(base);
|
|
80
82
|
const change = new GrantAggregatePrivileges({
|
|
81
83
|
aggregate,
|
|
@@ -83,12 +85,14 @@ describe("aggregate.privilege", () => {
|
|
|
83
85
|
privileges: [{ privilege: "EXECUTE", grantable: true }],
|
|
84
86
|
});
|
|
85
87
|
|
|
88
|
+
await assertValidSql(change.serialize());
|
|
89
|
+
|
|
86
90
|
expect(change.serialize()).toBe(
|
|
87
91
|
"GRANT ALL ON FUNCTION public.agg_sum(integer) TO role_exec WITH GRANT OPTION",
|
|
88
92
|
);
|
|
89
93
|
});
|
|
90
94
|
|
|
91
|
-
test("revoke privileges and grant option", () => {
|
|
95
|
+
test("revoke privileges and grant option", async () => {
|
|
92
96
|
const aggregate = new Aggregate(base);
|
|
93
97
|
const revoke = new RevokeAggregatePrivileges({
|
|
94
98
|
aggregate,
|
|
@@ -105,6 +109,7 @@ describe("aggregate.privilege", () => {
|
|
|
105
109
|
aggregate.stableId,
|
|
106
110
|
stableId.role("role_old"),
|
|
107
111
|
]);
|
|
112
|
+
await assertValidSql(revoke.serialize());
|
|
108
113
|
expect(revoke.serialize()).toBe(
|
|
109
114
|
"REVOKE ALL ON FUNCTION public.agg_sum(integer) FROM role_old",
|
|
110
115
|
);
|
|
@@ -123,6 +128,7 @@ describe("aggregate.privilege", () => {
|
|
|
123
128
|
aggregate.stableId,
|
|
124
129
|
stableId.role("role_with_option"),
|
|
125
130
|
]);
|
|
131
|
+
await assertValidSql(revokeGrantOption.serialize());
|
|
126
132
|
expect(revokeGrantOption.serialize()).toBe(
|
|
127
133
|
"REVOKE GRANT OPTION FOR ALL ON FUNCTION public.agg_sum(integer) FROM role_with_option",
|
|
128
134
|
);
|