const char *acls);
 
 static void getDependencies(Archive *fout);
+static void BuildArchiveDependencies(Archive *fout);
+static void findDumpableDependencies(ArchiveHandle *AH, DumpableObject *dobj,
+                        DumpId **dependencies, int *nDeps, int *allocDeps);
 
 static DumpableObject *createBoundaryObjects(void);
 static void addBoundaryDependencies(DumpableObject **dobjs, int numObjs,
 
    SetArchiveRestoreOptions(fout, ropt);
 
+   /*
+    * The archive's TOC entries are now marked as to which ones will
+    * actually be output, so we can set up their dependency lists properly.
+    * This isn't necessary for plain-text output, though.
+    */
+   if (!plainText)
+       BuildArchiveDependencies(fout);
+
    /*
     * And finally we can do the actual output.
     *
        copyStmt = NULL;
    }
 
+   /*
+    * Note: although the TableDataInfo is a full DumpableObject, we treat its
+    * dependency on its table as "special" and pass it to ArchiveEntry now.
+    * See comments for BuildArchiveDependencies.
+    */
    ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId,
                 tbinfo->dobj.name, tbinfo->dobj.namespace->dobj.name,
                 NULL, tbinfo->rolname,
                 false, "TABLE DATA", SECTION_DATA,
                 "", "", copyStmt,
-                tdinfo->dobj.dependencies, tdinfo->dobj.nDeps,
+                &(tbinfo->dobj.dumpId), 1,
                 dumpFn, tdinfo);
 
    destroyPQExpBuffer(copyBuf);
                 binfo->rolname, false,
                 "BLOB", SECTION_PRE_DATA,
                 cquery->data, dquery->data, NULL,
-                binfo->dobj.dependencies, binfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* set up tag for comment and/or ACL */
                         dobj->name, NULL, NULL, "",
                         false, "BLOBS", SECTION_DATA,
                         "", "", NULL,
-                        dobj->dependencies, dobj->nDeps,
+                        NULL, 0,
                         dumpBlobs, NULL);
            break;
        case DO_PRE_DATA_BOUNDARY:
                 nspinfo->rolname,
                 false, "SCHEMA", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                nspinfo->dobj.dependencies, nspinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Schema Comments and Security Labels */
                 "",
                 false, "EXTENSION", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                extinfo->dobj.dependencies, extinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Extension Comments and Security Labels */
                 tyinfo->rolname, false,
                 "TYPE", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Type Comments and Security Labels */
                 tyinfo->rolname, false,
                 "TYPE", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Type Comments and Security Labels */
                 tyinfo->rolname, false,
                 "TYPE", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Type Comments and Security Labels */
                 tyinfo->rolname, false,
                 "DOMAIN", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Domain Comments and Security Labels */
                 tyinfo->rolname, false,
                 "TYPE", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
 
                 stinfo->baseType->rolname, false,
                 "SHELL TYPE", SECTION_PRE_DATA,
                 q->data, "", NULL,
-                stinfo->dobj.dependencies, stinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    destroyPQExpBuffer(q);
                 lanschema, NULL, plang->lanowner,
                 false, "PROCEDURAL LANGUAGE", SECTION_PRE_DATA,
                 defqry->data, delqry->data, NULL,
-                plang->dobj.dependencies, plang->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Proc Lang Comments and Security Labels */
                 finfo->rolname, false,
                 "FUNCTION", SECTION_PRE_DATA,
                 q->data, delqry->data, NULL,
-                finfo->dobj.dependencies, finfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Function Comments and Security Labels */
                 "pg_catalog", NULL, "",
                 false, "CAST", SECTION_PRE_DATA,
                 defqry->data, delqry->data, NULL,
