0001-Fix-DROP-ROLE-when-specifying-duplicated-roles.patch
text/x-diff
Filename: 0001-Fix-DROP-ROLE-when-specifying-duplicated-roles.patch
Type: text/x-diff
Part: 0
Patch
Format: format-patch
Series: patch 0001
Subject: Fix DROP ROLE when specifying duplicated roles
| File | + | − |
|---|---|---|
| src/backend/commands/user.c | 5 | 11 |
| src/test/regress/expected/create_role.out | 2 | 1 |
| src/test/regress/sql/create_role.sql | 2 | 1 |
From 8a82a8813b31ead6f37d2b1576239c769bdacbda Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Fri, 26 Jan 2024 11:30:56 +0900
Subject: [PATCH] Fix DROP ROLE when specifying duplicated roles
This would cause failures with "tuple already updated by self", blah.
Reported-by: Alexander Lakhin
Discussion: https://postgr.es/m/18310-1eb233c5908189c8@postgresql.org
Backpatch-through: 12
---
src/backend/commands/user.c | 16 +++++-----------
src/test/regress/expected/create_role.out | 3 ++-
src/test/regress/sql/create_role.sql | 3 ++-
3 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 7a9c177b21..6839d44a2f 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -1093,7 +1093,7 @@ DropRole(DropRoleStmt *stmt)
Relation pg_authid_rel,
pg_auth_members_rel;
ListCell *item;
- List *role_addresses = NIL;
+ List *role_oids = NIL;
if (!have_createrole_privilege())
ereport(ERROR,
@@ -1119,7 +1119,6 @@ DropRole(DropRoleStmt *stmt)
ScanKeyData scankey;
SysScanDesc sscan;
Oid roleid;
- ObjectAddress *role_address;
if (rolspec->roletype != ROLESPEC_CSTRING)
ereport(ERROR,
@@ -1260,21 +1259,16 @@ DropRole(DropRoleStmt *stmt)
*/
CommandCounterIncrement();
- /* Looks tentatively OK, add it to the list. */
- role_address = palloc(sizeof(ObjectAddress));
- role_address->classId = AuthIdRelationId;
- role_address->objectId = roleid;
- role_address->objectSubId = 0;
- role_addresses = lappend(role_addresses, role_address);
+ /* Looks tentatively OK, add it to the list if not there yet. */
+ role_oids = list_append_unique_oid(role_oids, roleid);
}
/*
* Second pass over the roles to be removed.
*/
- foreach(item, role_addresses)
+ foreach(item, role_oids)
{
- ObjectAddress *role_address = lfirst(item);
- Oid roleid = role_address->objectId;
+ Oid roleid = lfirst_oid(item);
HeapTuple tuple;
Form_pg_authid roleform;
char *detail;
diff --git a/src/test/regress/expected/create_role.out b/src/test/regress/expected/create_role.out
index 7117e943c2..46d4f9efe9 100644
--- a/src/test/regress/expected/create_role.out
+++ b/src/test/regress/expected/create_role.out
@@ -251,7 +251,8 @@ DROP INDEX tenant_idx;
DROP TABLE tenant_table;
DROP VIEW tenant_view;
DROP SCHEMA regress_tenant2_schema;
-DROP ROLE regress_tenant;
+-- check for duplicated drop
+DROP ROLE regress_tenant, regress_tenant;
DROP ROLE regress_tenant2;
DROP ROLE regress_rolecreator;
DROP ROLE regress_role_admin;
diff --git a/src/test/regress/sql/create_role.sql b/src/test/regress/sql/create_role.sql
index 12582a3cc2..4491a28a8a 100644
--- a/src/test/regress/sql/create_role.sql
+++ b/src/test/regress/sql/create_role.sql
@@ -206,7 +206,8 @@ DROP INDEX tenant_idx;
DROP TABLE tenant_table;
DROP VIEW tenant_view;
DROP SCHEMA regress_tenant2_schema;
-DROP ROLE regress_tenant;
+-- check for duplicated drop
+DROP ROLE regress_tenant, regress_tenant;
DROP ROLE regress_tenant2;
DROP ROLE regress_rolecreator;
DROP ROLE regress_role_admin;
--
2.43.0