Skip to content

Commit 140766d

Browse files
committed
REASSIGN OWNED: Support foreign data wrappers and servers
This was overlooked when implementing those kinds of objects, in commit cae565e. Per report from Pawel Casperek.
1 parent 315cb2f commit 140766d

File tree

3 files changed

+115
-31
lines changed

3 files changed

+115
-31
lines changed

src/backend/catalog/pg_shdepend.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include "catalog/pg_conversion.h"
2525
#include "catalog/pg_database.h"
2626
#include "catalog/pg_default_acl.h"
27+
#include "catalog/pg_foreign_data_wrapper.h"
28+
#include "catalog/pg_foreign_server.h"
2729
#include "catalog/pg_language.h"
2830
#include "catalog/pg_largeobject.h"
2931
#include "catalog/pg_namespace.h"
@@ -1376,6 +1378,14 @@ shdepReassignOwned(List *roleids, Oid newrole)
13761378
AlterOpFamilyOwner_oid(sdepForm->objid, newrole);
13771379
break;
13781380

1381+
case ForeignServerRelationId:
1382+
AlterForeignServerOwner_oid(sdepForm->objid, newrole);
1383+
break;
1384+
1385+
case ForeignDataWrapperRelationId:
1386+
AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
1387+
break;
1388+
13791389
default:
13801390
elog(ERROR, "unexpected classid %u", sdepForm->classid);
13811391
break;

src/backend/commands/foreigncmds.c

Lines changed: 103 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -189,47 +189,34 @@ GetUserOidFromMapping(const char *username, bool missing_ok)
189189

190190

191191
/*
192-
* Change foreign-data wrapper owner.
192+
* Internal workhorse for changing a data wrapper's owner.
193193
*
194194
* Allow this only for superusers; also the new owner must be a
195195
* superuser.
196196
*/
197-
void
198-
AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
197+
static void
198+
AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
199199
{
200-
HeapTuple tup;
201-
Relation rel;
202-
Oid fdwId;
203200
Form_pg_foreign_data_wrapper form;
204201

205-
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
202+
form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
206203

207204
/* Must be a superuser to change a FDW owner */
208205
if (!superuser())
209206
ereport(ERROR,
210207
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
211208
errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
212-
name),
209+
NameStr(form->fdwname)),
213210
errhint("Must be superuser to change owner of a foreign-data wrapper.")));
214211

215212
/* New owner must also be a superuser */
216213
if (!superuser_arg(newOwnerId))
217214
ereport(ERROR,
218215
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
219216
errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
220-
name),
217+
NameStr(form->fdwname)),
221218
errhint("The owner of a foreign-data wrapper must be a superuser.")));
222219

223-
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(name));
224-
225-
if (!HeapTupleIsValid(tup))
226-
ereport(ERROR,
227-
(errcode(ERRCODE_UNDEFINED_OBJECT),
228-
errmsg("foreign-data wrapper \"%s\" does not exist", name)));
229-
230-
fdwId = HeapTupleGetOid(tup);
231-
form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
232-
233220
if (form->fdwowner != newOwnerId)
234221
{
235222
form->fdwowner = newOwnerId;
@@ -239,48 +226,88 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
239226

240227
/* Update owner dependency reference */
241228
changeDependencyOnOwner(ForeignDataWrapperRelationId,
242-
fdwId,
229+
HeapTupleGetOid(tup),
243230
newOwnerId);
244231
}
232+
}
233+
234+
/*
235+
* Change foreign-data wrapper owner -- by name
236+
*
237+
* Note restrictions in the "_internal" function, above.
238+
*/
239+
void
240+
AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
241+
{
242+
HeapTuple tup;
243+
Relation rel;
244+
245+
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
246+
247+
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(name));
248+
249+
if (!HeapTupleIsValid(tup))
250+
ereport(ERROR,
251+
(errcode(ERRCODE_UNDEFINED_OBJECT),
252+
errmsg("foreign-data wrapper \"%s\" does not exist", name)));
253+
254+
AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
245255

246256
heap_close(rel, NoLock);
247257
heap_freetuple(tup);
248258
}
249259