-                cast->dobj.dependencies, cast->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Cast Comments */
                 oprinfo->rolname,
                 false, "OPERATOR", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                oprinfo->dobj.dependencies, oprinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Operator Comments */
                 opcinfo->rolname,
                 false, "OPERATOR CLASS", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                opcinfo->dobj.dependencies, opcinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Operator Class Comments */
                 opfinfo->rolname,
                 false, "OPERATOR FAMILY", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                opfinfo->dobj.dependencies, opfinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Operator Family Comments */
                 collinfo->rolname,
                 false, "COLLATION", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                collinfo->dobj.dependencies, collinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Collation Comments */
                 convinfo->rolname,
                 false, "CONVERSION", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                convinfo->dobj.dependencies, convinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Conversion Comments */
                 agginfo->aggfn.rolname,
                 false, "AGGREGATE", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                agginfo->aggfn.dobj.dependencies, agginfo->aggfn.dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Aggregate Comments */
                 "",
                 false, "TEXT SEARCH PARSER", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                prsinfo->dobj.dependencies, prsinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Parser Comments */
                 dictinfo->rolname,
                 false, "TEXT SEARCH DICTIONARY", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                dictinfo->dobj.dependencies, dictinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Dictionary Comments */
                 "",
                 false, "TEXT SEARCH TEMPLATE", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                tmplinfo->dobj.dependencies, tmplinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Template Comments */
                 cfginfo->rolname,
                 false, "TEXT SEARCH CONFIGURATION", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                cfginfo->dobj.dependencies, cfginfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump Configuration Comments */
                 fdwinfo->rolname,
                 false, "FOREIGN DATA WRAPPER", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                fdwinfo->dobj.dependencies, fdwinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Handle the ACL */
                 srvinfo->rolname,
                 false, "SERVER", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                srvinfo->dobj.dependencies, srvinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Handle the ACL */
                 daclinfo->defaclrole,
                 false, "DEFAULT ACL", SECTION_POST_DATA,
                 q->data, "", NULL,
-                daclinfo->dobj.dependencies, daclinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    destroyPQExpBuffer(tag);
               (strcmp(reltypename, "TABLE") == 0) ? tbinfo->hasoids : false,
                 reltypename, SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                tbinfo->dobj.dependencies, tbinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
 
                 tbinfo->rolname,
                 false, "DEFAULT", SECTION_PRE_DATA,
                 q->data, delq->data, NULL,
-                adinfo->dobj.dependencies, adinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    destroyPQExpBuffer(q);
                     tbinfo->rolname, false,
                     "INDEX", SECTION_POST_DATA,
                     q->data, delq->data, NULL,
-                    indxinfo->dobj.dependencies, indxinfo->dobj.nDeps,
+                    NULL, 0,
                     NULL, NULL);
    }
 
                     tbinfo->rolname, false,
                     "CONSTRAINT", SECTION_POST_DATA,
                     q->data, delq->data, NULL,
-                    coninfo->dobj.dependencies, coninfo->dobj.nDeps,
+                    NULL, 0,
                     NULL, NULL);
    }
    else if (coninfo->contype == 'f')
                     tbinfo->rolname, false,
                     "FK CONSTRAINT", SECTION_POST_DATA,
                     q->data, delq->data, NULL,
-                    coninfo->dobj.dependencies, coninfo->dobj.nDeps,
+                    NULL, 0,
                     NULL, NULL);
    }
    else if (coninfo->contype == 'c' && tbinfo)
                         tbinfo->rolname, false,
                         "CHECK CONSTRAINT", SECTION_POST_DATA,
                         q->data, delq->data, NULL,
-                        coninfo->dobj.dependencies, coninfo->dobj.nDeps,
+                        NULL, 0,
                         NULL, NULL);
        }
    }
                         tyinfo->rolname, false,
                         "CHECK CONSTRAINT", SECTION_POST_DATA,
                         q->data, delq->data, NULL,
-                        coninfo->dobj.dependencies, coninfo->dobj.nDeps,
+                        NULL, 0,
                         NULL, NULL);
        }
    }
                     tbinfo->rolname,
                     false, "SEQUENCE", SECTION_PRE_DATA,
                     query->data, delqry->data, NULL,
-                    tbinfo->dobj.dependencies, tbinfo->dobj.nDeps,
+                    NULL, 0,
                     NULL, NULL);
 
        /*
                 tbinfo->rolname, false,
                 "TRIGGER", SECTION_POST_DATA,
                 query->data, delqry->data, NULL,
-                tginfo->dobj.dependencies, tginfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    dumpComment(fout, labelq->data,
                 tbinfo->rolname, false,
                 "RULE", SECTION_POST_DATA,
                 cmd->data, delcmd->data, NULL,
-                rinfo->dobj.dependencies, rinfo->dobj.nDeps,
+                NULL, 0,
                 NULL, NULL);
 
    /* Dump rule comments */
 }
 
 
