Hi,

I'm writing to share an observation regarding `pg_catalog` system objects
and their privileges during `pg_upgrade`. It's known that `pg_catalog`
system objects are not dumped, but their privileges are. However, if
user-created objects are placed within `pg_catalog` and their privileges
are altered, `pg_upgrade` can fail with an "object does not exist" error.

I've reproduced this behavior using the following steps:

**Old Cluster (PG18):**
```sql
postgres=# create user alice login;
postgres=# create table t1(a int);
CREATE TABLE
postgres=# alter table t1 set schema pg_catalog;
ALTER TABLE
postgres=# grant select on table pg_catalog.t1 to alice;
GRANT
postgres=# CREATE OR REPLACE FUNCTION pg_catalog.nont_ext_func() RETURNS
char AS $$ BEGIN return 'v'; END; $$ LANGUAGE plpgsql;
CREATE FUNCTION
postgres=# grant execute on function pg_catalog.non_ext_func to alice;
GRANT
```

**New Cluster (PG18):**
```bash
$ ./db/bin/pg_upgrade -b ../pg18/db/bin -B db/bin -d ../pg18/db/data -D
db/data
pg_restore: creating ACL "pg_catalog.FUNCTION "non_ext_func"()"
pg_restore: while PROCESSING TOC:
pg_restore: from TOC entry 3430; 0 0 ACL FUNCTION "non_ext_func"() vaibhav
pg_restore: error: could not execute query: ERROR: function
pg_catalog.non_ext_func() does not exist
Command was: GRANT ALL ON FUNCTION "pg_catalog"."non_ext_func"() TO "alice";
```

This issue arises because `pg_dump`/`pg_restore` or `pg_upgrade` attempts
to dump privileges for user objects within `pg_catalog` without first
dumping the objects themselves. I believe one of the following approaches
should be considered to prevent such failures:

1. Restrict the creation of user objects within the `pg_catalog` schema.
2. If user object creation within `pg_catalog` is allowed, then the objects
themselves should be dumped prior to their privileges.

This is my current understanding of the situation. I'd appreciate hearing
your thoughts on this behavior and if there's an alternative perspective.

Thanks,
Vaibhav

Reply via email to