Skip to content

Commit 9e03518

Browse files
committed
Disallow extensions from owning the schema they are assigned to.
This situation creates a dependency loop that confuses pg_dump and probably other things. Moreover, since the mental model is that the extension "contains" schemas it owns, but "is contained in" its extschema (even though neither is strictly true), having both true at once is confusing for people too. So prevent the situation from being set up. Reported and patched by Thom Brown. Back-patch to 9.1 where extensions were added.
1 parent 04e96bc commit 9e03518

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

src/backend/commands/extension.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,6 +2290,17 @@ AlterExtensionNamespace(List *names, const char *newschema)
22902290
if (aclresult != ACLCHECK_OK)
22912291
aclcheck_error(aclresult, ACL_KIND_NAMESPACE, newschema);
22922292

2293+
/*
2294+
* If the schema is currently a member of the extension, disallow moving
2295+
* the extension into the schema. That would create a dependency loop.
2296+
*/
2297+
if (getExtensionOfObject(NamespaceRelationId, nspOid) == extensionOid)
2298+
ereport(ERROR,
2299+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2300+
errmsg("cannot move extension \"%s\" into schema \"%s\" "
2301+
"because the extension contains the schema",
2302+
extensionName, newschema)));
2303+
22932304
/* Locate the pg_extension tuple */
22942305
extRel = heap_open(ExtensionRelationId, RowExclusiveLock);
22952306

@@ -2754,6 +2765,19 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt)
27542765
getObjectDescription(&object),
27552766
get_extension_name(oldExtension))));
27562767

2768+
/*
2769+
* Prevent a schema from being added to an extension if the schema
2770+
* contains the extension. That would create a dependency loop.
2771+
*/
2772+
if (object.classId == NamespaceRelationId &&
2773+
object.objectId == get_extension_schema(extension.objectId))
2774+
ereport(ERROR,
2775+
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
2776+
errmsg("cannot add schema \"%s\" to extension \"%s\" "
2777+
"because the schema contains the extension",
2778+
get_namespace_name(object.objectId),
2779+
stmt->extname)));
2780+
27572781
/*
27582782
* OK, add the dependency.
27592783
*/
@@ -2807,8 +2831,8 @@ AlterExtensionOwner_internal(Relation rel, Oid extensionOid, Oid newOwnerId)
28072831
{
28082832
Form_pg_extension extForm;
28092833
HeapTuple tup;
2810-
SysScanDesc scandesc;
2811-
ScanKeyData entry[1];
2834+
SysScanDesc scandesc;
2835+
ScanKeyData entry[1];
28122836

28132837
Assert(RelationGetRelid(rel) == ExtensionRelationId);
28142838

@@ -2876,7 +2900,7 @@ AlterExtensionOwner_oid(Oid extensionOid, Oid newOwnerId)
28762900
Relation rel;
28772901

28782902
rel = heap_open(ExtensionRelationId, RowExclusiveLock);
2879-
2903+
28802904
AlterExtensionOwner_internal(rel, extensionOid, newOwnerId);
28812905

28822906
heap_close(rel, NoLock);

0 commit comments

Comments
 (0)