Clean out column-level pg_init_privs entries when dropping tables.

DeleteInitPrivs did not get the memo about how, when dropping a
whole object (with subid == 0), you should drop entries relating
to its sub-objects too.  This is visible in the test_pg_dump test
case if one drops the extension at the end: the entry for
	GRANT SELECT(col1) ON regress_pg_dump_table TO public;
was still present in pg_init_privs afterwards, although it was
pointing to a dangling table OID.

Noted while fooling with a fix for REASSIGN OWNED for pg_init_privs
entries.  This bug is aboriginal in the pg_init_privs feature
though, and there seems no reason not to back-patch the fix.
This commit is contained in:
Tom Lane 2024-06-14 16:20:35 -04:00
parent 01aa88f712
commit 76618097a6
3 changed files with 27 additions and 6 deletions

View file

@ -1326,7 +1326,9 @@ deleteOneObject(const ObjectAddress *object, Relation *depRel, int flags)
/*
* Delete any comments, security labels, or initial privileges associated
* with this object. (This is a convenient place to do these things,
* rather than having every object type know to do it.)
* rather than having every object type know to do it.) As above, all
* these functions must remove records for sub-objects too if the subid is
* zero.
*/
DeleteComments(object->objectId, object->classId, object->objectSubId);
DeleteSecurityLabel(object);
@ -2784,6 +2786,7 @@ DeleteInitPrivs(const ObjectAddress *object)
{
Relation relation;
ScanKeyData key[3];
int nkeys;
SysScanDesc scan;
HeapTuple oldtuple;
@ -2797,13 +2800,19 @@ DeleteInitPrivs(const ObjectAddress *object)
Anum_pg_init_privs_classoid,
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(object->classId));
ScanKeyInit(&key[2],
Anum_pg_init_privs_objsubid,
BTEqualStrategyNumber, F_INT4EQ,
Int32GetDatum(object->objectSubId));
if (object->objectSubId != 0)
{
ScanKeyInit(&key[2],
Anum_pg_init_privs_objsubid,
BTEqualStrategyNumber, F_INT4EQ,
Int32GetDatum(object->objectSubId));
nkeys = 3;
}
else
nkeys = 2;
scan = systable_beginscan(relation, InitPrivsObjIndexId, true,
NULL, 3, key);
NULL, nkeys, key);
while (HeapTupleIsValid(oldtuple = systable_getnext(scan)))
CatalogTupleDelete(relation, &oldtuple->t_self);

View file

@ -276,3 +276,10 @@ SELECT pg_describe_object(classid,objid,objsubid) COLLATE "C" AS obj,
(0 rows)
DROP ROLE regress_dump_test_role;
DROP EXTENSION test_pg_dump;
-- shouldn't be anything left in pg_init_privs
SELECT * FROM pg_init_privs WHERE privtype = 'e';
objoid | classoid | objsubid | privtype | initprivs
--------+----------+----------+----------+-----------
(0 rows)

View file

@ -146,3 +146,8 @@ SELECT pg_describe_object(classid,objid,objsubid) COLLATE "C" AS obj,
ORDER BY 1, 3;
DROP ROLE regress_dump_test_role;
DROP EXTENSION test_pg_dump;
-- shouldn't be anything left in pg_init_privs
SELECT * FROM pg_init_privs WHERE privtype = 'e';