Skip to content

Commit cfd1c38

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 11c730f commit cfd1c38

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
@@ -25,6 +25,8 @@
2525
#include "catalog/pg_conversion.h"
2626
#include "catalog/pg_database.h"
2727
#include "catalog/pg_default_acl.h"
28+
#include "catalog/pg_foreign_data_wrapper.h"
29+
#include "catalog/pg_foreign_server.h"
2830
#include "catalog/pg_language.h"
2931
#include "catalog/pg_largeobject.h"
3032
#include "catalog/pg_namespace.h"
@@ -1382,6 +1384,14 @@ shdepReassignOwned(List *roleids, Oid newrole)
13821384
AlterOpFamilyOwner_oid(sdepForm->objid, newrole);
13831385
break;
13841386

1387+
case ForeignServerRelationId:
1388+
AlterForeignServerOwner_oid(sdepForm->objid, newrole);
1389+
break;
1390+
1391+
case ForeignDataWrapperRelationId:
1392+
AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole);
1393+
break;
1394+
13851395
default:
13861396
elog(ERROR, "unexpected classid %u", sdepForm->classid);
13871397
break;

src/backend/commands/foreigncmds.c

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

203203

204204
/*
205-
* Change foreign-data wrapper owner.
205+
* Internal workhorse for changing a data wrapper's owner.
206206
*
207207
* Allow this only for superusers; also the new owner must be a
208208
* superuser.
209209
*/
210-
void
211-
AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
210+
static void
211+
AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
212212
{
213-
HeapTuple tup;
214-
Relation rel;
215-
Oid fdwId;
216213
Form_pg_foreign_data_wrapper form;
217214

218-
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
215+
form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
219216

220217
/* Must be a superuser to change a FDW owner */
221218
if (!superuser())
222219
ereport(ERROR,
223220
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
224221
errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
225-
name),
222+
NameStr(form->fdwname)),
226223
errhint("Must be superuser to change owner of a foreign-data wrapper.")));
227224

228225
/* New owner must also be a superuser */
229226
if (!superuser_arg(newOwnerId))
230227
ereport(ERROR,
231228
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
232229
errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
233-
name),
230+
NameStr(form->fdwname)),
234231
errhint("The owner of a foreign-data wrapper must be a superuser.")));
235232

236-
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(name));
237-
238-
if (!HeapTupleIsValid(tup))
239-
ereport(ERROR,
240-
(errcode(ERRCODE_UNDEFINED_OBJECT),
241-
errmsg("foreign-data wrapper \"%s\" does not exist", name)));
242-
243-
fdwId = HeapTupleGetOid(tup);
244-
form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
245-
246233
if (form->fdwowner != newOwnerId)
247234
{
248235
form->fdwowner = newOwnerId;
@@ -252,49 +239,89 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
252239

253240
/* Update owner dependency reference */
254241
changeDependencyOnOwner(ForeignDataWrapperRelationId,
255-
fdwId,
242+
HeapTupleGetOid(tup),
256243
newOwnerId);
257244
}
245+
}
246+
247+
/*
248+
* Change foreign-data wrapper owner -- by name
249+
*
250+
* Note restrictions in the "_internal" function, above.
251+
*/
252+
void
253+
AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
254+
{
255+
HeapTuple tup;
256+
Relation rel;
257+
258+
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
259+
260+
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(name));
261+
262+
if (!HeapTupleIsValid(tup))
263+
ereport(ERROR,
264+
(errcode(ERRCODE_UNDEFINED_OBJECT),
265+
errmsg("foreign-data wrapper \"%s\" does not exist", name)));
266+
267+
AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
258268

259269
heap_freetuple(tup);
260270

261271
heap_close(rel, RowExclusiveLock);
262272
}
263273

264-
265274
/*
266-
* Change foreign server owner
275+
* Change foreign-data wrapper owner -- by OID
276+
*
277+
* Note restrictions in the "_internal" function, above.
267278
*/
268279
void
269-
AlterForeignServerOwner(const char *name, Oid newOwnerId)
280+
AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId)
270281
{
271282
HeapTuple tup;
272283
Relation rel;
273-
Oid srvId;
274-
AclResult aclresult;
275-
Form_pg_foreign_server form;
276284

277-
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
285+
rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
278286

279-
tup = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(name));
287+
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fwdId));
280288

