aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2024-06-14 16:20:35 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2024-06-14 16:20:35 -0400
commit9cf4beb9e7adf3225c33df256c4e7d54805ec4f8 (patch)
tree045e5635179c56472e668d637aead595caf93160 /src
parent086ecd12bc1c27054ded1eeea5329e84e3f72c97 (diff)
downloadpostgresql-9cf4beb9e7adf3225c33df256c4e7d54805ec4f8.tar.gz
postgresql-9cf4beb9e7adf3225c33df256c4e7d54805ec4f8.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/catalog/dependency.c21
-rw-r--r--src/test/modules/test_pg_dump/expected/test_pg_dump.out7
-rw-r--r--src/test/modules/test_pg_dump/sql/test_pg_dump.sql5
3 files changed, 27 insertions, 6 deletions
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 9af2cab29d7..494738824cb 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -1382,7 +1382,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);
@@ -2992,6 +2994,7 @@ DeleteInitPrivs(const ObjectAddress *object)
{
Relation relation;
ScanKeyData key[3];
+ int nkeys;
SysScanDesc scan;
HeapTuple oldtuple;
@@ -3005,13 +3008,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);
diff --git a/src/test/modules/test_pg_dump/expected/test_pg_dump.out b/src/test/modules/test_pg_dump/expected/test_pg_dump.out
index f14f3a66646..8df7f090544 100644
--- a/src/test/modules/test_pg_dump/expected/test_pg_dump.out
+++ b/src/test/modules/test_pg_dump/expected/test_pg_dump.out
@@ -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)
+
diff --git a/src/test/modules/test_pg_dump/sql/test_pg_dump.sql b/src/test/modules/test_pg_dump/sql/test_pg_dump.sql
index a61a7c8c4ce..7f2e7d32f6d 100644
--- a/src/test/modules/test_pg_dump/sql/test_pg_dump.sql
+++ b/src/test/modules/test_pg_dump/sql/test_pg_dump.sql
@@ -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';