@@ -226,11 +226,11 @@ static void dumpUserMappings(Archive *fout,
226
226
const char *owner, CatalogId catalogId, DumpId dumpId);
227
227
static void dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo);
228
228
229
- static void dumpACL(Archive *fout, CatalogId objCatId , DumpId objDumpId ,
230
- const char *type, const char *name, const char *subname,
231
- const char *nspname, const char *owner,
232
- const char *acls, const char *racls,
233
- const char *initacls, const char *initracls);
229
+ static DumpId dumpACL(Archive *fout, DumpId objDumpId , DumpId altDumpId ,
230
+ const char *type, const char *name, const char *subname,
231
+ const char *nspname, const char *owner,
232
+ const char *acls, const char *racls,
233
+ const char *initacls, const char *initracls);
234
234
235
235
static void getDependencies(Archive *fout);
236
236
static void BuildArchiveDependencies(Archive *fout);
@@ -2922,7 +2922,7 @@ dumpDatabase(Archive *fout)
2922
2922
* Dump ACL if any. Note that we do not support initial privileges
2923
2923
* (pg_init_privs) on databases.
2924
2924
*/
2925
- dumpACL(fout, dbCatId, dbDumpId , "DATABASE",
2925
+ dumpACL(fout, dbDumpId, InvalidDumpId , "DATABASE",
2926
2926
qdatname, NULL, NULL,
2927
2927
dba, datacl, rdatacl, "", "");
2928
2928
@@ -3407,7 +3407,7 @@ dumpBlob(Archive *fout, BlobInfo *binfo)
3407
3407
3408
3408
/* Dump ACL if any */
3409
3409
if (binfo->blobacl && (binfo->dobj.dump & DUMP_COMPONENT_ACL))
3410
- dumpACL(fout, binfo->dobj.catId, binfo->dobj.dumpId , "LARGE OBJECT",
3410
+ dumpACL(fout, binfo->dobj.dumpId, InvalidDumpId , "LARGE OBJECT",
3411
3411
binfo->dobj.name, NULL,
3412
3412
NULL, binfo->rolname, binfo->blobacl, binfo->rblobacl,
3413
3413
binfo->initblobacl, binfo->initrblobacl);
@@ -10085,7 +10085,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
10085
10085
nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
10086
10086
10087
10087
if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
10088
- dumpACL(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId , "SCHEMA",
10088
+ dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId , "SCHEMA",
10089
10089
qnspname, NULL, NULL,
10090
10090
nspinfo->rolname, nspinfo->nspacl, nspinfo->rnspacl,
10091
10091
nspinfo->initnspacl, nspinfo->initrnspacl);
@@ -10369,7 +10369,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
10369
10369
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10370
10370
10371
10371
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10372
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10372
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10373
10373
qtypname, NULL,
10374
10374
tyinfo->dobj.namespace->dobj.name,
10375
10375
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10495,7 +10495,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
10495
10495
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10496
10496
10497
10497
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10498
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10498
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10499
10499
qtypname, NULL,
10500
10500
tyinfo->dobj.namespace->dobj.name,
10501
10501
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10567,7 +10567,7 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
10567
10567
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10568
10568
10569
10569
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10570
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10570
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10571
10571
qtypname, NULL,
10572
10572
tyinfo->dobj.namespace->dobj.name,
10573
10573
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10848,7 +10848,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
10848
10848
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10849
10849
10850
10850
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10851
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10851
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10852
10852
qtypname, NULL,
10853
10853
tyinfo->dobj.namespace->dobj.name,
10854
10854
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11004,7 +11004,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
11004
11004
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11005
11005
11006
11006
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11007
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
11007
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
11008
11008
qtypname, NULL,
11009
11009
tyinfo->dobj.namespace->dobj.name,
11010
11010
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11226,7 +11226,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
11226
11226
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11227
11227
11228
11228
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11229
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
11229
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
11230
11230
qtypname, NULL,
11231
11231
tyinfo->dobj.namespace->dobj.name,
11232
11232
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11526,7 +11526,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
11526
11526
plang->dobj.catId, 0, plang->dobj.dumpId);
11527
11527
11528
11528
if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
11529
- dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId , "LANGUAGE",
11529
+ dumpACL(fout, plang->dobj.dumpId, InvalidDumpId , "LANGUAGE",
11530
11530
qlanname, NULL, NULL,
11531
11531
plang->lanowner, plang->lanacl, plang->rlanacl,
11532
11532
plang->initlanacl, plang->initrlanacl);
@@ -12236,7 +12236,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
12236
12236
finfo->dobj.catId, 0, finfo->dobj.dumpId);
12237
12237
12238
12238
if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
12239
- dumpACL(fout, finfo->dobj.catId, finfo->dobj.dumpId , keyword,
12239
+ dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId , keyword,
12240
12240
funcsig, NULL,
12241
12241
finfo->dobj.namespace->dobj.name,
12242
12242
finfo->rolname, finfo->proacl, finfo->rproacl,
@@ -14257,7 +14257,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
14257
14257
aggsig = format_function_signature(fout, &agginfo->aggfn, true);
14258
14258
14259
14259
if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
14260
- dumpACL(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId ,
14260
+ dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId ,
14261
14261
"FUNCTION", aggsig, NULL,
14262
14262
agginfo->aggfn.dobj.namespace->dobj.name,
14263
14263
agginfo->aggfn.rolname, agginfo->aggfn.proacl,
@@ -14659,7 +14659,7 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
14659
14659
14660
14660
/* Handle the ACL */
14661
14661
if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
14662
- dumpACL(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId ,
14662
+ dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId ,
14663
14663
"FOREIGN DATA WRAPPER", qfdwname, NULL,
14664
14664
NULL, fdwinfo->rolname,
14665
14665
fdwinfo->fdwacl, fdwinfo->rfdwacl,
@@ -14748,7 +14748,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
14748
14748
14749
14749
/* Handle the ACL */
14750
14750
if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
14751
- dumpACL(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId ,
14751
+ dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId ,
14752
14752
"FOREIGN SERVER", qsrvname, NULL,
14753
14753
NULL, srvinfo->rolname,
14754
14754
srvinfo->srvacl, srvinfo->rsrvacl,
@@ -14941,8 +14941,9 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
14941
14941
/*----------
14942
14942
* Write out grant/revoke information
14943
14943
*
14944
- * 'objCatId' is the catalog ID of the underlying object.
14945
14944
* 'objDumpId' is the dump ID of the underlying object.
14945
+ * 'altDumpId' can be a second dumpId that the ACL entry must also depend on,
14946
+ * or InvalidDumpId if there is no need for a second dependency.
14946
14947
* 'type' must be one of
14947
14948
* TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, TABLESPACE,
14948
14949
* FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT.
@@ -14965,25 +14966,29 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
14965
14966
* NB: initacls/initracls are needed because extensions can set privileges on
14966
14967
* an object during the extension's script file and we record those into
14967
14968
* pg_init_privs as that object's initial privileges.
14969
+ *
14970
+ * Returns the dump ID assigned to the ACL TocEntry, or InvalidDumpId if
14971
+ * no ACL entry was created.
14968
14972
*----------
14969
14973
*/
14970
- static void
14971
- dumpACL(Archive *fout, CatalogId objCatId , DumpId objDumpId ,
14974
+ static DumpId
14975
+ dumpACL(Archive *fout, DumpId objDumpId , DumpId altDumpId ,
14972
14976
const char *type, const char *name, const char *subname,
14973
14977
const char *nspname, const char *owner,
14974
14978
const char *acls, const char *racls,
14975
14979
const char *initacls, const char *initracls)
14976
14980
{
14981
+ DumpId aclDumpId = InvalidDumpId;
14977
14982
DumpOptions *dopt = fout->dopt;
14978
14983
PQExpBuffer sql;
14979
14984
14980
14985
/* Do nothing if ACL dump is not enabled */
14981
14986
if (dopt->aclsSkip)
14982
- return;
14987
+ return InvalidDumpId ;
14983
14988
14984
14989
/* --data-only skips ACLs *except* BLOB ACLs */
14985
14990
if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
14986
- return;
14991
+ return InvalidDumpId ;
14987
14992
14988
14993
sql = createPQExpBuffer();
14989
14994
@@ -15015,25 +15020,36 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
15015
15020
if (sql->len > 0)
15016
15021
{
15017
15022
PQExpBuffer tag = createPQExpBuffer();
15023
+ DumpId aclDeps[2];
15024
+ int nDeps = 0;
15018
15025
15019
15026
if (subname)
15020
15027
appendPQExpBuffer(tag, "COLUMN %s.%s", name, subname);
15021
15028
else
15022
15029
appendPQExpBuffer(tag, "%s %s", type, name);
15023
15030
15024
- ArchiveEntry(fout, nilCatalogId, createDumpId(),
15031
+ aclDeps[nDeps++] = objDumpId;
15032
+ if (altDumpId != InvalidDumpId)
15033
+ aclDeps[nDeps++] = altDumpId;
15034
+
15035
+ aclDumpId = createDumpId();
15036
+
15037
+ ArchiveEntry(fout, nilCatalogId, aclDumpId,
15025
15038
ARCHIVE_OPTS(.tag = tag->data,
15026
15039
.namespace = nspname,
15027
15040
.owner = owner,
15028
15041
.description = "ACL",
15029
15042
.section = SECTION_NONE,
15030
15043
.createStmt = sql->data,
15031
- .deps = &objDumpId,
15032
- .nDeps = 1));
15044
+ .deps = aclDeps,
15045
+ .nDeps = nDeps));
15046
+
15033
15047
destroyPQExpBuffer(tag);
15034
15048
}
15035
15049
15036
15050
destroyPQExpBuffer(sql);
15051
+
15052
+ return aclDumpId;
15037
15053
}
15038
15054
15039
15055
/*
@@ -15359,6 +15375,7 @@ static void
15359
15375
dumpTable(Archive *fout, TableInfo *tbinfo)
15360
15376
{
15361
15377
DumpOptions *dopt = fout->dopt;
15378
+ DumpId tableAclDumpId = InvalidDumpId;
15362
15379
char *namecopy;
15363
15380
15364
15381
/*
@@ -15380,11 +15397,12 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
15380
15397
const char *objtype =
15381
15398
(tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
15382
15399
15383
- dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
15384
- objtype, namecopy, NULL,
15385
- tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
15386
- tbinfo->relacl, tbinfo->rrelacl,
15387
- tbinfo->initrelacl, tbinfo->initrrelacl);
15400
+ tableAclDumpId =
15401
+ dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
15402
+ objtype, namecopy, NULL,
15403
+ tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
15404
+ tbinfo->relacl, tbinfo->rrelacl,
15405
+ tbinfo->initrelacl, tbinfo->initrrelacl);
15388
15406
}
15389
15407
15390
15408
/*
@@ -15468,8 +15486,13 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
15468
15486
char *attnamecopy;
15469
15487
15470
15488
attnamecopy = pg_strdup(fmtId(attname));
15471
- /* Column's GRANT type is always TABLE */
15472
- dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
15489
+
15490
+ /*
15491
+ * Column's GRANT type is always TABLE. Each column ACL depends
15492
+ * on the table-level ACL, since we can restore column ACLs in
15493
+ * parallel but the table-level ACL has to be done first.
15494
+ */
15495
+ dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
15473
15496
"TABLE", namecopy, attnamecopy,
15474
15497
tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
15475
15498
attacl, rattacl, initattacl, initrattacl);
0 commit comments