const char *owner, CatalogId catalogId, DumpId dumpId);
static void dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo);
-static void dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
- const char *type, const char *name, const char *subname,
- const char *nspname, const char *owner,
- const char *acls, const char *racls,
- const char *initacls, const char *initracls);
+static DumpId dumpACL(Archive *fout, DumpId objDumpId, DumpId altDumpId,
+ const char *type, const char *name, const char *subname,
+ const char *nspname, const char *owner,
+ const char *acls, const char *racls,
+ const char *initacls, const char *initracls);
static void getDependencies(Archive *fout);
static void BuildArchiveDependencies(Archive *fout);
* Dump ACL if any. Note that we do not support initial privileges
* (pg_init_privs) on databases.
*/
- dumpACL(fout, dbCatId, dbDumpId, "DATABASE",
+ dumpACL(fout, dbDumpId, InvalidDumpId, "DATABASE",
qdatname, NULL, NULL,
dba, datacl, rdatacl, "", "");
/* Dump ACL if any */
if (binfo->blobacl && (binfo->dobj.dump & DUMP_COMPONENT_ACL))
- dumpACL(fout, binfo->dobj.catId, binfo->dobj.dumpId, "LARGE OBJECT",
+ dumpACL(fout, binfo->dobj.dumpId, InvalidDumpId, "LARGE OBJECT",
binfo->dobj.name, NULL,
NULL, binfo->rolname, binfo->blobacl, binfo->rblobacl,
binfo->initblobacl, binfo->initrblobacl);
nspinfo->dobj.catId, 0, nspinfo->dobj.dumpId);
if (nspinfo->dobj.dump & DUMP_COMPONENT_ACL)
- dumpACL(fout, nspinfo->dobj.catId, nspinfo->dobj.dumpId, "SCHEMA",
+ dumpACL(fout, nspinfo->dobj.dumpId, InvalidDumpId, "SCHEMA",
qnspname, NULL, NULL,
nspinfo->rolname, nspinfo->nspacl, nspinfo->rnspacl,
nspinfo->initnspacl, nspinfo->initrnspacl);
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
qtypname, NULL,
tyinfo->dobj.namespace->dobj.name,
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
qtypname, NULL,
tyinfo->dobj.namespace->dobj.name,
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
qtypname, NULL,
tyinfo->dobj.namespace->dobj.name,
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
qtypname, NULL,
tyinfo->dobj.namespace->dobj.name,
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
qtypname, NULL,
tyinfo->dobj.namespace->dobj.name,
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
tyinfo->dobj.catId, 0, tyinfo->dobj.dumpId);
if (tyinfo->dobj.dump & DUMP_COMPONENT_ACL)
- dumpACL(fout, tyinfo->dobj.catId, tyinfo->dobj.dumpId, "TYPE",
+ dumpACL(fout, tyinfo->dobj.dumpId, InvalidDumpId, "TYPE",
qtypname, NULL,
tyinfo->dobj.namespace->dobj.name,
tyinfo->rolname, tyinfo->typacl, tyinfo->rtypacl,
plang->dobj.catId, 0, plang->dobj.dumpId);
if (plang->lanpltrusted && plang->dobj.dump & DUMP_COMPONENT_ACL)
- dumpACL(fout, plang->dobj.catId, plang->dobj.dumpId, "LANGUAGE",
+ dumpACL(fout, plang->dobj.dumpId, InvalidDumpId, "LANGUAGE",
qlanname, NULL, NULL,
plang->lanowner, plang->lanacl, plang->rlanacl,
plang->initlanacl, plang->initrlanacl);
finfo->dobj.catId, 0, finfo->dobj.dumpId);
if (finfo->dobj.dump & DUMP_COMPONENT_ACL)
- dumpACL(fout, finfo->dobj.catId, finfo->dobj.dumpId, keyword,
+ dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId, keyword,
funcsig, NULL,
finfo->dobj.namespace->dobj.name,
finfo->rolname, finfo->proacl, finfo->rproacl,
aggsig = format_function_signature(fout, &agginfo->aggfn, true);
if (agginfo->aggfn.dobj.dump & DUMP_COMPONENT_ACL)
- dumpACL(fout, agginfo->aggfn.dobj.catId, agginfo->aggfn.dobj.dumpId,
+ dumpACL(fout, agginfo->aggfn.dobj.dumpId, InvalidDumpId,
"FUNCTION", aggsig, NULL,
agginfo->aggfn.dobj.namespace->dobj.name,
agginfo->aggfn.rolname, agginfo->aggfn.proacl,
/* Handle the ACL */
if (fdwinfo->dobj.dump & DUMP_COMPONENT_ACL)
- dumpACL(fout, fdwinfo->dobj.catId, fdwinfo->dobj.dumpId,
+ dumpACL(fout, fdwinfo->dobj.dumpId, InvalidDumpId,
"FOREIGN DATA WRAPPER", qfdwname, NULL,
NULL, fdwinfo->rolname,
fdwinfo->fdwacl, fdwinfo->rfdwacl,
/* Handle the ACL */
if (srvinfo->dobj.dump & DUMP_COMPONENT_ACL)
- dumpACL(fout, srvinfo->dobj.catId, srvinfo->dobj.dumpId,
+ dumpACL(fout, srvinfo->dobj.dumpId, InvalidDumpId,
"FOREIGN SERVER", qsrvname, NULL,
NULL, srvinfo->rolname,
srvinfo->srvacl, srvinfo->rsrvacl,
/*----------
* Write out grant/revoke information
*
- * 'objCatId' is the catalog ID of the underlying object.
* 'objDumpId' is the dump ID of the underlying object.
+ * 'altDumpId' can be a second dumpId that the ACL entry must also depend on,
+ * or InvalidDumpId if there is no need for a second dependency.
* 'type' must be one of
* TABLE, SEQUENCE, FUNCTION, LANGUAGE, SCHEMA, DATABASE, TABLESPACE,
* FOREIGN DATA WRAPPER, SERVER, or LARGE OBJECT.
* NB: initacls/initracls are needed because extensions can set privileges on
* an object during the extension's script file and we record those into
* pg_init_privs as that object's initial privileges.
+ *
+ * Returns the dump ID assigned to the ACL TocEntry, or InvalidDumpId if
+ * no ACL entry was created.
*----------
*/
-static void
-dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
+static DumpId
+dumpACL(Archive *fout, DumpId objDumpId, DumpId altDumpId,
const char *type, const char *name, const char *subname,
const char *nspname, const char *owner,
const char *acls, const char *racls,
const char *initacls, const char *initracls)
{
+ DumpId aclDumpId = InvalidDumpId;
DumpOptions *dopt = fout->dopt;
PQExpBuffer sql;
/* Do nothing if ACL dump is not enabled */
if (dopt->aclsSkip)
- return;
+ return InvalidDumpId;
/* --data-only skips ACLs *except* BLOB ACLs */
if (dopt->dataOnly && strcmp(type, "LARGE OBJECT") != 0)
- return;
+ return InvalidDumpId;
sql = createPQExpBuffer();
if (sql->len > 0)
{
PQExpBuffer tag = createPQExpBuffer();
+ DumpId aclDeps[2];
+ int nDeps = 0;
if (subname)
appendPQExpBuffer(tag, "COLUMN %s.%s", name, subname);
else
appendPQExpBuffer(tag, "%s %s", type, name);
- ArchiveEntry(fout, nilCatalogId, createDumpId(),
+ aclDeps[nDeps++] = objDumpId;
+ if (altDumpId != InvalidDumpId)
+ aclDeps[nDeps++] = altDumpId;
+
+ aclDumpId = createDumpId();
+
+ ArchiveEntry(fout, nilCatalogId, aclDumpId,
ARCHIVE_OPTS(.tag = tag->data,
.namespace = nspname,
.owner = owner,
.description = "ACL",
.section = SECTION_NONE,
.createStmt = sql->data,
- .deps = &objDumpId,
- .nDeps = 1));
+ .deps = aclDeps,
+ .nDeps = nDeps));
+
destroyPQExpBuffer(tag);
}
destroyPQExpBuffer(sql);
+
+ return aclDumpId;
}
/*
dumpTable(Archive *fout, TableInfo *tbinfo)
{
DumpOptions *dopt = fout->dopt;
+ DumpId tableAclDumpId = InvalidDumpId;
char *namecopy;
/*
const char *objtype =
(tbinfo->relkind == RELKIND_SEQUENCE) ? "SEQUENCE" : "TABLE";
- dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
- objtype, namecopy, NULL,
- tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
- tbinfo->relacl, tbinfo->rrelacl,
- tbinfo->initrelacl, tbinfo->initrrelacl);
+ tableAclDumpId =
+ dumpACL(fout, tbinfo->dobj.dumpId, InvalidDumpId,
+ objtype, namecopy, NULL,
+ tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
+ tbinfo->relacl, tbinfo->rrelacl,
+ tbinfo->initrelacl, tbinfo->initrrelacl);
}
/*
char *attnamecopy;
attnamecopy = pg_strdup(fmtId(attname));
- /* Column's GRANT type is always TABLE */
- dumpACL(fout, tbinfo->dobj.catId, tbinfo->dobj.dumpId,
+
+ /*
+ * Column's GRANT type is always TABLE. Each column ACL depends
+ * on the table-level ACL, since we can restore column ACLs in
+ * parallel but the table-level ACL has to be done first.
+ */
+ dumpACL(fout, tbinfo->dobj.dumpId, tableAclDumpId,
"TABLE", namecopy, attnamecopy,
tbinfo->dobj.namespace->dobj.name, tbinfo->rolname,
attacl, rattacl, initattacl, initrattacl);