Commit 4d642b59 authored by Tom Lane's avatar Tom Lane

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.
parent a9732965
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment