Re: BUG #6699: pg_restore with -j -- doesn't restore view that groups by primary key

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: BUG #6699: pg_restore with -j -- doesn't restore view that groups by primary key
Дата
Msg-id 16032.1340255828@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: BUG #6699: pg_restore with -j -- doesn't restore view that groups by primary key  (Tom Lane <tgl@sss.pgh.pa.us>)
Ответы Re: BUG #6699: pg_restore with -j -- doesn't restore view that groups by primary key  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-bugs
I wrote:
>> We could possibly hack something for the special case of rules, but
>> I don't think this would be the last time we hear about this type of
>> issue.  I'm inclined to think that the best solution would be to add
>> generic logic to pg_dump that "looks through" any dependency references
>> to objects that are not going to be dumped, and replaces them with the
>> IDs of any objects they depend on that are going to be dumped.

> I wrote a trial patch that does things that way (attached) and it
> appears to work and solve the problem.  However, it's not committable
> as-is because it breaks the build of pg_restore:

> ld: Unsatisfied symbols:
>    findObjectByDumpId (code)

> since findObjectByDumpId is in common.c which isn't linked into
> pg_restore.  I guess a brute force solution would be to link it,
> but probably we ought to think about refactoring the code to avoid
> that.

Actually, that brute force solution doesn't work at all, because
common.c contains many call-backs into pg_dump.c, and we certainly
don't want to link pg_dump.c into pg_restore.  I thought for a little
bit about breaking common.c into two pieces, but am not excited about
doing major refactoring on the spur of the moment.  (Mind you, this
code probably *needs* wholesale refactoring; I just don't want to do
it as part of a bug fix.)

Another problem I noticed after further thought is that in a partial or
data-only dump, this patch could rearrange dependencies that pg_restore
has hardwired knowledge of, such as the dependency of a TABLE DATA item
on its table.  I'm not certain that that would break anything, but it
seems pretty darn dangerous.  I think that we don't want to rearrange
any dependencies that are "built in" by pg_dump itself rather than being
obtained from pg_depend --- this includes the TABLE DATA case as well
as COMMENT, ACL, and SECURITY LABEL items' dependencies on their parent
objects.

So attached is another try that puts the work into pg_dump.c.  There are
a couple things I don't especially like, but don't see an easy way to
improve on:

* This code would be the first in pg_dump.c that looks through Archive
to ArchiveHandle.  Although we've muttered before that that distinction
is useless, doing this here still seems a bit out of place.  But we
can't put it in pg_backup_archiver.c because of the findObjectByDumpId
dependence, so I see no better answer.

* To handle the "built in" dependency problem mentioned above, I
introduced a convention that only "built in" dependencies should be
explicitly passed to ArchiveEntry(); everything with regular
dependencies should pass NULL/0, and then we build the real dependencies
at the very end of the archive construction process.  This is annoying
because it's easy to do the wrong thing: if you forget and use the old
style of passing the DumpableObject's dependencies to ArchiveEntry, it
will *appear* to work, and only break when/if one of these indirection
cases comes up.  A less error-prone convention would be nice, but I
can't think of a good one offhand.

Another thing that might be a showstopper is that this will only work
as-is in HEAD and 9.2, because only since commit
4317e0246c645f60c39e6572644cff1cb03b4c65 do we have explicit advance
marking of which TOC entries are going to get dumped.  If we want to
fix this problem this way in older branches, we're going to have to
back-port parts of that commit.  I don't actually see any alternative
way to fix it, though.  How concerned are we about making this work
in released branches?

Comments?

            regards, tom lane

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 5fde18921ac3c20f878fbe5ad22c60fabc13a916..247406364c734c918543a54dc37cb6b4fc188a2c 100644
*** a/src/bin/pg_dump/pg_dump.c
--- b/src/bin/pg_dump/pg_dump.c
*************** static void dumpACL(Archive *fout, Catal
*** 210,215 ****
--- 210,219 ----
          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 void getDomainConstraints(Archive *fout, TypeInfo *tyinfo);
  static void getTableData(TableInfo *tblinfo, int numTables, bool oids);
  static void makeTableDataInfo(TableInfo *tbinfo, bool oids);
*************** main(int argc, char **argv)
*** 753,758 ****
--- 757,770 ----
      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.
       *
       * Note: for non-plain-text output formats, the output file is written
*************** dumpTableData(Archive *fout, TableDataIn
*** 1558,1569 ****
          copyStmt = NULL;
      }

      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,
                   dumpFn, tdinfo);

      destroyPQExpBuffer(copyBuf);