250-
251260
/*
252-
* Change foreign server owner
261+
* Change foreign-data wrapper owner -- by OID
262+
*
263+
* Note restrictions in the "_internal" function, above.
253264
*/
254265
void
255-
AlterForeignServerOwner(const char *name, Oid newOwnerId)
266+
AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId)
256267
{
257268
HeapTuple tup;
258269
Relation rel;
259-
Oid srvId;
260-
AclResult aclresult;
261-
Form_pg_foreign_server form;
262270

263-
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
271+
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
264272

265-
tup = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(name));
273+
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fwdId));
266274

267275
if (!HeapTupleIsValid(tup))
268276
ereport(ERROR,
269277
(errcode(ERRCODE_UNDEFINED_OBJECT),
270-
errmsg("server \"%s\" does not exist", name)));
278+
errmsg("foreign-data wrapper with OID \"%u\" does not exist", fwdId)));
279+
280+
AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
281+
282+
heap_freetuple(tup);
283+
284+
heap_close(rel, RowExclusiveLock);
285+
}
286+
287+
/*
288+
* Internal workhorse for changing a foreign server's owner
289+
*/
290+
static void
291+
AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
292+
{
293+
Form_pg_foreign_server form;
271294

272-
srvId = HeapTupleGetOid(tup);
273295
form = (Form_pg_foreign_server) GETSTRUCT(tup);
274296

275297
if (form->srvowner != newOwnerId)
276298
{
277299
/* Superusers can always do it */
278300
if (!superuser())
279301
{
302+
Oid srvId;
303+
AclResult aclresult;
304+
305+
srvId = HeapTupleGetOid(tup);
306+
280307
/* Must be owner */
281308
if (!pg_foreign_server_ownercheck(srvId, GetUserId()))
282309
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
283-
name);
310+
NameStr(form->srvname));
284311

285312
/* Must be able to become new owner */
286313
check_is_member_of_role(GetUserId(), newOwnerId);
@@ -304,11 +331,56 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId)
304331
changeDependencyOnOwner(ForeignServerRelationId, HeapTupleGetOid(tup),
305332
newOwnerId);
306333
}
334+
}
335+
336+
/*
337+
* Change foreign server owner -- by name
338+
*/
339+
void
340+
AlterForeignServerOwner(const char *name, Oid newOwnerId)
341+
{
342+
HeapTuple tup;
343+
Relation rel;
344+
345+
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
346+
347+
tup = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(name));
348+
349+
if (!HeapTupleIsValid(tup))
350+
ereport(ERROR,
351+
(errcode(ERRCODE_UNDEFINED_OBJECT),
352+
errmsg("server \"%s\" does not exist", name)));
353+
354+
AlterForeignServerOwner_internal(rel, tup, newOwnerId);
307355

308356
heap_close(rel, NoLock);
309357
heap_freetuple(tup);
310358
}
311359

360+
/*
361+
* Change foreign server owner -- by OID
362+
*/
363+
void
364+
AlterForeignServerOwner_oid(Oid srvId, Oid newOwnerId)
365+
{
366+
HeapTuple tup;
367+
Relation rel;
368+
369+
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
370+
371+
tup = SearchSysCacheCopy1(FOREIGNSERVEROID, ObjectIdGetDatum(srvId));
372+
373+
if (!HeapTupleIsValid(tup))
374+
ereport(ERROR,
375+
(errcode(ERRCODE_UNDEFINED_OBJECT),
376+
errmsg("server with OID \"%u\" does not exist", srvId)));
377+
378+
AlterForeignServerOwner_internal(rel, tup, newOwnerId);
379+
380+
heap_freetuple(tup);
381+
382+
heap_close(rel, RowExclusiveLock);
383+
}
312384

313385
/*
314386
* Convert a validator function name passed from the parser to an Oid.

src/include/commands/defrem.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ extern List *deserialize_deflist(Datum txt);
130130

131131
/* commands/foreigncmds.c */
132132
extern void AlterForeignServerOwner(const char *name, Oid newOwnerId);
133+
extern void AlterForeignServerOwner_oid(Oid , Oid newOwnerId);
133134
extern void AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId);
135+
extern void AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId);
134136
extern void CreateForeignDataWrapper(CreateFdwStmt *stmt);
135137
extern void AlterForeignDataWrapper(AlterFdwStmt *stmt);
136138
extern void RemoveForeignDataWrapper(DropFdwStmt *stmt);

0 commit comments

Comments
 (0)