diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index 0eabe18335e..39db7584f33 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -2750,7 +2750,7 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o { Oid extensionOid; Oid nspOid; - Oid oldNspOid = InvalidOid; + Oid oldNspOid; AclResult aclresult; Relation extRel; ScanKeyData key[2]; @@ -2833,6 +2833,9 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o objsMoved = new_object_addresses(); + /* store the OID of the namespace to-be-changed */ + oldNspOid = extForm->extnamespace; + /* * Scan pg_depend to find objects that depend directly on the extension, * and alter each one's schema. @@ -2912,12 +2915,6 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o nspOid, objsMoved); - /* - * Remember previous namespace of first object that has one - */ - if (oldNspOid == InvalidOid && dep_oldNspOid != InvalidOid) - oldNspOid = dep_oldNspOid; - /* * If not all the objects had the same old namespace (ignoring any * that are not in namespaces), complain. diff --git a/src/test/modules/test_extensions/expected/test_extensions.out b/src/test/modules/test_extensions/expected/test_extensions.out index a31775a2609..254bd938be0 100644 --- a/src/test/modules/test_extensions/expected/test_extensions.out +++ b/src/test/modules/test_extensions/expected/test_extensions.out @@ -312,6 +312,49 @@ Objects in extension "test_ext_cine" table ext_cine_tab3 (9 rows) +-- +-- Test extension with objects outside the extension's schema. +-- +CREATE SCHEMA test_func_dep1; +CREATE SCHEMA test_func_dep2; +CREATE SCHEMA test_func_dep3; +CREATE EXTENSION test_ext_req_schema1 SCHEMA test_func_dep1; +ALTER FUNCTION test_func_dep1.dep_req1() SET SCHEMA test_func_dep2; +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as objref, + deptype + FROM pg_depend + WHERE classid = 'pg_extension'::regclass AND + objid = (SELECT oid FROM pg_extension WHERE extname = 'test_ext_req_schema1') + ORDER BY 1, 2; + obj | objref | deptype +--------------------------------+-----------------------+--------- + extension test_ext_req_schema1 | schema test_func_dep1 | n +(1 row) + +-- fails, as function dep_req1 is not in the same schema as the extension. +ALTER EXTENSION test_ext_req_schema1 SET SCHEMA test_func_dep3; +ERROR: extension "test_ext_req_schema1" does not support SET SCHEMA +DETAIL: function test_func_dep2.dep_req1() is not in the extension's schema "test_func_dep1" +-- Move back the function, and the extension can be moved. +ALTER FUNCTION test_func_dep2.dep_req1() SET SCHEMA test_func_dep1; +ALTER EXTENSION test_ext_req_schema1 SET SCHEMA test_func_dep3; +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as objref, + deptype + FROM pg_depend + WHERE classid = 'pg_extension'::regclass AND + objid = (SELECT oid FROM pg_extension WHERE extname = 'test_ext_req_schema1') + ORDER BY 1, 2; + obj | objref | deptype +--------------------------------+-----------------------+--------- + extension test_ext_req_schema1 | schema test_func_dep3 | n +(1 row) + +DROP EXTENSION test_ext_req_schema1 CASCADE; +DROP SCHEMA test_func_dep1; +DROP SCHEMA test_func_dep2; +DROP SCHEMA test_func_dep3; -- -- Test @extschema:extname@ syntax and no_relocate option -- diff --git a/src/test/modules/test_extensions/sql/test_extensions.sql b/src/test/modules/test_extensions/sql/test_extensions.sql index f4947e7da6f..50110861835 100644 --- a/src/test/modules/test_extensions/sql/test_extensions.sql +++ b/src/test/modules/test_extensions/sql/test_extensions.sql @@ -210,6 +210,38 @@ ALTER EXTENSION test_ext_cine UPDATE TO '1.1'; \dx+ test_ext_cine +-- +-- Test extension with objects outside the extension's schema. +-- +CREATE SCHEMA test_func_dep1; +CREATE SCHEMA test_func_dep2; +CREATE SCHEMA test_func_dep3; +CREATE EXTENSION test_ext_req_schema1 SCHEMA test_func_dep1; +ALTER FUNCTION test_func_dep1.dep_req1() SET SCHEMA test_func_dep2; +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as objref, + deptype + FROM pg_depend + WHERE classid = 'pg_extension'::regclass AND + objid = (SELECT oid FROM pg_extension WHERE extname = 'test_ext_req_schema1') + ORDER BY 1, 2; +-- fails, as function dep_req1 is not in the same schema as the extension. +ALTER EXTENSION test_ext_req_schema1 SET SCHEMA test_func_dep3; +-- Move back the function, and the extension can be moved. +ALTER FUNCTION test_func_dep2.dep_req1() SET SCHEMA test_func_dep1; +ALTER EXTENSION test_ext_req_schema1 SET SCHEMA test_func_dep3; +SELECT pg_describe_object(classid, objid, objsubid) as obj, + pg_describe_object(refclassid, refobjid, refobjsubid) as objref, + deptype + FROM pg_depend + WHERE classid = 'pg_extension'::regclass AND + objid = (SELECT oid FROM pg_extension WHERE extname = 'test_ext_req_schema1') + ORDER BY 1, 2; +DROP EXTENSION test_ext_req_schema1 CASCADE; +DROP SCHEMA test_func_dep1; +DROP SCHEMA test_func_dep2; +DROP SCHEMA test_func_dep3; + -- -- Test @extschema:extname@ syntax and no_relocate option --