I'm upgrading our Postgres installation from 7.4 to 8.2 (I know, I know, but we've been busy). The biggest thing to change will be our user/group management scripts, as they directly modify pg_shadow and pg_group. Beyond being potentially stupid (but hey, I didn't write it), this just won't work anymore, for a few reasons, which I will get to in a bit.
What we used to do (all in a transaction block so it's nice and atomic): For users: Delete pg_shadow, read in logins/uids from /etc/passwd and create users, making sure the Unix uid matches up with the postgres sysid. For groups: For each group, drop the group, read in the new group from either another database table or some other mechanism.
Now, having the Unix uids match up with the Postgres sysids isn't such a big deal since we'll be using Kerberos, which can presumably match up based on login name. It was nice to have them match up, but it's probably not necessary. However, the above mechanisms won't work for the following reasons:
1. pg_shadow and pg_group are now views, and you can't update views. 2a. Simply dropping a user is insufficient if the user owns anything in the database cluster. 2b. Deleting a user by removing the row from pg_authid works, but then the object owner is unknown and the object disappears unless you know where to look for it in the system tables. The objects are effectively orphaned. 3. There seems to be no way to recover the old sysid, as the "WITH SYSID uid" clause in CREATE USER/CREATE ROLE is now just noise, and trying to insert it directly into the system table proved fruitless. If you can't recover the old sysid, it leads to the orphaned objects problem described in 2b.
So, I'm wondering how I can do something roughly equivalent to this, I've been considering using some sort of "diff"-like mechanism, but it'd be nice to have something simpler. Any help would be greatly appreciated.