diff options
Diffstat (limited to 'src/backend/commands/tablespace.c')
-rw-r--r-- | src/backend/commands/tablespace.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 05a89f0bde2..d73e5e826dc 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -67,6 +67,7 @@ #include "commands/seclabel.h" #include "commands/tablecmds.h" #include "commands/tablespace.h" +#include "commands/user.h" #include "common/relpath.h" #include "miscadmin.h" #include "postmaster/bgwriter.h" @@ -994,6 +995,7 @@ AlterTableSpaceMove(AlterTableSpaceMoveStmt *stmt) HeapTuple tuple; Oid orig_tablespaceoid; Oid new_tablespaceoid; + List *role_oids = roleNamesToIds(stmt->roles); /* Ensure we were not asked to move something we can't */ if (!stmt->move_all && stmt->objtype != OBJECT_TABLE && @@ -1075,14 +1077,10 @@ AlterTableSpaceMove(AlterTableSpaceMoveStmt *stmt) relForm->relnamespace == PG_TOAST_NAMESPACE) continue; - /* - * Only move objects that we are considered an owner of and only - * objects which can actually have a tablespace. - */ - if (!pg_class_ownercheck(relOid, GetUserId()) || - (relForm->relkind != RELKIND_RELATION && - relForm->relkind != RELKIND_INDEX && - relForm->relkind != RELKIND_MATVIEW)) + /* Only consider objects which live in tablespaces */ + if (relForm->relkind != RELKIND_RELATION && + relForm->relkind != RELKIND_INDEX && + relForm->relkind != RELKIND_MATVIEW) continue; /* Check if we were asked to only move a certain type of object */ @@ -1095,6 +1093,21 @@ AlterTableSpaceMove(AlterTableSpaceMoveStmt *stmt) relForm->relkind != RELKIND_MATVIEW))) continue; + /* Check if we are only moving objects owned by certain roles */ + if (role_oids != NIL && !list_member_oid(role_oids, relForm->relowner)) + continue; + + /* + * Handle permissions-checking here since we are locking the tables + * and also to avoid doing a bunch of work only to fail part-way. + * Note that permissions will also be checked by AlterTableInternal(). + * + * Caller must be considered an owner on the table to move it. + */ + if (!pg_class_ownercheck(relOid, GetUserId())) + aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, + NameStr(relForm->relname)); + if (stmt->nowait && !ConditionalLockRelationOid(relOid, AccessExclusiveLock)) ereport(ERROR, |