@@ -216,7 +216,7 @@ static void dumpUserMappings(Archive *fout,
216
216
const char *owner, CatalogId catalogId, DumpId dumpId);
217
217
static void dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo);
218
218
219
- staticvoid dumpACL(Archive *fout,CatalogId objCatId , DumpIdobjDumpId ,
219
+ staticDumpId dumpACL(Archive *fout,DumpId objDumpId , DumpIdaltDumpId ,
220
220
const char *type, const char *name, const char *subname,
221
221
const char *nspname, const char *owner,
222
222
const char *acls, const char *racls,
@@ -3080,7 +3080,7 @@ dumpBlob(Archive *fout, BlobInfo *binfo)
3080
3080
3081
3081
/* Dump ACL if any */
3082
3082
if (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",
3084
3084
binfo->dobj.name, NULL,
3085
3085
NULL, binfo->rolname, binfo->blobacl, binfo->rblobacl,
3086
3086
binfo->initblobacl, binfo->initrblobacl);
@@ -9571,7 +9571,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
9571
9571
nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
9572
9572
9573
9573
if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
9574
- dumpACL(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId , "SCHEMA",
9574
+ dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId , "SCHEMA",
9575
9575
qnspname, NULL, NULL,
9576
9576
nspinfo->rolname, nspinfo->nspacl, nspinfo->rnspacl,
9577
9577
nspinfo->initnspacl, nspinfo->initrnspacl);
@@ -9851,7 +9851,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
9851
9851
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
9852
9852
9853
9853
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
9854
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
9854
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
9855
9855
qtypname, NULL,
9856
9856
tyinfo->dobj.namespace->dobj.name,
9857
9857
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -9977,7 +9977,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
9977
9977
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
9978
9978
9979
9979
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
9980
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
9980
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
9981
9981
qtypname, NULL,
9982
9982
tyinfo->dobj.namespace->dobj.name,
9983
9983
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10049,7 +10049,7 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
10049
10049
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10050
10050
10051
10051
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10052
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10052
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10053
10053
qtypname, NULL,
10054
10054
tyinfo->dobj.namespace->dobj.name,
10055
10055
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10327,7 +10327,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
10327
10327
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10328
10328
10329
10329
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10330
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10330
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10331
10331
qtypname, NULL,
10332
10332
tyinfo->dobj.namespace->dobj.name,
10333
10333
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10483,7 +10483,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
10483
10483
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10484
10484
10485
10485
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10486
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10486
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10487
10487
qtypname, NULL,
10488
10488
tyinfo->dobj.namespace->dobj.name,
10489
10489
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10705,7 +10705,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
10705
10705
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10706
10706
10707
10707
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10708
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10708
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10709
10709
qtypname, NULL,
10710
10710
tyinfo->dobj.namespace->dobj.name,
10711
10711
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11000,7 +11000,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
11000
11000
plang->dobj.catId, 0, plang->dobj.dumpId);
11001
11001
11002
11002
if (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",
11004
11004
qlanname, NULL, NULL,
11005
11005
plang->lanowner, plang->lanacl, plang->rlanacl,
11006
11006
plang->initlanacl, plang->initrlanacl);
@@ -11645,7 +11645,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
11645
11645
finfo->dobj.catId, 0, finfo->dobj.dumpId);
11646
11646
11647
11647
if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
11648
- dumpACL(fout, finfo->dobj.catId, finfo->dobj.dumpId , "FUNCTION",
11648
+ dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId , "FUNCTION",
11649
11649
funcsig, NULL,
11650
11650
finfo->dobj.namespace->dobj.name,
11651
11651
finfo->rolname, finfo->proacl, finfo->rproacl,
@@ -13580,7 +13580,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
13580
13580
aggsig = format_function_signature(fout, &agginfo->aggfn, true);
13581
13581
13582
13582
if (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 ,
13584
13584
"FUNCTION", aggsig, NULL,
13585
13585
agginfo->aggfn.dobj.namespace->dobj.name,
13586
13586
agginfo->aggfn.rolname, agginfo->aggfn.proacl,
@@ -13984,7 +13984,7 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
13984
13984
13985
13985
/* Handle the ACL */
13986
13986
if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
13987
- dumpACL(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId ,
13987
+ dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId ,
13988
13988
"FOREIGN DATA WRAPPER", qfdwname, NULL,
13989
13989
NULL, fdwinfo->rolname,
13990
13990
fdwinfo->fdwacl, fdwinfo->rfdwacl,
@@ -14075,7 +14075,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
14075
14075
14076
14076
/* Handle the ACL */
14077
14077
if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
14078
- dumpACL(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId ,
14078
+ dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId ,
14079
14079
"FOREIGN SERVER", qsrvname, NULL,
14080
14080
NULL, srvinfo->rolname,
14081
14081
srvinfo->srvacl, srvinfo->rsrvacl,
@@ -14277,8 +14277,9 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
14277
14277
/*----------
14278
14278
* Write out grant/revoke information
14279
14279
*
14280
- * 'objCatId' is the catalog ID of the underlying object.
14281
14280
* '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.
14282
14283
* 'type' must be one of
14283
14284
*TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, TABLESPACE,
14284
14285
*FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT.
@@ -14301,25 +14302,29 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
14301
14302
* NB: initacls/initracls are needed because extensions can set privileges on
14302
14303
* an object during the extension's script file and we record those into
14303
14304
* 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.
14304
14308
*----------
14305
14309
*/
14306
- staticvoid
14307
- dumpACL(Archive *fout,CatalogId objCatId , DumpIdobjDumpId ,
14310
+ staticDumpId
14311
+ dumpACL(Archive *fout,DumpId objDumpId , DumpIdaltDumpId ,
14308
14312
const char *type, const char *name, const char *subname,
14309
14313
const char *nspname, const char *owner,
14310
14314
const char *acls, const char *racls,
14311
14315
const char *initacls, const char *initracls)
14312
14316
{
14317
+ DumpIdaclDumpId = InvalidDumpId;
14313
14318
DumpOptions *dopt = fout->dopt;
14314
14319
PQExpBuffer sql;
14315
14320
14316
14321
/* Do nothing if ACL dump is not enabled */
14317
14322
if (dopt->aclsSkip)
14318
- return;
14323
+ return InvalidDumpId ;
14319
14324
14320
14325
/* --data-only skips ACLs *except* BLOB ACLs */
14321
14326
if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
14322
- return;
14327
+ return InvalidDumpId ;
14323
14328
14324
14329
sql = createPQExpBuffer();
14325
14330
@@ -14353,24 +14358,35 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
14353
14358
if (sql->len > 0)
14354
14359
{
14355
14360
PQExpBuffer tag = createPQExpBuffer();
14361
+ DumpIdaclDeps[2];
14362
+ intnDeps = 0;
14356
14363
14357
14364
if (subname)
14358
14365
appendPQExpBuffer(tag, "COLUMN %s.%s", name, subname);
14359
14366
else
14360
14367
appendPQExpBuffer(tag, "%s %s", type, name);
14361
14368
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,
14363
14376
tag->data, nspname,
14364
14377
NULL,
14365
14378
owner ? owner : "",
14366
14379
false, "ACL", SECTION_NONE,
14367
14380
sql->data, "", NULL,
14368
- &(objDumpId), 1 ,
14381
+ aclDeps, nDeps ,
14369
14382
NULL, NULL);
14383
+
14370
14384
destroyPQExpBuffer(tag);
14371
14385
}
14372
14386
14373
14387
destroyPQExpBuffer(sql);
14388
+
14389
+ return aclDumpId;
14374
14390
}
14375
14391
14376
14392
/*
@@ -14692,6 +14708,7 @@ static void
14692
14708
dumpTable(Archive *fout, TableInfo *tbinfo)
14693
14709
{
14694
14710
DumpOptions *dopt = fout->dopt;
14711
+ DumpIdtableAclDumpId = InvalidDumpId;
14695
14712
char *namecopy;
14696
14713
14697
14714
/*
@@ -14713,11 +14730,12 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
14713
14730
const char *objtype =
14714
14731
(tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
14715
14732
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);
14721
14739
}
14722
14740
14723
14741
/*
@@ -14801,8 +14819,13 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
14801
14819
char *attnamecopy;
14802
14820
14803
14821
attnamecopy = 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,
14806
14829
"TABLE", namecopy, attnamecopy,
14807
14830
tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
14808
14831
attacl, rattacl, initattacl, initrattacl);