Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions internal/migration_acceptance_tests/object_owner_cases_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package migration_acceptance_tests

import (
"testing"

"github.com/stripe/pg-schema-diff/pkg/diff"
)

var objectOwnerAcceptanceTestCases = []acceptanceTestCase{
{
name: "Change table owner",
roles: []string{"owner_a", "owner_b"},
oldSchemaDDL: []string{`
CREATE TABLE owner_test(id int);
ALTER TABLE owner_test OWNER TO owner_a;
`},
newSchemaDDL: []string{`
CREATE TABLE owner_test(id int);
ALTER TABLE owner_test OWNER TO owner_b;
`},
expectedHazardTypes: []diff.MigrationHazardType{diff.MigrationHazardTypeAuthzUpdate},
expectedPlanDDL: []string{`ALTER TABLE "public"."owner_test" OWNER TO "owner_b"`},
},
{
name: "Change function owner",
roles: []string{"owner_a", "owner_b"},
oldSchemaDDL: []string{`
CREATE FUNCTION owner_add(a integer, b integer) RETURNS integer
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT
RETURN a + b;
ALTER FUNCTION owner_add(a integer, b integer) OWNER TO owner_a;
`},
newSchemaDDL: []string{`
CREATE FUNCTION owner_add(a integer, b integer) RETURNS integer
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT
RETURN a + b;
ALTER FUNCTION owner_add(a integer, b integer) OWNER TO owner_b;
`},
expectedHazardTypes: []diff.MigrationHazardType{diff.MigrationHazardTypeAuthzUpdate},
expectedPlanDDL: []string{`ALTER FUNCTION "public"."owner_add"(a integer, b integer) OWNER TO "owner_b"`},
},
{
name: "Change procedure owner",
roles: []string{"owner_a", "owner_b"},
oldSchemaDDL: []string{`
CREATE PROCEDURE owner_work()
LANGUAGE plpgsql
AS $$
BEGIN
END;
$$;
ALTER PROCEDURE owner_work() OWNER TO owner_a;
`},
newSchemaDDL: []string{`
CREATE PROCEDURE owner_work()
LANGUAGE plpgsql
AS $$
BEGIN
END;
$$;
ALTER PROCEDURE owner_work() OWNER TO owner_b;
`},
expectedHazardTypes: []diff.MigrationHazardType{diff.MigrationHazardTypeAuthzUpdate},
expectedPlanDDL: []string{`ALTER PROCEDURE "public"."owner_work"() OWNER TO "owner_b"`},
},
{
name: "Change enum owner",
roles: []string{"owner_a", "owner_b"},
oldSchemaDDL: []string{`
CREATE TYPE owner_color AS ENUM ('red', 'blue');
ALTER TYPE owner_color OWNER TO owner_a;
`},
newSchemaDDL: []string{`
CREATE TYPE owner_color AS ENUM ('red', 'blue');
ALTER TYPE owner_color OWNER TO owner_b;
`},
expectedHazardTypes: []diff.MigrationHazardType{diff.MigrationHazardTypeAuthzUpdate},
expectedPlanDDL: []string{`ALTER TYPE "public"."owner_color" OWNER TO "owner_b"`},
},
{
name: "Change sequence owner",
roles: []string{"owner_a", "owner_b"},
oldSchemaDDL: []string{`
CREATE SEQUENCE owner_seq OWNED BY NONE;
ALTER SEQUENCE owner_seq OWNER TO owner_a;
`},
newSchemaDDL: []string{`
CREATE SEQUENCE owner_seq OWNED BY NONE;
ALTER SEQUENCE owner_seq OWNER TO owner_b;
`},
expectedHazardTypes: []diff.MigrationHazardType{diff.MigrationHazardTypeAuthzUpdate},
expectedPlanDDL: []string{`ALTER SEQUENCE "public"."owner_seq" OWNER TO "owner_b"`},
},
{
name: "Change view owner",
roles: []string{"owner_a", "owner_b"},
oldSchemaDDL: []string{`
CREATE TABLE owner_base(id int);
CREATE VIEW owner_view AS SELECT id FROM owner_base;
ALTER VIEW owner_view OWNER TO owner_a;
`},
newSchemaDDL: []string{`
CREATE TABLE owner_base(id int);
CREATE VIEW owner_view AS SELECT id FROM owner_base;
ALTER VIEW owner_view OWNER TO owner_b;
`},
expectedHazardTypes: []diff.MigrationHazardType{diff.MigrationHazardTypeAuthzUpdate},
expectedPlanDDL: []string{`ALTER VIEW "public"."owner_view" OWNER TO "owner_b"`},
},
{
name: "Change materialized view owner",
roles: []string{"owner_a", "owner_b"},
oldSchemaDDL: []string{`
CREATE TABLE owner_base(id int);
CREATE MATERIALIZED VIEW owner_mview AS SELECT id FROM owner_base;
ALTER MATERIALIZED VIEW owner_mview OWNER TO owner_a;
`},
newSchemaDDL: []string{`
CREATE TABLE owner_base(id int);
CREATE MATERIALIZED VIEW owner_mview AS SELECT id FROM owner_base;
ALTER MATERIALIZED VIEW owner_mview OWNER TO owner_b;
`},
expectedHazardTypes: []diff.MigrationHazardType{diff.MigrationHazardTypeAuthzUpdate},
expectedPlanDDL: []string{`ALTER MATERIALIZED VIEW "public"."owner_mview" OWNER TO "owner_b"`},
},
}