+/*
+ * BuildArchiveDependencies - create dependency data for archive TOC entries
+ *
+ * The raw dependency data obtained by getDependencies() is not terribly
+ * useful in an archive dump, because in many cases there are dependency
+ * chains linking through objects that don't appear explicitly in the dump.
+ * For example, a view will depend on its _RETURN rule while the _RETURN rule
+ * will depend on other objects --- but the rule will not appear as a separate
+ * object in the dump.  We need to adjust the view's dependencies to include
+ * whatever the rule depends on that is included in the dump.
+ *
+ * Just to make things more complicated, there are also "special" dependencies
+ * such as the dependency of a TABLE DATA item on its TABLE, which we must
+ * not rearrange because pg_restore knows that TABLE DATA only depends on
+ * its table.  In these cases we must leave the dependencies strictly as-is
+ * even if they refer to not-to-be-dumped objects.
+ *
+ * To handle this, the convention is that "special" dependencies are created
+ * during ArchiveEntry calls, and an archive TOC item that has any such
+ * entries will not be touched here.  Otherwise, we recursively search the
+ * DumpableObject data structures to build the correct dependencies for each
+ * archive TOC item.
+ */
+static void
+BuildArchiveDependencies(Archive *fout)
+{
+   ArchiveHandle *AH = (ArchiveHandle *) fout;
+   TocEntry   *te;
+
+   /* Scan all TOC entries in the archive */
+   for (te = AH->toc->next; te != AH->toc; te = te->next)
+   {
+       DumpableObject *dobj;
+       DumpId     *dependencies;
+       int         nDeps;
+       int         allocDeps;
+
+       /* No need to process entries that will not be dumped */
+       if (te->reqs == 0)
+           continue;
+       /* Ignore entries that already have "special" dependencies */
+       if (te->nDeps > 0)
+           continue;
+       /* Otherwise, look up the item's original DumpableObject, if any */
+       dobj = findObjectByDumpId(te->dumpId);
+       if (dobj == NULL)
+           continue;
+       /* No work if it has no dependencies */
+       if (dobj->nDeps <= 0)
+           continue;
+       /* Set up work array */
+       allocDeps = 64;
+       dependencies = (DumpId *) pg_malloc(allocDeps * sizeof(DumpId));
+       nDeps = 0;
+       /* Recursively find all dumpable dependencies */
+       findDumpableDependencies(AH, dobj,
+                                &dependencies, &nDeps, &allocDeps);
+       /* And save 'em ... */
+       if (nDeps > 0)
+       {
+           dependencies = (DumpId *) pg_realloc(dependencies,
+                                                nDeps * sizeof(DumpId));
+           te->dependencies = dependencies;
+           te->nDeps = nDeps;
+       }
+       else
+           free(dependencies);
+   }
+}
+
+/* Recursive search subroutine for BuildArchiveDependencies */
+static void
+findDumpableDependencies(ArchiveHandle *AH, DumpableObject *dobj,
+                        DumpId **dependencies, int *nDeps, int *allocDeps)
+{
+   int         i;
+
+   /*
+    * Ignore section boundary objects: if we search through them, we'll
+    * report lots of bogus dependencies.
+    */
+   if (dobj->objType == DO_PRE_DATA_BOUNDARY ||
+       dobj->objType == DO_POST_DATA_BOUNDARY)
+       return;
+
+   for (i = 0; i < dobj->nDeps; i++)
+   {
+       DumpId      depid = dobj->dependencies[i];
+
+       if (TocIDRequired(AH, depid) != 0)
+       {
+           /* Object will be dumped, so just reference it as a dependency */
+           if (*nDeps >= *allocDeps)
+           {
+               *allocDeps *= 2;
+               *dependencies = (DumpId *) pg_realloc(*dependencies,
+                                             *allocDeps * sizeof(DumpId));
+           }
+           (*dependencies)[*nDeps] = depid;
+           (*nDeps)++;
+       }
+       else
+       {
+           /*
+            * Object will not be dumped, so recursively consider its deps.
+            * We rely on the assumption that sortDumpableObjects already
+            * broke any dependency loops, else we might recurse infinitely.
+            */
+           DumpableObject *otherdobj = findObjectByDumpId(depid);
+
+           if (otherdobj)
+               findDumpableDependencies(AH, otherdobj,
+                                        dependencies, nDeps, allocDeps);
+       }
+   }
+}
+
+
 /*
  * selectSourceSchema - make the specified schema the active search path
  * in the source database.