diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index f1948f4..b80f083 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -2192,6 +2192,7 @@ AlterExtensionNamespace(List *names, const char *newschema) Oid extensionOid; Oid nspOid; Oid oldNspOid = InvalidOid; + Oid extensionOfSchema; AclResult aclresult; Relation extRel; ScanKeyData key[2]; @@ -2327,6 +2328,23 @@ AlterExtensionNamespace(List *names, const char *newschema) get_namespace_name(oldNspOid)))); } + /* + * If the schema is a member of the extension, disallow moving the extension + * into that schema. This would otherwise cause a dependency loop. + */ + extensionOfSchema = getExtensionOfObject(NamespaceRelationId, nspOid); + + if(OidIsValid(extensionOfSchema)) + { + if(extensionOfSchema == extensionOid) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + + errmsg("cannot move extension \"%s\" to schema \"%s\" as the extension contains the schema", + NameStr(extForm->extname), + get_namespace_name(nspOid)))); + } + systable_endscan(depScan); relation_close(depRel, AccessShareLock); @@ -2649,6 +2667,7 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt) ObjectAddress object; Relation relation; Oid oldExtension; + Oid extensionSchemaOid; extension.classId = ExtensionRelationId; extension.objectId = get_extension_oid(stmt->extname, false); @@ -2690,6 +2709,22 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt) get_extension_name(oldExtension)))); /* + * Prevent schemas being added to an extension if that schema contains + * the extension. This would otherwise cause a dependency loop. + */ + if(stmt->objtype == OBJECT_SCHEMA) + { + extensionSchemaOid = get_extension_schema(extension.objectId); + + if(extensionSchemaOid == object.objectId) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("cannot add schema \"%s\" to extension \"%s\" as the schema contains the extension", + get_namespace_name(object.objectId), + get_extension_name(extension.objectId)))); + } + + /* * OK, add the dependency. */ recordDependencyOn(&object, &extension, DEPENDENCY_EXTENSION);