Hi All,

Consider the below test:

postgres@53130=#create role test WITH login createdb;
CREATE ROLE
postgres@53130=#\c - test
You are now connected to database "postgres" as user "test".
postgres@53150=#create database test;
CREATE DATABASE
postgres@53150=#\c - rushabh
You are now connected to database "postgres" as user "rushabh".
postgres@53162=#
postgres@53162=#
-- This was working before the below mentioned commit.
postgres@53162=#drop owned by test;
ERROR:  global objects cannot be deleted by doDeletion

Commit 6566133c5f52771198aca07ed18f84519fac1be7 ensure that
pg_auth_members.grantor is always valid.  This commit did changes
into shdepDropOwned() function and combined the SHARED_DEPENDENCY_ACL
and SHARED_DEPENDENCY_OWNER.  In that process it removed condition for
local object in owner dependency.

                case SHARED_DEPENDENCY_OWNER:
-                   /* If a local object, save it for deletion below */
-                   if (sdepForm->dbid == MyDatabaseId)
+                   /* Save it for deletion below */

Case ending up with above error because of the above removed condition.

Please find the attached patch which fixes the case.

Thanks,
Rushabh Lathia
www.EnterpriseDB.com
diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c
index f2f227f..6134fe3 100644
--- a/src/backend/catalog/pg_shdepend.c
+++ b/src/backend/catalog/pg_shdepend.c
@@ -1411,8 +1411,6 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
 												sdepForm->objid);
 						break;
 					}
-					/* FALLTHROUGH */
-				case SHARED_DEPENDENCY_OWNER:
 					/* Save it for deletion below */
 					obj.classId = sdepForm->classid;
 					obj.objectId = sdepForm->objid;
@@ -1426,6 +1424,24 @@ shdepDropOwned(List *roleids, DropBehavior behavior)
 					}
 					add_exact_object_address(&obj, deleteobjs);
 					break;
+				case SHARED_DEPENDENCY_OWNER:
+					/* If a local object, save it for deletion below */
+					if (sdepForm->dbid == MyDatabaseId)
+					{
+						/* Save it for deletion below */
+						obj.classId = sdepForm->classid;
+						obj.objectId = sdepForm->objid;
+						obj.objectSubId = sdepForm->objsubid;
+						/* as above */
+						AcquireDeletionLock(&obj, 0);
+						if (!systable_recheck_tuple(scan, tuple))
+						{
+							ReleaseDeletionLock(&obj);
+							break;
+						}
+						add_exact_object_address(&obj, deleteobjs);
+					}
+					break;
 			}
 		}
 

Reply via email to