*** a/doc/src/sgml/ref/drop_owned.sgml
--- b/doc/src/sgml/ref/drop_owned.sgml
***************
*** 111,116 **** DROP OWNED BY name [, ...] [ CASCAD
--- 111,117 ----
See Also
+
*** /dev/null
--- b/doc/src/sgml/ref/drop_privileges_owned.sgml
***************
*** 0 ****
--- 1,72 ----
+
+
+
+
+ DROP PRIVILEGES OWNED
+
+
+
+ DROP PRIVILEGES OWNED
+ 7
+ SQL - Language Statements
+
+
+
+ DROP PRIVILEGES OWNED
+ remove privileges granted to a database role
+
+
+
+
+ DROP PRIVILEGES OWNED BY name [, ...]
+
+
+
+
+ Description
+
+
+ DROP PRIVILEGES OWNED revokes all privileges granted to
+ the given roles on objects in the current database and on shared objects
+ (databases, tablespaces).
+
+
+
+
+ Parameters
+
+
+
+ name
+
+
+ The name of a role whose privileges will be revoked.
+
+
+
+
+
+
+
+ Compatibility
+
+
+ The DROP PRIVILEGES OWNED statement is a
+ PostgreSQL extension.
+
+
+
+
+ See Also
+
+
+
+
+
+
+
+
+
*** a/src/backend/catalog/pg_shdepend.c
--- b/src/backend/catalog/pg_shdepend.c
***************
*** 1162,1174 **** isSharedObjectPinned(Oid classId, Oid objectId, Relation sdepRel)
* interdependent objects in the wrong order.
*/
void
! shdepDropOwned(List *roleids, DropBehavior behavior)
{
Relation sdepRel;
ListCell *cell;
! ObjectAddresses *deleteobjs;
! deleteobjs = new_object_addresses();
/*
* We don't need this strong a lock here, but we'll call routines that
--- 1162,1175 ----
* interdependent objects in the wrong order.
*/
void
! shdepDropOwned(List *roleids, DropBehavior behavior, bool privilegesOnly)
{
Relation sdepRel;
ListCell *cell;
! ObjectAddresses *deleteobjs = NULL;
! if (!privilegesOnly)
! deleteobjs = new_object_addresses();
/*
* We don't need this strong a lock here, but we'll call routines that
***************
*** 1243,1249 **** shdepDropOwned(List *roleids, DropBehavior behavior)
break;
case SHARED_DEPENDENCY_OWNER:
/* If a local object, save it for deletion below */
! if (sdepForm->dbid == MyDatabaseId)
{
obj.classId = sdepForm->classid;
obj.objectId = sdepForm->objid;
--- 1244,1250 ----
break;
case SHARED_DEPENDENCY_OWNER:
/* If a local object, save it for deletion below */
! if (!privilegesOnly && sdepForm->dbid == MyDatabaseId)
{
obj.classId = sdepForm->classid;
obj.objectId = sdepForm->objid;
***************
*** 1257,1268 **** shdepDropOwned(List *roleids, DropBehavior behavior)
systable_endscan(scan);
}
! /* the dependency mechanism does the actual work */
! performMultipleDeletions(deleteobjs, behavior, 0);
heap_close(sdepRel, RowExclusiveLock);
! free_object_addresses(deleteobjs);
}
/*
--- 1258,1274 ----
systable_endscan(scan);
}
! /*
! * Unless we were asked not to drop objects, now is the time to let the
! * dependency mechanism do the actual work of dropping them.
! */
! if (!privilegesOnly)
! performMultipleDeletions(deleteobjs, behavior, 0);
heap_close(sdepRel, RowExclusiveLock);
! if (deleteobjs)
! free_object_addresses(deleteobjs);
}
/*
*** a/src/backend/commands/event_trigger.c
--- b/src/backend/commands/event_trigger.c
***************
*** 264,269 **** check_ddl_tag(const char *tag)
--- 264,270 ----
pg_strcasecmp(tag, "ALTER DEFAULT PRIVILEGES") == 0 ||
pg_strcasecmp(tag, "ALTER LARGE OBJECT") == 0 ||
pg_strcasecmp(tag, "DROP OWNED") == 0 ||
+ pg_strcasecmp(tag, "DROP PRIVILEGES OWNED") == 0 ||
pg_strcasecmp(tag, "IMPORT FOREIGN SCHEMA") == 0)
return EVENT_TRIGGER_COMMAND_TAG_OK;
*** a/src/backend/commands/user.c
--- b/src/backend/commands/user.c
***************
*** 1308,1314 **** DropOwnedObjects(DropOwnedStmt *stmt)
}
/* Ok, do it */
! shdepDropOwned(role_ids, stmt->behavior);
}
/*
--- 1308,1340 ----
}
/* Ok, do it */
! shdepDropOwned(role_ids, stmt->behavior, false);
! }
!
! /*
! * DropOwnedPrivileges
! *
! * Revoke privileges granted to a given list of roles.
! */
! void
! DropOwnedPrivileges(DropPrivilegesOwnedStmt *stmt)
! {
! List *role_ids = roleNamesToIds(stmt->roles);
! ListCell *cell;
!
! /* Check privileges */
! foreach(cell, role_ids)
! {
! Oid roleid = lfirst_oid(cell);
!
! if (!has_privs_of_role(GetUserId(), roleid))
! ereport(ERROR,
! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
! errmsg("permission denied to drop privileges")));
! }
!
! /* Ok, do it */
! shdepDropOwned(role_ids, DROP_RESTRICT, true);
}
/*
*** a/src/backend/nodes/copyfuncs.c
--- b/src/backend/nodes/copyfuncs.c
***************
*** 3844,3849 **** _copyDropOwnedStmt(const DropOwnedStmt *from)
--- 3844,3859 ----
return newnode;
}
+ static DropPrivilegesOwnedStmt *
+ _copyDropPrivilegesOwnedStmt(const DropPrivilegesOwnedStmt *from)
+ {
+ DropPrivilegesOwnedStmt *newnode = makeNode(DropPrivilegesOwnedStmt);
+
+ COPY_NODE_FIELD(roles);
+
+ return newnode;
+ }
+
static ReassignOwnedStmt *
_copyReassignOwnedStmt(const ReassignOwnedStmt *from)
{
***************
*** 4616,4621 **** copyObject(const void *from)
--- 4626,4634 ----
case T_DropOwnedStmt:
retval = _copyDropOwnedStmt(from);
break;
+ case T_DropPrivilegesOwnedStmt:
+ retval = _copyDropPrivilegesOwnedStmt(from);
+ break;
case T_ReassignOwnedStmt:
retval = _copyReassignOwnedStmt(from);
break;
*** a/src/backend/nodes/equalfuncs.c
--- b/src/backend/nodes/equalfuncs.c
***************
*** 1978,1983 **** _equalDropOwnedStmt(const DropOwnedStmt *a, const DropOwnedStmt *b)
--- 1978,1991 ----
}
static bool
+ _equalDropPrivilegesOwnedStmt(const DropPrivilegesOwnedStmt *a, const DropPrivilegesOwnedStmt *b)
+ {
+ COMPARE_NODE_FIELD(roles);
+
+ return true;
+ }
+
+ static bool
_equalReassignOwnedStmt(const ReassignOwnedStmt *a, const ReassignOwnedStmt *b)
{
COMPARE_NODE_FIELD(roles);
***************
*** 3043,3048 **** equal(const void *a, const void *b)
--- 3051,3059 ----
case T_DropOwnedStmt:
retval = _equalDropOwnedStmt(a, b);
break;
+ case T_DropPrivilegesOwnedStmt:
+ retval = _equalDropPrivilegesOwnedStmt(a, b);
+ break;
case T_ReassignOwnedStmt:
retval = _equalReassignOwnedStmt(a, b);
break;
*** a/src/backend/parser/gram.y
--- b/src/backend/parser/gram.y
***************
*** 256,262 **** static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
VariableResetStmt VariableSetStmt VariableShowStmt
ViewStmt CheckPointStmt CreateConversionStmt
DeallocateStmt PrepareStmt ExecuteStmt
! DropOwnedStmt ReassignOwnedStmt
AlterTSConfigurationStmt AlterTSDictionaryStmt
CreateMatViewStmt RefreshMatViewStmt
--- 256,262 ----
VariableResetStmt VariableSetStmt VariableShowStmt
ViewStmt CheckPointStmt CreateConversionStmt
DeallocateStmt PrepareStmt ExecuteStmt
! DropOwnedStmt DropPrivilegesOwnedStmt ReassignOwnedStmt
AlterTSConfigurationStmt AlterTSDictionaryStmt
CreateMatViewStmt RefreshMatViewStmt
***************
*** 807,812 **** stmt :
--- 807,813 ----
| DropOpFamilyStmt
| DropOwnedStmt
| DropPolicyStmt
+ | DropPrivilegesOwnedStmt
| DropPLangStmt
| DropRuleStmt
| DropStmt
***************
*** 5389,5394 **** DropOpFamilyStmt:
--- 5390,5396 ----
* QUERY:
*
* DROP OWNED BY username [, username ...] [ RESTRICT | CASCADE ]
+ * DROP PRIVILEGES OWNED BY username [, username ...]
* REASSIGN OWNED BY username [, username ...] TO username
*
*****************************************************************************/
***************
*** 5400,5405 **** DropOwnedStmt:
--- 5402,5416 ----
n->behavior = $5;
$$ = (Node *)n;
}
+ ;
+
+ DropPrivilegesOwnedStmt:
+ DROP PRIVILEGES OWNED BY role_list
+ {
+ DropPrivilegesOwnedStmt *n = makeNode(DropPrivilegesOwnedStmt);
+ n->roles = $5;
+ $$ = (Node *)n;
+ }
;
ReassignOwnedStmt:
*** a/src/backend/tcop/utility.c
--- b/src/backend/tcop/utility.c
***************
*** 189,194 **** check_xact_readonly(Node *parsetree)
--- 189,195 ----
case T_AlterDefaultPrivilegesStmt:
case T_TruncateStmt:
case T_DropOwnedStmt:
+ case T_DropPrivilegesOwnedStmt:
case T_ReassignOwnedStmt:
case T_AlterTSDictionaryStmt:
case T_AlterTSConfigurationStmt:
***************
*** 1319,1324 **** ProcessUtilitySlow(Node *parsetree,
--- 1320,1329 ----
DropOwnedObjects((DropOwnedStmt *) parsetree);
break;
+ case T_DropPrivilegesOwnedStmt:
+ DropOwnedPrivileges((DropPrivilegesOwnedStmt *) parsetree);
+ break;
+
case T_AlterDefaultPrivilegesStmt:
ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
break;
***************
*** 2256,2261 **** CreateCommandTag(Node *parsetree)
--- 2261,2270 ----
tag = "DROP OWNED";
break;
+ case T_DropPrivilegesOwnedStmt:
+ tag = "DROP PRIVILEGES OWNED";
+ break;
+
case T_ReassignOwnedStmt:
tag = "REASSIGN OWNED";
break;
***************
*** 2813,2818 **** GetCommandLogLevel(Node *parsetree)
--- 2822,2831 ----
lev = LOGSTMT_DDL;
break;
+ case T_DropPrivilegesOwnedStmt:
+ lev = LOGSTMT_DDL;
+ break;
+
case T_ReassignOwnedStmt:
lev = LOGSTMT_DDL;
break;
*** a/src/include/catalog/dependency.h
--- b/src/include/catalog/dependency.h
***************
*** 255,261 **** extern void copyTemplateDependencies(Oid templateDbId, Oid newDbId);
extern void dropDatabaseDependencies(Oid databaseId);
! extern void shdepDropOwned(List *relids, DropBehavior behavior);
extern void shdepReassignOwned(List *relids, Oid newrole);
--- 255,261 ----
extern void dropDatabaseDependencies(Oid databaseId);
! extern void shdepDropOwned(List *relids, DropBehavior behavior, bool privilegesOnly);
extern void shdepReassignOwned(List *relids, Oid newrole);
*** a/src/include/commands/user.h
--- b/src/include/commands/user.h
***************
*** 29,34 **** extern void DropRole(DropRoleStmt *stmt);
--- 29,35 ----
extern void GrantRole(GrantRoleStmt *stmt);
extern Oid RenameRole(const char *oldname, const char *newname);
extern void DropOwnedObjects(DropOwnedStmt *stmt);
+ extern void DropOwnedPrivileges(DropPrivilegesOwnedStmt *stmt);
extern void ReassignOwnedObjects(ReassignOwnedStmt *stmt);
extern List *roleNamesToIds(List *memberNames);
*** a/src/include/nodes/nodes.h
--- b/src/include/nodes/nodes.h
***************
*** 342,347 **** typedef enum NodeTag
--- 342,348 ----
T_AlterObjectSchemaStmt,
T_AlterOwnerStmt,
T_DropOwnedStmt,
+ T_DropPrivilegesOwnedStmt,
T_ReassignOwnedStmt,
T_CompositeTypeStmt,
T_CreateEnumStmt,
*** a/src/include/nodes/parsenodes.h
--- b/src/include/nodes/parsenodes.h
***************
*** 2816,2821 **** typedef struct DropOwnedStmt
--- 2816,2830 ----
} DropOwnedStmt;
/*
+ * DROP PRIVILEGES OWNED statement
+ */
+ typedef struct DropPrivilegesOwnedStmt
+ {
+ NodeTag type;
+ List *roles;
+ } DropPrivilegesOwnedStmt;
+
+ /*
* REASSIGN OWNED statement
*/
typedef struct ReassignOwnedStmt
*** a/src/test/regress/expected/dependency.out
--- b/src/test/regress/expected/dependency.out
***************
*** 61,67 **** GRANT ALL ON deptest1 TO regression_user1 WITH GRANT OPTION;
--- 61,84 ----
SET SESSION AUTHORIZATION regression_user1;
CREATE TABLE deptest (a serial primary key, b text);
GRANT ALL ON deptest1 TO regression_user2;
+ GRANT ALL ON deptest TO regression_user2;
RESET SESSION AUTHORIZATION;
+ \z deptest
+ Access privileges
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+ --------+---------+-------+-------------------------------------------+-------------------+----------
+ public | deptest | table | regression_user1=arwdDxt/regression_user1+| |
+ | | | regression_user2=arwdDxt/regression_user1 | |
+ (1 row)
+
+ DROP PRIVILEGES OWNED BY regression_user2;
+ \z deptest
+ Access privileges
+ Schema | Name | Type | Access privileges | Column privileges | Policies
+ --------+---------+-------+-------------------------------------------+-------------------+----------
+ public | deptest | table | regression_user1=arwdDxt/regression_user1 | |
+ (1 row)
+
\z deptest1
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
*** a/src/test/regress/sql/dependency.sql
--- b/src/test/regress/sql/dependency.sql
***************
*** 63,71 **** GRANT ALL ON deptest1 TO regression_user1 WITH GRANT OPTION;
SET SESSION AUTHORIZATION regression_user1;
CREATE TABLE deptest (a serial primary key, b text);
GRANT ALL ON deptest1 TO regression_user2;
RESET SESSION AUTHORIZATION;
- \z deptest1
DROP OWNED BY regression_user1;
-- all grants revoked
\z deptest1
--- 63,76 ----
SET SESSION AUTHORIZATION regression_user1;
CREATE TABLE deptest (a serial primary key, b text);
GRANT ALL ON deptest1 TO regression_user2;
+ GRANT ALL ON deptest TO regression_user2;
RESET SESSION AUTHORIZATION;
+ \z deptest
+ DROP PRIVILEGES OWNED BY regression_user2;
+ \z deptest
+
+ \z deptest1
DROP OWNED BY regression_user1;
-- all grants revoked
\z deptest1