@@ -220,11 +220,11 @@ static void dumpUserMappings(Archive *fout,
220220 const char *owner, CatalogId catalogId, DumpId dumpId);
221221static void dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo);
222222
223- static void dumpACL(Archive *fout, CatalogId objCatId , DumpId objDumpId ,
224- const char *type, const char *name, const char *subname,
225- const char *nspname, const char *owner,
226- const char *acls, const char *racls,
227- const char *initacls, const char *initracls);
223+ static DumpId dumpACL(Archive *fout, DumpId objDumpId , DumpId altDumpId ,
224+ const char *type, const char *name, const char *subname,
225+ const char *nspname, const char *owner,
226+ const char *acls, const char *racls,
227+ const char *initacls, const char *initracls);
228228
229229static void getDependencies(Archive *fout);
230230static void BuildArchiveDependencies(Archive *fout);
@@ -2992,7 +2992,7 @@ dumpDatabase(Archive *fout)
29922992 * Dump ACL if any. Note that we do not support initial privileges
29932993 * (pg_init_privs) on databases.
29942994 */
2995- dumpACL(fout, dbCatId, dbDumpId , "DATABASE",
2995+ dumpACL(fout, dbDumpId, InvalidDumpId , "DATABASE",
29962996 qdatname, NULL, NULL,
29972997 dba, datacl, rdatacl, "", "");
29982998
@@ -3477,7 +3477,7 @@ dumpBlob(Archive *fout, BlobInfo *binfo)
34773477
34783478 /* Dump ACL if any */
34793479 if (binfo->blobacl && (binfo->dobj.dump & DUMP_COMPONENT_ACL))
3480- dumpACL(fout, binfo->dobj.catId, binfo->dobj.dumpId , "LARGE OBJECT",
3480+ dumpACL(fout, binfo->dobj.dumpId, InvalidDumpId , "LARGE OBJECT",
34813481 binfo->dobj.name, NULL,
34823482 NULL, binfo->rolname, binfo->blobacl, binfo->rblobacl,
34833483 binfo->initblobacl, binfo->initrblobacl);
@@ -10155,7 +10155,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
1015510155 nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
1015610156
1015710157 if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
10158- dumpACL(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId , "SCHEMA",
10158+ dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId , "SCHEMA",
1015910159 qnspname, NULL, NULL,
1016010160 nspinfo->rolname, nspinfo->nspacl, nspinfo->rnspacl,
1016110161 nspinfo->initnspacl, nspinfo->initrnspacl);
@@ -10439,7 +10439,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
1043910439 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
1044010440
1044110441 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10442- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10442+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
1044310443 qtypname, NULL,
1044410444 tyinfo->dobj.namespace->dobj.name,
1044510445 tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10565,7 +10565,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
1056510565 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
1056610566
1056710567 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10568- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10568+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
1056910569 qtypname, NULL,
1057010570 tyinfo->dobj.namespace->dobj.name,
1057110571 tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10637,7 +10637,7 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
1063710637 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
1063810638
1063910639 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10640- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10640+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
1064110641 qtypname, NULL,
1064210642 tyinfo->dobj.namespace->dobj.name,
1064310643 tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10918,7 +10918,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
1091810918 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
1091910919
1092010920 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10921- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10921+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
1092210922 qtypname, NULL,
1092310923 tyinfo->dobj.namespace->dobj.name,
1092410924 tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11074,7 +11074,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
1107411074 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
1107511075
1107611076 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11077- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
11077+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
1107811078 qtypname, NULL,
1107911079 tyinfo->dobj.namespace->dobj.name,
1108011080 tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11296,7 +11296,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
1129611296 tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
1129711297
1129811298 if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11299- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
11299+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
1130011300 qtypname, NULL,
1130111301 tyinfo->dobj.namespace->dobj.name,
1130211302 tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11596,7 +11596,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
1159611596 plang->dobj.catId, 0, plang->dobj.dumpId);
1159711597
1159811598 if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
11599- dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId , "LANGUAGE",
11599+ dumpACL(fout, plang->dobj.dumpId, InvalidDumpId , "LANGUAGE",
1160011600 qlanname, NULL, NULL,
1160111601 plang->lanowner, plang->lanacl, plang->rlanacl,
1160211602 plang->initlanacl, plang->initrlanacl);
@@ -12306,7 +12306,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
1230612306 finfo->dobj.catId, 0, finfo->dobj.dumpId);
1230712307
1230812308 if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
12309- dumpACL(fout, finfo->dobj.catId, finfo->dobj.dumpId , keyword,
12309+ dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId , keyword,
1231012310 funcsig, NULL,
1231112311 finfo->dobj.namespace->dobj.name,
1231212312 finfo->rolname, finfo->proacl, finfo->rproacl,
@@ -14304,7 +14304,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
1430414304 aggsig = format_function_signature(fout, &agginfo->aggfn, true);
1430514305
1430614306 if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
14307- dumpACL(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId ,
14307+ dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId ,
1430814308 "FUNCTION", aggsig, NULL,
1430914309 agginfo->aggfn.dobj.namespace->dobj.name,
1431014310 agginfo->aggfn.rolname, agginfo->aggfn.proacl,
@@ -14706,7 +14706,7 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
1470614706
1470714707 /* Handle the ACL */
1470814708 if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
14709- dumpACL(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId ,
14709+ dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId ,
1471014710 "FOREIGN DATA WRAPPER", qfdwname, NULL,
1471114711 NULL, fdwinfo->rolname,
1471214712 fdwinfo->fdwacl, fdwinfo->rfdwacl,
@@ -14795,7 +14795,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
1479514795
1479614796 /* Handle the ACL */
1479714797 if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
14798- dumpACL(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId ,
14798+ dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId ,
1479914799 "FOREIGN SERVER", qsrvname, NULL,
1480014800 NULL, srvinfo->rolname,
1480114801 srvinfo->srvacl, srvinfo->rsrvacl,
@@ -14988,8 +14988,9 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
1498814988/*----------
1498914989 * Write out grant/revoke information
1499014990 *
14991- * 'objCatId' is the catalog ID of the underlying object.
1499214991 * 'objDumpId' is the dump ID of the underlying object.
14992+ * 'altDumpId' can be a second dumpId that the ACL entry must also depend on,
14993+ * or InvalidDumpId if there is no need for a second dependency.
1499314994 * 'type' must be one of
1499414995 * TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, TABLESPACE,
1499514996 * FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT.
@@ -15012,25 +15013,29 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
1501215013 * NB: initacls/initracls are needed because extensions can set privileges on
1501315014 * an object during the extension's script file and we record those into
1501415015 * pg_init_privs as that object's initial privileges.
15016+ *
15017+ * Returns the dump ID assigned to the ACL TocEntry, or InvalidDumpId if
15018+ * no ACL entry was created.
1501515019 *----------
1501615020 */
15017- static void
15018- dumpACL(Archive *fout, CatalogId objCatId , DumpId objDumpId ,
15021+ static DumpId
15022+ dumpACL(Archive *fout, DumpId objDumpId , DumpId altDumpId ,
1501915023 const char *type, const char *name, const char *subname,
1502015024 const char *nspname, const char *owner,
1502115025 const char *acls, const char *racls,
1502215026 const char *initacls, const char *initracls)
1502315027{
15028+ DumpId aclDumpId = InvalidDumpId;
1502415029 DumpOptions *dopt = fout->dopt;
1502515030 PQExpBuffer sql;
1502615031
1502715032 /* Do nothing if ACL dump is not enabled */
1502815033 if (dopt->aclsSkip)
15029- return;
15034+ return InvalidDumpId ;
1503015035
1503115036 /* --data-only skips ACLs *except* BLOB ACLs */
1503215037 if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
15033- return;
15038+ return InvalidDumpId ;
1503415039
1503515040 sql = createPQExpBuffer();
1503615041
@@ -15062,25 +15067,36 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
1506215067 if (sql->len > 0)
1506315068 {
1506415069 PQExpBuffer tag = createPQExpBuffer();
15070+ DumpId aclDeps[2];
15071+ int nDeps = 0;
1506515072
1506615073 if (subname)
1506715074 appendPQExpBuffer(tag, "COLUMN %s.%s", name, subname);
1506815075 else
1506915076 appendPQExpBuffer(tag, "%s %s", type, name);
1507015077
15071- ArchiveEntry(fout, nilCatalogId, createDumpId(),
15078+ aclDeps[nDeps++] = objDumpId;
15079+ if (altDumpId != InvalidDumpId)
15080+ aclDeps[nDeps++] = altDumpId;
15081+
15082+ aclDumpId = createDumpId();
15083+
15084+ ArchiveEntry(fout, nilCatalogId, aclDumpId,
1507215085 ARCHIVE_OPTS(.tag = tag->data,
1507315086 .namespace = nspname,
1507415087 .owner = owner,
1507515088 .description = "ACL",
1507615089 .section = SECTION_NONE,
1507715090 .createStmt = sql->data,
15078- .deps = &objDumpId,
15079- .nDeps = 1));
15091+ .deps = aclDeps,
15092+ .nDeps = nDeps));
15093+
1508015094 destroyPQExpBuffer(tag);
1508115095 }
1508215096
1508315097 destroyPQExpBuffer(sql);
15098+
15099+ return aclDumpId;
1508415100}
1508515101
1508615102/*
@@ -15406,6 +15422,7 @@ static void
1540615422dumpTable(Archive *fout, TableInfo *tbinfo)
1540715423{
1540815424 DumpOptions *dopt = fout->dopt;
15425+ DumpId tableAclDumpId = InvalidDumpId;
1540915426 char *namecopy;
1541015427
1541115428 /*
@@ -15427,11 +15444,12 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
1542715444 const char *objtype =
1542815445 (tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
1542915446
15430- dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
15431- objtype, namecopy, NULL,
15432- tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
15433- tbinfo->relacl, tbinfo->rrelacl,
15434- tbinfo->initrelacl, tbinfo->initrrelacl);
15447+ tableAclDumpId =
15448+ dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
15449+ objtype, namecopy, NULL,
15450+ tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
15451+ tbinfo->relacl, tbinfo->rrelacl,
15452+ tbinfo->initrelacl, tbinfo->initrrelacl);
1543515453 }
1543615454
1543715455 /*
@@ -15515,8 +15533,13 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
1551515533 char *attnamecopy;
1551615534
1551715535 attnamecopy = pg_strdup(fmtId(attname));
15518- /* Column's GRANT type is always TABLE */
15519- dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
15536+
15537+ /*
15538+ * Column's GRANT type is always TABLE. Each column ACL depends
15539+ * on the table-level ACL, since we can restore column ACLs in
15540+ * parallel but the table-level ACL has to be done first.
15541+ */
15542+ dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
1552015543 "TABLE", namecopy, attnamecopy,
1552115544 tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
1552215545 attacl, rattacl, initattacl, initrattacl);
0 commit comments