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 14084.1340159655@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.  I'm not coming up with any very nice ideas about exactly how
to refactor, though.  Thoughts?

            regards, tom lane

diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index aa9c8eed5dafabd49429874d973e22abe93d5294..2db67d6fd3d5616944ff0b086aa606af11e9eed4 100644
*** a/src/bin/pg_dump/pg_backup_archiver.c
--- b/src/bin/pg_dump/pg_backup_archiver.c
*************** static void _becomeUser(ArchiveHandle *A
*** 129,134 ****
--- 129,135 ----
  static void _becomeOwner(ArchiveHandle *AH, TocEntry *te);
  static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName);
  static void _selectTablespace(ArchiveHandle *AH, const char *tablespace);
+ static void writeDependencies(ArchiveHandle *AH, const DumpId *dependencies, int nDeps);
  static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te);
  static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te);
  static teReqs _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt);
*************** WriteToc(ArchiveHandle *AH)
*** 2144,2150 ****
      TocEntry   *te;
      char        workbuf[32];
      int            tocCount;
-     int            i;

      /* count entries that will actually be dumped */
      tocCount = 0;
--- 2145,2150 ----
*************** WriteToc(ArchiveHandle *AH)
*** 2184,2195 ****
          WriteStr(AH, te->withOids ? "true" : "false");

          /* Dump list of dependencies */
!         for (i = 0; i < te->nDeps; i++)
!         {
!             sprintf(workbuf, "%d", te->dependencies[i]);
!             WriteStr(AH, workbuf);
!         }
!         WriteStr(AH, NULL);        /* Terminate List */

          if (AH->WriteExtraTocPtr)
              (*AH->WriteExtraTocPtr) (AH, te);
--- 2184,2191 ----
          WriteStr(AH, te->withOids ? "true" : "false");

          /* Dump list of dependencies */
!         writeDependencies(AH, te->dependencies, te->nDeps);
!         WriteStr(AH, NULL);        /* list terminator */

          if (AH->WriteExtraTocPtr)
              (*AH->WriteExtraTocPtr) (AH, te);
*************** ReadToc(ArchiveHandle *AH)
*** 2353,2358 ****
--- 2349,2400 ----
      }
  }

+ /*
+  * Dump an object's dependencies in a usable form, ie, referencing only
+  * objects that are included in the dump.  We need to make this distinction
+  * since, 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 have to look through the rule to get
+  * a useful representation of the view's dependencies.
+  *
+  * We rely here on the assumption that sortDumpableObjects already broke any
+  * dependency loops, else we might recurse infinitely.
+  */
+ static void
+ writeDependencies(ArchiveHandle *AH, const DumpId *dependencies, int nDeps)
+ {
+     char        workbuf[32];
+     int            i;
+
+     for (i = 0; i < nDeps; i++)
+     {
+         DumpId        depid = dependencies[i];
+         TocEntry   *depte = getTocEntryByDumpId(AH, depid);
+
+         if (depte &&
+             (depte->reqs & (REQ_SCHEMA | REQ_DATA | REQ_SPECIAL)) != 0)
+         {
+             /* Object will be dumped, so just reference it as a dependency */
+             /* Dependency IDs are printed as strings for historical reasons */
+             sprintf(workbuf, "%d", depid);
+             WriteStr(AH, workbuf);
+         }
+         else
+         {
+             /*
+              * Object will not be dumped, so recursively consider its deps.
+              * Here we must resort to the underlying DumpableObject data
+              * structures, since often there will be no TocEntry for such
+              * an object.
+              */
+             DumpableObject *dobj = findObjectByDumpId(depid);
+
+             if (dobj)
+                 writeDependencies(AH, dobj->dependencies, dobj->nDeps);
+         }
+     }
+ }
+
  static void
  processEncodingEntry(ArchiveHandle *AH, TocEntry *te)
  {

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

Предыдущее
От: Tom Lane
Дата:
Сообщение: 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