func TestObjectOwnerTestCases(t *testing.T) {
runTestCases(t, objectOwnerAcceptanceTestCases)
}
12 changes: 12 additions & 0 deletions internal/queries/queries.sql
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ SELECT
c.oid,
c.relname::TEXT AS table_name,
table_namespace.nspname::TEXT AS table_schema_name,
owner_role.rolname::TEXT AS owner,
c.relreplident::TEXT AS replica_identity,
c.relrowsecurity AS rls_enabled,
c.relforcerowsecurity AS rls_forced,
Expand All @@ -38,6 +39,7 @@ FROM pg_catalog.pg_class AS c
INNER JOIN
pg_catalog.pg_namespace AS table_namespace
ON c.relnamespace = table_namespace.oid
INNER JOIN pg_catalog.pg_roles AS owner_role ON c.relowner = owner_role.oid
LEFT JOIN
pg_catalog.pg_inherits AS table_inherits
ON c.oid = table_inherits.inhrelid
Expand Down Expand Up @@ -262,6 +264,7 @@ SELECT
pg_proc.oid,
pg_proc.proname::TEXT AS func_name,
proc_namespace.nspname::TEXT AS func_schema_name,
owner_role.rolname::TEXT AS owner,
proc_lang.lanname::TEXT AS func_lang,
pg_catalog.pg_get_function_identity_arguments(
pg_proc.oid
Expand All @@ -271,6 +274,7 @@ FROM pg_catalog.pg_proc
INNER JOIN
pg_catalog.pg_namespace AS proc_namespace
ON pg_proc.pronamespace = proc_namespace.oid
INNER JOIN pg_catalog.pg_roles AS owner_role ON pg_proc.proowner = owner_role.oid
INNER JOIN
pg_catalog.pg_language AS proc_lang
ON pg_proc.prolang = proc_lang.oid
Expand Down Expand Up @@ -341,6 +345,7 @@ WHERE
SELECT
seq_c.relname::TEXT AS sequence_name,
seq_ns.nspname::TEXT AS sequence_schema_name,
owner_role.rolname::TEXT AS owner,
COALESCE(owner_attr.attname, '')::TEXT AS owner_column_name,
COALESCE(owner_ns.nspname, '')::TEXT AS owner_schema_name,
COALESCE(owner_c.relname, '')::TEXT AS owner_table_name,
Expand All @@ -354,6 +359,7 @@ SELECT
FROM pg_catalog.pg_sequence AS pg_seq
INNER JOIN pg_catalog.pg_class AS seq_c ON pg_seq.seqrelid = seq_c.oid
INNER JOIN pg_catalog.pg_namespace AS seq_ns ON seq_c.relnamespace = seq_ns.oid
INNER JOIN pg_catalog.pg_roles AS owner_role ON seq_c.relowner = owner_role.oid
LEFT JOIN pg_catalog.pg_depend AS depend
ON
depend.classid = 'pg_class'::REGCLASS
Expand Down Expand Up @@ -405,6 +411,7 @@ WHERE
SELECT
pg_type.typname::TEXT AS enum_name,
type_namespace.nspname::TEXT AS enum_schema_name,
owner_role.rolname::TEXT AS owner,
(SELECT
ARRAY_AGG(
pg_enum.enumlabel
Expand All @@ -416,6 +423,7 @@ FROM pg_catalog.pg_type AS pg_type
INNER JOIN
pg_catalog.pg_namespace AS type_namespace
ON pg_type.typnamespace = type_namespace.oid
INNER JOIN pg_catalog.pg_roles AS owner_role ON pg_type.typowner = owner_role.oid
WHERE
pg_type.typtype = 'e'
AND type_namespace.nspname NOT IN ('pg_catalog', 'information_schema')
Expand Down Expand Up @@ -488,6 +496,7 @@ WHERE
SELECT
n.nspname::TEXT AS schema_name,
c.relname::TEXT AS view_name,
owner_role.rolname::TEXT AS owner,
c.reloptions::TEXT [] AS rel_options,
(SELECT
ARRAY_AGG(DISTINCT JSONB_BUILD_OBJECT(
Expand Down Expand Up @@ -539,6 +548,7 @@ SELECT
PG_GET_VIEWDEF(c.oid, true) AS view_definition
FROM pg_catalog.pg_class AS c
INNER JOIN pg_catalog.pg_namespace AS n ON c.relnamespace = n.oid
INNER JOIN pg_catalog.pg_roles AS owner_role ON c.relowner = owner_role.oid
WHERE
c.relkind = 'v'
AND n.nspname NOT IN ('pg_catalog', 'information_schema')
Expand All @@ -557,6 +567,7 @@ WHERE
SELECT
n.nspname::TEXT AS schema_name,
c.relname::TEXT AS view_name,
owner_role.rolname::TEXT AS owner,
c.reloptions::TEXT [] AS rel_options,
COALESCE(ts.spcname, '')::TEXT AS tablespace_name,
(SELECT
Expand Down Expand Up @@ -610,6 +621,7 @@ SELECT
PG_GET_VIEWDEF(c.oid, true) AS view_definition
FROM pg_catalog.pg_class AS c
INNER JOIN pg_catalog.pg_namespace AS n ON c.relnamespace = n.oid
INNER JOIN pg_catalog.pg_roles AS owner_role ON c.relowner = owner_role.oid
LEFT JOIN pg_catalog.pg_tablespace AS ts ON c.reltablespace = ts.oid
WHERE
c.relkind = 'm'
Expand Down
Loading