Skip to content

Commit 8357a41

Browse files
committed
Fix ordering of GRANT commands in pg_dump for database creation
This uses a method similar to 68a7c24, which guarantees that GRANT commands using the WITH GRANT OPTION are dumped in a way so as cascading dependencies are respected. As databases do not have support for initial privileges via pg_init_privs, we need to repeat again the same ACL reordering method. ACL for databases have been moved from pg_dumpall to pg_dump in v11, so this impacts pg_dump for v11 and above, and pg_dumpall for v9.6 and v10. Discussion: https://postgr.es/m/15788-4e18847520ebcc75@postgresql.org Author: Nathan Bossart Reviewed-by: Haribabu Kommi Backpatch-through: 9.6
1 parent 9fea0b0 commit 8357a41

File tree

1 file changed

+28
-7
lines changed

1 file changed

+28
-7
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2566,20 +2566,41 @@ dumpDatabase(Archive *fout)
25662566
if (g_verbose)
25672567
write_msg(NULL, "saving database definition\n");
25682568

2569-
/* Fetch the database-level properties for this database */
2569+
/*
2570+
* Fetch the database-level properties for this database.
2571+
*
2572+
* The order in which privileges are in the ACL string (the order they
2573+
* have been GRANT'd in, which the backend maintains) must be preserved to
2574+
* ensure that GRANTs WITH GRANT OPTION and subsequent GRANTs based on
2575+
* those are dumped in the correct order. Note that initial privileges
2576+
* (pg_init_privs) are not supported on databases, so this logic cannot
2577+
* make use of buildACLQueries().
2578+
*/
25702579
if (fout->remoteVersion >= 90600)
25712580
{
25722581
appendPQExpBuffer(dbQry, "SELECT tableoid, oid, datname, "
25732582
"(%s datdba) AS dba, "
25742583
"pg_encoding_to_char(encoding) AS encoding, "
25752584
"datcollate, datctype, datfrozenxid, datminmxid, "
2576-
"(SELECT array_agg(acl ORDER BY acl::text COLLATE \"C\") FROM ( "
2577-
" SELECT unnest(coalesce(datacl,acldefault('d',datdba))) AS acl "
2578-
" EXCEPT SELECT unnest(acldefault('d',datdba))) as datacls)"
2585+
"(SELECT array_agg(acl ORDER BY row_n) FROM "
2586+
" (SELECT acl, row_n FROM "
2587+
" unnest(coalesce(datacl,acldefault('d',datdba))) "
2588+
" WITH ORDINALITY AS perm(acl,row_n) "
2589+
" WHERE NOT EXISTS ( "
2590+
" SELECT 1 "
2591+
" FROM unnest(acldefault('d',datdba)) "
2592+
" AS init(init_acl) "
2593+
" WHERE acl = init_acl)) AS datacls) "
25792594
" AS datacl, "
2580-
"(SELECT array_agg(acl ORDER BY acl::text COLLATE \"C\") FROM ( "
2581-
" SELECT unnest(acldefault('d',datdba)) AS acl "
2582-
" EXCEPT SELECT unnest(coalesce(datacl,acldefault('d',datdba)))) as rdatacls)"
2595+
"(SELECT array_agg(acl ORDER BY row_n) FROM "
2596+
" (SELECT acl, row_n FROM "
2597+
" unnest(acldefault('d',datdba)) "
2598+
" WITH ORDINALITY AS initp(acl,row_n) "
2599+
" WHERE NOT EXISTS ( "
2600+
" SELECT 1 "
2601+
" FROM unnest(coalesce(datacl,acldefault('d',datdba))) "
2602+
" AS permp(orig_acl) "
2603+
" WHERE acl = orig_acl)) AS rdatacls) "
25832604
" AS rdatacl, "
25842605
"datistemplate, datconnlimit, "
25852606
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = dattablespace) AS tablespace, "

0 commit comments

Comments
 (0)