summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2012-02-21 17:58:02 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2012-02-22 17:32:42 -0300
commitcfd1c382f0e85dea157ec6d56352d0513f7b7f0f (patch)
tree580ff75178af72959592deb6df977495d1d11321
parent11c730f4122ee8677b1cfdd5647faeaabc471af8 (diff)
downloadpostgresql-cfd1c382f0e85dea157ec6d56352d0513f7b7f0f.tar.gz
REASSIGN OWNED: Support foreign data wrappers and servers
This was overlooked when implementing those kinds of objects, in commit cae565e503c42a0942ca1771665243b4453c5770. Per report from Pawel Casperek.
-rw-r--r--src/backend/catalog/pg_shdepend.c10
-rw-r--r--src/backend/commands/foreigncmds.c134
-rw-r--r--src/include/commands/defrem.h2
3 files changed, 115 insertions, 31 deletions
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index 591352d4b4..b3696325c9 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -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;
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index 3a3c131366..ddeb38e249 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -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.
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index bbc024f50c..d2a6352822 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -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);