@@ -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);
@@ -10208,7 +10208,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
10208
10208
nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
10209
10209
10210
10210
if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
10211
- dumpACL(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId , "SCHEMA",
10211
+ dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId , "SCHEMA",
10212
10212
qnspname, NULL, NULL,
10213
10213
nspinfo->rolname, nspinfo->nspacl, nspinfo->rnspacl,
10214
10214
nspinfo->initnspacl, nspinfo->initrnspacl);
@@ -10492,7 +10492,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
10492
10492
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10493
10493
10494
10494
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10495
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10495
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10496
10496
qtypname, NULL,
10497
10497
tyinfo->dobj.namespace->dobj.name,
10498
10498
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10618,7 +10618,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
10618
10618
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10619
10619
10620
10620
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10621
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10621
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10622
10622
qtypname, NULL,
10623
10623
tyinfo->dobj.namespace->dobj.name,
10624
10624
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10690,7 +10690,7 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
10690
10690
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10691
10691
10692
10692
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10693
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10693
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10694
10694
qtypname, NULL,
10695
10695
tyinfo->dobj.namespace->dobj.name,
10696
10696
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -10971,7 +10971,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
10971
10971
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
10972
10972
10973
10973
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
10974
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
10974
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
10975
10975
qtypname, NULL,
10976
10976
tyinfo->dobj.namespace->dobj.name,
10977
10977
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11127,7 +11127,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
11127
11127
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11128
11128
11129
11129
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11130
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
11130
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
11131
11131
qtypname, NULL,
11132
11132
tyinfo->dobj.namespace->dobj.name,
11133
11133
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11349,7 +11349,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
11349
11349
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
11350
11350
11351
11351
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
11352
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId , "TYPE",
11352
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId , "TYPE",
11353
11353
qtypname, NULL,
11354
11354
tyinfo->dobj.namespace->dobj.name,
11355
11355
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
@@ -11649,7 +11649,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
11649
11649
plang->dobj.catId, 0, plang->dobj.dumpId);
11650
11650
11651
11651
if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
11652
- dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId , "LANGUAGE",
11652
+ dumpACL(fout, plang->dobj.dumpId, InvalidDumpId , "LANGUAGE",
11653
11653
qlanname, NULL, NULL,
11654
11654
plang->lanowner, plang->lanacl, plang->rlanacl,
11655
11655
plang->initlanacl, plang->initrlanacl);
@@ -12359,7 +12359,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
12359
12359
finfo->dobj.catId, 0, finfo->dobj.dumpId);
12360
12360
12361
12361
if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
12362
- dumpACL(fout, finfo->dobj.catId, finfo->dobj.dumpId , keyword,
12362
+ dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId , keyword,
12363
12363
funcsig, NULL,
12364
12364
finfo->dobj.namespace->dobj.name,
12365
12365
finfo->rolname, finfo->proacl, finfo->rproacl,
@@ -14380,7 +14380,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
14380
14380
aggsig = format_function_signature(fout, &agginfo->aggfn, true);
14381
14381
14382
14382
if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
14383
- dumpACL(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId ,
14383
+ dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId ,
14384
14384
"FUNCTION", aggsig, NULL,
14385
14385
agginfo->aggfn.dobj.namespace->dobj.name,
14386
14386
agginfo->aggfn.rolname, agginfo->aggfn.proacl,
@@ -14782,7 +14782,7 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
14782
14782
14783
14783
/* Handle the ACL */
14784
14784
if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
14785
- dumpACL(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId ,
14785
+ dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId ,
14786
14786
"FOREIGN DATA WRAPPER", qfdwname, NULL,
14787
14787
NULL, fdwinfo->rolname,
14788
14788
fdwinfo->fdwacl, fdwinfo->rfdwacl,
@@ -14871,7 +14871,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
14871
14871
14872
14872
/* Handle the ACL */
14873
14873
if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
14874
- dumpACL(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId ,
14874
+ dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId ,
14875
14875
"FOREIGN SERVER", qsrvname, NULL,
14876
14876
NULL, srvinfo->rolname,
14877
14877
srvinfo->srvacl, srvinfo->rsrvacl,
@@ -15064,8 +15064,9 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
15064
15064
/*----------
15065
15065
* Write out grant/revoke information
15066
15066
*
15067
- * 'objCatId' is the catalog ID of the underlying object.
15068
15067
* 'objDumpId' is the dump ID of the underlying object.
15068
+ * 'altDumpId' can be a second dumpId that the ACL entry must also depend on,
15069
+ * or InvalidDumpId if there is no need for a second dependency.
15069
15070
* 'type' must be one of
15070
15071
* TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, TABLESPACE,
15071
15072
* FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT.
@@ -15088,25 +15089,29 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
15088
15089
* NB: initacls/initracls are needed because extensions can set privileges on
15089
15090
* an object during the extension's script file and we record those into
15090
15091
* pg_init_privs as that object's initial privileges.
15092
+ *
15093
+ * Returns the dump ID assigned to the ACL TocEntry, or InvalidDumpId if
15094
+ * no ACL entry was created.
15091
15095
*----------
15092
15096
*/
15093
- static void
15094
- dumpACL(Archive *fout, CatalogId objCatId , DumpId objDumpId ,
15097
+ static DumpId
15098
+ dumpACL(Archive *fout, DumpId objDumpId , DumpId altDumpId ,
15095
15099
const char *type, const char *name, const char *subname,
15096
15100
const char *nspname, const char *owner,
15097
15101
const char *acls, const char *racls,
15098
15102
const char *initacls, const char *initracls)
15099
15103
{
15104
+ DumpId aclDumpId = InvalidDumpId;
15100
15105
DumpOptions *dopt = fout->dopt;
15101
15106
PQExpBuffer sql;
15102
15107
15103
15108
/* Do nothing if ACL dump is not enabled */
15104
15109
if (dopt->aclsSkip)
15105
- return;
15110
+ return InvalidDumpId ;
15106
15111
15107
15112
/* --data-only skips ACLs *except* BLOB ACLs */
15108
15113
if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
15109
- return;
15114
+ return InvalidDumpId ;
15110
15115
15111
15116
sql = createPQExpBuffer();
15112
15117
@@ -15138,25 +15143,36 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
15138
15143
if (sql->len > 0)
15139
15144
{
15140
15145
PQExpBuffer tag = createPQExpBuffer();
15146
+ DumpId aclDeps[2];
15147
+ int nDeps = 0;
15141
15148
15142
15149
if (subname)
15143
15150
appendPQExpBuffer(tag, "COLUMN %s.%s", name, subname);
15144
15151
else
15145
15152
appendPQExpBuffer(tag, "%s %s", type, name);
15146
15153
15147
- ArchiveEntry(fout, nilCatalogId, createDumpId(),
15154
+ aclDeps[nDeps++] = objDumpId;
15155
+ if (altDumpId != InvalidDumpId)
15156
+ aclDeps[nDeps++] = altDumpId;
15157
+
15158
+ aclDumpId = createDumpId();
15159
+
15160
+ ArchiveEntry(fout, nilCatalogId, aclDumpId,
15148
15161
ARCHIVE_OPTS(.tag = tag->data,
15149
15162
.namespace = nspname,
15150
15163
.owner = owner,
15151
15164
.description = "ACL",
15152
15165
.section = SECTION_NONE,
15153
15166
.createStmt = sql->data,
15154
- .deps = &objDumpId,
15155
- .nDeps = 1));
15167
+ .deps = aclDeps,
15168
+ .nDeps = nDeps));
15169
+
15156
15170
destroyPQExpBuffer(tag);
15157
15171
}
15158
15172
15159
15173
destroyPQExpBuffer(sql);
15174
+
15175
+ return aclDumpId;
15160
15176
}
15161
15177
15162
15178
/*
@@ -15482,6 +15498,7 @@ static void
15482
15498
dumpTable(Archive *fout, TableInfo *tbinfo)
15483
15499
{
15484
15500
DumpOptions *dopt = fout->dopt;
15501
+ DumpId tableAclDumpId = InvalidDumpId;
15485
15502
char *namecopy;
15486
15503
15487
15504
/*
@@ -15503,11 +15520,12 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
15503
15520
const char *objtype =
15504
15521
(tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
15505
15522
15506
- dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
15507
- objtype, namecopy, NULL,
15508
- tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
15509
- tbinfo->relacl, tbinfo->rrelacl,
15510
- tbinfo->initrelacl, tbinfo->initrrelacl);
15523
+ tableAclDumpId =
15524
+ dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
15525
+ objtype, namecopy, NULL,
15526
+ tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
15527
+ tbinfo->relacl, tbinfo->rrelacl,
15528
+ tbinfo->initrelacl, tbinfo->initrrelacl);
15511
15529
}
15512
15530
15513
15531
/*
@@ -15591,8 +15609,13 @@ dumpTable(Archive *fout, TableInfo *tbinfo)
15591
15609
char *attnamecopy;
15592
15610
15593
15611
attnamecopy = pg_strdup(fmtId(attname));
15594
- /* Column's GRANT type is always TABLE */
15595
- dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
15612
+
15613
+ /*
15614
+ * Column's GRANT type is always TABLE. Each column ACL depends
15615
+ * on the table-level ACL, since we can restore column ACLs in
15616
+ * parallel but the table-level ACL has to be done first.
15617
+ */
15618
+ dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
15596
15619
"TABLE", namecopy, attnamecopy,
15597
15620
tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
15598
15621
attacl, rattacl, initattacl, initrattacl);
0 commit comments