]> granicus.if.org Git - postgresql/commitdiff
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:32:42 +0000 (17:32 -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 591352d4b4376fe1f074b8b48a6c4523681f3013..b3696325c9d924111c549cdc010f3846d03e5cb2 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 3a3c131366829018913e8a0b7afa12661718c371..ddeb38e249438dc619fc3fb02feeb3331fa85b3d 100644 (file)
@@ -202,27 +202,24 @@ GetUserOidFromMapping(const char *username, bool missing_ok)
 
 
 /*
- * 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 */
@@ -230,19 +227,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;
@@ -252,38 +239,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)
@@ -291,10 +313,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);
@@ -318,12 +345,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 bbc024f50ccbc8063a65ca739170587a11a00e7c..d2a635282268b94312a9ecf0e46a42b211514e9a 100644 (file)
@@ -149,7 +149,9 @@ extern List *deserialize_deflist(Datum txt);
 
 /* commands/foreigncmds.c */
 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 RemoveForeignDataWrapper(DropFdwStmt *stmt);