]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Clean out column-level pg_init_privs entries when dropping tables.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 14 Jun 2024 20:20:35 +0000 (16:20 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 14 Jun 2024 20:20:35 +0000 (16:20 -0400)
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.

src/backend/catalog/dependency.c
src/test/modules/test_pg_dump/expected/test_pg_dump.out
src/test/modules/test_pg_dump/sql/test_pg_dump.sql

index 3cca107449034a7b94448cf8c774b2ac53b21534..24f1e0184a79a0f7c2727ca42115405291f8c44b 100644 (file)
@@ -1374,7 +1374,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);
@@ -2985,6 +2987,7 @@ DeleteInitPrivs(const ObjectAddress *object)
 {
        Relation        relation;
        ScanKeyData key[3];
+       int                     nkeys;
        SysScanDesc scan;
        HeapTuple       oldtuple;
 
@@ -2998,13 +3001,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);
index f14f3a6664614da802d686b81e5b3607973019b5..8df7f09054416ac7a4ae6ef251d23a449c1edac6 100644 (file)
@@ -91,3 +91,10 @@ ALTER EXTENSION test_pg_dump DROP SERVER s0;
 ALTER EXTENSION test_pg_dump DROP TABLE test_pg_dump_t1;
 ALTER EXTENSION test_pg_dump DROP TYPE test_pg_dump_e1;
 ALTER EXTENSION test_pg_dump DROP VIEW test_pg_dump_v1;
+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)
+
index a61a7c8c4ce9557b744c135c5541c5af2976ece6..7f2e7d32f6dbabd28725e49ff916eea7ad3df2be 100644 (file)
@@ -106,3 +106,8 @@ ALTER EXTENSION test_pg_dump DROP SERVER s0;
 ALTER EXTENSION test_pg_dump DROP TABLE test_pg_dump_t1;
 ALTER EXTENSION test_pg_dump DROP TYPE test_pg_dump_e1;
 ALTER EXTENSION test_pg_dump DROP VIEW test_pg_dump_v1;
+
+DROP EXTENSION test_pg_dump;
+
+-- shouldn't be anything left in pg_init_privs
+SELECT * FROM pg_init_privs WHERE privtype = 'e';