const char *owner, CatalogId catalogId, DumpId dumpId);
 static void dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo);
 
-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,
 
    /* 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, "FUNCTION",
+       dumpACL(fout, finfo->dobj.dumpId, InvalidDumpId, "FUNCTION",
                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,
                     tag->data, nspname,
                     NULL,
                     owner ? owner : "",
                     false, "ACL", SECTION_NONE,
                     sql->data, "", NULL,
-                    &(objDumpId), 1,
+                    aclDeps, nDeps,
                     NULL, NULL);
+
        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);