REASSIGN OWNED: Support foreign data wrappers and servers
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Tue, 21 Feb 2012 20:58:02 +0000 (17:58 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Wed, 22 Feb 2012 20:33:12 +0000 (17:33 -0300)
This was overlooked when implementing those kinds of objects, in commit
cae565e503c42a0942ca1771665243b4453c5770.

Per report from Pawel Casperek.

src/backend/catalog/pg_shdepend.c
src/backend/commands/foreigncmds.c
src/include/commands/defrem.h

index 11cb9883a762a30bb86eb1a23437459fcc26fd8c..bcc663515c1f9270745282e2318fe5c3c0a4a451 100644 (file)
@@ -25,6 +25,8 @@
 #include "catalog/pg_conversion.h"
 #include "catalog/pg_database.h"
 #include "catalog/pg_default_acl.h"
+#include "catalog/pg_foreign_data_wrapper.h"
+#include "catalog/pg_foreign_server.h"
 #include "catalog/pg_language.h"
 #include "catalog/pg_largeobject.h"
 #include "catalog/pg_namespace.h"
@@ -1382,6 +1384,14 @@ shdepReassignOwned(List *roleids, Oid newrole)
                    AlterOpFamilyOwner_oid(sdepForm->objid, newrole);
                    break;
 
+               case ForeignServerRelationId:
+                   AlterForeignServerOwner_oid(sdepForm->objid, newrole);
+                   break;
+
+               case ForeignDataWrapperRelationId:
+                   AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
+                   break;
+
                default:
                    elog(ERROR, "unexpected classid %u", sdepForm->classid);
                    break;
index 4135e268575f46bc8afe43179b0beed19f74e7c1..990875de76bb42fb316963b8480b54689a940bd7 100644 (file)
@@ -277,27 +277,24 @@ RenameForeignServer(const char *oldname, const char *newname)
 
 
 /*
- * Change foreign-data wrapper owner.
+ * Internal workhorse for changing a data wrapper's owner.
  *
  * Allow this only for superusers; also the new owner must be a
  * superuser.
  */
-void
-AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
+static void
+AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
 {
-   HeapTuple   tup;
-   Relation    rel;
-   Oid         fdwId;
    Form_pg_foreign_data_wrapper form;
 
-   rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
+   form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
 
    /* Must be a superuser to change a FDW owner */
    if (!superuser())
        ereport(ERROR,
                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                 errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
-                       name),
+                       NameStr(form->fdwname)),
                 errhint("Must be superuser to change owner of a foreign-data wrapper.")));
 
    /* New owner must also be a superuser */
@@ -305,19 +302,9 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
        ereport(ERROR,
                (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                 errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
-                       name),
+                       NameStr(form->fdwname)),
        errhint("The owner of a foreign-data wrapper must be a superuser.")));
 
-   tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(name));
-
-   if (!HeapTupleIsValid(tup))
-       ereport(ERROR,
-               (errcode(ERRCODE_UNDEFINED_OBJECT),
-                errmsg("foreign-data wrapper \"%s\" does not exist", name)));
-
-   fdwId = HeapTupleGetOid(tup);
-   form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
-
    if (form->fdwowner != newOwnerId)
    {
        form->fdwowner = newOwnerId;
@@ -327,38 +314,73 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
 
        /* Update owner dependency reference */
        changeDependencyOnOwner(ForeignDataWrapperRelationId,
-                               fdwId,
+                               HeapTupleGetOid(tup),
                                newOwnerId);
    }
+}
+
+/*
+ * Change foreign-data wrapper owner -- by name
+ *
+ * Note restrictions in the "_internal" function, above.
+ */
+void
+AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
+{
+   HeapTuple   tup;
+   Relation    rel;
+
+   rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
+
+   tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(name));
+
+   if (!HeapTupleIsValid(tup))
+       ereport(ERROR,
+               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                errmsg("foreign-data wrapper \"%s\" does not exist", name)));
+
+   AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
 
    heap_freetuple(tup);
 
    heap_close(rel, RowExclusiveLock);
 }
 
