@@ -220,11 +220,11 @@ static void dumpUserMappings(Archive *fout,
220
220
const char *owner, CatalogId catalogId, DumpId dumpId);
221
221
static void dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo);
222
222
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);
228
228
229
229
static void getDependencies(Archive *fout);
230
230
static void BuildArchiveDependencies(Archive *fout);
@@ -2992,7 +2992,7 @@ dumpDatabase(Archive *fout)
2992
2992
* Dump ACL if any. Note that we do not support initial privileges
2993
2993
* (pg_init_privs) on databases.
2994
2994
*/
2995
- dumpACL(fout, dbCatId, dbDumpId , "DATABASE",
2995
+ dumpACL(fout, dbDumpId, InvalidDumpId , "DATABASE",
2996
2996
qdatname, NULL, NULL,
2997
2997
dba, datacl, rdatacl, "", "");
2998
2998
@@ -3477,7 +3477,7 @@ dumpBlob(Archive *fout, BlobInfo *binfo)
3477
3477
3478
3478
/* Dump ACL if any */
3479
3479
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",
3481
3481
binfo->dobj.name, NULL,
3482
3482
NULL, binfo->rolname, binfo->blobacl, binfo->rblobacl,
3483
3483
binfo->initblobacl, binfo->initrblobacl);
@@ -10155,7 +10155,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
10155
10155
nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
10156
10156
10157
10157
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",
10159
10159
qnspname, NULL, NULL,
10160
10160
nspinfo->rolname, nspinfo->nspacl, nspinfo->rnspacl,
10161
10161
nspinfo->initnspacl, nspinfo->initrnspacl);
@@ -10439,7 +10439,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
10439
10439
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10440
10440
10441
10441
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",
10443
10443
qtypname, NULL,
10444
10444
tyinfo->dobj.namespace->dobj.name,
10445
10445
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10565,7 +10565,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
10565
10565
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10566
10566
10567
10567
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",
10569
10569
qtypname, NULL,
10570
10570
tyinfo->dobj.namespace->dobj.name,
10571
10571
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10637,7 +10637,7 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
10637
10637
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10638
10638
10639
10639
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",
10641
10641
qtypname, NULL,
10642
10642
tyinfo->dobj.namespace->dobj.name,
10643
10643
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10918,7 +10918,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
10918
10918
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10919
10919
10920
10920
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",
10922
10922
qtypname, NULL,
10923
10923
tyinfo->dobj.namespace->dobj.name,
10924
10924
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11074,7 +11074,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
11074
11074
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11075
11075
11076
11076
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",
11078
11078
qtypname, NULL,
11079
11079
tyinfo->dobj.namespace->dobj.name,
11080
11080
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11296,7 +11296,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
11296
11296
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11297
11297
11298
11298
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",
11300
11300
qtypname, NULL,
11301
11301
tyinfo->dobj.namespace->dobj.name,
11302
11302
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11596,7 +11596,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
11596
11596
plang->dobj.catId, 0, plang->dobj.dumpId);
11597
11597
11598
11598
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",
11600
11600
qlanname, NULL, NULL,
11601
11601
plang->lanowner, plang->lanacl, plang->rlanacl,
11602
11602
plang->initlanacl, plang->initrlanacl);
@@ -12306,7 +12306,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
12306
12306
finfo->dobj.catId, 0, finfo->dobj.dumpId);
12307
12307
12308
12308
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,
12310
12310
funcsig, NULL,
12311
12311
finfo->dobj.namespace->dobj.name,
12312
12312
finfo->rolname, finfo->proacl, finfo->rproacl,
@@ -14304,7 +14304,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
14304
14304
aggsig = format_function_signature(fout, &agginfo->aggfn, true);
14305
14305
14306
14306
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 ,
14308
14308
"FUNCTION", aggsig, NULL,
14309
14309
agginfo->aggfn.dobj.namespace->dobj.name,
14310
14310
agginfo->aggfn.rolname, agginfo->aggfn.proacl,
@@ -14706,7 +14706,7 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
14706
14706
14707
14707
/* Handle the ACL */
14708
14708
if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
14709
- dumpACL(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId ,
14709
+ dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId ,
14710
14710
"FOREIGN DATA WRAPPER", qfdwname, NULL,
14711
14711
NULL, fdwinfo->rolname,
14712
14712
fdwinfo->fdwacl, fdwinfo->rfdwacl,
@@ -14795,7 +14795,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
14795
14795
14796
14796
/* Handle the ACL */
14797
14797
if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
14798
- dumpACL(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId ,
14798
+ dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId ,
14799
14799
"FOREIGN SERVER", qsrvname, NULL,
14800
14800
NULL, srvinfo->rolname,
14801
14801
srvinfo->srvacl, srvinfo->rsrvacl,
@@ -14988,8 +14988,9 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
14988
14988
/*----------
14989
14989
* Write out grant/revoke information
14990
14990
*
14991
- * 'objCatId' is the catalog ID of the underlying object.
14992
14991
* '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.
14993
14994
* 'type' must be one of
14994
14995
* TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, TABLESPACE,
14995
14996
* FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT.
@@ -15012,25 +15013,29 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
15012
15013
* NB: initacls/initracls are needed because extensions can set privileges on
15013
15014
* an object during the extension's script file and we record those into
15014
15015
* 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.
15015
15019
*----------
15016
15020
*/
15017
- static void
15018
- dumpACL(Archive *fout, CatalogId objCatId , DumpId objDumpId ,
15021
+ static DumpId
15022
+ dumpACL(Archive *fout, DumpId objDumpId , DumpId altDumpId ,
15019
15023
const char *type, const char *name, const char *subname,
15020
15024
const char *nspname, const char *owner,
15021
15025
const char *acls, const char *racls,
15022
15026
const char *initacls, const char *initracls)
15023
15027
{
15028
+ DumpId aclDumpId = InvalidDumpId;
15024
15029
DumpOptions *dopt = fout->dopt;
15025
15030
PQExpBuffer sql;
15026
15031
15027
15032
/* Do nothing if ACL dump is not enabled */
15028
15033
if (dopt->aclsSkip)
15029
- return;
15034
+ return InvalidDumpId ;
15030
15035
15031
15036
/* --data-only skips ACLs *except* BLOB ACLs */
15032
15037
if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
15033
- return;
15038
+ return InvalidDumpId ;
15034
15039
15035
15040
sql = createPQExpBuffer();
15036
15041
@@ -15062,25 +15067,36 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
15062
15067
if (sql->len > 0)
15063
15068
{
15064
15069
PQExpBuffer tag = createPQExpBuffer();
15070
+ DumpId aclDeps[2];
15071
+ int nDeps = 0;
15065
15072
15066
15073
if (subname)
15067
15074
appendPQExpBuffer(tag, "COLUMN %s.%s", name, subname);
15068
15075
else
15069
15076
appendPQExpBuffer(tag, "%s %s", type, name);
15070
15077
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,
15072
15085
ARCHIVE_OPTS(.tag = tag->data,
15073
15086
.namespace = nspname,
15074
15087
.owner = owner,
15075
15088
.description = "ACL",
15076
15089
.section = SECTION_NONE,
15077
15090
.createStmt = sql->data,
15078
- .deps = &objDumpId,
15079
- .nDeps = 1));
15091
+ .deps = aclDeps,
15092
+ .nDeps = nDeps));
15093
+
15080
15094
destroyPQExpBuffer(tag);
15081
15095
}
15082
15096
15083
15097
destroyPQExpBuffer(sql);
15098
+
15099
+ return aclDumpId;
15084
15100
}
15085
15101
15086
15102
/*
@@ -15406,6 +15422,7 @@ static void
15406
15422
dumpTable(Archive *fout, TableInfo *tbinfo)
15407
15423
{
15408
15424
DumpOptions *dopt = fout->dopt;
15425
+ DumpId tableAclDumpId = InvalidDumpId;
15409
15426
char *namecopy;
15410
15427
15411
15428
/*
@@ -15427,11 +15444,12 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
15427
15444
const char *objtype =
15428
15445
(tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
15429
15446
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);
15435
15453
}
15436
15454
15437
15455
/*
@@ -15515,8 +15533,13 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
15515
15533
char *attnamecopy;
15516
15534
15517
15535
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,
15520
15543
"TABLE", namecopy, attnamecopy,
15521
15544
tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
15522
15545
attacl, rattacl, initattacl, initrattacl);
0 commit comments