From 344dc1fbfe572ef0f4b93c00ce811aa524e30ec4 Mon Sep 17 00:00:00 2001 From: "tender.wang" Date: Thu, 18 Jan 2024 23:26:16 +0800 Subject: [PATCH] Fix dropped same role id twice error. --- src/backend/commands/user.c | 23 +++++++++++++++++++++++ src/test/regress/expected/create_role.out | 3 +++ src/test/regress/sql/create_role.sql | 5 +++++ 3 files changed, 31 insertions(+) diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index 7e81589711..1fc6b9e201 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -1083,6 +1083,19 @@ AlterRoleSet(AlterRoleSetStmt *stmt) return roleid; } +/* list_sort comparator to sort ObjectAddress by objectId */ +static int +objectId_comparator(const ListCell *p1, const ListCell *p2) +{ + Oid o1 = ((ObjectAddress *) lfirst(p1))->objectId; + Oid o2 = ((ObjectAddress *) lfirst(p2))->objectId; + + if (o1 > o2) + return -1; + if (o1 < o2) + return 1; + return 0; +} /* * DROP ROLE @@ -1093,6 +1106,7 @@ DropRole(DropRoleStmt *stmt) Relation pg_authid_rel, pg_auth_members_rel; ListCell *item; + ObjectAddress *pre_object = NULL; List *role_addresses = NIL; if (!have_createrole_privilege()) @@ -1268,6 +1282,9 @@ DropRole(DropRoleStmt *stmt) role_addresses = lappend(role_addresses, role_address); } + /* Sort the role_addresses to avoid to remove same roleid repeatedly */ + list_sort(role_addresses, objectId_comparator); + /* * Second pass over the roles to be removed. */ @@ -1280,6 +1297,12 @@ DropRole(DropRoleStmt *stmt) char *detail; char *detail_log; + /* Skip same roleid */ + if (pre_object && + pre_object->objectId == role_address->objectId) + continue; + else + pre_object = role_address; /* * Re-find the pg_authid tuple. * diff --git a/src/test/regress/expected/create_role.out b/src/test/regress/expected/create_role.out index 7117e943c2..cbfd1c6b56 100644 --- a/src/test/regress/expected/create_role.out +++ b/src/test/regress/expected/create_role.out @@ -4,6 +4,9 @@ CREATE ROLE regress_role_admin CREATEDB CREATEROLE REPLICATION BYPASSRLS; GRANT CREATE ON DATABASE regression TO regress_role_admin WITH GRANT OPTION; CREATE ROLE regress_role_limited_admin CREATEROLE; CREATE ROLE regress_role_normal; +--ok, can drop same role repeatedly +CREATE ROLE regress_role_dropped; +DROP ROLE regress_role_dropped, regress_role_dropped; -- fail, CREATEROLE user can't give away role attributes without having them SET SESSION AUTHORIZATION regress_role_limited_admin; CREATE ROLE regress_nosuch_superuser SUPERUSER; diff --git a/src/test/regress/sql/create_role.sql b/src/test/regress/sql/create_role.sql index 12582a3cc2..96a503bf2d 100644 --- a/src/test/regress/sql/create_role.sql +++ b/src/test/regress/sql/create_role.sql @@ -5,6 +5,11 @@ GRANT CREATE ON DATABASE regression TO regress_role_admin WITH GRANT OPTION; CREATE ROLE regress_role_limited_admin CREATEROLE; CREATE ROLE regress_role_normal; +--ok, can drop same role repeatedly +CREATE ROLE regress_role_dropped; + +DROP ROLE regress_role_dropped, regress_role_dropped; + -- fail, CREATEROLE user can't give away role attributes without having them SET SESSION AUTHORIZATION regress_role_limited_admin; CREATE ROLE regress_nosuch_superuser SUPERUSER; -- 2.25.1