@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
|
@@ -148,7 +148,7 @@ select
|
|
|
148
148
|
)
|
|
149
149
|
order by x.grantee, x.privilege_type
|
|
150
150
|
)
|
|
151
|
-
from lateral aclexplode(c.relacl) as x(grantor, grantee, privilege_type, is_grantable)
|
|
151
|
+
from lateral aclexplode(COALESCE(c.relacl, acldefault('S', c.relowner))) as x(grantor, grantee, privilege_type, is_grantable)
|
|
152
152
|
), '[]'
|
|
153
153
|
) as privileges,
|
|
154
154
|
c.relowner::regrole::text as owner
|
|
@@ -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 { Subscription } from "../subscription.model.ts";
|
|
4
5
|
import {
|
|
@@ -44,18 +45,20 @@ const makeSubscription = (override: Partial<SubscriptionProps> = {}) =>
|
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
describe("subscription.alter", () => {
|
|
47
|
-
test("set connection serializes conninfo literal", () => {
|
|
48
|
+
test("set connection serializes conninfo literal", async () => {
|
|
48
49
|
const subscription = makeSubscription({
|
|
49
50
|
conninfo: "dbname=postgres host=replica",
|
|
50
51
|
});
|
|
51
52
|
const change = new AlterSubscriptionSetConnection({ subscription });
|
|
52
53
|
|
|
54
|
+
await assertValidSql(change.serialize());
|
|
55
|
+
|
|
53
56
|
expect(change.serialize()).toBe(
|
|
54
57
|
"ALTER SUBSCRIPTION sub_base CONNECTION 'dbname=postgres host=replica'",
|
|
55
58
|
);
|
|
56
59
|
});
|
|
57
60
|
|
|
58
|
-
test("set publication preserves ordering and refresh hint when disabled", () => {
|
|
61
|
+
test("set publication preserves ordering and refresh hint when disabled", async () => {
|
|
59
62
|
const enabledSubscription = makeSubscription({
|
|
60
63
|
publications: ["pub_a", "pub_b"],
|
|
61
64
|
enabled: true,
|
|
@@ -64,6 +67,8 @@ describe("subscription.alter", () => {
|
|
|
64
67
|
subscription: enabledSubscription,
|
|
65
68
|
});
|
|
66
69
|
|
|
70
|
+
await assertValidSql(enabledChange.serialize());
|
|
71
|
+
|
|
67
72
|
expect(enabledChange.serialize()).toBe(
|
|
68
73
|
"ALTER SUBSCRIPTION sub_base SET PUBLICATION pub_a, pub_b",
|
|
69
74
|
);
|
|
@@ -76,12 +81,14 @@ describe("subscription.alter", () => {
|
|
|
76
81
|
subscription: disabledSubscription,
|
|
77
82
|
});
|
|
78
83
|
|
|
84
|
+
await assertValidSql(disabledChange.serialize());
|
|
85
|
+
|
|
79
86
|
expect(disabledChange.serialize()).toBe(
|
|
80
87
|
"ALTER SUBSCRIPTION sub_base SET PUBLICATION pub_a, pub_b WITH (refresh = false)",
|
|
81
88
|
);
|
|
82
89
|
});
|
|
83
90
|
|
|
84
|
-
test("toggle enablement serializes ENABLE and DISABLE statements", () => {
|
|
91
|
+
test("toggle enablement serializes ENABLE and DISABLE statements", async () => {
|
|
85
92
|
const subscription = makeSubscription();
|
|
86
93
|
|
|
87
94
|
expect(new AlterSubscriptionEnable({ subscription }).serialize()).toBe(
|
|
@@ -92,7 +99,7 @@ describe("subscription.alter", () => {
|
|
|
92
99
|
);
|
|
93
100
|
});
|
|
94
101
|
|
|
95
|
-
test("set options delegates to option formatter", () => {
|
|
102
|
+
test("set options delegates to option formatter", async () => {
|
|
96
103
|
const subscription = makeSubscription({
|
|
97
104
|
slot_name: "custom_slot",
|
|
98
105
|
slot_is_none: false,
|
|
@@ -104,12 +111,14 @@ describe("subscription.alter", () => {
|
|
|
104
111
|
options: ["slot_name", "disable_on_error", "origin"],
|
|
105
112
|
});
|
|
106
113
|
|
|
114
|
+
await assertValidSql(change.serialize());
|
|
115
|
+
|
|
107
116
|
expect(change.serialize()).toBe(
|
|
108
117
|
"ALTER SUBSCRIPTION sub_base SET (slot_name = 'custom_slot', disable_on_error = true, origin = 'none')",
|
|
109
118
|
);
|
|
110
119
|
});
|
|
111
120
|
|
|
112
|
-
test("set owner tracks role dependency", () => {
|
|
121
|
+
test("set owner tracks role dependency", async () => {
|
|
113
122
|
const subscription = makeSubscription();
|
|
114
123
|
const change = new AlterSubscriptionSetOwner({
|
|
115
124
|
subscription,
|
|
@@ -117,6 +126,7 @@ describe("subscription.alter", () => {
|
|
|
117
126
|
});
|
|
118
127
|
|
|
119
128
|
expect(change.requires).toEqual([stableId.role("new_owner")]);
|
|
129
|
+
await assertValidSql(change.serialize());
|
|
120
130
|
expect(change.serialize()).toBe(
|
|
121
131
|
"ALTER SUBSCRIPTION sub_base OWNER TO new_owner",
|
|
122
132
|
);
|
|
@@ -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 { Subscription } from "../subscription.model.ts";
|
|
4
5
|
import {
|
|
@@ -40,7 +41,7 @@ const makeSubscription = (override: Partial<SubscriptionProps> = {}) =>
|
|
|
40
41
|
});
|
|
41
42
|
|
|
42
43
|
describe("subscription.comment", () => {
|
|
43
|
-
test("create comment serializes and declares dependencies", () => {
|
|
44
|
+
test("create comment serializes and declares dependencies", async () => {
|
|
44
45
|
const subscription = makeSubscription({
|
|
45
46
|
comment: "subscription's metadata",
|
|
46
47
|
});
|
|
@@ -48,12 +49,13 @@ describe("subscription.comment", () => {
|
|
|
48
49
|
|
|
49
50
|
expect(change.creates).toEqual([stableId.comment(subscription.stableId)]);
|
|
50
51
|
expect(change.requires).toEqual([subscription.stableId]);
|
|
52
|
+
await assertValidSql(change.serialize());
|
|
51
53
|
expect(change.serialize()).toBe(
|
|
52
54
|
"COMMENT ON SUBSCRIPTION sub_base IS 'subscription''s metadata'",
|
|
53
55
|
);
|
|
54
56
|
});
|
|
55
57
|
|
|
56
|
-
test("drop comment serializes and tracks drops", () => {
|
|
58
|
+
test("drop comment serializes and tracks drops", async () => {
|
|
57
59
|
const subscription = makeSubscription({ comment: "not used" });
|
|
58
60
|
const change = new DropCommentOnSubscription({ subscription });
|
|
59
61
|
|
|
@@ -62,6 +64,7 @@ describe("subscription.comment", () => {
|
|
|
62
64
|
stableId.comment(subscription.stableId),
|
|
63
65
|
subscription.stableId,
|
|
64
66
|
]);
|
|
67
|
+
await assertValidSql(change.serialize());
|
|
65
68
|
expect(change.serialize()).toBe("COMMENT ON SUBSCRIPTION sub_base IS NULL");
|
|
66
69
|
});
|
|
67
70
|
});
|
|
@@ -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 { Subscription } from "../subscription.model.ts";
|
|
4
5
|
import { CreateSubscription } from "./subscription.create.ts";
|
|
@@ -37,18 +38,19 @@ const makeSubscription = (override: Partial<SubscriptionProps> = {}) =>
|
|
|
37
38
|
});
|
|
38
39
|
|
|
39
40
|
describe("subscription.create", () => {
|
|
40
|
-
test("serialize minimal subscription", () => {
|
|
41
|
+
test("serialize minimal subscription", async () => {
|
|
41
42
|
const subscription = makeSubscription();
|
|
42
43
|
const change = new CreateSubscription({ subscription });
|
|
43
44
|
|
|
44
45
|
expect(change.creates).toEqual([subscription.stableId]);
|
|
45
46
|
expect(change.requires).toEqual([stableId.role(subscription.owner)]);
|
|
47
|
+
await assertValidSql(change.serialize());
|
|
46
48
|
expect(change.serialize()).toBe(
|
|
47
49
|
"CREATE SUBSCRIPTION sub_base CONNECTION 'host=example dbname=postgres' PUBLICATION pub_base",
|
|
48
50
|
);
|
|
49
51
|
});
|
|
50
52
|
|
|
51
|
-
test("serialize subscription with extended options", () => {
|
|
53
|
+
test("serialize subscription with extended options", async () => {
|
|
52
54
|
const subscription = makeSubscription({
|
|
53
55
|
enabled: false,
|
|
54
56
|
binary: true,
|
|
@@ -70,6 +72,7 @@ describe("subscription.create", () => {
|
|
|
70
72
|
const change = new CreateSubscription({ subscription });
|
|
71
73
|
|
|
72
74
|
expect(change.requires).toEqual([stableId.role(subscription.owner)]);
|
|
75
|
+
await assertValidSql(change.serialize());
|
|
73
76
|
expect(change.serialize()).toBe(
|
|
74
77
|
"CREATE SUBSCRIPTION sub_base CONNECTION 'dbname=postgres application_name=sub_base' PUBLICATION pub_a, pub_b WITH (enabled = false, slot_name = 'custom_slot', binary = true, streaming = 'parallel', synchronous_commit = 'local', two_phase = true, disable_on_error = true, password_required = false, run_as_owner = true, origin = 'none', failover = true, create_slot = false, connect = false)",
|
|
75
78
|
);
|
|
@@ -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 { Subscription } from "../subscription.model.ts";
|
|
3
4
|
import { DropSubscription } from "./subscription.drop.ts";
|
|
4
5
|
|
|
@@ -36,11 +37,12 @@ const makeSubscription = (override: Partial<SubscriptionProps> = {}) =>
|
|
|
36
37
|
});
|
|
37
38
|
|
|
38
39
|
describe("subscription.drop", () => {
|
|
39
|
-
test("serialize drop subscription", () => {
|
|
40
|
+
test("serialize drop subscription", async () => {
|
|
40
41
|
const subscription = makeSubscription();
|
|
41
42
|
const change = new DropSubscription({ subscription });
|
|
42
43
|
|
|
43
44
|
expect(change.drops).toEqual([subscription.stableId]);
|
|
45
|
+
await assertValidSql(change.serialize());
|
|
44
46
|
expect(change.serialize()).toBe("DROP SUBSCRIPTION sub_base");
|
|
45
47
|
});
|
|
46
48
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import type { ObjectDiffContext } from "../diff-context.ts";
|
|
2
3
|
import {
|
|
3
4
|
AlterSubscriptionDisable,
|
|
4
5
|
AlterSubscriptionEnable,
|
|
@@ -16,6 +17,10 @@ import { DropSubscription } from "./changes/subscription.drop.ts";
|
|
|
16
17
|
import { diffSubscriptions } from "./subscription.diff.ts";
|
|
17
18
|
import { Subscription, type SubscriptionProps } from "./subscription.model.ts";
|
|
18
19
|
|
|
20
|
+
const ctx: Pick<ObjectDiffContext, "currentUser"> = {
|
|
21
|
+
currentUser: "postgres",
|
|
22
|
+
};
|
|
23
|
+
|
|
19
24
|
const baseProps: SubscriptionProps = {
|
|
20
25
|
name: "mysub",
|
|
21
26
|
raw_name: "mysub",
|
|
@@ -42,7 +47,7 @@ describe.concurrent("subscription.diff", () => {
|
|
|
42
47
|
test("create and drop subscription", () => {
|
|
43
48
|
const subscription = new Subscription(baseProps);
|
|
44
49
|
const created = diffSubscriptions(
|
|
45
|
-
|
|
50
|
+
ctx,
|
|
46
51
|
{},
|
|
47
52
|
{ [subscription.stableId]: subscription },
|
|
48
53
|
);
|
|
@@ -51,7 +56,7 @@ describe.concurrent("subscription.diff", () => {
|
|
|
51
56
|
);
|
|
52
57
|
|
|
53
58
|
const dropped = diffSubscriptions(
|
|
54
|
-
|
|
59
|
+
ctx,
|
|
55
60
|
{ [subscription.stableId]: subscription },
|
|
56
61
|
{},
|
|
57
62
|
);
|
|
@@ -68,7 +73,7 @@ describe.concurrent("subscription.diff", () => {
|
|
|
68
73
|
conninfo: "host=replica port=5433 dbname=postgres",
|
|
69
74
|
});
|
|
70
75
|
const changes = diffSubscriptions(
|
|
71
|
-
|
|
76
|
+
ctx,
|
|
72
77
|
{ [mainSubscription.stableId]: mainSubscription },
|
|
73
78
|
{ [branchSubscription.stableId]: branchSubscription },
|
|
74
79
|
);
|
|
@@ -87,7 +92,7 @@ describe.concurrent("subscription.diff", () => {
|
|
|
87
92
|
publications: ["pub_a", "pub_b"],
|
|
88
93
|
});
|
|
89
94
|
const changes = diffSubscriptions(
|
|
90
|
-
|
|
95
|
+
ctx,
|
|
91
96
|
{ [mainSubscription.stableId]: mainSubscription },
|
|
92
97
|
{ [branchSubscription.stableId]: branchSubscription },
|
|
93
98
|
);
|
|
@@ -105,7 +110,7 @@ describe.concurrent("subscription.diff", () => {
|
|
|
105
110
|
enabled: false,
|
|
106
111
|
});
|
|
107
112
|
const disableChanges = diffSubscriptions(
|
|
108
|
-
|
|
113
|
+
ctx,
|
|
109
114
|
{ [mainSubscription.stableId]: mainSubscription },
|
|
110
115
|
{ [branchDisabled.stableId]: branchDisabled },
|
|
111
116
|
);
|
|
@@ -116,7 +121,7 @@ describe.concurrent("subscription.diff", () => {
|
|
|
116
121
|
).toBe(true);
|
|
117
122
|
|
|
118
123
|
const enableChanges = diffSubscriptions(
|
|
119
|
-
|
|
124
|
+
ctx,
|
|
120
125
|
{ [branchDisabled.stableId]: branchDisabled },
|
|
121
126
|
{ [mainSubscription.stableId]: mainSubscription },
|
|
122
127
|
);
|
|
@@ -141,7 +146,7 @@ describe.concurrent("subscription.diff", () => {
|
|
|
141
146
|
slot_is_none: false,
|
|
142
147
|
});
|
|
143
148
|
const changes = diffSubscriptions(
|
|
144
|
-
|
|
149
|
+
ctx,
|
|
145
150
|
{ [mainSubscription.stableId]: mainSubscription },
|
|
146
151
|
{ [branchSubscription.stableId]: branchSubscription },
|
|
147
152
|
);
|
|
@@ -163,7 +168,7 @@ describe.concurrent("subscription.diff", () => {
|
|
|
163
168
|
replication_slot_created: false,
|
|
164
169
|
});
|
|
165
170
|
const changes = diffSubscriptions(
|
|
166
|
-
|
|
171
|
+
ctx,
|
|
167
172
|
{ [mainSubscription.stableId]: mainSubscription },
|
|
168
173
|
{ [branchSubscription.stableId]: branchSubscription },
|
|
169
174
|
);
|
|
@@ -184,7 +189,7 @@ describe.concurrent("subscription.diff", () => {
|
|
|
184
189
|
comment: "replication subscription",
|
|
185
190
|
});
|
|
186
191
|
const changes = diffSubscriptions(
|
|
187
|
-
|
|
192
|
+
ctx,
|
|
188
193
|
{ [mainSubscription.stableId]: mainSubscription },
|
|
189
194
|
{ [branchSubscription.stableId]: branchSubscription },
|
|
190
195
|
);
|
|
@@ -200,7 +205,7 @@ describe.concurrent("subscription.diff", () => {
|
|
|
200
205
|
comment: null,
|
|
201
206
|
});
|
|
202
207
|
const dropCommentChanges = diffSubscriptions(
|
|
203
|
-
|
|
208
|
+
ctx,
|
|
204
209
|
{ [branchSubscription.stableId]: branchSubscription },
|
|
205
210
|
{ [removeCommentSubscription.stableId]: removeCommentSubscription },
|
|
206
211
|
);
|
|
@@ -218,7 +223,7 @@ describe.concurrent("subscription.diff", () => {
|
|
|
218
223
|
two_phase: true,
|
|
219
224
|
});
|
|
220
225
|
const changes = diffSubscriptions(
|
|
221
|
-
|
|
226
|
+
ctx,
|
|
222
227
|
{ [mainSubscription.stableId]: mainSubscription },
|
|
223
228
|
{ [branchSubscription.stableId]: branchSubscription },
|
|
224
229
|
);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { diffObjects } from "../base.diff.ts";
|
|
2
|
+
import type { ObjectDiffContext } from "../diff-context.ts";
|
|
2
3
|
import { hasNonAlterableChanges } from "../utils.ts";
|
|
3
4
|
import {
|
|
4
5
|
AlterSubscriptionDisable,
|
|
@@ -35,7 +36,7 @@ const SETTABLE_OPTIONS: SubscriptionSettableOption[] = [
|
|
|
35
36
|
];
|
|
36
37
|
|
|
37
38
|
export function diffSubscriptions(
|
|
38
|
-
ctx:
|
|
39
|
+
ctx: Pick<ObjectDiffContext, "currentUser">,
|
|
39
40
|
main: Record<string, Subscription>,
|
|
40
41
|
branch: Record<string, Subscription>,
|
|
41
42
|
): SubscriptionChange[] {
|
|
@@ -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 type { ColumnProps } from "../../base.model.ts";
|
|
3
4
|
import { Table, type TableProps } from "../table.model.ts";
|
|
4
5
|
import {
|
|
@@ -28,7 +29,7 @@ import {
|
|
|
28
29
|
|
|
29
30
|
describe.concurrent("table", () => {
|
|
30
31
|
describe("alter", () => {
|
|
31
|
-
test("change owner", () => {
|
|
32
|
+
test("change owner", async () => {
|
|
32
33
|
const props: Omit<TableProps, "owner"> = {
|
|
33
34
|
schema: "public",
|
|
34
35
|
name: "test_table",
|
|
@@ -57,12 +58,14 @@ describe.concurrent("table", () => {
|
|
|
57
58
|
|
|
58
59
|
const change = new AlterTableChangeOwner({ table, owner: "new_owner" });
|
|
59
60
|
|
|
61
|
+
await assertValidSql(change.serialize());
|
|
62
|
+
|
|
60
63
|
expect(change.serialize()).toBe(
|
|
61
64
|
"ALTER TABLE public.test_table OWNER TO new_owner",
|
|
62
65
|
);
|
|
63
66
|
});
|
|
64
67
|
|
|
65
|
-
test("set unlogged", () => {
|
|
68
|
+
test("set unlogged", async () => {
|
|
66
69
|
const props: Omit<TableProps, "owner" | "options"> = {
|
|
67
70
|
schema: "public",
|
|
68
71
|
name: "test_table",
|
|
@@ -86,12 +89,13 @@ describe.concurrent("table", () => {
|
|
|
86
89
|
const table = new Table({ ...props, owner: "o1", options: null });
|
|
87
90
|
|
|
88
91
|
const change = new AlterTableSetUnlogged({ table });
|
|
92
|
+
await assertValidSql(change.serialize());
|
|
89
93
|
expect(change.serialize()).toBe(
|
|
90
94
|
"ALTER TABLE public.test_table SET UNLOGGED",
|
|
91
95
|
);
|
|
92
96
|
});
|
|
93
97
|
|
|
94
|
-
test("set logged", () => {
|
|
98
|
+
test("set logged", async () => {
|
|
95
99
|
const props: Omit<TableProps, "owner" | "options"> = {
|
|
96
100
|
schema: "public",
|
|
97
101
|
name: "test_table",
|
|
@@ -115,12 +119,13 @@ describe.concurrent("table", () => {
|
|
|
115
119
|
const table = new Table({ ...props, owner: "o1", options: null });
|
|
116
120
|
|
|
117
121
|
const change = new AlterTableSetLogged({ table });
|
|
122
|
+
await assertValidSql(change.serialize());
|
|
118
123
|
expect(change.serialize()).toBe(
|
|
119
124
|
"ALTER TABLE public.test_table SET LOGGED",
|
|
120
125
|
);
|
|
121
126
|
});
|
|
122
127
|
|
|
123
|
-
test("enable/disable row level security", () => {
|
|
128
|
+
test("enable/disable row level security", async () => {
|
|
124
129
|
const base: Omit<TableProps, "owner" | "options" | "row_security"> = {
|
|
125
130
|
schema: "public",
|
|
126
131
|
name: "test_table",
|
|
@@ -148,6 +153,7 @@ describe.concurrent("table", () => {
|
|
|
148
153
|
row_security: false,
|
|
149
154
|
}),
|
|
150
155
|
});
|
|
156
|
+
await assertValidSql(enable.serialize());
|
|
151
157
|
expect(enable.serialize()).toBe(
|
|
152
158
|
"ALTER TABLE public.test_table ENABLE ROW LEVEL SECURITY",
|
|
153
159
|
);
|
|
@@ -159,12 +165,13 @@ describe.concurrent("table", () => {
|
|
|
159
165
|
row_security: true,
|
|
160
166
|
}),
|
|
161
167
|
});
|
|
168
|
+
await assertValidSql(disable.serialize());
|
|
162
169
|
expect(disable.serialize()).toBe(
|
|
163
170
|
"ALTER TABLE public.test_table DISABLE ROW LEVEL SECURITY",
|
|
164
171
|
);
|
|
165
172
|
});
|
|
166
173
|
|
|
167
|
-
test("force/no force row level security", () => {
|
|
174
|
+
test("force/no force row level security", async () => {
|
|
168
175
|
const base: Omit<TableProps, "owner" | "options" | "force_row_security"> =
|
|
169
176
|
{
|
|
170
177
|
schema: "public",
|
|
@@ -193,6 +200,7 @@ describe.concurrent("table", () => {
|
|
|
193
200
|
force_row_security: false,
|
|
194
201
|
}),
|
|
195
202
|
});
|
|
203
|
+
await assertValidSql(force.serialize());
|
|
196
204
|
expect(force.serialize()).toBe(
|
|
197
205
|
"ALTER TABLE public.test_table FORCE ROW LEVEL SECURITY",
|
|
198
206
|
);
|
|
@@ -204,12 +212,13 @@ describe.concurrent("table", () => {
|
|
|
204
212
|
force_row_security: true,
|
|
205
213
|
}),
|
|
206
214
|
});
|
|
215
|
+
await assertValidSql(noforce.serialize());
|
|
207
216
|
expect(noforce.serialize()).toBe(
|
|
208
217
|
"ALTER TABLE public.test_table NO FORCE ROW LEVEL SECURITY",
|
|
209
218
|
);
|
|
210
219
|
});
|
|
211
220
|
|
|
212
|
-
test("set storage params", () => {
|
|
221
|
+
test("set storage params", async () => {
|
|
213
222
|
const base: Omit<TableProps, "owner" | "options"> = {
|
|
214
223
|
schema: "public",
|
|
215
224
|
name: "test_table",
|
|
@@ -234,12 +243,13 @@ describe.concurrent("table", () => {
|
|
|
234
243
|
table: new Table({ ...base, owner: "o1", options: null }),
|
|
235
244
|
options: ["fillfactor=90"],
|
|
236
245
|
});
|
|
246
|
+
await assertValidSql(change.serialize());
|
|
237
247
|
expect(change.serialize()).toBe(
|
|
238
248
|
"ALTER TABLE public.test_table SET (fillfactor=90)",
|
|
239
249
|
);
|
|
240
250
|
});
|
|
241
251
|
|
|
242
|
-
test("reset storage params", () => {
|
|
252
|
+
test("reset storage params", async () => {
|
|
243
253
|
const base: Omit<TableProps, "owner" | "options"> = {
|
|
244
254
|
schema: "public",
|
|
245
255
|
name: "test_table",
|
|
@@ -269,12 +279,13 @@ describe.concurrent("table", () => {
|
|
|
269
279
|
table,
|
|
270
280
|
params: ["fillfactor", "autovacuum_enabled"],
|
|
271
281
|
});
|
|
282
|
+
await assertValidSql(change.serialize());
|
|
272
283
|
expect(change.serialize()).toBe(
|
|
273
284
|
"ALTER TABLE public.test_table RESET (fillfactor, autovacuum_enabled)",
|
|
274
285
|
);
|
|
275
286
|
});
|
|
276
287
|
|
|
277
|
-
test("replica identity default/nothing/full", () => {
|
|
288
|
+
test("replica identity default/nothing/full", async () => {
|
|
278
289
|
const baseProps: Omit<
|
|
279
290
|
TableProps,
|
|
280
291
|
"owner" | "options" | "replica_identity"
|
|
@@ -329,7 +340,7 @@ describe.concurrent("table", () => {
|
|
|
329
340
|
).toBe("ALTER TABLE public.test_table REPLICA IDENTITY FULL");
|
|
330
341
|
});
|
|
331
342
|
|
|
332
|
-
test("replica identity DEFAULT and INDEX fallback", () => {
|
|
343
|
+
test("replica identity DEFAULT and INDEX fallback", async () => {
|
|
333
344
|
const baseProps: Omit<
|
|
334
345
|
TableProps,
|
|
335
346
|
"owner" | "options" | "replica_identity"
|
|
@@ -385,7 +396,7 @@ describe.concurrent("table", () => {
|
|
|
385
396
|
).toBe("ALTER TABLE public.test_table REPLICA IDENTITY DEFAULT");
|
|
386
397
|
});
|
|
387
398
|
|
|
388
|
-
test("columns add/drop/alter", () => {
|
|
399
|
+
test("columns add/drop/alter", async () => {
|
|
389
400
|
const tableProps: Omit<TableProps, "owner" | "options"> = {
|
|
390
401
|
schema: "public",
|
|
391
402
|
name: "test_table",
|
|
@@ -440,6 +451,7 @@ describe.concurrent("table", () => {
|
|
|
440
451
|
table: withCols,
|
|
441
452
|
column: colInt,
|
|
442
453
|
});
|
|
454
|
+
await assertValidSql(changeAdd.serialize());
|
|
443
455
|
expect(changeAdd.serialize()).toBe(
|
|
444
456
|
"ALTER TABLE public.test_table ADD COLUMN a integer",
|
|
445
457
|
);
|
|
@@ -454,6 +466,7 @@ describe.concurrent("table", () => {
|
|
|
454
466
|
table: dropFrom,
|
|
455
467
|
column: colText,
|
|
456
468
|
});
|
|
469
|
+
await assertValidSql(changeDrop.serialize());
|
|
457
470
|
expect(changeDrop.serialize()).toBe(
|
|
458
471
|
"ALTER TABLE public.test_table DROP COLUMN b",
|
|
459
472
|
);
|
|
@@ -462,6 +475,7 @@ describe.concurrent("table", () => {
|
|
|
462
475
|
table: withCols,
|
|
463
476
|
column: colText,
|
|
464
477
|
});
|
|
478
|
+
await assertValidSql(changeType.serialize());
|
|
465
479
|
expect(changeType.serialize()).toBe(
|
|
466
480
|
"ALTER TABLE public.test_table ALTER COLUMN b TYPE text",
|
|
467
481
|
);
|
|
@@ -470,6 +484,7 @@ describe.concurrent("table", () => {
|
|
|
470
484
|
table: withCols,
|
|
471
485
|
column: { ...colInt, default: "0" },
|
|
472
486
|
});
|
|
487
|
+
await assertValidSql(changeSetDefault.serialize());
|
|
473
488
|
expect(changeSetDefault.serialize()).toBe(
|
|
474
489
|
"ALTER TABLE public.test_table ALTER COLUMN a SET DEFAULT 0",
|
|
475
490
|
);
|
|
@@ -478,6 +493,7 @@ describe.concurrent("table", () => {
|
|
|
478
493
|
table: withCols,
|
|
479
494
|
column: { ...colInt, default: null },
|
|
480
495
|
});
|
|
496
|
+
await assertValidSql(changeDropDefault.serialize());
|
|
481
497
|
expect(changeDropDefault.serialize()).toBe(
|
|
482
498
|
"ALTER TABLE public.test_table ALTER COLUMN a DROP DEFAULT",
|
|
483
499
|
);
|
|
@@ -486,6 +502,7 @@ describe.concurrent("table", () => {
|
|
|
486
502
|
table: withCols,
|
|
487
503
|
column: { ...colInt, not_null: true },
|
|
488
504
|
});
|
|
505
|
+
await assertValidSql(changeSetNotNull.serialize());
|
|
489
506
|
expect(changeSetNotNull.serialize()).toBe(
|
|
490
507
|
"ALTER TABLE public.test_table ALTER COLUMN a SET NOT NULL",
|
|
491
508
|
);
|
|
@@ -494,12 +511,13 @@ describe.concurrent("table", () => {
|
|
|
494
511
|
table: withCols,
|
|
495
512
|
column: { ...colInt, not_null: false },
|
|
496
513
|
});
|
|
514
|
+
await assertValidSql(changeDropNotNull.serialize());
|
|
497
515
|
expect(changeDropNotNull.serialize()).toBe(
|
|
498
516
|
"ALTER TABLE public.test_table ALTER COLUMN a DROP NOT NULL",
|
|
499
517
|
);
|
|
500
518
|
});
|
|
501
519
|
|
|
502
|
-
test("add column with collation, default and not null", () => {
|
|
520
|
+
test("add column with collation, default and not null", async () => {
|
|
503
521
|
const tableProps: Omit<TableProps, "owner" | "options"> = {
|
|
504
522
|
schema: "public",
|
|
505
523
|
name: "test_table",
|
|
@@ -540,12 +558,13 @@ describe.concurrent("table", () => {
|
|
|
540
558
|
comment: null,
|
|
541
559
|
};
|
|
542
560
|
const change = new AlterTableAddColumn({ table: withCols, column: col });
|
|
561
|
+
await assertValidSql(change.serialize());
|
|
543
562
|
expect(change.serialize()).toBe(
|
|
544
563
|
"ALTER TABLE public.test_table ADD COLUMN a integer COLLATE mycoll DEFAULT 0 NOT NULL",
|
|
545
564
|
);
|
|
546
565
|
});
|
|
547
566
|
|
|
548
|
-
test("alter column type with collation", () => {
|
|
567
|
+
test("alter column type with collation", async () => {
|
|
549
568
|
const tableProps: Omit<TableProps, "owner" | "options"> = {
|
|
550
569
|
schema: "public",
|
|
551
570
|
name: "test_table",
|
|
@@ -589,12 +608,13 @@ describe.concurrent("table", () => {
|
|
|
589
608
|
table: withCols,
|
|
590
609
|
column: col,
|
|
591
610
|
});
|
|
611
|
+
await assertValidSql(change.serialize());
|
|
592
612
|
expect(change.serialize()).toBe(
|
|
593
613
|
"ALTER TABLE public.test_table ALTER COLUMN b TYPE text COLLATE mycoll",
|
|
594
614
|
);
|
|
595
615
|
});
|
|
596
616
|
|
|
597
|
-
test("set default NULL fallback", () => {
|
|
617
|
+
test("set default NULL fallback", async () => {
|
|
598
618
|
const tableProps: Omit<TableProps, "owner" | "options"> = {
|
|
599
619
|
schema: "public",
|
|
600
620
|
name: "test_table",
|
|
@@ -638,12 +658,13 @@ describe.concurrent("table", () => {
|
|
|
638
658
|
table: withCols,
|
|
639
659
|
column: col,
|
|
640
660
|
});
|
|
661
|
+
await assertValidSql(change.serialize());
|
|
641
662
|
expect(change.serialize()).toBe(
|
|
642
663
|
"ALTER TABLE public.test_table ALTER COLUMN a SET DEFAULT NULL",
|
|
643
664
|
);
|
|
644
665
|
});
|
|
645
666
|
|
|
646
|
-
test("constraints add/drop/validate and flavors", () => {
|
|
667
|
+
test("constraints add/drop/validate and flavors", async () => {
|
|
647
668
|
const t = new Table({
|
|
648
669
|
schema: "public",
|
|
649
670
|
name: "test_table",
|
|
@@ -736,7 +757,7 @@ describe.concurrent("table", () => {
|
|
|
736
757
|
).toBe("ALTER TABLE public.test_table VALIDATE CONSTRAINT pk_t");
|
|
737
758
|
});
|
|
738
759
|
|
|
739
|
-
test("attach/detach partition", () => {
|
|
760
|
+
test("attach/detach partition", async () => {
|
|
740
761
|
const table = new Table({
|
|
741
762
|
schema: "public",
|
|
742
763
|
name: "events",
|
|
@@ -807,6 +828,7 @@ describe.concurrent("table", () => {
|
|
|
807
828
|
table,
|
|
808
829
|
partition: part2025,
|
|
809
830
|
});
|
|
831
|
+
await assertValidSql(attach.serialize());
|
|
810
832
|
expect(attach.serialize()).toBe(
|
|
811
833
|
"ALTER TABLE public.events ATTACH PARTITION public.events_2025 FOR VALUES FROM ('2025-01-01 00:00:00') TO ('2026-01-01 00:00:00')",
|
|
812
834
|
);
|
|
@@ -815,6 +837,7 @@ describe.concurrent("table", () => {
|
|
|
815
837
|
table,
|
|
816
838
|
partition: part2025,
|
|
817
839
|
});
|
|
840
|
+
await assertValidSql(detach.serialize());
|
|
818
841
|
expect(detach.serialize()).toBe(
|
|
819
842
|
"ALTER TABLE public.events DETACH PARTITION public.events_2025",
|
|
820
843
|
);
|
|
@@ -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 { CreateTable } from "./table.create.ts";
|
|
4
5
|
|
|
@@ -26,13 +27,14 @@ const base: TableProps = {
|
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
describe.concurrent("table.create", () => {
|
|
29
|
-
test("minimal create with no columns", () => {
|
|
30
|
+
test("minimal create with no columns", async () => {
|
|
30
31
|
const t = new Table(base);
|
|
31
32
|
const change = new CreateTable({ table: t });
|
|
33
|
+
await assertValidSql(change.serialize());
|
|
32
34
|
expect(change.serialize()).toBe("CREATE TABLE public.t ()");
|
|
33
35
|
});
|
|
34
36
|
|
|
35
|
-
test("TEMPORARY with columns, inherits and options", () => {
|
|
37
|
+
test("TEMPORARY with columns, inherits and options", async () => {
|
|
36
38
|
const t = new Table({
|
|
37
39
|
...base,
|
|
38
40
|
persistence: "t",
|
|
@@ -134,17 +136,53 @@ describe.concurrent("table.create", () => {
|
|
|
134
136
|
});
|
|
135
137
|
|
|
136
138
|
const change = new CreateTable({ table: t });
|
|
139
|
+
await assertValidSql(change.serialize());
|
|
137
140
|
expect(change.serialize()).toBe(
|
|
138
141
|
'CREATE TEMPORARY TABLE public.t (c1 integer DEFAULT 0 NOT NULL, c2 text COLLATE "en_US", c3 integer GENERATED ALWAYS AS IDENTITY, c4 text GENERATED ALWAYS AS (lower((name))) STORED, c5 integer GENERATED BY DEFAULT AS IDENTITY) INHERITS (public.parent) WITH (fillfactor=90, autovacuum_enabled=true)',
|
|
139
142
|
);
|
|
140
143
|
});
|
|
141
144
|
|
|
142
|
-
test("UNLOGGED minimal create (no columns)", () => {
|
|
145
|
+
test("UNLOGGED minimal create (no columns)", async () => {
|
|
143
146
|
const t = new Table({
|
|
144
147
|
...base,
|
|
145
148
|
persistence: "u",
|
|
146
149
|
});
|
|
147
150
|
const change = new CreateTable({ table: t });
|
|
151
|
+
await assertValidSql(change.serialize());
|
|
148
152
|
expect(change.serialize()).toBe("CREATE UNLOGGED TABLE public.t ()");
|
|
149
153
|
});
|
|
154
|
+
|
|
155
|
+
test("requires does NOT include procedure stableIds from DEFAULT expressions (handled by pg_depend catalog constraints)", async () => {
|
|
156
|
+
// Function dependencies in DEFAULT expressions are resolved through pg_depend
|
|
157
|
+
// in the sort pipeline, which provides exact argument types and covers all
|
|
158
|
+
// expression contexts. The CreateTable change itself does not need to list them.
|
|
159
|
+
const t = new Table({
|
|
160
|
+
...base,
|
|
161
|
+
columns: [
|
|
162
|
+
{
|
|
163
|
+
name: "auth_role",
|
|
164
|
+
position: 1,
|
|
165
|
+
data_type: "text",
|
|
166
|
+
data_type_str: "text",
|
|
167
|
+
is_custom_type: false,
|
|
168
|
+
custom_type_type: null,
|
|
169
|
+
custom_type_category: null,
|
|
170
|
+
custom_type_schema: null,
|
|
171
|
+
custom_type_name: null,
|
|
172
|
+
not_null: false,
|
|
173
|
+
is_identity: false,
|
|
174
|
+
is_identity_always: false,
|
|
175
|
+
is_generated: false,
|
|
176
|
+
collation: null,
|
|
177
|
+
default: "auth.role()",
|
|
178
|
+
comment: null,
|
|
179
|
+
},
|
|
180
|
+
],
|
|
181
|
+
});
|
|
182
|
+
const change = new CreateTable({ table: t });
|
|
183
|
+
const procedureRequires = change.requires.filter((r) =>
|
|
184
|
+
r.startsWith("procedure:"),
|
|
185
|
+
);
|
|
186
|
+
expect(procedureRequires).toEqual([]);
|
|
187
|
+
});
|
|
150
188
|
});
|