--- 1570,1586 ----
          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,
!                  &(tbinfo->dobj.dumpId), 1,
                   dumpFn, tdinfo);

      destroyPQExpBuffer(copyBuf);
*************** dumpBlob(Archive *fout, BlobInfo *binfo)
*** 2247,2253 ****
                   binfo->rolname, false,
                   "BLOB", SECTION_PRE_DATA,
                   cquery->data, dquery->data, NULL,
!                  binfo->dobj.dependencies, binfo->dobj.nDeps,
                   NULL, NULL);

      /* set up tag for comment and/or ACL */
--- 2264,2270 ----
                   binfo->rolname, false,
                   "BLOB", SECTION_PRE_DATA,
                   cquery->data, dquery->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* set up tag for comment and/or ACL */
*************** dumpDumpableObject(Archive *fout, Dumpab
*** 7181,7187 ****
                           dobj->name, NULL, NULL, "",
                           false, "BLOBS", SECTION_DATA,
                           "", "", NULL,
!                          dobj->dependencies, dobj->nDeps,
                           dumpBlobs, NULL);
              break;
      }
--- 7198,7204 ----
                           dobj->name, NULL, NULL, "",
                           false, "BLOBS", SECTION_DATA,
                           "", "", NULL,
!                          NULL, 0,
                           dumpBlobs, NULL);
              break;
      }