281289
if (!HeapTupleIsValid(tup))
282290
ereport(ERROR,
283291
(errcode(ERRCODE_UNDEFINED_OBJECT),
284-
errmsg("server \"%s\" does not exist", name)));
292+
errmsg("foreign-data wrapper with OID \"%u\" does not exist", fwdId)));
293+
294+
AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
295+
296+
heap_freetuple(tup);
297+
298+
heap_close(rel, RowExclusiveLock);
299+
}
300+
301+
/*
302+
* Internal workhorse for changing a foreign server's owner
303+
*/
304+
static void
305+
AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
306+
{
307+
Form_pg_foreign_server form;
285308

286-
srvId = HeapTupleGetOid(tup);
287309
form = (Form_pg_foreign_server) GETSTRUCT(tup);
288310

289311
if (form->srvowner != newOwnerId)
290312
{
291313
/* Superusers can always do it */
292314
if (!superuser())
293315
{
316+
Oid srvId;
317+
AclResult aclresult;
318+
319+
srvId = HeapTupleGetOid(tup);
320+
294321
/* Must be owner */
295322
if (!pg_foreign_server_ownercheck(srvId, GetUserId()))
296323
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_FOREIGN_SERVER,
297-
name);
324+
NameStr(form->srvname));
298325

299326
/* Must be able to become new owner */
300327
check_is_member_of_role(GetUserId(), newOwnerId);
@@ -318,12 +345,57 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId)
318345
changeDependencyOnOwner(ForeignServerRelationId, HeapTupleGetOid(tup),
319346
newOwnerId);
320347
}
348+
}
349+
350+
/*
351+
* Change foreign server owner -- by name
352+
*/
353+
void
354+
AlterForeignServerOwner(const char *name, Oid newOwnerId)
355+
{
356+
HeapTuple tup;
357+
Relation rel;
358+
359+
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
360+
361+
tup = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(name));
362+
363+
if (!HeapTupleIsValid(tup))
364+
ereport(ERROR,
365+
(errcode(ERRCODE_UNDEFINED_OBJECT),
366+
errmsg("server \"%s\" does not exist", name)));
367+
368+
AlterForeignServerOwner_internal(rel, tup, newOwnerId);
321369

322370
heap_freetuple(tup);
323371

324372
heap_close(rel, RowExclusiveLock);
325373
}
326374

375+
/*
376+
* Change foreign server owner -- by OID
377+
*/
378+
void
379+
AlterForeignServerOwner_oid(Oid srvId, Oid newOwnerId)
380+
{
381+
HeapTuple tup;
382+
Relation rel;
383+
384+
rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
385+
386+
tup = SearchSysCacheCopy1(FOREIGNSERVEROID, ObjectIdGetDatum(srvId));
387+
388+
if (!HeapTupleIsValid(tup))
389+
ereport(ERROR,
390+
(errcode(ERRCODE_UNDEFINED_OBJECT),
391+
errmsg("server with OID \"%u\" does not exist", srvId)));
392+
393+
AlterForeignServerOwner_internal(rel, tup, newOwnerId);
394+
395+
heap_freetuple(tup);
396+
397+
heap_close(rel, RowExclusiveLock);
398+
}
327399

328400
/*
329401
* Convert a handler 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
@@ -149,7 +149,9 @@ extern List *deserialize_deflist(Datum txt);
149149

150150
/* commands/foreigncmds.c */
151151
extern void AlterForeignServerOwner(const char *name, Oid newOwnerId);
152+
extern void AlterForeignServerOwner_oid(Oid , Oid newOwnerId);
152153
extern void AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId);
154+
extern void AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId);
153155
extern void CreateForeignDataWrapper(CreateFdwStmt *stmt);
154156
extern void AlterForeignDataWrapper(AlterFdwStmt *stmt);
155157
extern void RemoveForeignDataWrapper(DropFdwStmt *stmt);

0 commit comments

Comments
 (0)