]> granicus.if.org Git - postgresql/commitdiff
Disallow extensions from owning the schema they are assigned to.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 15 Aug 2012 15:26:55 +0000 (11:26 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 15 Aug 2012 15:28:03 +0000 (11:28 -0400)
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.

src/backend/commands/extension.c

index f1948f4d7c25518a829b971199172df97c957820..8512cdbe31700f6c7abc5f9fa54aaec4582b4fb4 100644 (file)
@@ -2225,6 +2225,17 @@ AlterExtensionNamespace(List *names, const char *newschema)
        if (aclresult != ACLCHECK_OK)
                aclcheck_error(aclresult, ACL_KIND_NAMESPACE, newschema);
 
+       /*
+        * If the schema is currently a member of the extension, disallow moving
+        * the extension into the schema.  That would create a dependency loop.
+        */
+       if (getExtensionOfObject(NamespaceRelationId, nspOid) == extensionOid)
+               ereport(ERROR,
+                               (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+                                errmsg("cannot move extension \"%s\" into schema \"%s\" "
+                                               "because the extension contains the schema",
+                                               extensionName, newschema)));
+
        /* Locate the pg_extension tuple */
        extRel = heap_open(ExtensionRelationId, RowExclusiveLock);
 
@@ -2689,6 +2700,19 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt)
                                                        getObjectDescription(&object),
                                                        get_extension_name(oldExtension))));
 
+               /*
+                * Prevent a schema from being added to an extension if the schema
+                * contains the extension.      That would create a dependency loop.
+                */
+               if (object.classId == NamespaceRelationId &&
+                       object.objectId == get_extension_schema(extension.objectId))
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+                                        errmsg("cannot add schema \"%s\" to extension \"%s\" "
+                                                       "because the schema contains the extension",
+                                                       get_namespace_name(object.objectId),
+                                                       stmt->extname)));
+
                /*
                 * OK, add the dependency.
                 */
@@ -2742,8 +2766,8 @@ AlterExtensionOwner_internal(Relation rel, Oid extensionOid, Oid newOwnerId)
 {
        Form_pg_extension extForm;
        HeapTuple       tup;
-       SysScanDesc     scandesc;
-       ScanKeyData     entry[1];
+       SysScanDesc scandesc;
+       ScanKeyData entry[1];
 
        Assert(RelationGetRelid(rel) == ExtensionRelationId);
 
@@ -2811,7 +2835,7 @@ AlterExtensionOwner_oid(Oid extensionOid, Oid newOwnerId)
        Relation        rel;
 
        rel = heap_open(ExtensionRelationId, RowExclusiveLock);
-       
+
        AlterExtensionOwner_internal(rel, extensionOid, newOwnerId);
 
        heap_close(rel, NoLock);