*************** dumpNamespace(Archive *fout, NamespaceIn
*** 7228,7234 ****
                   nspinfo->rolname,
                   false, "SCHEMA", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  nspinfo->dobj.dependencies, nspinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Schema Comments and Security Labels */
--- 7245,7251 ----
                   nspinfo->rolname,
                   false, "SCHEMA", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Schema Comments and Security Labels */
*************** dumpExtension(Archive *fout, ExtensionIn
*** 7346,7352 ****
                   "",
                   false, "EXTENSION", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  extinfo->dobj.dependencies, extinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Extension Comments and Security Labels */
--- 7363,7369 ----
                   "",
                   false, "EXTENSION", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Extension Comments and Security Labels */
*************** dumpEnumType(Archive *fout, TypeInfo *ty
*** 7494,7500 ****
                   tyinfo->rolname, false,
                   "TYPE", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Type Comments and Security Labels */
--- 7511,7517 ----
                   tyinfo->rolname, false,
                   "TYPE", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Type Comments and Security Labels */
*************** dumpRangeType(Archive *fout, TypeInfo *t
*** 7619,7625 ****
                   tyinfo->rolname, false,
                   "TYPE", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Type Comments and Security Labels */
--- 7636,7642 ----
                   tyinfo->rolname, false,
                   "TYPE", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Type Comments and Security Labels */
*************** dumpBaseType(Archive *fout, TypeInfo *ty
*** 8001,8007 ****
                   tyinfo->rolname, false,
                   "TYPE", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Type Comments and Security Labels */
--- 8018,8024 ----
                   tyinfo->rolname, false,
                   "TYPE", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Type Comments and Security Labels */
*************** dumpDomain(Archive *fout, TypeInfo *tyin
*** 8156,8162 ****
                   tyinfo->rolname, false,
                   "DOMAIN", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Domain Comments and Security Labels */
--- 8173,8179 ----
                   tyinfo->rolname, false,
                   "DOMAIN", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Domain Comments and Security Labels */
*************** dumpCompositeType(Archive *fout, TypeInf
*** 8363,8369 ****
                   tyinfo->rolname, false,
                   "TYPE", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  tyinfo->dobj.dependencies, tyinfo->dobj.nDeps,
                   NULL, NULL);


--- 8380,8386 ----
                   tyinfo->rolname, false,
                   "TYPE", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);


*************** dumpShellType(Archive *fout, ShellTypeIn
*** 8535,8541 ****
                   stinfo->baseType->rolname, false,
                   "SHELL TYPE", SECTION_PRE_DATA,
                   q->data, "", NULL,
!                  stinfo->dobj.dependencies, stinfo->dobj.nDeps,
                   NULL, NULL);

      destroyPQExpBuffer(q);
--- 8552,8558 ----
                   stinfo->baseType->rolname, false,
                   "SHELL TYPE", SECTION_PRE_DATA,
                   q->data, "", NULL,
!                  NULL, 0,
                   NULL, NULL);

      destroyPQExpBuffer(q);
*************** dumpProcLang(Archive *fout, ProcLangInfo
*** 8709,8715 ****
                   lanschema, NULL, plang->lanowner,
                   false, "PROCEDURAL LANGUAGE", SECTION_PRE_DATA,
                   defqry->data, delqry->data, NULL,
!                  plang->dobj.dependencies, plang->dobj.nDeps,
                   NULL, NULL);

      /* Dump Proc Lang Comments and Security Labels */
--- 8726,8732 ----
                   lanschema, NULL, plang->lanowner,
                   false, "PROCEDURAL LANGUAGE", SECTION_PRE_DATA,
                   defqry->data, delqry->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Proc Lang Comments and Security Labels */
*************** dumpFunc(Archive *fout, FuncInfo *finfo)
*** 9296,9302 ****
                   finfo->rolname, false,
                   "FUNCTION", SECTION_PRE_DATA,
                   q->data, delqry->data, NULL,
!                  finfo->dobj.dependencies, finfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Function Comments and Security Labels */
--- 9313,9319 ----
                   finfo->rolname, false,
                   "FUNCTION", SECTION_PRE_DATA,
                   q->data, delqry->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Function Comments and Security Labels */
*************** dumpCast(Archive *fout, CastInfo *cast)
*** 9466,9472 ****
                   "pg_catalog", NULL, "",
                   false, "CAST", SECTION_PRE_DATA,
                   defqry->data, delqry->data, NULL,
!                  cast->dobj.dependencies, cast->dobj.nDeps,
                   NULL, NULL);

      /* Dump Cast Comments */
--- 9483,9489 ----
                   "pg_catalog", NULL, "",
                   false, "CAST", SECTION_PRE_DATA,
                   defqry->data, delqry->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Cast Comments */
*************** dumpOpr(Archive *fout, OprInfo *oprinfo)
*** 9700,9706 ****
                   oprinfo->rolname,
                   false, "OPERATOR", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  oprinfo->dobj.dependencies, oprinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Operator Comments */
--- 9717,9723 ----
                   oprinfo->rolname,
                   false, "OPERATOR", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Operator Comments */
*************** dumpOpclass(Archive *fout, OpclassInfo *
*** 10207,10213 ****
                   opcinfo->rolname,
                   false, "OPERATOR CLASS", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  opcinfo->dobj.dependencies, opcinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Operator Class Comments */
--- 10224,10230 ----
                   opcinfo->rolname,
                   false, "OPERATOR CLASS", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Operator Class Comments */
*************** dumpOpfamily(Archive *fout, OpfamilyInfo
*** 10520,10526 ****
                   opfinfo->rolname,
                   false, "OPERATOR FAMILY", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  opfinfo->dobj.dependencies, opfinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Operator Family Comments */
--- 10537,10543 ----
                   opfinfo->rolname,
                   false, "OPERATOR FAMILY", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Operator Family Comments */
*************** dumpCollation(Archive *fout, CollInfo *c
*** 10609,10615 ****
                   collinfo->rolname,
                   false, "COLLATION", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  collinfo->dobj.dependencies, collinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Collation Comments */
--- 10626,10632 ----
                   collinfo->rolname,
                   false, "COLLATION", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Collation Comments */
*************** dumpConversion(Archive *fout, ConvInfo *
*** 10708,10714 ****
                   convinfo->rolname,
                   false, "CONVERSION", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  convinfo->dobj.dependencies, convinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Conversion Comments */
--- 10725,10731 ----
                   convinfo->rolname,
                   false, "CONVERSION", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Conversion Comments */
*************** dumpAgg(Archive *fout, AggInfo *agginfo)
*** 10945,10951 ****
                   agginfo->aggfn.rolname,
                   false, "AGGREGATE", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  agginfo->aggfn.dobj.dependencies, agginfo->aggfn.dobj.nDeps,
                   NULL, NULL);

      /* Dump Aggregate Comments */
--- 10962,10968 ----
                   agginfo->aggfn.rolname,
                   false, "AGGREGATE", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Aggregate Comments */
*************** dumpTSParser(Archive *fout, TSParserInfo
*** 11043,11049 ****
                   "",
                   false, "TEXT SEARCH PARSER", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  prsinfo->dobj.dependencies, prsinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Parser Comments */
--- 11060,11066 ----
                   "",
                   false, "TEXT SEARCH PARSER", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Parser Comments */
*************** dumpTSDictionary(Archive *fout, TSDictIn
*** 11130,11136 ****
                   dictinfo->rolname,
                   false, "TEXT SEARCH DICTIONARY", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  dictinfo->dobj.dependencies, dictinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Dictionary Comments */
--- 11147,11153 ----
                   dictinfo->rolname,
                   false, "TEXT SEARCH DICTIONARY", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Dictionary Comments */
*************** dumpTSTemplate(Archive *fout, TSTemplate
*** 11196,11202 ****
                   "",
                   false, "TEXT SEARCH TEMPLATE", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  tmplinfo->dobj.dependencies, tmplinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Template Comments */
--- 11213,11219 ----
                   "",
                   false, "TEXT SEARCH TEMPLATE", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Template Comments */
*************** dumpTSConfig(Archive *fout, TSConfigInfo
*** 11324,11330 ****
                   cfginfo->rolname,
                   false, "TEXT SEARCH CONFIGURATION", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  cfginfo->dobj.dependencies, cfginfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump Configuration Comments */
--- 11341,11347 ----
                   cfginfo->rolname,
                   false, "TEXT SEARCH CONFIGURATION", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump Configuration Comments */
*************** dumpForeignDataWrapper(Archive *fout, Fd
*** 11398,11404 ****
                   fdwinfo->rolname,
                   false, "FOREIGN DATA WRAPPER", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  fdwinfo->dobj.dependencies, fdwinfo->dobj.nDeps,
                   NULL, NULL);

      /* Handle the ACL */
--- 11415,11421 ----
                   fdwinfo->rolname,
                   false, "FOREIGN DATA WRAPPER", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Handle the ACL */
*************** dumpForeignServer(Archive *fout, Foreign
*** 11490,11496 ****
                   srvinfo->rolname,
                   false, "SERVER", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  srvinfo->dobj.dependencies, srvinfo->dobj.nDeps,
                   NULL, NULL);

      /* Handle the ACL */
--- 11507,11513 ----
                   srvinfo->rolname,
                   false, "SERVER", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Handle the ACL */
*************** dumpDefaultACL(Archive *fout, DefaultACL
*** 11674,11680 ****
                   daclinfo->defaclrole,
                   false, "DEFAULT ACL", SECTION_NONE,
                   q->data, "", NULL,
!                  daclinfo->dobj.dependencies, daclinfo->dobj.nDeps,
                   NULL, NULL);

      destroyPQExpBuffer(tag);
--- 11691,11697 ----
                   daclinfo->defaclrole,
                   false, "DEFAULT ACL", SECTION_NONE,
                   q->data, "", NULL,
!                  NULL, 0,
                   NULL, NULL);

      destroyPQExpBuffer(tag);
*************** dumpTableSchema(Archive *fout, TableInfo
*** 12673,12679 ****
                 (strcmp(reltypename, "TABLE") == 0) ? tbinfo->hasoids : false,
                   reltypename, SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  tbinfo->dobj.dependencies, tbinfo->dobj.nDeps,
                   NULL, NULL);


--- 12690,12696 ----
                 (strcmp(reltypename, "TABLE") == 0) ? tbinfo->hasoids : false,
                   reltypename, SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);


*************** dumpAttrDef(Archive *fout, AttrDefInfo *
*** 12745,12751 ****
                   tbinfo->rolname,
                   false, "DEFAULT", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  adinfo->dobj.dependencies, adinfo->dobj.nDeps,
                   NULL, NULL);

      destroyPQExpBuffer(q);
--- 12762,12768 ----
                   tbinfo->rolname,
                   false, "DEFAULT", SECTION_PRE_DATA,
                   q->data, delq->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      destroyPQExpBuffer(q);
*************** dumpIndex(Archive *fout, IndxInfo *indxi
*** 12847,12853 ****
                       tbinfo->rolname, false,
                       "INDEX", SECTION_POST_DATA,
                       q->data, delq->data, NULL,
!                      indxinfo->dobj.dependencies, indxinfo->dobj.nDeps,
                       NULL, NULL);
      }

--- 12864,12870 ----
                       tbinfo->rolname, false,
                       "INDEX", SECTION_POST_DATA,
                       q->data, delq->data, NULL,
!                      NULL, 0,
                       NULL, NULL);
      }

*************** dumpConstraint(Archive *fout, Constraint
*** 12968,12974 ****
                       tbinfo->rolname, false,
                       "CONSTRAINT", SECTION_POST_DATA,
                       q->data, delq->data, NULL,
!                      coninfo->dobj.dependencies, coninfo->dobj.nDeps,
                       NULL, NULL);
      }
      else if (coninfo->contype == 'f')
--- 12985,12991 ----
                       tbinfo->rolname, false,
                       "CONSTRAINT", SECTION_POST_DATA,
                       q->data, delq->data, NULL,
!                      NULL, 0,
                       NULL, NULL);
      }
      else if (coninfo->contype == 'f')
*************** dumpConstraint(Archive *fout, Constraint
*** 13001,13007 ****
                       tbinfo->rolname, false,
                       "FK CONSTRAINT", SECTION_POST_DATA,
                       q->data, delq->data, NULL,
!                      coninfo->dobj.dependencies, coninfo->dobj.nDeps,
                       NULL, NULL);
      }
      else if (coninfo->contype == 'c' && tbinfo)
--- 13018,13024 ----
                       tbinfo->rolname, false,
                       "FK CONSTRAINT", SECTION_POST_DATA,
                       q->data, delq->data, NULL,
!                      NULL, 0,
                       NULL, NULL);
      }
      else if (coninfo->contype == 'c' && tbinfo)
