@@ -216,7 +216,7 @@ static void dumpUserMappings(Archive *fout,
216216 const char *owner, CatalogId catalogId, DumpId dumpId);
217217static void dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo);
218218
219- staticvoid dumpACL(Archive *fout,CatalogId objCatId , DumpIdobjDumpId ,
219+ staticDumpId dumpACL(Archive *fout,DumpId objDumpId , DumpIdaltDumpId ,
220220const char *type, const char *name, const char *subname,
221221const char *nspname, const char *owner,
222222const char *acls, const char *racls,
@@ -3080,7 +3080,7 @@ dumpBlob(Archive *fout, BlobInfo *binfo)
30803080
30813081/* Dump ACL if any */
30823082if (binfo->blobacl && (binfo->dobj.dump & DUMP_COMPONENT_ACL))
3083- dumpACL(fout, binfo->dobj.catId, binfo->dobj.dumpId , "LARGE OBJECT",
3083+ dumpACL(fout, binfo->dobj.dumpId, InvalidDumpId , "LARGE OBJECT",
30843084binfo->dobj.name, NULL,
30853085NULL, binfo->rolname, binfo->blobacl, binfo->rblobacl,
30863086binfo->initblobacl, binfo->initrblobacl);
@@ -9571,7 +9571,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
95719571 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
95729572
95739573if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
9574- dumpACL(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId , "SCHEMA",
9574+ dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId , "SCHEMA",
95759575qnspname, NULL, NULL,
95769576nspinfo->rolname, nspinfo->nspacl, nspinfo->rnspacl,
95779577nspinfo->initnspacl, nspinfo->initrnspacl);
@@ -9851,7 +9851,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
98519851 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
98529852
98539853if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
9854- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
9854+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
98559855qtypname, NULL,
98569856tyinfo->dobj.namespace->dobj.name,
98579857tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -9977,7 +9977,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
99779977 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
99789978
99799979if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
9980- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
9980+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
99819981qtypname, NULL,
99829982tyinfo->dobj.namespace->dobj.name,
99839983tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10049,7 +10049,7 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
1004910049 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
1005010050
1005110051if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10052- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10052+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
1005310053qtypname, NULL,
1005410054tyinfo->dobj.namespace->dobj.name,
1005510055tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10327,7 +10327,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
1032710327 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
1032810328
1032910329if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10330- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10330+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
1033110331qtypname, NULL,
1033210332tyinfo->dobj.namespace->dobj.name,
1033310333tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10483,7 +10483,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
1048310483 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
1048410484
1048510485if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10486- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10486+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
1048710487qtypname, NULL,
1048810488tyinfo->dobj.namespace->dobj.name,
1048910489tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10705,7 +10705,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
1070510705 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
1070610706
1070710707if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10708- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10708+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
1070910709qtypname, NULL,
1071010710tyinfo->dobj.namespace->dobj.name,
1071110711tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11000,7 +11000,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
1100011000 plang->dobj.catId, 0, plang->dobj.dumpId);
1100111001
1100211002if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
11003- dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId , "LANGUAGE",
11003+ dumpACL(fout, plang->dobj.dumpId, InvalidDumpId , "LANGUAGE",
1100411004qlanname, NULL, NULL,
1100511005plang->lanowner, plang->lanacl, plang->rlanacl,
1100611006plang->initlanacl, plang->initrlanacl);
@@ -11645,7 +11645,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
1164511645 finfo->dobj.catId, 0, finfo->dobj.dumpId);
1164611646
1164711647if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
11648- dumpACL(fout, finfo->dobj.catId, finfo->dobj.dumpId , "FUNCTION",
11648+ dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId , "FUNCTION",
1164911649funcsig, NULL,
1165011650finfo->dobj.namespace->dobj.name,
1165111651finfo->rolname, finfo->proacl, finfo->rproacl,
@@ -13580,7 +13580,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
1358013580aggsig = format_function_signature(fout, &agginfo->aggfn, true);
1358113581
1358213582if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
13583- dumpACL(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId ,
13583+ dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId ,
1358413584"FUNCTION", aggsig, NULL,
1358513585agginfo->aggfn.dobj.namespace->dobj.name,
1358613586agginfo->aggfn.rolname, agginfo->aggfn.proacl,
@@ -13984,7 +13984,7 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
1398413984
1398513985/* Handle the ACL */
1398613986if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
13987- dumpACL(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId ,
13987+ dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId ,
1398813988"FOREIGN DATA WRAPPER", qfdwname, NULL,
1398913989NULL, fdwinfo->rolname,
1399013990fdwinfo->fdwacl, fdwinfo->rfdwacl,
@@ -14075,7 +14075,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
1407514075
1407614076/* Handle the ACL */
1407714077if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
14078- dumpACL(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId ,
14078+ dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId ,
1407914079"FOREIGN SERVER", qsrvname, NULL,
1408014080NULL, srvinfo->rolname,
1408114081srvinfo->srvacl, srvinfo->rsrvacl,
@@ -14277,8 +14277,9 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
1427714277/*----------
1427814278 * Write out grant/revoke information
1427914279 *
14280- * 'objCatId' is the catalog ID of the underlying object.
1428114280 * 'objDumpId' is the dump ID of the underlying object.
14281+ * 'altDumpId' can be a second dumpId that the ACL entry must also depend on,
14282+ *or InvalidDumpId if there is no need for a second dependency.
1428214283 * 'type' must be one of
1428314284 *TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, TABLESPACE,
1428414285 *FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT.
@@ -14301,25 +14302,29 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
1430114302 * NB: initacls/initracls are needed because extensions can set privileges on
1430214303 * an object during the extension's script file and we record those into
1430314304 * pg_init_privs as that object's initial privileges.
14305+ *
14306+ * Returns the dump ID assigned to the ACL TocEntry, or InvalidDumpId if
14307+ * no ACL entry was created.
1430414308 *----------
1430514309 */
14306- staticvoid
14307- dumpACL(Archive *fout,CatalogId objCatId , DumpIdobjDumpId ,
14310+ staticDumpId
14311+ dumpACL(Archive *fout,DumpId objDumpId , DumpIdaltDumpId ,
1430814312const char *type, const char *name, const char *subname,
1430914313const char *nspname, const char *owner,
1431014314const char *acls, const char *racls,
1431114315const char *initacls, const char *initracls)
1431214316{
14317+ DumpIdaclDumpId = InvalidDumpId;
1431314318DumpOptions *dopt = fout->dopt;
1431414319PQExpBuffer sql;
1431514320
1431614321/* Do nothing if ACL dump is not enabled */
1431714322if (dopt->aclsSkip)
14318- return;
14323+ return InvalidDumpId ;
1431914324
1432014325/* --data-only skips ACLs *except* BLOB ACLs */
1432114326if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
14322- return;
14327+ return InvalidDumpId ;
1432314328
1432414329sql = createPQExpBuffer();
1432514330
@@ -14353,24 +14358,35 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
1435314358if (sql->len > 0)
1435414359{
1435514360PQExpBuffer tag = createPQExpBuffer();
14361+ DumpIdaclDeps[2];
14362+ intnDeps = 0;
1435614363
1435714364if (subname)
1435814365appendPQExpBuffer(tag, "COLUMN %s.%s", name, subname);
1435914366else
1436014367appendPQExpBuffer(tag, "%s %s", type, name);
1436114368
14362- ArchiveEntry(fout, nilCatalogId, createDumpId(),
14369+ aclDeps[nDeps++] = objDumpId;
14370+ if (altDumpId != InvalidDumpId)
14371+ aclDeps[nDeps++] = altDumpId;
14372+
14373+ aclDumpId = createDumpId();
14374+
14375+ ArchiveEntry(fout, nilCatalogId, aclDumpId,
1436314376 tag->data, nspname,
1436414377 NULL,
1436514378 owner ? owner : "",
1436614379 false, "ACL", SECTION_NONE,
1436714380 sql->data, "", NULL,
14368- &(objDumpId), 1 ,
14381+ aclDeps, nDeps ,
1436914382 NULL, NULL);
14383+
1437014384destroyPQExpBuffer(tag);
1437114385}
1437214386
1437314387destroyPQExpBuffer(sql);
14388+
14389+ return aclDumpId;
1437414390}
1437514391
1437614392/*
@@ -14692,6 +14708,7 @@ static void
1469214708dumpTable(Archive *fout, TableInfo *tbinfo)
1469314709{
1469414710DumpOptions *dopt = fout->dopt;
14711+ DumpIdtableAclDumpId = InvalidDumpId;
1469514712char *namecopy;
1469614713
1469714714/*
@@ -14713,11 +14730,12 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
1471314730const char *objtype =
1471414731(tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
1471514732
14716- dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
14717- objtype, namecopy, NULL,
14718- tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
14719- tbinfo->relacl, tbinfo->rrelacl,
14720- tbinfo->initrelacl, tbinfo->initrrelacl);
14733+ tableAclDumpId =
14734+ dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
14735+ objtype, namecopy, NULL,
14736+ tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
14737+ tbinfo->relacl, tbinfo->rrelacl,
14738+ tbinfo->initrelacl, tbinfo->initrrelacl);
1472114739}
1472214740
1472314741/*
@@ -14801,8 +14819,13 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
1480114819char *attnamecopy;
1480214820
1480314821attnamecopy = pg_strdup(fmtId(attname));
14804- /* Column's GRANT type is always TABLE */
14805- dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
14822+
14823+ /*
14824+ * Column's GRANT type is always TABLE. Each column ACL depends
14825+ * on the table-level ACL, since we can restore column ACLs in
14826+ * parallel but the table-level ACL has to be done first.
14827+ */
14828+ dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
1480614829"TABLE", namecopy, attnamecopy,
1480714830tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
1480814831attacl, rattacl, initattacl, initrattacl);