-
 /*
- * Change foreign server owner
+ * Change foreign-data wrapper owner -- by OID
+ *
+ * Note restrictions in the "_internal" function, above.
  */
 void
-AlterForeignServerOwner(const char *name, Oid newOwnerId)
+AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId)
 {
    HeapTuple   tup;
    Relation    rel;
-   Oid         srvId;
-   AclResult   aclresult;
-   Form_pg_foreign_server form;
 
-   rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
+   rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
 
-   tup = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(name));
+   tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fwdId));
 
    if (!HeapTupleIsValid(tup))
        ereport(ERROR,
                (errcode(ERRCODE_UNDEFINED_OBJECT),
-                errmsg("server \"%s\" does not exist", name)));
+                errmsg("foreign-data wrapper with OID \"%u\" does not exist", fwdId)));
+
+   AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
+
+   heap_freetuple(tup);
+
+   heap_close(rel, RowExclusiveLock);
+}
+
+/*
+ * Internal workhorse for changing a foreign server's owner
+ */
+static void
+AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
+{
+   Form_pg_foreign_server form;
 
-   srvId = HeapTupleGetOid(tup);
    form = (Form_pg_foreign_server) GETSTRUCT(tup);
 
    if (form->srvowner != newOwnerId)
@@ -366,10 +388,15 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId)
        /* Superusers can always do it */
        if (!superuser())
        {
+           Oid         srvId;
+           AclResult   aclresult;
+
+           srvId = HeapTupleGetOid(tup);
+
            /* Must be owner */
            if (!pg_foreign_server_ownercheck(srvId, GetUserId()))
                aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
-                              name);
+                              NameStr(form->srvname));
 
            /* Must be able to become new owner */
            check_is_member_of_role(GetUserId(), newOwnerId);
@@ -393,12 +420,57 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId)
        changeDependencyOnOwner(ForeignServerRelationId, HeapTupleGetOid(tup),
                                newOwnerId);
    }
+}
+
+/*
+ * Change foreign server owner -- by name
+ */
+void
+AlterForeignServerOwner(const char *name, Oid newOwnerId)
+{
+   HeapTuple   tup;
+   Relation    rel;
+
+   rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
+
+   tup = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(name));
+
+   if (!HeapTupleIsValid(tup))
+       ereport(ERROR,
+               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                errmsg("server \"%s\" does not exist", name)));
+
+   AlterForeignServerOwner_internal(rel, tup, newOwnerId);
 
    heap_freetuple(tup);
 
    heap_close(rel, RowExclusiveLock);
 }
 
+/*
+ * Change foreign server owner -- by OID
+ */
+void
+AlterForeignServerOwner_oid(Oid srvId, Oid newOwnerId)
+{
+   HeapTuple   tup;
+   Relation    rel;
+
+   rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
+
+   tup = SearchSysCacheCopy1(FOREIGNSERVEROID, ObjectIdGetDatum(srvId));
+
+   if (!HeapTupleIsValid(tup))
+       ereport(ERROR,
+               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                errmsg("server with OID \"%u\" does not exist", srvId)));
+
+   AlterForeignServerOwner_internal(rel, tup, newOwnerId);
+
+   heap_freetuple(tup);
+
+   heap_close(rel, RowExclusiveLock);
+}
 
 /*
  * Convert a handler function name passed from the parser to an Oid.
index 6c7c04f898775c378bf29d4d05265ae7f56567df..163b2ea002b7f4312c446413fb4e8e097aa9b2e0 100644 (file)
@@ -149,7 +149,9 @@ extern List *deserialize_deflist(Datum txt);
 extern void RenameForeignServer(const char *oldname, const char *newname);
 extern void RenameForeignDataWrapper(const char *oldname, const char *newname);
 extern void AlterForeignServerOwner(const char *name, Oid newOwnerId);
+extern void AlterForeignServerOwner_oid(Oid , Oid newOwnerId);
 extern void AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId);
+extern void AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId);
 extern void CreateForeignDataWrapper(CreateFdwStmt *stmt);
 extern void AlterForeignDataWrapper(AlterFdwStmt *stmt);
 extern void RemoveForeignDataWrapperById(Oid fdwId);