*************** dumpConstraint(Archive *fout, Constraint
*** 13036,13042 ****
                           tbinfo->rolname, false,
                           "CHECK CONSTRAINT", SECTION_POST_DATA,
                           q->data, delq->data, NULL,
!                          coninfo->dobj.dependencies, coninfo->dobj.nDeps,
                           NULL, NULL);
          }
      }
--- 13053,13059 ----
                           tbinfo->rolname, false,
                           "CHECK CONSTRAINT", SECTION_POST_DATA,
                           q->data, delq->data, NULL,
!                          NULL, 0,
                           NULL, NULL);
          }
      }
*************** dumpConstraint(Archive *fout, Constraint
*** 13072,13078 ****
                           tyinfo->rolname, false,
                           "CHECK CONSTRAINT", SECTION_POST_DATA,
                           q->data, delq->data, NULL,
!                          coninfo->dobj.dependencies, coninfo->dobj.nDeps,
                           NULL, NULL);
          }
      }
--- 13089,13095 ----
                           tyinfo->rolname, false,
                           "CHECK CONSTRAINT", SECTION_POST_DATA,
                           q->data, delq->data, NULL,
!                          NULL, 0,
                           NULL, NULL);
          }
      }
*************** dumpSequence(Archive *fout, TableInfo *t
*** 13334,13340 ****
                       tbinfo->rolname,
                       false, "SEQUENCE", SECTION_PRE_DATA,
                       query->data, delqry->data, NULL,
!                      tbinfo->dobj.dependencies, tbinfo->dobj.nDeps,
                       NULL, NULL);

          /*
--- 13351,13357 ----
                       tbinfo->rolname,
                       false, "SEQUENCE", SECTION_PRE_DATA,
                       query->data, delqry->data, NULL,
!                      NULL, 0,
                       NULL, NULL);

          /*
*************** dumpTrigger(Archive *fout, TriggerInfo *
*** 13600,13606 ****
                   tbinfo->rolname, false,
                   "TRIGGER", SECTION_POST_DATA,
                   query->data, delqry->data, NULL,
!                  tginfo->dobj.dependencies, tginfo->dobj.nDeps,
                   NULL, NULL);

      dumpComment(fout, labelq->data,
--- 13617,13623 ----
                   tbinfo->rolname, false,
                   "TRIGGER", SECTION_POST_DATA,
                   query->data, delqry->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      dumpComment(fout, labelq->data,
*************** dumpRule(Archive *fout, RuleInfo *rinfo)
*** 13721,13727 ****
                   tbinfo->rolname, false,
                   "RULE", SECTION_POST_DATA,
                   cmd->data, delcmd->data, NULL,
!                  rinfo->dobj.dependencies, rinfo->dobj.nDeps,
                   NULL, NULL);

      /* Dump rule comments */
--- 13738,13744 ----
                   tbinfo->rolname, false,
                   "RULE", SECTION_POST_DATA,
                   cmd->data, delcmd->data, NULL,
!                  NULL, 0,
                   NULL, NULL);

      /* Dump rule comments */
*************** getDependencies(Archive *fout)
*** 14028,14033 ****
--- 14045,14160 ----


  /*
+  * 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;
+
+     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.
   *

В списке pgsql-bugs по дате отправления:

Предыдущее
От: Pavel Stehule
Дата:
Сообщение: Re: BUG #6701: IS NOT NULL doesn't work on complex composites
Следующее
От: Rikard Pavelic
Дата:
Сообщение: Re: BUG #6701: IS NOT NULL doesn't work on complex composites