@@ -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,
@@ -2827,7 +2827,7 @@ dumpDatabase(Archive *fout)
2827
2827
* Dump ACL if any. Note that we do not support initial privileges
2828
2828
* (pg_init_privs) on databases.
2829
2829
*/
2830
- dumpACL(fout,dbCatId, dbDumpId , "DATABASE",
2830
+ dumpACL(fout,dbDumpId, InvalidDumpId , "DATABASE",
2831
2831
qdatname, NULL, NULL,
2832
2832
dba, datacl, rdatacl, "", "");
2833
2833
@@ -3365,7 +3365,7 @@ dumpBlob(Archive *fout, BlobInfo *binfo)
3365
3365
3366
3366
/* Dump ACL if any */
3367
3367
if (binfo->blobacl && (binfo->dobj.dump & DUMP_COMPONENT_ACL))
3368
- dumpACL(fout, binfo->dobj.catId, binfo->dobj.dumpId , "LARGE OBJECT",
3368
+ dumpACL(fout, binfo->dobj.dumpId, InvalidDumpId , "LARGE OBJECT",
3369
3369
binfo->dobj.name, NULL,
3370
3370
NULL, binfo->rolname, binfo->blobacl, binfo->rblobacl,
3371
3371
binfo->initblobacl, binfo->initrblobacl);
@@ -10032,7 +10032,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
10032
10032
nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
10033
10033
10034
10034
if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
10035
- dumpACL(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId , "SCHEMA",
10035
+ dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId , "SCHEMA",
10036
10036
qnspname, NULL, NULL,
10037
10037
nspinfo->rolname, nspinfo->nspacl, nspinfo->rnspacl,
10038
10038
nspinfo->initnspacl, nspinfo->initrnspacl);
@@ -10319,7 +10319,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
10319
10319
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10320
10320
10321
10321
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10322
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10322
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10323
10323
qtypname, NULL,
10324
10324
tyinfo->dobj.namespace->dobj.name,
10325
10325
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10446,7 +10446,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
10446
10446
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10447
10447
10448
10448
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10449
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10449
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10450
10450
qtypname, NULL,
10451
10451
tyinfo->dobj.namespace->dobj.name,
10452
10452
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10519,7 +10519,7 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
10519
10519
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10520
10520
10521
10521
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10522
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10522
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10523
10523
qtypname, NULL,
10524
10524
tyinfo->dobj.namespace->dobj.name,
10525
10525
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10801,7 +10801,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
10801
10801
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10802
10802
10803
10803
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10804
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10804
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10805
10805
qtypname, NULL,
10806
10806
tyinfo->dobj.namespace->dobj.name,
10807
10807
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10958,7 +10958,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
10958
10958
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10959
10959
10960
10960
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10961
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10961
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10962
10962
qtypname, NULL,
10963
10963
tyinfo->dobj.namespace->dobj.name,
10964
10964
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11181,7 +11181,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
11181
11181
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11182
11182
11183
11183
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11184
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
11184
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
11185
11185
qtypname, NULL,
11186
11186
tyinfo->dobj.namespace->dobj.name,
11187
11187
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11481,7 +11481,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
11481
11481
plang->dobj.catId, 0, plang->dobj.dumpId);
11482
11482
11483
11483
if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
11484
- dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId , "LANGUAGE",
11484
+ dumpACL(fout, plang->dobj.dumpId, InvalidDumpId , "LANGUAGE",
11485
11485
qlanname, NULL, NULL,
11486
11486
plang->lanowner, plang->lanacl, plang->rlanacl,
11487
11487
plang->initlanacl, plang->initrlanacl);
@@ -12159,7 +12159,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
12159
12159
finfo->dobj.catId, 0, finfo->dobj.dumpId);
12160
12160
12161
12161
if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
12162
- dumpACL(fout, finfo->dobj.catId, finfo->dobj.dumpId , keyword,
12162
+ dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId , keyword,
12163
12163
funcsig, NULL,
12164
12164
finfo->dobj.namespace->dobj.name,
12165
12165
finfo->rolname, finfo->proacl, finfo->rproacl,
@@ -14176,7 +14176,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
14176
14176
aggsig = format_function_signature(fout, &agginfo->aggfn, true);
14177
14177
14178
14178
if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
14179
- dumpACL(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId ,
14179
+ dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId ,
14180
14180
"FUNCTION", aggsig, NULL,
14181
14181
agginfo->aggfn.dobj.namespace->dobj.name,
14182
14182
agginfo->aggfn.rolname, agginfo->aggfn.proacl,
@@ -14586,7 +14586,7 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
14586
14586
14587
14587
/* Handle the ACL */
14588
14588
if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
14589
- dumpACL(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId ,
14589
+ dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId ,
14590
14590
"FOREIGN DATA WRAPPER", qfdwname, NULL,
14591
14591
NULL, fdwinfo->rolname,
14592
14592
fdwinfo->fdwacl, fdwinfo->rfdwacl,
@@ -14677,7 +14677,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
14677
14677
14678
14678
/* Handle the ACL */
14679
14679
if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
14680
- dumpACL(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId ,
14680
+ dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId ,
14681
14681
"FOREIGN SERVER", qsrvname, NULL,
14682
14682
NULL, srvinfo->rolname,
14683
14683
srvinfo->srvacl, srvinfo->rsrvacl,
@@ -14873,8 +14873,9 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
14873
14873
/*----------
14874
14874
* Write out grant/revoke information
14875
14875
*
14876
- * 'objCatId' is the catalog ID of the underlying object.
14877
14876
* 'objDumpId' is the dump ID of the underlying object.
14877
+ * 'altDumpId' can be a second dumpId that the ACL entry must also depend on,
14878
+ *or InvalidDumpId if there is no need for a second dependency.
14878
14879
* 'type' must be one of
14879
14880
*TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, TABLESPACE,
14880
14881
*FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT.
@@ -14897,25 +14898,29 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
14897
14898
* NB: initacls/initracls are needed because extensions can set privileges on
14898
14899
* an object during the extension's script file and we record those into
14899
14900
* pg_init_privs as that object's initial privileges.
14901
+ *
14902
+ * Returns the dump ID assigned to the ACL TocEntry, or InvalidDumpId if
14903
+ * no ACL entry was created.
14900
14904
*----------
14901
14905
*/
14902
- staticvoid
14903
- dumpACL(Archive *fout,CatalogId objCatId , DumpIdobjDumpId ,
14906
+ staticDumpId
14907
+ dumpACL(Archive *fout,DumpId objDumpId , DumpIdaltDumpId ,
14904
14908
const char *type, const char *name, const char *subname,
14905
14909
const char *nspname, const char *owner,
14906
14910
const char *acls, const char *racls,
14907
14911
const char *initacls, const char *initracls)
14908
14912
{
14913
+ DumpIdaclDumpId = InvalidDumpId;
14909
14914
DumpOptions *dopt = fout->dopt;
14910
14915
PQExpBuffer sql;
14911
14916
14912
14917
/* Do nothing if ACL dump is not enabled */
14913
14918
if (dopt->aclsSkip)
14914
- return;
14919
+ return InvalidDumpId ;
14915
14920
14916
14921
/* --data-only skips ACLs *except* BLOB ACLs */
14917
14922
if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
14918
- return;
14923
+ return InvalidDumpId ;
14919
14924
14920
14925
sql = createPQExpBuffer();
14921
14926
@@ -14949,24 +14954,35 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
14949
14954
if (sql->len > 0)
14950
14955
{
14951
14956
PQExpBuffer tag = createPQExpBuffer();
14957
+ DumpIdaclDeps[2];
14958
+ intnDeps = 0;
14952
14959
14953
14960
if (subname)
14954
14961
appendPQExpBuffer(tag, "COLUMN %s.%s", name, subname);
14955
14962
else
14956
14963
appendPQExpBuffer(tag, "%s %s", type, name);
14957
14964
14958
- ArchiveEntry(fout, nilCatalogId, createDumpId(),
14965
+ aclDeps[nDeps++] = objDumpId;
14966
+ if (altDumpId != InvalidDumpId)
14967
+ aclDeps[nDeps++] = altDumpId;
14968
+
14969
+ aclDumpId = createDumpId();
14970
+
14971
+ ArchiveEntry(fout, nilCatalogId, aclDumpId,
14959
14972
tag->data, nspname,
14960
14973
NULL,
14961
14974
owner ? owner : "",
14962
14975
false, "ACL", SECTION_NONE,
14963
14976
sql->data, "", NULL,
14964
- &(objDumpId), 1 ,
14977
+ aclDeps, nDeps ,
14965
14978
NULL, NULL);
14979
+
14966
14980
destroyPQExpBuffer(tag);
14967
14981
}
14968
14982
14969
14983
destroyPQExpBuffer(sql);
14984
+
14985
+ return aclDumpId;
14970
14986
}
14971
14987
14972
14988
/*
@@ -15288,6 +15304,7 @@ static void
15288
15304
dumpTable(Archive *fout, TableInfo *tbinfo)
15289
15305
{
15290
15306
DumpOptions *dopt = fout->dopt;
15307
+ DumpIdtableAclDumpId = InvalidDumpId;
15291
15308
char *namecopy;
15292
15309
15293
15310
/*
@@ -15309,11 +15326,12 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
15309
15326
const char *objtype =
15310
15327
(tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
15311
15328
15312
- dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
15313
- objtype, namecopy, NULL,
15314
- tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
15315
- tbinfo->relacl, tbinfo->rrelacl,
15316
- tbinfo->initrelacl, tbinfo->initrrelacl);
15329
+ tableAclDumpId =
15330
+ dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
15331
+ objtype, namecopy, NULL,
15332
+ tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
15333
+ tbinfo->relacl, tbinfo->rrelacl,
15334
+ tbinfo->initrelacl, tbinfo->initrrelacl);
15317
15335
}
15318
15336
15319
15337
/*
@@ -15397,8 +15415,13 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
15397
15415
char *attnamecopy;
15398
15416
15399
15417
attnamecopy = pg_strdup(fmtId(attname));
15400
- /* Column's GRANT type is always TABLE */
15401
- dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
15418
+
15419
+ /*
15420
+ * Column's GRANT type is always TABLE. Each column ACL depends
15421
+ * on the table-level ACL, since we can restore column ACLs in
15422
+ * parallel but the table-level ACL has to be done first.
15423
+ */
15424
+ dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
15402
15425
"TABLE", namecopy, attnamecopy,
15403
15426
tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
15404
15427
attacl, rattacl, initattacl, initrattacl);