PostgreSQL Source Code  git master
pg_backup_archiver.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_backup_archiver.c
4  *
5  * Private implementation of the archiver routines.
6  *
7  * See the headers to pg_restore for more details.
8  *
9  * Copyright (c) 2000, Philip Warner
10  * Rights are granted to use this software in any way so long
11  * as this notice is not removed.
12  *
13  * The author is not responsible for loss or damages that may
14  * result from its use.
15  *
16  *
17  * IDENTIFICATION
18  * src/bin/pg_dump/pg_backup_archiver.c
19  *
20  *-------------------------------------------------------------------------
21  */
22 #include "postgres_fe.h"
23 
24 #include <ctype.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27 #include <sys/stat.h>
28 #include <sys/wait.h>
29 #ifdef WIN32
30 #include <io.h>
31 #endif
32 
33 #include "common/string.h"
34 #include "dumputils.h"
35 #include "fe_utils/string_utils.h"
36 #include "lib/stringinfo.h"
37 #include "libpq/libpq-fs.h"
38 #include "parallel.h"
39 #include "pg_backup_archiver.h"
40 #include "pg_backup_db.h"
41 #include "pg_backup_utils.h"
42 
43 #define TEXT_DUMP_HEADER "--\n-- PostgreSQL database dump\n--\n\n"
44 #define TEXT_DUMPALL_HEADER "--\n-- PostgreSQL database cluster dump\n--\n\n"
45 
46 /* state needed to save/restore an archive's output target */
47 typedef struct _outputContext
48 {
49  void *OF;
50  int gzOut;
52 
53 /*
54  * State for tracking TocEntrys that are ready to process during a parallel
55  * restore. (This used to be a list, and we still call it that, though now
56  * it's really an array so that we can apply qsort to it.)
57  *
58  * tes[] is sized large enough that we can't overrun it.
59  * The valid entries are indexed first_te .. last_te inclusive.
60  * We periodically sort the array to bring larger-by-dataLength entries to
61  * the front; "sorted" is true if the valid entries are known sorted.
62  */
63 typedef struct _parallelReadyList
64 {
65  TocEntry **tes; /* Ready-to-dump TocEntrys */
66  int first_te; /* index of first valid entry in tes[] */
67  int last_te; /* index of last valid entry in tes[] */
68  bool sorted; /* are valid entries currently sorted? */
70 
71 
72 static ArchiveHandle *_allocAH(const char *FileSpec, const ArchiveFormat fmt,
73  const int compression, bool dosync, ArchiveMode mode,
74  SetupWorkerPtrType setupWorkerPtr);
75 static void _getObjectDescription(PQExpBuffer buf, const TocEntry *te);
76 static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData);
77 static char *sanitize_line(const char *str, bool want_hyphen);
78 static void _doSetFixedOutputState(ArchiveHandle *AH);
79 static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
80 static void _reconnectToDB(ArchiveHandle *AH, const char *dbname);
81 static void _becomeUser(ArchiveHandle *AH, const char *user);
82 static void _becomeOwner(ArchiveHandle *AH, TocEntry *te);
83 static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName);
84 static void _selectTablespace(ArchiveHandle *AH, const char *tablespace);
85 static void _selectTableAccessMethod(ArchiveHandle *AH, const char *tableam);
86 static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te);
87 static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te);
88 static void processSearchPathEntry(ArchiveHandle *AH, TocEntry *te);
89 static int _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH);
91 static bool _tocEntryIsACL(TocEntry *te);
94 static void buildTocEntryArrays(ArchiveHandle *AH);
95 static void _moveBefore(TocEntry *pos, TocEntry *te);
97 
98 static int RestoringToDB(ArchiveHandle *AH);
99 static void dump_lo_buf(ArchiveHandle *AH);
100 static void dumpTimestamp(ArchiveHandle *AH, const char *msg, time_t tim);
101 static void SetOutput(ArchiveHandle *AH, const char *filename, int compression);
103 static void RestoreOutput(ArchiveHandle *AH, OutputContext savedContext);
104 
105 static int restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel);
107  TocEntry *pending_list);
109  ParallelState *pstate,
110  TocEntry *pending_list);
112  TocEntry *pending_list);
113 static void pending_list_header_init(TocEntry *l);
114 static void pending_list_append(TocEntry *l, TocEntry *te);
115 static void pending_list_remove(TocEntry *te);
116 static void ready_list_init(ParallelReadyList *ready_list, int tocCount);
117 static void ready_list_free(ParallelReadyList *ready_list);
118 static void ready_list_insert(ParallelReadyList *ready_list, TocEntry *te);
119 static void ready_list_remove(ParallelReadyList *ready_list, int i);
120 static void ready_list_sort(ParallelReadyList *ready_list);
121 static int TocEntrySizeCompare(const void *p1, const void *p2);
122 static void move_to_ready_list(TocEntry *pending_list,
123  ParallelReadyList *ready_list,
124  RestorePass pass);
125 static TocEntry *pop_next_work_item(ParallelReadyList *ready_list,
126  ParallelState *pstate);
127 static void mark_dump_job_done(ArchiveHandle *AH,
128  TocEntry *te,
129  int status,
130  void *callback_data);
131 static void mark_restore_job_done(ArchiveHandle *AH,
132  TocEntry *te,
133  int status,
134  void *callback_data);
135 static void fix_dependencies(ArchiveHandle *AH);
136 static bool has_lock_conflicts(TocEntry *te1, TocEntry *te2);
139 static void reduce_dependencies(ArchiveHandle *AH, TocEntry *te,
140  ParallelReadyList *ready_list);
141 static void mark_create_done(ArchiveHandle *AH, TocEntry *te);
143 
144 static void StrictNamesCheck(RestoreOptions *ropt);
145 
146 
147 /*
148  * Allocate a new DumpOptions block containing all default values.
149  */
150 DumpOptions *
152 {
154 
156  return opts;
157 }
158 
159 /*
160  * Initialize a DumpOptions struct to all default values
161  */
162 void
164 {
165  memset(opts, 0, sizeof(DumpOptions));
166  /* set any fields that shouldn't default to zeroes */
167  opts->include_everything = true;
168  opts->cparams.promptPassword = TRI_DEFAULT;
169  opts->dumpSections = DUMP_UNSECTIONED;
170 }
171 
172 /*
173  * Create a freshly allocated DumpOptions with options equivalent to those
174  * found in the given RestoreOptions.
175  */
176 DumpOptions *
178 {
179  DumpOptions *dopt = NewDumpOptions();
180 
181  /* this is the inverse of what's at the end of pg_dump.c's main() */
182  dopt->cparams.dbname = ropt->cparams.dbname ? pg_strdup(ropt->cparams.dbname) : NULL;
183  dopt->cparams.pgport = ropt->cparams.pgport ? pg_strdup(ropt->cparams.pgport) : NULL;
184  dopt->cparams.pghost = ropt->cparams.pghost ? pg_strdup(ropt->cparams.pghost) : NULL;
185  dopt->cparams.username = ropt->cparams.username ? pg_strdup(ropt->cparams.username) : NULL;
187  dopt->outputClean = ropt->dropSchema;
188  dopt->dataOnly = ropt->dataOnly;
189  dopt->schemaOnly = ropt->schemaOnly;
190  dopt->if_exists = ropt->if_exists;
191  dopt->column_inserts = ropt->column_inserts;
192  dopt->dumpSections = ropt->dumpSections;
193  dopt->aclsSkip = ropt->aclsSkip;
194  dopt->outputSuperuser = ropt->superuser;
195  dopt->outputCreateDB = ropt->createDB;
196  dopt->outputNoOwner = ropt->noOwner;
197  dopt->outputNoTableAm = ropt->noTableAm;
198  dopt->outputNoTablespaces = ropt->noTablespace;
199  dopt->disable_triggers = ropt->disable_triggers;
200  dopt->use_setsessauth = ropt->use_setsessauth;
202  dopt->dump_inserts = ropt->dump_inserts;
203  dopt->no_comments = ropt->no_comments;
204  dopt->no_publications = ropt->no_publications;
206  dopt->no_subscriptions = ropt->no_subscriptions;
207  dopt->lockWaitTimeout = ropt->lockWaitTimeout;
210  dopt->sequence_data = ropt->sequence_data;
211 
212  return dopt;
213 }
214 
215 
216 /*
217  * Wrapper functions.
218  *
219  * The objective is to make writing new formats and dumpers as simple
220  * as possible, if necessary at the expense of extra function calls etc.
221  *
222  */
223 
224 /*
225  * The dump worker setup needs lots of knowledge of the internals of pg_dump,
226  * so it's defined in pg_dump.c and passed into OpenArchive. The restore worker
227  * setup doesn't need to know anything much, so it's defined here.
228  */
229 static void
231 {
232  ArchiveHandle *AH = (ArchiveHandle *) AHX;
233 
234  AH->ReopenPtr(AH);
235 }
236 
237 
238 /* Create a new archive */
239 /* Public */
240 Archive *
241 CreateArchive(const char *FileSpec, const ArchiveFormat fmt,
242  const int compression, bool dosync, ArchiveMode mode,
244 
245 {
246  ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, dosync,
248 
249  return (Archive *) AH;
250 }
251 
252 /* Open an existing archive */
253 /* Public */
254 Archive *
255 OpenArchive(const char *FileSpec, const ArchiveFormat fmt)
256 {
257  ArchiveHandle *AH = _allocAH(FileSpec, fmt, 0, true, archModeRead, setupRestoreWorker);
258 
259  return (Archive *) AH;
260 }
261 
262 /* Public */
263 void
265 {
266  int res = 0;
267  ArchiveHandle *AH = (ArchiveHandle *) AHX;
268 
269  AH->ClosePtr(AH);
270 
271  /* Close the output */
272  errno = 0; /* in case gzclose() doesn't set it */
273  if (AH->gzOut)
274  res = GZCLOSE(AH->OF);
275  else if (AH->OF != stdout)
276  res = fclose(AH->OF);
277 
278  if (res != 0)
279  pg_fatal("could not close output file: %m");
280 }
281 
282 /* Public */
283 void
285 {
286  /* Caller can omit dump options, in which case we synthesize them */
287  if (dopt == NULL && ropt != NULL)
288  dopt = dumpOptionsFromRestoreOptions(ropt);
289 
290  /* Save options for later access */
291  AH->dopt = dopt;
292  AH->ropt = ropt;
293 }
294 
295 /* Public */
296 void
298 {
299  ArchiveHandle *AH = (ArchiveHandle *) AHX;
300  RestoreOptions *ropt = AH->public.ropt;
301  TocEntry *te;
302  teSection curSection;
303 
304  /* Decide which TOC entries will be dumped/restored, and mark them */
305  curSection = SECTION_PRE_DATA;
306  for (te = AH->toc->next; te != AH->toc; te = te->next)
307  {
308  /*
309  * When writing an archive, we also take this opportunity to check
310  * that we have generated the entries in a sane order that respects
311  * the section divisions. When reading, don't complain, since buggy
312  * old versions of pg_dump might generate out-of-order archives.
313  */
314  if (AH->mode != archModeRead)
315  {
316  switch (te->section)
317  {
318  case SECTION_NONE:
319  /* ok to be anywhere */
320  break;
321  case SECTION_PRE_DATA:
322  if (curSection != SECTION_PRE_DATA)
323  pg_log_warning("archive items not in correct section order");
324  break;
325  case SECTION_DATA:
326  if (curSection == SECTION_POST_DATA)
327  pg_log_warning("archive items not in correct section order");
328  break;
329  case SECTION_POST_DATA:
330  /* ok no matter which section we were in */
331  break;
332  default:
333  pg_fatal("unexpected section code %d",
334  (int) te->section);
335  break;
336  }
337  }
338 
339  if (te->section != SECTION_NONE)
340  curSection = te->section;
341 
342  te->reqs = _tocEntryRequired(te, curSection, AH);
343  }
344 
345  /* Enforce strict names checking */
346  if (ropt->strict_names)
347  StrictNamesCheck(ropt);
348 }
349 
350 /* Public */
351 void
353 {
354  ArchiveHandle *AH = (ArchiveHandle *) AHX;
355  RestoreOptions *ropt = AH->public.ropt;
356  bool parallel_mode;
357  TocEntry *te;
358  OutputContext sav;
359 
361 
362  /*
363  * If we're going to do parallel restore, there are some restrictions.
364  */
365  parallel_mode = (AH->public.numWorkers > 1 && ropt->useDB);
366  if (parallel_mode)
367  {
368  /* We haven't got round to making this work for all archive formats */
369  if (AH->ClonePtr == NULL || AH->ReopenPtr == NULL)
370  pg_fatal("parallel restore is not supported with this archive file format");
371 
372  /* Doesn't work if the archive represents dependencies as OIDs */
373  if (AH->version < K_VERS_1_8)
374  pg_fatal("parallel restore is not supported with archives made by pre-8.0 pg_dump");
375 
376  /*
377  * It's also not gonna work if we can't reopen the input file, so
378  * let's try that immediately.
379  */
380  AH->ReopenPtr(AH);
381  }
382 
383  /*
384  * Make sure we won't need (de)compression we haven't got
385  */
386 #ifndef HAVE_LIBZ
387  if (AH->compression != 0 && AH->PrintTocDataPtr != NULL)
388  {
389  for (te = AH->toc->next; te != AH->toc; te = te->next)
390  {
391  if (te->hadDumper && (te->reqs & REQ_DATA) != 0)
392  pg_fatal("cannot restore from compressed archive (compression not supported in this installation)");
393  }
394  }
395 #endif
396 
397  /*
398  * Prepare index arrays, so we can assume we have them throughout restore.
399  * It's possible we already did this, though.
400  */
401  if (AH->tocsByDumpId == NULL)
403 
404  /*
405  * If we're using a DB connection, then connect it.
406  */
407  if (ropt->useDB)
408  {
409  pg_log_info("connecting to database for restore");
410  if (AH->version < K_VERS_1_3)
411  pg_fatal("direct database connections are not supported in pre-1.3 archives");
412 
413  /*
414  * We don't want to guess at whether the dump will successfully
415  * restore; allow the attempt regardless of the version of the restore
416  * target.
417  */
418  AHX->minRemoteVersion = 0;
419  AHX->maxRemoteVersion = 9999999;
420 
421  ConnectDatabase(AHX, &ropt->cparams, false);
422 
423  /*
424  * If we're talking to the DB directly, don't send comments since they
425  * obscure SQL when displaying errors
426  */
427  AH->noTocComments = 1;
428  }
429 
430  /*
431  * Work out if we have an implied data-only restore. This can happen if
432  * the dump was data only or if the user has used a toc list to exclude
433  * all of the schema data. All we do is look for schema entries - if none
434  * are found then we set the dataOnly flag.
435  *
436  * We could scan for wanted TABLE entries, but that is not the same as
437  * dataOnly. At this stage, it seems unnecessary (6-Mar-2001).
438  */
439  if (!ropt->dataOnly)
440  {
441  int impliedDataOnly = 1;
442 
443  for (te = AH->toc->next; te != AH->toc; te = te->next)
444  {
445  if ((te->reqs & REQ_SCHEMA) != 0)
446  { /* It's schema, and it's wanted */
447  impliedDataOnly = 0;
448  break;
449  }
450  }
451  if (impliedDataOnly)
452  {
453  ropt->dataOnly = impliedDataOnly;
454  pg_log_info("implied data-only restore");
455  }
456  }
457 
458  /*
459  * Setup the output file if necessary.
460  */
461  sav = SaveOutput(AH);
462  if (ropt->filename || ropt->compression)
463  SetOutput(AH, ropt->filename, ropt->compression);
464 
465  ahprintf(AH, "--\n-- PostgreSQL database dump\n--\n\n");
466 
467  if (AH->archiveRemoteVersion)
468  ahprintf(AH, "-- Dumped from database version %s\n",
470  if (AH->archiveDumpVersion)
471  ahprintf(AH, "-- Dumped by pg_dump version %s\n",
472  AH->archiveDumpVersion);
473 
474  ahprintf(AH, "\n");
475 
476  if (AH->public.verbose)
477  dumpTimestamp(AH, "Started on", AH->createDate);
478 
479  if (ropt->single_txn)
480  {
481  if (AH->connection)
482  StartTransaction(AHX);
483  else
484  ahprintf(AH, "BEGIN;\n\n");
485  }
486 
487  /*
488  * Establish important parameter values right away.
489  */
491 
492  AH->stage = STAGE_PROCESSING;
493 
494  /*
495  * Drop the items at the start, in reverse order
496  */
497  if (ropt->dropSchema)
498  {
499  for (te = AH->toc->prev; te != AH->toc; te = te->prev)
500  {
501  AH->currentTE = te;
502 
503  /*
504  * In createDB mode, issue a DROP *only* for the database as a
505  * whole. Issuing drops against anything else would be wrong,
506  * because at this point we're connected to the wrong database.
507  * (The DATABASE PROPERTIES entry, if any, should be treated like
508  * the DATABASE entry.)
509  */
510  if (ropt->createDB)
511  {
512  if (strcmp(te->desc, "DATABASE") != 0 &&
513  strcmp(te->desc, "DATABASE PROPERTIES") != 0)
514  continue;
515  }
516 
517  /* Otherwise, drop anything that's selected and has a dropStmt */
518  if (((te->reqs & (REQ_SCHEMA | REQ_DATA)) != 0) && te->dropStmt)
519  {
520  pg_log_info("dropping %s %s", te->desc, te->tag);
521  /* Select owner and schema as necessary */
522  _becomeOwner(AH, te);
523  _selectOutputSchema(AH, te->namespace);
524 
525  /*
526  * Now emit the DROP command, if the object has one. Note we
527  * don't necessarily emit it verbatim; at this point we add an
528  * appropriate IF EXISTS clause, if the user requested it.
529  */
530  if (*te->dropStmt != '\0')
531  {
532  if (!ropt->if_exists)
533  {
534  /* No --if-exists? Then just use the original */
535  ahprintf(AH, "%s", te->dropStmt);
536  }
537  else
538  {
539  /*
540  * Inject an appropriate spelling of "if exists". For
541  * large objects, we have a separate routine that
542  * knows how to do it, without depending on
543  * te->dropStmt; use that. For other objects we need
544  * to parse the command.
545  */
546  if (strncmp(te->desc, "BLOB", 4) == 0)
547  {
548  DropBlobIfExists(AH, te->catalogId.oid);
549  }
550  else
551  {
552  char *dropStmt = pg_strdup(te->dropStmt);
553  char *dropStmtOrig = dropStmt;
554  PQExpBuffer ftStmt = createPQExpBuffer();
555 
556  /*
557  * Need to inject IF EXISTS clause after ALTER
558  * TABLE part in ALTER TABLE .. DROP statement
559  */
560  if (strncmp(dropStmt, "ALTER TABLE", 11) == 0)
561  {
562  appendPQExpBufferStr(ftStmt,
563  "ALTER TABLE IF EXISTS");
564  dropStmt = dropStmt + 11;
565  }
566 
567  /*
568  * ALTER TABLE..ALTER COLUMN..DROP DEFAULT does
569  * not support the IF EXISTS clause, and therefore
570  * we simply emit the original command for DEFAULT
571  * objects (modulo the adjustment made above).
572  *
573  * Likewise, don't mess with DATABASE PROPERTIES.
574  *
575  * If we used CREATE OR REPLACE VIEW as a means of
576  * quasi-dropping an ON SELECT rule, that should
577  * be emitted unchanged as well.
578  *
579  * For other object types, we need to extract the
580  * first part of the DROP which includes the
581  * object type. Most of the time this matches
582  * te->desc, so search for that; however for the
583  * different kinds of CONSTRAINTs, we know to
584  * search for hardcoded "DROP CONSTRAINT" instead.
585  */
586  if (strcmp(te->desc, "DEFAULT") == 0 ||
587  strcmp(te->desc, "DATABASE PROPERTIES") == 0 ||
588  strncmp(dropStmt, "CREATE OR REPLACE VIEW", 22) == 0)
589  appendPQExpBufferStr(ftStmt, dropStmt);
590  else
591  {
592  char buffer[40];
593  char *mark;
594 
595  if (strcmp(te->desc, "CONSTRAINT") == 0 ||
596  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
597  strcmp(te->desc, "FK CONSTRAINT") == 0)
598  strcpy(buffer, "DROP CONSTRAINT");
599  else
600  snprintf(buffer, sizeof(buffer), "DROP %s",
601  te->desc);
602 
603  mark = strstr(dropStmt, buffer);
604 
605  if (mark)
606  {
607  *mark = '\0';
608  appendPQExpBuffer(ftStmt, "%s%s IF EXISTS%s",
609  dropStmt, buffer,
610  mark + strlen(buffer));
611  }
612  else
613  {
614  /* complain and emit unmodified command */
615  pg_log_warning("could not find where to insert IF EXISTS in statement \"%s\"",
616  dropStmtOrig);
617  appendPQExpBufferStr(ftStmt, dropStmt);
618  }
619  }
620 
621  ahprintf(AH, "%s", ftStmt->data);
622 
623  destroyPQExpBuffer(ftStmt);
624  pg_free(dropStmtOrig);
625  }
626  }
627  }
628  }
629  }
630 
631  /*
632  * _selectOutputSchema may have set currSchema to reflect the effect
633  * of a "SET search_path" command it emitted. However, by now we may
634  * have dropped that schema; or it might not have existed in the first
635  * place. In either case the effective value of search_path will not
636  * be what we think. Forcibly reset currSchema so that we will
637  * re-establish the search_path setting when needed (after creating
638  * the schema).
639  *
640  * If we treated users as pg_dump'able objects then we'd need to reset
641  * currUser here too.
642  */
643  free(AH->currSchema);
644  AH->currSchema = NULL;
645  }
646 
647  if (parallel_mode)
648  {
649  /*
650  * In parallel mode, turn control over to the parallel-restore logic.
651  */
652  ParallelState *pstate;
653  TocEntry pending_list;
654 
655  /* The archive format module may need some setup for this */
656  if (AH->PrepParallelRestorePtr)
657  AH->PrepParallelRestorePtr(AH);
658 
659  pending_list_header_init(&pending_list);
660 
661  /* This runs PRE_DATA items and then disconnects from the database */
662  restore_toc_entries_prefork(AH, &pending_list);
663  Assert(AH->connection == NULL);
664 
665  /* ParallelBackupStart() will actually fork the processes */
666  pstate = ParallelBackupStart(AH);
667  restore_toc_entries_parallel(AH, pstate, &pending_list);
668  ParallelBackupEnd(AH, pstate);
669 
670  /* reconnect the leader and see if we missed something */
671  restore_toc_entries_postfork(AH, &pending_list);
672  Assert(AH->connection != NULL);
673  }
674  else
675  {
676  /*
677  * In serial mode, process everything in three phases: normal items,
678  * then ACLs, then post-ACL items. We might be able to skip one or
679  * both extra phases in some cases, eg data-only restores.
680  */
681  bool haveACL = false;
682  bool havePostACL = false;
683 
684  for (te = AH->toc->next; te != AH->toc; te = te->next)
685  {
686  if ((te->reqs & (REQ_SCHEMA | REQ_DATA)) == 0)
687  continue; /* ignore if not to be dumped at all */
688 
689  switch (_tocEntryRestorePass(te))
690  {
691  case RESTORE_PASS_MAIN:
692  (void) restore_toc_entry(AH, te, false);
693  break;
694  case RESTORE_PASS_ACL:
695  haveACL = true;
696  break;
697  case RESTORE_PASS_POST_ACL:
698  havePostACL = true;
699  break;
700  }
701  }
702 
703  if (haveACL)
704  {
705  for (te = AH->toc->next; te != AH->toc; te = te->next)
706  {
707  if ((te->reqs & (REQ_SCHEMA | REQ_DATA)) != 0 &&
709  (void) restore_toc_entry(AH, te, false);
710  }
711  }
712 
713  if (havePostACL)
714  {
715  for (te = AH->toc->next; te != AH->toc; te = te->next)
716  {
717  if ((te->reqs & (REQ_SCHEMA | REQ_DATA)) != 0 &&
718  _tocEntryRestorePass(te) == RESTORE_PASS_POST_ACL)
719  (void) restore_toc_entry(AH, te, false);
720  }
721  }
722  }
723 
724  if (ropt->single_txn)
725  {
726  if (AH->connection)
727  CommitTransaction(AHX);
728  else
729  ahprintf(AH, "COMMIT;\n\n");
730  }
731 
732  if (AH->public.verbose)
733  dumpTimestamp(AH, "Completed on", time(NULL));
734 
735  ahprintf(AH, "--\n-- PostgreSQL database dump complete\n--\n\n");
736 
737  /*
738  * Clean up & we're done.
739  */
740  AH->stage = STAGE_FINALIZING;
741 
742  if (ropt->filename || ropt->compression)
743  RestoreOutput(AH, sav);
744 
745  if (ropt->useDB)
747 }
748 
749 /*
750  * Restore a single TOC item. Used in both parallel and non-parallel restore;
751  * is_parallel is true if we are in a worker child process.
752  *
753  * Returns 0 normally, but WORKER_CREATE_DONE or WORKER_INHIBIT_DATA if
754  * the parallel parent has to make the corresponding status update.
755  */
756 static int
757 restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
758 {
759  RestoreOptions *ropt = AH->public.ropt;
760  int status = WORKER_OK;
761  int reqs;
762  bool defnDumped;
763 
764  AH->currentTE = te;
765 
766  /* Dump any relevant dump warnings to stderr */
767  if (!ropt->suppressDumpWarnings && strcmp(te->desc, "WARNING") == 0)
768  {
769  if (!ropt->dataOnly && te->defn != NULL && strlen(te->defn) != 0)
770  pg_log_warning("warning from original dump file: %s", te->defn);
771  else if (te->copyStmt != NULL && strlen(te->copyStmt) != 0)
772  pg_log_warning("warning from original dump file: %s", te->copyStmt);
773  }
774 
775  /* Work out what, if anything, we want from this entry */
776  reqs = te->reqs;
777 
778  defnDumped = false;
779 
780  /*
781  * If it has a schema component that we want, then process that
782  */
783  if ((reqs & REQ_SCHEMA) != 0)
784  {
785  /* Show namespace in log message if available */
786  if (te->namespace)
787  pg_log_info("creating %s \"%s.%s\"",
788  te->desc, te->namespace, te->tag);
789  else
790  pg_log_info("creating %s \"%s\"",
791  te->desc, te->tag);
792 
793  _printTocEntry(AH, te, false);
794  defnDumped = true;
795 
796  if (strcmp(te->desc, "TABLE") == 0)
797  {
798  if (AH->lastErrorTE == te)
799  {
800  /*
801  * We failed to create the table. If
802  * --no-data-for-failed-tables was given, mark the
803  * corresponding TABLE DATA to be ignored.
804  *
805  * In the parallel case this must be done in the parent, so we
806  * just set the return value.
807  */
808  if (ropt->noDataForFailedTables)
809  {
810  if (is_parallel)
812  else
814  }
815  }
816  else
817  {
818  /*
819  * We created the table successfully. Mark the corresponding
820  * TABLE DATA for possible truncation.
821  *
822  * In the parallel case this must be done in the parent, so we
823  * just set the return value.
824  */
825  if (is_parallel)
827  else
828  mark_create_done(AH, te);
829  }
830  }
831 
832  /*
833  * If we created a DB, connect to it. Also, if we changed DB
834  * properties, reconnect to ensure that relevant GUC settings are
835  * applied to our session.
836  */
837  if (strcmp(te->desc, "DATABASE") == 0 ||
838  strcmp(te->desc, "DATABASE PROPERTIES") == 0)
839  {
840  pg_log_info("connecting to new database \"%s\"", te->tag);
841  _reconnectToDB(AH, te->tag);
842  }
843  }
844 
845  /*
846  * If it has a data component that we want, then process that
847  */
848  if ((reqs & REQ_DATA) != 0)
849  {
850  /*
851  * hadDumper will be set if there is genuine data component for this
852  * node. Otherwise, we need to check the defn field for statements
853  * that need to be executed in data-only restores.
854  */
855  if (te->hadDumper)
856  {
857  /*
858  * If we can output the data, then restore it.
859  */
860  if (AH->PrintTocDataPtr != NULL)
861  {
862  _printTocEntry(AH, te, true);
863 
864  if (strcmp(te->desc, "BLOBS") == 0 ||
865  strcmp(te->desc, "BLOB COMMENTS") == 0)
866  {
867  pg_log_info("processing %s", te->desc);
868 
869  _selectOutputSchema(AH, "pg_catalog");
870 
871  /* Send BLOB COMMENTS data to ExecuteSimpleCommands() */
872  if (strcmp(te->desc, "BLOB COMMENTS") == 0)
874 
875  AH->PrintTocDataPtr(AH, te);
876 
878  }
879  else
880  {
882 
883  /* Select owner and schema as necessary */
884  _becomeOwner(AH, te);
885  _selectOutputSchema(AH, te->namespace);
886 
887  pg_log_info("processing data for table \"%s.%s\"",
888  te->namespace, te->tag);
889 
890  /*
891  * In parallel restore, if we created the table earlier in
892  * the run then we wrap the COPY in a transaction and
893  * precede it with a TRUNCATE. If archiving is not on
894  * this prevents WAL-logging the COPY. This obtains a
895  * speedup similar to that from using single_txn mode in
896  * non-parallel restores.
897  */
898  if (is_parallel && te->created)
899  {
900  /*
901  * Parallel restore is always talking directly to a
902  * server, so no need to see if we should issue BEGIN.
903  */
904  StartTransaction(&AH->public);
905 
906  /*
907  * Issue TRUNCATE with ONLY so that child tables are
908  * not wiped.
909  */
910  ahprintf(AH, "TRUNCATE TABLE ONLY %s;\n\n",
911  fmtQualifiedId(te->namespace, te->tag));
912  }
913 
914  /*
915  * If we have a copy statement, use it.
916  */
917  if (te->copyStmt && strlen(te->copyStmt) > 0)
918  {
919  ahprintf(AH, "%s", te->copyStmt);
921  }
922  else
924 
925  AH->PrintTocDataPtr(AH, te);
926 
927  /*
928  * Terminate COPY if needed.
929  */
930  if (AH->outputKind == OUTPUT_COPYDATA &&
931  RestoringToDB(AH))
932  EndDBCopyMode(&AH->public, te->tag);
934 
935  /* close out the transaction started above */
936  if (is_parallel && te->created)
938 
940  }
941  }
942  }
943  else if (!defnDumped)
944  {
945  /* If we haven't already dumped the defn part, do so now */
946  pg_log_info("executing %s %s", te->desc, te->tag);
947  _printTocEntry(AH, te, false);
948  }
949  }
950 
951  if (AH->public.n_errors > 0 && status == WORKER_OK)
953 
954  return status;
955 }
956 
957 /*
958  * Allocate a new RestoreOptions block.
959  * This is mainly so we can initialize it, but also for future expansion,
960  */
963 {
965 
967 
968  /* set any fields that shouldn't default to zeroes */
969  opts->format = archUnknown;
970  opts->cparams.promptPassword = TRI_DEFAULT;
971  opts->dumpSections = DUMP_UNSECTIONED;
972 
973  return opts;
974 }
975 
976 static void
978 {
979  RestoreOptions *ropt = AH->public.ropt;
980 
981  /* This hack is only needed in a data-only restore */
982  if (!ropt->dataOnly || !ropt->disable_triggers)
983  return;
984 
985  pg_log_info("disabling triggers for %s", te->tag);
986 
987  /*
988  * Become superuser if possible, since they are the only ones who can
989  * disable constraint triggers. If -S was not given, assume the initial
990  * user identity is a superuser. (XXX would it be better to become the
991  * table owner?)
992  */
993  _becomeUser(AH, ropt->superuser);
994 
995  /*
996  * Disable them.
997  */
998  ahprintf(AH, "ALTER TABLE %s DISABLE TRIGGER ALL;\n\n",
999  fmtQualifiedId(te->namespace, te->tag));
1000 }
1001 
1002 static void
1004 {
1005  RestoreOptions *ropt = AH->public.ropt;
1006 
1007  /* This hack is only needed in a data-only restore */
1008  if (!ropt->dataOnly || !ropt->disable_triggers)
1009  return;
1010 
1011  pg_log_info("enabling triggers for %s", te->tag);
1012 
1013  /*
1014  * Become superuser if possible, since they are the only ones who can
1015  * disable constraint triggers. If -S was not given, assume the initial
1016  * user identity is a superuser. (XXX would it be better to become the
1017  * table owner?)
1018  */
1019  _becomeUser(AH, ropt->superuser);
1020 
1021  /*
1022  * Enable them.
1023  */
1024  ahprintf(AH, "ALTER TABLE %s ENABLE TRIGGER ALL;\n\n",
1025  fmtQualifiedId(te->namespace, te->tag));
1026 }
1027 
1028 /*
1029  * This is a routine that is part of the dumper interface, hence the 'Archive*' parameter.
1030  */
1031 
1032 /* Public */
1033 void
1034 WriteData(Archive *AHX, const void *data, size_t dLen)
1035 {
1036  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1037 
1038  if (!AH->currToc)
1039  pg_fatal("internal error -- WriteData cannot be called outside the context of a DataDumper routine");
1040 
1041  AH->WriteDataPtr(AH, data, dLen);
1042 }
1043 
1044 /*
1045  * Create a new TOC entry. The TOC was designed as a TOC, but is now the
1046  * repository for all metadata. But the name has stuck.
1047  *
1048  * The new entry is added to the Archive's TOC list. Most callers can ignore
1049  * the result value because nothing else need be done, but a few want to
1050  * manipulate the TOC entry further.
1051  */
1052 
1053 /* Public */
1054 TocEntry *
1055 ArchiveEntry(Archive *AHX, CatalogId catalogId, DumpId dumpId,
1056  ArchiveOpts *opts)
1057 {
1058  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1059  TocEntry *newToc;
1060 
1061  newToc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
1062 
1063  AH->tocCount++;
1064  if (dumpId > AH->maxDumpId)
1065  AH->maxDumpId = dumpId;
1066 
1067  newToc->prev = AH->toc->prev;
1068  newToc->next = AH->toc;
1069  AH->toc->prev->next = newToc;
1070  AH->toc->prev = newToc;
1071 
1072  newToc->catalogId = catalogId;
1073  newToc->dumpId = dumpId;
1074  newToc->section = opts->section;
1075 
1076  newToc->tag = pg_strdup(opts->tag);
1077  newToc->namespace = opts->namespace ? pg_strdup(opts->namespace) : NULL;
1078  newToc->tablespace = opts->tablespace ? pg_strdup(opts->tablespace) : NULL;
1079  newToc->tableam = opts->tableam ? pg_strdup(opts->tableam) : NULL;
1080  newToc->owner = opts->owner ? pg_strdup(opts->owner) : NULL;
1081  newToc->desc = pg_strdup(opts->description);
1082  newToc->defn = opts->createStmt ? pg_strdup(opts->createStmt) : NULL;
1083  newToc->dropStmt = opts->dropStmt ? pg_strdup(opts->dropStmt) : NULL;
1084  newToc->copyStmt = opts->copyStmt ? pg_strdup(opts->copyStmt) : NULL;
1085 
1086  if (opts->nDeps > 0)
1087  {
1088  newToc->dependencies = (DumpId *) pg_malloc(opts->nDeps * sizeof(DumpId));
1089  memcpy(newToc->dependencies, opts->deps, opts->nDeps * sizeof(DumpId));
1090  newToc->nDeps = opts->nDeps;
1091  }
1092  else
1093  {
1094  newToc->dependencies = NULL;
1095  newToc->nDeps = 0;
1096  }
1097 
1098  newToc->dataDumper = opts->dumpFn;
1099  newToc->dataDumperArg = opts->dumpArg;
1100  newToc->hadDumper = opts->dumpFn ? true : false;
1101 
1102  newToc->formatData = NULL;
1103  newToc->dataLength = 0;
1104 
1105  if (AH->ArchiveEntryPtr != NULL)
1106  AH->ArchiveEntryPtr(AH, newToc);
1107 
1108  return newToc;
1109 }
1110 
1111 /* Public */
1112 void
1114 {
1115  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1116  RestoreOptions *ropt = AH->public.ropt;
1117  TocEntry *te;
1118  teSection curSection;
1119  OutputContext sav;
1120  const char *fmtName;
1121  char stamp_str[64];
1122 
1123  sav = SaveOutput(AH);
1124  if (ropt->filename)
1125  SetOutput(AH, ropt->filename, 0 /* no compression */ );
1126 
1127  if (strftime(stamp_str, sizeof(stamp_str), PGDUMP_STRFTIME_FMT,
1128  localtime(&AH->createDate)) == 0)
1129  strcpy(stamp_str, "[unknown]");
1130 
1131  ahprintf(AH, ";\n; Archive created at %s\n", stamp_str);
1132  ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n",
1133  sanitize_line(AH->archdbname, false),
1134  AH->tocCount, AH->compression);
1135 
1136  switch (AH->format)
1137  {
1138  case archCustom:
1139  fmtName = "CUSTOM";
1140  break;
1141  case archDirectory:
1142  fmtName = "DIRECTORY";
1143  break;
1144  case archTar:
1145  fmtName = "TAR";
1146  break;
1147  default:
1148  fmtName = "UNKNOWN";
1149  }
1150 
1151  ahprintf(AH, "; Dump Version: %d.%d-%d\n",
1153  ahprintf(AH, "; Format: %s\n", fmtName);
1154  ahprintf(AH, "; Integer: %d bytes\n", (int) AH->intSize);
1155  ahprintf(AH, "; Offset: %d bytes\n", (int) AH->offSize);
1156  if (AH->archiveRemoteVersion)
1157  ahprintf(AH, "; Dumped from database version: %s\n",
1158  AH->archiveRemoteVersion);
1159  if (AH->archiveDumpVersion)
1160  ahprintf(AH, "; Dumped by pg_dump version: %s\n",
1161  AH->archiveDumpVersion);
1162 
1163  ahprintf(AH, ";\n;\n; Selected TOC Entries:\n;\n");
1164 
1165  curSection = SECTION_PRE_DATA;
1166  for (te = AH->toc->next; te != AH->toc; te = te->next)
1167  {
1168  if (te->section != SECTION_NONE)
1169  curSection = te->section;
1170  if (ropt->verbose ||
1171  (_tocEntryRequired(te, curSection, AH) & (REQ_SCHEMA | REQ_DATA)) != 0)
1172  {
1173  char *sanitized_name;
1174  char *sanitized_schema;
1175  char *sanitized_owner;
1176 
1177  /*
1178  */
1179  sanitized_name = sanitize_line(te->tag, false);
1180  sanitized_schema = sanitize_line(te->namespace, true);
1181  sanitized_owner = sanitize_line(te->owner, false);
1182 
1183  ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
1184  te->catalogId.tableoid, te->catalogId.oid,
1185  te->desc, sanitized_schema, sanitized_name,
1186  sanitized_owner);
1187 
1188  free(sanitized_name);
1189  free(sanitized_schema);
1190  free(sanitized_owner);
1191  }
1192  if (ropt->verbose && te->nDeps > 0)
1193  {
1194  int i;
1195 
1196  ahprintf(AH, ";\tdepends on:");
1197  for (i = 0; i < te->nDeps; i++)
1198  ahprintf(AH, " %d", te->dependencies[i]);
1199  ahprintf(AH, "\n");
1200  }
1201  }
1202 
1203  /* Enforce strict names checking */
1204  if (ropt->strict_names)
1205  StrictNamesCheck(ropt);
1206 
1207  if (ropt->filename)
1208  RestoreOutput(AH, sav);
1209 }
1210 
1211 /***********
1212  * BLOB Archival
1213  ***********/
1214 
1215 /* Called by a dumper to signal start of a BLOB */
1216 int
1218 {
1219  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1220 
1221  if (!AH->StartBlobPtr)
1222  pg_fatal("large-object output not supported in chosen format");
1223 
1224  AH->StartBlobPtr(AH, AH->currToc, oid);
1225 
1226  return 1;
1227 }
1228 
1229 /* Called by a dumper to signal end of a BLOB */
1230 int
1231 EndBlob(Archive *AHX, Oid oid)
1232 {
1233  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1234 
1235  if (AH->EndBlobPtr)
1236  AH->EndBlobPtr(AH, AH->currToc, oid);
1237 
1238  return 1;
1239 }
1240 
1241 /**********
1242  * BLOB Restoration
1243  **********/
1244 
1245 /*
1246  * Called by a format handler before any blobs are restored
1247  */
1248 void
1250 {
1251  RestoreOptions *ropt = AH->public.ropt;
1252 
1253  if (!ropt->single_txn)
1254  {
1255  if (AH->connection)
1256  StartTransaction(&AH->public);
1257  else
1258  ahprintf(AH, "BEGIN;\n\n");
1259  }
1260 
1261  AH->blobCount = 0;
1262 }
1263 
1264 /*
1265  * Called by a format handler after all blobs are restored
1266  */
1267 void
1269 {
1270  RestoreOptions *ropt = AH->public.ropt;
1271 
1272  if (!ropt->single_txn)
1273  {
1274  if (AH->connection)
1275  CommitTransaction(&AH->public);
1276  else
1277  ahprintf(AH, "COMMIT;\n\n");
1278  }
1279 
1280  pg_log_info(ngettext("restored %d large object",
1281  "restored %d large objects",
1282  AH->blobCount),
1283  AH->blobCount);
1284 }
1285 
1286 
1287 /*
1288  * Called by a format handler to initiate restoration of a blob
1289  */
1290 void
1291 StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop)
1292 {
1293  bool old_blob_style = (AH->version < K_VERS_1_12);
1294  Oid loOid;
1295 
1296  AH->blobCount++;
1297 
1298  /* Initialize the LO Buffer */
1299  AH->lo_buf_used = 0;
1300 
1301  pg_log_info("restoring large object with OID %u", oid);
1302 
1303  /* With an old archive we must do drop and create logic here */
1304  if (old_blob_style && drop)
1305  DropBlobIfExists(AH, oid);
1306 
1307  if (AH->connection)
1308  {
1309  if (old_blob_style)
1310  {
1311  loOid = lo_create(AH->connection, oid);
1312  if (loOid == 0 || loOid != oid)
1313  pg_fatal("could not create large object %u: %s",
1314  oid, PQerrorMessage(AH->connection));
1315  }
1316  AH->loFd = lo_open(AH->connection, oid, INV_WRITE);
1317  if (AH->loFd == -1)
1318  pg_fatal("could not open large object %u: %s",
1319  oid, PQerrorMessage(AH->connection));
1320  }
1321  else
1322  {
1323  if (old_blob_style)
1324  ahprintf(AH, "SELECT pg_catalog.lo_open(pg_catalog.lo_create('%u'), %d);\n",
1325  oid, INV_WRITE);
1326  else
1327  ahprintf(AH, "SELECT pg_catalog.lo_open('%u', %d);\n",
1328  oid, INV_WRITE);
1329  }
1330 
1331  AH->writingBlob = 1;
1332 }
1333 
1334 void
1336 {
1337  if (AH->lo_buf_used > 0)
1338  {
1339  /* Write remaining bytes from the LO buffer */
1340  dump_lo_buf(AH);
1341  }
1342 
1343  AH->writingBlob = 0;
1344 
1345  if (AH->connection)
1346  {
1347  lo_close(AH->connection, AH->loFd);
1348  AH->loFd = -1;
1349  }
1350  else
1351  {
1352  ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
1353  }
1354 }
1355 
1356 /***********
1357  * Sorting and Reordering
1358  ***********/
1359 
1360 void
1362 {
1363  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1364  RestoreOptions *ropt = AH->public.ropt;
1365  FILE *fh;
1366  StringInfoData linebuf;
1367 
1368  /* Allocate space for the 'wanted' array, and init it */
1369  ropt->idWanted = (bool *) pg_malloc0(sizeof(bool) * AH->maxDumpId);
1370 
1371  /* Setup the file */
1372  fh = fopen(ropt->tocFile, PG_BINARY_R);
1373  if (!fh)
1374  pg_fatal("could not open TOC file \"%s\": %m", ropt->tocFile);
1375 
1376  initStringInfo(&linebuf);
1377 
1378  while (pg_get_line_buf(fh, &linebuf))
1379  {
1380  char *cmnt;
1381  char *endptr;
1382  DumpId id;
1383  TocEntry *te;
1384 
1385  /* Truncate line at comment, if any */
1386  cmnt = strchr(linebuf.data, ';');
1387  if (cmnt != NULL)
1388  {
1389  cmnt[0] = '\0';
1390  linebuf.len = cmnt - linebuf.data;
1391  }
1392 
1393  /* Ignore if all blank */
1394  if (strspn(linebuf.data, " \t\r\n") == linebuf.len)
1395  continue;
1396 
1397  /* Get an ID, check it's valid and not already seen */
1398  id = strtol(linebuf.data, &endptr, 10);
1399  if (endptr == linebuf.data || id <= 0 || id > AH->maxDumpId ||
1400  ropt->idWanted[id - 1])
1401  {
1402  pg_log_warning("line ignored: %s", linebuf.data);
1403  continue;
1404  }
1405 
1406  /* Find TOC entry */
1407  te = getTocEntryByDumpId(AH, id);
1408  if (!te)
1409  pg_fatal("could not find entry for ID %d",
1410  id);
1411 
1412  /* Mark it wanted */
1413  ropt->idWanted[id - 1] = true;
1414 
1415  /*
1416  * Move each item to the end of the list as it is selected, so that
1417  * they are placed in the desired order. Any unwanted items will end
1418  * up at the front of the list, which may seem unintuitive but it's
1419  * what we need. In an ordinary serial restore that makes no
1420  * difference, but in a parallel restore we need to mark unrestored
1421  * items' dependencies as satisfied before we start examining
1422  * restorable items. Otherwise they could have surprising
1423  * side-effects on the order in which restorable items actually get
1424  * restored.
1425  */
1426  _moveBefore(AH->toc, te);
1427  }
1428 
1429  pg_free(linebuf.data);
1430 
1431  if (fclose(fh) != 0)
1432  pg_fatal("could not close TOC file: %m");
1433 }
1434 
1435 /**********************
1436  * Convenience functions that look like standard IO functions
1437  * for writing data when in dump mode.
1438  **********************/
1439 
1440 /* Public */
1441 void
1442 archputs(const char *s, Archive *AH)
1443 {
1444  WriteData(AH, s, strlen(s));
1445 }
1446 
1447 /* Public */
1448 int
1449 archprintf(Archive *AH, const char *fmt,...)
1450 {
1451  int save_errno = errno;
1452  char *p;
1453  size_t len = 128; /* initial assumption about buffer size */
1454  size_t cnt;
1455 
1456  for (;;)
1457  {
1458  va_list args;
1459 
1460  /* Allocate work buffer. */
1461  p = (char *) pg_malloc(len);
1462 
1463  /* Try to format the data. */
1464  errno = save_errno;
1465  va_start(args, fmt);
1466  cnt = pvsnprintf(p, len, fmt, args);
1467  va_end(args);
1468 
1469  if (cnt < len)
1470  break; /* success */
1471 
1472  /* Release buffer and loop around to try again with larger len. */
1473  free(p);
1474  len = cnt;
1475  }
1476 
1477  WriteData(AH, p, cnt);
1478  free(p);
1479  return (int) cnt;
1480 }
1481 
1482 
1483 /*******************************
1484  * Stuff below here should be 'private' to the archiver routines
1485  *******************************/
1486 
1487 static void
1488 SetOutput(ArchiveHandle *AH, const char *filename, int compression)
1489 {
1490  int fn;
1491 
1492  if (filename)
1493  {
1494  if (strcmp(filename, "-") == 0)
1495  fn = fileno(stdout);
1496  else
1497  fn = -1;
1498  }
1499  else if (AH->FH)
1500  fn = fileno(AH->FH);
1501  else if (AH->fSpec)
1502  {
1503  fn = -1;
1504  filename = AH->fSpec;
1505  }
1506  else
1507  fn = fileno(stdout);
1508 
1509  /* If compression explicitly requested, use gzopen */
1510 #ifdef HAVE_LIBZ
1511  if (compression != 0)
1512  {
1513  char fmode[14];
1514 
1515  /* Don't use PG_BINARY_x since this is zlib */
1516  sprintf(fmode, "wb%d", compression);
1517  if (fn >= 0)
1518  AH->OF = gzdopen(dup(fn), fmode);
1519  else
1520  AH->OF = gzopen(filename, fmode);
1521  AH->gzOut = 1;
1522  }
1523  else
1524 #endif
1525  { /* Use fopen */
1526  if (AH->mode == archModeAppend)
1527  {
1528  if (fn >= 0)
1529  AH->OF = fdopen(dup(fn), PG_BINARY_A);
1530  else
1531  AH->OF = fopen(filename, PG_BINARY_A);
1532  }
1533  else
1534  {
1535  if (fn >= 0)
1536  AH->OF = fdopen(dup(fn), PG_BINARY_W);
1537  else
1538  AH->OF = fopen(filename, PG_BINARY_W);
1539  }
1540  AH->gzOut = 0;
1541  }
1542 
1543  if (!AH->OF)
1544  {
1545  if (filename)
1546  pg_fatal("could not open output file \"%s\": %m", filename);
1547  else
1548  pg_fatal("could not open output file: %m");
1549  }
1550 }
1551 
1552 static OutputContext
1554 {
1555  OutputContext sav;
1556 
1557  sav.OF = AH->OF;
1558  sav.gzOut = AH->gzOut;
1559 
1560  return sav;
1561 }
1562 
1563 static void
1565 {
1566  int res;
1567 
1568  errno = 0; /* in case gzclose() doesn't set it */
1569  if (AH->gzOut)
1570  res = GZCLOSE(AH->OF);
1571  else
1572  res = fclose(AH->OF);
1573 
1574  if (res != 0)
1575  pg_fatal("could not close output file: %m");
1576 
1577  AH->gzOut = savedContext.gzOut;
1578  AH->OF = savedContext.OF;
1579 }
1580 
1581 
1582 
1583 /*
1584  * Print formatted text to the output file (usually stdout).
1585  */
1586 int
1587 ahprintf(ArchiveHandle *AH, const char *fmt,...)
1588 {
1589  int save_errno = errno;
1590  char *p;
1591  size_t len = 128; /* initial assumption about buffer size */
1592  size_t cnt;
1593 
1594  for (;;)
1595  {
1596  va_list args;
1597 
1598  /* Allocate work buffer. */
1599  p = (char *) pg_malloc(len);
1600 
1601  /* Try to format the data. */
1602  errno = save_errno;
1603  va_start(args, fmt);
1604  cnt = pvsnprintf(p, len, fmt, args);
1605  va_end(args);
1606 
1607  if (cnt < len)
1608  break; /* success */
1609 
1610  /* Release buffer and loop around to try again with larger len. */
1611  free(p);
1612  len = cnt;
1613  }
1614 
1615  ahwrite(p, 1, cnt, AH);
1616  free(p);
1617  return (int) cnt;
1618 }
1619 
1620 /*
1621  * Single place for logic which says 'We are restoring to a direct DB connection'.
1622  */
1623 static int
1625 {
1626  RestoreOptions *ropt = AH->public.ropt;
1627 
1628  return (ropt && ropt->useDB && AH->connection);
1629 }
1630 
1631 /*
1632  * Dump the current contents of the LO data buffer while writing a BLOB
1633  */
1634 static void
1636 {
1637  if (AH->connection)
1638  {
1639  int res;
1640 
1641  res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used);
1642  pg_log_debug(ngettext("wrote %zu byte of large object data (result = %d)",
1643  "wrote %zu bytes of large object data (result = %d)",
1644  AH->lo_buf_used),
1645  AH->lo_buf_used, res);
1646  /* We assume there are no short writes, only errors */
1647  if (res != AH->lo_buf_used)
1648  warn_or_exit_horribly(AH, "could not write to large object: %s",
1649  PQerrorMessage(AH->connection));
1650  }
1651  else
1652  {
1654 
1656  (const unsigned char *) AH->lo_buf,
1657  AH->lo_buf_used,
1658  AH);
1659 
1660  /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
1661  AH->writingBlob = 0;
1662  ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
1663  AH->writingBlob = 1;
1664 
1666  }
1667  AH->lo_buf_used = 0;
1668 }
1669 
1670 
1671 /*
1672  * Write buffer to the output file (usually stdout). This is used for
1673  * outputting 'restore' scripts etc. It is even possible for an archive
1674  * format to create a custom output routine to 'fake' a restore if it
1675  * wants to generate a script (see TAR output).
1676  */
1677 void
1678 ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
1679 {
1680  int bytes_written = 0;
1681 
1682  if (AH->writingBlob)
1683  {
1684  size_t remaining = size * nmemb;
1685 
1686  while (AH->lo_buf_used + remaining > AH->lo_buf_size)
1687  {
1688  size_t avail = AH->lo_buf_size - AH->lo_buf_used;
1689 
1690  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, avail);
1691  ptr = (const void *) ((const char *) ptr + avail);
1692  remaining -= avail;
1693  AH->lo_buf_used += avail;
1694  dump_lo_buf(AH);
1695  }
1696 
1697  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
1698  AH->lo_buf_used += remaining;
1699 
1700  bytes_written = size * nmemb;
1701  }
1702  else if (AH->gzOut)
1703  bytes_written = GZWRITE(ptr, size, nmemb, AH->OF);
1704  else if (AH->CustomOutPtr)
1705  bytes_written = AH->CustomOutPtr(AH, ptr, size * nmemb);
1706 
1707  else
1708  {
1709  /*
1710  * If we're doing a restore, and it's direct to DB, and we're
1711  * connected then send it to the DB.
1712  */
1713  if (RestoringToDB(AH))
1714  bytes_written = ExecuteSqlCommandBuf(&AH->public, (const char *) ptr, size * nmemb);
1715  else
1716  bytes_written = fwrite(ptr, size, nmemb, AH->OF) * size;
1717  }
1718 
1719  if (bytes_written != size * nmemb)
1721 }
1722 
1723 /* on some error, we may decide to go on... */
1724 void
1726 {
1727  va_list ap;
1728 
1729  switch (AH->stage)
1730  {
1731 
1732  case STAGE_NONE:
1733  /* Do nothing special */
1734  break;
1735 
1736  case STAGE_INITIALIZING:
1737  if (AH->stage != AH->lastErrorStage)
1738  pg_log_info("while INITIALIZING:");
1739  break;
1740 
1741  case STAGE_PROCESSING:
1742  if (AH->stage != AH->lastErrorStage)
1743  pg_log_info("while PROCESSING TOC:");
1744  break;
1745 
1746  case STAGE_FINALIZING:
1747  if (AH->stage != AH->lastErrorStage)
1748  pg_log_info("while FINALIZING:");
1749  break;
1750  }
1751  if (AH->currentTE != NULL && AH->currentTE != AH->lastErrorTE)
1752  {
1753  pg_log_info("from TOC entry %d; %u %u %s %s %s",
1754  AH->currentTE->dumpId,
1756  AH->currentTE->catalogId.oid,
1757  AH->currentTE->desc ? AH->currentTE->desc : "(no desc)",
1758  AH->currentTE->tag ? AH->currentTE->tag : "(no tag)",
1759  AH->currentTE->owner ? AH->currentTE->owner : "(no owner)");
1760  }
1761  AH->lastErrorStage = AH->stage;
1762  AH->lastErrorTE = AH->currentTE;
1763 
1764  va_start(ap, fmt);
1766  va_end(ap);
1767 
1768  if (AH->public.exit_on_error)
1769  exit_nicely(1);
1770  else
1771  AH->public.n_errors++;
1772 }
1773 
1774 #ifdef NOT_USED
1775 
1776 static void
1777 _moveAfter(ArchiveHandle *AH, TocEntry *pos, TocEntry *te)
1778 {
1779  /* Unlink te from list */
1780  te->prev->next = te->next;
1781  te->next->prev = te->prev;
1782 
1783  /* and insert it after "pos" */
1784  te->prev = pos;
1785  te->next = pos->next;
1786  pos->next->prev = te;
1787  pos->next = te;
1788 }
1789 #endif
1790 
1791 static void
1793 {
1794  /* Unlink te from list */
1795  te->prev->next = te->next;
1796  te->next->prev = te->prev;
1797 
1798  /* and insert it before "pos" */
1799  te->prev = pos->prev;
1800  te->next = pos;
1801  pos->prev->next = te;
1802  pos->prev = te;
1803 }
1804 
1805 /*
1806  * Build index arrays for the TOC list
1807  *
1808  * This should be invoked only after we have created or read in all the TOC
1809  * items.
1810  *
1811  * The arrays are indexed by dump ID (so entry zero is unused). Note that the
1812  * array entries run only up to maxDumpId. We might see dependency dump IDs
1813  * beyond that (if the dump was partial); so always check the array bound
1814  * before trying to touch an array entry.
1815  */
1816 static void
1818 {
1819  DumpId maxDumpId = AH->maxDumpId;
1820  TocEntry *te;
1821 
1822  AH->tocsByDumpId = (TocEntry **) pg_malloc0((maxDumpId + 1) * sizeof(TocEntry *));
1823  AH->tableDataId = (DumpId *) pg_malloc0((maxDumpId + 1) * sizeof(DumpId));
1824 
1825  for (te = AH->toc->next; te != AH->toc; te = te->next)
1826  {
1827  /* this check is purely paranoia, maxDumpId should be correct */
1828  if (te->dumpId <= 0 || te->dumpId > maxDumpId)
1829  pg_fatal("bad dumpId");
1830 
1831  /* tocsByDumpId indexes all TOCs by their dump ID */
1832  AH->tocsByDumpId[te->dumpId] = te;
1833 
1834  /*
1835  * tableDataId provides the TABLE DATA item's dump ID for each TABLE
1836  * TOC entry that has a DATA item. We compute this by reversing the
1837  * TABLE DATA item's dependency, knowing that a TABLE DATA item has
1838  * just one dependency and it is the TABLE item.
1839  */
1840  if (strcmp(te->desc, "TABLE DATA") == 0 && te->nDeps > 0)
1841  {
1842  DumpId tableId = te->dependencies[0];
1843 
1844  /*
1845  * The TABLE item might not have been in the archive, if this was
1846  * a data-only dump; but its dump ID should be less than its data
1847  * item's dump ID, so there should be a place for it in the array.
1848  */
1849  if (tableId <= 0 || tableId > maxDumpId)
1850  pg_fatal("bad table dumpId for TABLE DATA item");
1851 
1852  AH->tableDataId[tableId] = te->dumpId;
1853  }
1854  }
1855 }
1856 
1857 TocEntry *
1859 {
1860  /* build index arrays if we didn't already */
1861  if (AH->tocsByDumpId == NULL)
1862  buildTocEntryArrays(AH);
1863 
1864  if (id > 0 && id <= AH->maxDumpId)
1865  return AH->tocsByDumpId[id];
1866 
1867  return NULL;
1868 }
1869 
1870 int
1872 {
1873  TocEntry *te = getTocEntryByDumpId(AH, id);
1874 
1875  if (!te)
1876  return 0;
1877 
1878  return te->reqs;
1879 }
1880 
1881 size_t
1882 WriteOffset(ArchiveHandle *AH, pgoff_t o, int wasSet)
1883 {
1884  int off;
1885 
1886  /* Save the flag */
1887  AH->WriteBytePtr(AH, wasSet);
1888 
1889  /* Write out pgoff_t smallest byte first, prevents endian mismatch */
1890  for (off = 0; off < sizeof(pgoff_t); off++)
1891  {
1892  AH->WriteBytePtr(AH, o & 0xFF);
1893  o >>= 8;
1894  }
1895  return sizeof(pgoff_t) + 1;
1896 }
1897 
1898 int
1900 {
1901  int i;
1902  int off;
1903  int offsetFlg;
1904 
1905  /* Initialize to zero */
1906  *o = 0;
1907 
1908  /* Check for old version */
1909  if (AH->version < K_VERS_1_7)
1910  {
1911  /* Prior versions wrote offsets using WriteInt */
1912  i = ReadInt(AH);
1913  /* -1 means not set */
1914  if (i < 0)
1915  return K_OFFSET_POS_NOT_SET;
1916  else if (i == 0)
1917  return K_OFFSET_NO_DATA;
1918 
1919  /* Cast to pgoff_t because it was written as an int. */
1920  *o = (pgoff_t) i;
1921  return K_OFFSET_POS_SET;
1922  }
1923 
1924  /*
1925  * Read the flag indicating the state of the data pointer. Check if valid
1926  * and die if not.
1927  *
1928  * This used to be handled by a negative or zero pointer, now we use an
1929  * extra byte specifically for the state.
1930  */
1931  offsetFlg = AH->ReadBytePtr(AH) & 0xFF;
1932 
1933  switch (offsetFlg)
1934  {
1935  case K_OFFSET_POS_NOT_SET:
1936  case K_OFFSET_NO_DATA:
1937  case K_OFFSET_POS_SET:
1938 
1939  break;
1940 
1941  default:
1942  pg_fatal("unexpected data offset flag %d", offsetFlg);
1943  }
1944 
1945  /*
1946  * Read the bytes
1947  */
1948  for (off = 0; off < AH->offSize; off++)
1949  {
1950  if (off < sizeof(pgoff_t))
1951  *o |= ((pgoff_t) (AH->ReadBytePtr(AH))) << (off * 8);
1952  else
1953  {
1954  if (AH->ReadBytePtr(AH) != 0)
1955  pg_fatal("file offset in dump file is too large");
1956  }
1957  }
1958 
1959  return offsetFlg;
1960 }
1961 
1962 size_t
1964 {
1965  int b;
1966 
1967  /*
1968  * This is a bit yucky, but I don't want to make the binary format very
1969  * dependent on representation, and not knowing much about it, I write out
1970  * a sign byte. If you change this, don't forget to change the file
1971  * version #, and modify ReadInt to read the new format AS WELL AS the old
1972  * formats.
1973  */
1974 
1975  /* SIGN byte */
1976  if (i < 0)
1977  {
1978  AH->WriteBytePtr(AH, 1);
1979  i = -i;
1980  }
1981  else
1982  AH->WriteBytePtr(AH, 0);
1983 
1984  for (b = 0; b < AH->intSize; b++)
1985  {
1986  AH->WriteBytePtr(AH, i & 0xFF);
1987  i >>= 8;
1988  }
1989 
1990  return AH->intSize + 1;
1991 }
1992 
1993 int
1995 {
1996  int res = 0;
1997  int bv,
1998  b;
1999  int sign = 0; /* Default positive */
2000  int bitShift = 0;
2001 
2002  if (AH->version > K_VERS_1_0)
2003  /* Read a sign byte */
2004  sign = AH->ReadBytePtr(AH);
2005 
2006  for (b = 0; b < AH->intSize; b++)
2007  {
2008  bv = AH->ReadBytePtr(AH) & 0xFF;
2009  if (bv != 0)
2010  res = res + (bv << bitShift);
2011  bitShift += 8;
2012  }
2013 
2014  if (sign)
2015  res = -res;
2016 
2017  return res;
2018 }
2019 
2020 size_t
2021 WriteStr(ArchiveHandle *AH, const char *c)
2022 {
2023  size_t res;
2024 
2025  if (c)
2026  {
2027  int len = strlen(c);
2028 
2029  res = WriteInt(AH, len);
2030  AH->WriteBufPtr(AH, c, len);
2031  res += len;
2032  }
2033  else
2034  res = WriteInt(AH, -1);
2035 
2036  return res;
2037 }
2038 
2039 char *
2041 {
2042  char *buf;
2043  int l;
2044 
2045  l = ReadInt(AH);
2046  if (l < 0)
2047  buf = NULL;
2048  else
2049  {
2050  buf = (char *) pg_malloc(l + 1);
2051  AH->ReadBufPtr(AH, (void *) buf, l);
2052 
2053  buf[l] = '\0';
2054  }
2055 
2056  return buf;
2057 }
2058 
2059 static int
2061 {
2062  FILE *fh;
2063  char sig[6]; /* More than enough */
2064  size_t cnt;
2065  int wantClose = 0;
2066 
2067  pg_log_debug("attempting to ascertain archive format");
2068 
2069  free(AH->lookahead);
2070 
2071  AH->readHeader = 0;
2072  AH->lookaheadSize = 512;
2073  AH->lookahead = pg_malloc0(512);
2074  AH->lookaheadLen = 0;
2075  AH->lookaheadPos = 0;
2076 
2077  if (AH->fSpec)
2078  {
2079  struct stat st;
2080 
2081  wantClose = 1;
2082 
2083  /*
2084  * Check if the specified archive is a directory. If so, check if
2085  * there's a "toc.dat" (or "toc.dat.gz") file in it.
2086  */
2087  if (stat(AH->fSpec, &st) == 0 && S_ISDIR(st.st_mode))
2088  {
2089  char buf[MAXPGPATH];
2090 
2091  if (snprintf(buf, MAXPGPATH, "%s/toc.dat", AH->fSpec) >= MAXPGPATH)
2092  pg_fatal("directory name too long: \"%s\"",
2093  AH->fSpec);
2094  if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
2095  {
2096  AH->format = archDirectory;
2097  return AH->format;
2098  }
2099 
2100 #ifdef HAVE_LIBZ
2101  if (snprintf(buf, MAXPGPATH, "%s/toc.dat.gz", AH->fSpec) >= MAXPGPATH)
2102  pg_fatal("directory name too long: \"%s\"",
2103  AH->fSpec);
2104  if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
2105  {
2106  AH->format = archDirectory;
2107  return AH->format;
2108  }
2109 #endif
2110  pg_fatal("directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)",
2111  AH->fSpec);
2112  fh = NULL; /* keep compiler quiet */
2113  }
2114  else
2115  {
2116  fh = fopen(AH->fSpec, PG_BINARY_R);
2117  if (!fh)
2118  pg_fatal("could not open input file \"%s\": %m", AH->fSpec);
2119  }
2120  }
2121  else
2122  {
2123  fh = stdin;
2124  if (!fh)
2125  pg_fatal("could not open input file: %m");
2126  }
2127 
2128  if ((cnt = fread(sig, 1, 5, fh)) != 5)
2129  {
2130  if (ferror(fh))
2131  pg_fatal("could not read input file: %m");
2132  else
2133  pg_fatal("input file is too short (read %lu, expected 5)",
2134  (unsigned long) cnt);
2135  }
2136 
2137  /* Save it, just in case we need it later */
2138  memcpy(&AH->lookahead[0], sig, 5);
2139  AH->lookaheadLen = 5;
2140 
2141  if (strncmp(sig, "PGDMP", 5) == 0)
2142  {
2143  /* It's custom format, stop here */
2144  AH->format = archCustom;
2145  AH->readHeader = 1;
2146  }
2147  else
2148  {
2149  /*
2150  * *Maybe* we have a tar archive format file or a text dump ... So,
2151  * read first 512 byte header...
2152  */
2153  cnt = fread(&AH->lookahead[AH->lookaheadLen], 1, 512 - AH->lookaheadLen, fh);
2154  /* read failure is checked below */
2155  AH->lookaheadLen += cnt;
2156 
2157  if (AH->lookaheadLen >= strlen(TEXT_DUMPALL_HEADER) &&
2158  (strncmp(AH->lookahead, TEXT_DUMP_HEADER, strlen(TEXT_DUMP_HEADER)) == 0 ||
2159  strncmp(AH->lookahead, TEXT_DUMPALL_HEADER, strlen(TEXT_DUMPALL_HEADER)) == 0))
2160  {
2161  /*
2162  * looks like it's probably a text format dump. so suggest they
2163  * try psql
2164  */
2165  pg_fatal("input file appears to be a text format dump. Please use psql.");
2166  }
2167 
2168  if (AH->lookaheadLen != 512)
2169  {
2170  if (feof(fh))
2171  pg_fatal("input file does not appear to be a valid archive (too short?)");
2172  else
2173  READ_ERROR_EXIT(fh);
2174  }
2175 
2176  if (!isValidTarHeader(AH->lookahead))
2177  pg_fatal("input file does not appear to be a valid archive");
2178 
2179  AH->format = archTar;
2180  }
2181 
2182  /* Close the file if we opened it */
2183  if (wantClose)
2184  {
2185  if (fclose(fh) != 0)
2186  pg_fatal("could not close input file: %m");
2187  /* Forget lookahead, since we'll re-read header after re-opening */
2188  AH->readHeader = 0;
2189  AH->lookaheadLen = 0;
2190  }
2191 
2192  return AH->format;
2193 }
2194 
2195 
2196 /*
2197  * Allocate an archive handle
2198  */
2199 static ArchiveHandle *
2200 _allocAH(const char *FileSpec, const ArchiveFormat fmt,
2201  const int compression, bool dosync, ArchiveMode mode,
2202  SetupWorkerPtrType setupWorkerPtr)
2203 {
2204  ArchiveHandle *AH;
2205 
2206  pg_log_debug("allocating AH for %s, format %d",
2207  FileSpec ? FileSpec : "(stdio)", fmt);
2208 
2209  AH = (ArchiveHandle *) pg_malloc0(sizeof(ArchiveHandle));
2210 
2211  AH->version = K_VERS_SELF;
2212 
2213  /* initialize for backwards compatible string processing */
2214  AH->public.encoding = 0; /* PG_SQL_ASCII */
2215  AH->public.std_strings = false;
2216 
2217  /* sql error handling */
2218  AH->public.exit_on_error = true;
2219  AH->public.n_errors = 0;
2220 
2221  AH->archiveDumpVersion = PG_VERSION;
2222 
2223  AH->createDate = time(NULL);
2224 
2225  AH->intSize = sizeof(int);
2226  AH->offSize = sizeof(pgoff_t);
2227  if (FileSpec)
2228  {
2229  AH->fSpec = pg_strdup(FileSpec);
2230 
2231  /*
2232  * Not used; maybe later....
2233  *
2234  * AH->workDir = pg_strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;
2235  * i--) if (AH->workDir[i-1] == '/')
2236  */
2237  }
2238  else
2239  AH->fSpec = NULL;
2240 
2241  AH->currUser = NULL; /* unknown */
2242  AH->currSchema = NULL; /* ditto */
2243  AH->currTablespace = NULL; /* ditto */
2244  AH->currTableAm = NULL; /* ditto */
2245 
2246  AH->toc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2247 
2248  AH->toc->next = AH->toc;
2249  AH->toc->prev = AH->toc;
2250 
2251  AH->mode = mode;
2252  AH->compression = compression;
2253  AH->dosync = dosync;
2254 
2255  memset(&(AH->sqlparse), 0, sizeof(AH->sqlparse));
2256 
2257  /* Open stdout with no compression for AH output handle */
2258  AH->gzOut = 0;
2259  AH->OF = stdout;
2260 
2261  /*
2262  * On Windows, we need to use binary mode to read/write non-text files,
2263  * which include all archive formats as well as compressed plain text.
2264  * Force stdin/stdout into binary mode if that is what we are using.
2265  */
2266 #ifdef WIN32
2267  if ((fmt != archNull || compression != 0) &&
2268  (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0))
2269  {
2270  if (mode == archModeWrite)
2271  _setmode(fileno(stdout), O_BINARY);
2272  else
2273  _setmode(fileno(stdin), O_BINARY);
2274  }
2275 #endif
2276 
2277  AH->SetupWorkerPtr = setupWorkerPtr;
2278 
2279  if (fmt == archUnknown)
2280  AH->format = _discoverArchiveFormat(AH);
2281  else
2282  AH->format = fmt;
2283 
2284  switch (AH->format)
2285  {
2286  case archCustom:
2288  break;
2289 
2290  case archNull:
2291  InitArchiveFmt_Null(AH);
2292  break;
2293 
2294  case archDirectory:
2296  break;
2297 
2298  case archTar:
2299  InitArchiveFmt_Tar(AH);
2300  break;
2301 
2302  default:
2303  pg_fatal("unrecognized file format \"%d\"", fmt);
2304  }
2305 
2306  return AH;
2307 }
2308 
2309 /*
2310  * Write out all data (tables & blobs)
2311  */
2312 void
2314 {
2315  TocEntry *te;
2316 
2317  if (pstate && pstate->numWorkers > 1)
2318  {
2319  /*
2320  * In parallel mode, this code runs in the leader process. We
2321  * construct an array of candidate TEs, then sort it into decreasing
2322  * size order, then dispatch each TE to a data-transfer worker. By
2323  * dumping larger tables first, we avoid getting into a situation
2324  * where we're down to one job and it's big, losing parallelism.
2325  */
2326  TocEntry **tes;
2327  int ntes;
2328 
2329  tes = (TocEntry **) pg_malloc(AH->tocCount * sizeof(TocEntry *));
2330  ntes = 0;
2331  for (te = AH->toc->next; te != AH->toc; te = te->next)
2332  {
2333  /* Consider only TEs with dataDumper functions ... */
2334  if (!te->dataDumper)
2335  continue;
2336  /* ... and ignore ones not enabled for dump */
2337  if ((te->reqs & REQ_DATA) == 0)
2338  continue;
2339 
2340  tes[ntes++] = te;
2341  }
2342 
2343  if (ntes > 1)
2344  qsort((void *) tes, ntes, sizeof(TocEntry *),
2346 
2347  for (int i = 0; i < ntes; i++)
2348  DispatchJobForTocEntry(AH, pstate, tes[i], ACT_DUMP,
2349  mark_dump_job_done, NULL);
2350 
2351  pg_free(tes);
2352 
2353  /* Now wait for workers to finish. */
2354  WaitForWorkers(AH, pstate, WFW_ALL_IDLE);
2355  }
2356  else
2357  {
2358  /* Non-parallel mode: just dump all candidate TEs sequentially. */
2359  for (te = AH->toc->next; te != AH->toc; te = te->next)
2360  {
2361  /* Must have same filter conditions as above */
2362  if (!te->dataDumper)
2363  continue;
2364  if ((te->reqs & REQ_DATA) == 0)
2365  continue;
2366 
2368  }
2369  }
2370 }
2371 
2372 
2373 /*
2374  * Callback function that's invoked in the leader process after a step has
2375  * been parallel dumped.
2376  *
2377  * We don't need to do anything except check for worker failure.
2378  */
2379 static void
2381  TocEntry *te,
2382  int status,
2383  void *callback_data)
2384 {
2385  pg_log_info("finished item %d %s %s",
2386  te->dumpId, te->desc, te->tag);
2387 
2388  if (status != 0)
2389  pg_fatal("worker process failed: exit code %d",
2390  status);
2391 }
2392 
2393 
2394 void
2396 {
2397  StartDataPtrType startPtr;
2398  EndDataPtrType endPtr;
2399 
2400  AH->currToc = te;
2401 
2402  if (strcmp(te->desc, "BLOBS") == 0)
2403  {
2404  startPtr = AH->StartBlobsPtr;
2405  endPtr = AH->EndBlobsPtr;
2406  }
2407  else
2408  {
2409  startPtr = AH->StartDataPtr;
2410  endPtr = AH->EndDataPtr;
2411  }
2412 
2413  if (startPtr != NULL)
2414  (*startPtr) (AH, te);
2415 
2416  /*
2417  * The user-provided DataDumper routine needs to call AH->WriteData
2418  */
2419  te->dataDumper((Archive *) AH, te->dataDumperArg);
2420 
2421  if (endPtr != NULL)
2422  (*endPtr) (AH, te);
2423 
2424  AH->currToc = NULL;
2425 }
2426 
2427 void
2429 {
2430  TocEntry *te;
2431  char workbuf[32];
2432  int tocCount;
2433  int i;
2434 
2435  /* count entries that will actually be dumped */
2436  tocCount = 0;
2437  for (te = AH->toc->next; te != AH->toc; te = te->next)
2438  {
2439  if ((te->reqs & (REQ_SCHEMA | REQ_DATA | REQ_SPECIAL)) != 0)
2440  tocCount++;
2441  }
2442 
2443  /* printf("%d TOC Entries to save\n", tocCount); */
2444 
2445  WriteInt(AH, tocCount);
2446 
2447  for (te = AH->toc->next; te != AH->toc; te = te->next)
2448  {
2449  if ((te->reqs & (REQ_SCHEMA | REQ_DATA | REQ_SPECIAL)) == 0)
2450  continue;
2451 
2452  WriteInt(AH, te->dumpId);
2453  WriteInt(AH, te->dataDumper ? 1 : 0);
2454 
2455  /* OID is recorded as a string for historical reasons */
2456  sprintf(workbuf, "%u", te->catalogId.tableoid);
2457  WriteStr(AH, workbuf);
2458  sprintf(workbuf, "%u", te->catalogId.oid);
2459  WriteStr(AH, workbuf);
2460 
2461  WriteStr(AH, te->tag);
2462  WriteStr(AH, te->desc);
2463  WriteInt(AH, te->section);
2464  WriteStr(AH, te->defn);
2465  WriteStr(AH, te->dropStmt);
2466  WriteStr(AH, te->copyStmt);
2467  WriteStr(AH, te->namespace);
2468  WriteStr(AH, te->tablespace);
2469  WriteStr(AH, te->tableam);
2470  WriteStr(AH, te->owner);
2471  WriteStr(AH, "false");
2472 
2473  /* Dump list of dependencies */
2474  for (i = 0; i < te->nDeps; i++)
2475  {
2476  sprintf(workbuf, "%d", te->dependencies[i]);
2477  WriteStr(AH, workbuf);
2478  }
2479  WriteStr(AH, NULL); /* Terminate List */
2480 
2481  if (AH->WriteExtraTocPtr)
2482  AH->WriteExtraTocPtr(AH, te);
2483  }
2484 }
2485 
2486 void
2488 {
2489  int i;
2490  char *tmp;
2491  DumpId *deps;
2492  int depIdx;
2493  int depSize;
2494  TocEntry *te;
2495  bool is_supported;
2496 
2497  AH->tocCount = ReadInt(AH);
2498  AH->maxDumpId = 0;
2499 
2500  for (i = 0; i < AH->tocCount; i++)
2501  {
2502  te = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2503  te->dumpId = ReadInt(AH);
2504 
2505  if (te->dumpId > AH->maxDumpId)
2506  AH->maxDumpId = te->dumpId;
2507 
2508  /* Sanity check */
2509  if (te->dumpId <= 0)
2510  pg_fatal("entry ID %d out of range -- perhaps a corrupt TOC",
2511  te->dumpId);
2512 
2513  te->hadDumper = ReadInt(AH);
2514 
2515  if (AH->version >= K_VERS_1_8)
2516  {
2517  tmp = ReadStr(AH);
2518  sscanf(tmp, "%u", &te->catalogId.tableoid);
2519  free(tmp);
2520  }
2521  else
2523  tmp = ReadStr(AH);
2524  sscanf(tmp, "%u", &te->catalogId.oid);
2525  free(tmp);
2526 
2527  te->tag = ReadStr(AH);
2528  te->desc = ReadStr(AH);
2529 
2530  if (AH->version >= K_VERS_1_11)
2531  {
2532  te->section = ReadInt(AH);
2533  }
2534  else
2535  {
2536  /*
2537  * Rules for pre-8.4 archives wherein pg_dump hasn't classified
2538  * the entries into sections. This list need not cover entry
2539  * types added later than 8.4.
2540  */
2541  if (strcmp(te->desc, "COMMENT") == 0 ||
2542  strcmp(te->desc, "ACL") == 0 ||
2543  strcmp(te->desc, "ACL LANGUAGE") == 0)
2544  te->section = SECTION_NONE;
2545  else if (strcmp(te->desc, "TABLE DATA") == 0 ||
2546  strcmp(te->desc, "BLOBS") == 0 ||
2547  strcmp(te->desc, "BLOB COMMENTS") == 0)
2548  te->section = SECTION_DATA;
2549  else if (strcmp(te->desc, "CONSTRAINT") == 0 ||
2550  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
2551  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
2552  strcmp(te->desc, "INDEX") == 0 ||
2553  strcmp(te->desc, "RULE") == 0 ||
2554  strcmp(te->desc, "TRIGGER") == 0)
2555  te->section = SECTION_POST_DATA;
2556  else
2557  te->section = SECTION_PRE_DATA;
2558  }
2559 
2560  te->defn = ReadStr(AH);
2561  te->dropStmt = ReadStr(AH);
2562 
2563  if (AH->version >= K_VERS_1_3)
2564  te->copyStmt = ReadStr(AH);
2565 
2566  if (AH->version >= K_VERS_1_6)
2567  te->namespace = ReadStr(AH);
2568 
2569  if (AH->version >= K_VERS_1_10)
2570  te->tablespace = ReadStr(AH);
2571 
2572  if (AH->version >= K_VERS_1_14)
2573  te->tableam = ReadStr(AH);
2574 
2575  te->owner = ReadStr(AH);
2576  is_supported = true;
2577  if (AH->version < K_VERS_1_9)
2578  is_supported = false;
2579  else
2580  {
2581  tmp = ReadStr(AH);
2582 
2583  if (strcmp(tmp, "true") == 0)
2584  is_supported = false;
2585 
2586  free(tmp);
2587  }
2588 
2589  if (!is_supported)
2590  pg_log_warning("restoring tables WITH OIDS is not supported anymore");
2591 
2592  /* Read TOC entry dependencies */
2593  if (AH->version >= K_VERS_1_5)
2594  {
2595  depSize = 100;
2596  deps = (DumpId *) pg_malloc(sizeof(DumpId) * depSize);
2597  depIdx = 0;
2598  for (;;)
2599  {
2600  tmp = ReadStr(AH);
2601  if (!tmp)
2602  break; /* end of list */
2603  if (depIdx >= depSize)
2604  {
2605  depSize *= 2;
2606  deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depSize);
2607  }
2608  sscanf(tmp, "%d", &deps[depIdx]);
2609  free(tmp);
2610  depIdx++;
2611  }
2612 
2613  if (depIdx > 0) /* We have a non-null entry */
2614  {
2615  deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depIdx);
2616  te->dependencies = deps;
2617  te->nDeps = depIdx;
2618  }
2619  else
2620  {
2621  free(deps);
2622  te->dependencies = NULL;
2623  te->nDeps = 0;
2624  }
2625  }
2626  else
2627  {
2628  te->dependencies = NULL;
2629  te->nDeps = 0;
2630  }
2631  te->dataLength = 0;
2632 
2633  if (AH->ReadExtraTocPtr)
2634  AH->ReadExtraTocPtr(AH, te);
2635 
2636  pg_log_debug("read TOC entry %d (ID %d) for %s %s",
2637  i, te->dumpId, te->desc, te->tag);
2638 
2639  /* link completed entry into TOC circular list */
2640  te->prev = AH->toc->prev;
2641  AH->toc->prev->next = te;
2642  AH->toc->prev = te;
2643  te->next = AH->toc;
2644 
2645  /* special processing immediately upon read for some items */
2646  if (strcmp(te->desc, "ENCODING") == 0)
2647  processEncodingEntry(AH, te);
2648  else if (strcmp(te->desc, "STDSTRINGS") == 0)
2649  processStdStringsEntry(AH, te);
2650  else if (strcmp(te->desc, "SEARCHPATH") == 0)
2651  processSearchPathEntry(AH, te);
2652  }
2653 }
2654 
2655 static void
2657 {
2658  /* te->defn should have the form SET client_encoding = 'foo'; */
2659  char *defn = pg_strdup(te->defn);
2660  char *ptr1;
2661  char *ptr2 = NULL;
2662  int encoding;
2663 
2664  ptr1 = strchr(defn, '\'');
2665  if (ptr1)
2666  ptr2 = strchr(++ptr1, '\'');
2667  if (ptr2)
2668  {
2669  *ptr2 = '\0';
2670  encoding = pg_char_to_encoding(ptr1);
2671  if (encoding < 0)
2672  pg_fatal("unrecognized encoding \"%s\"",
2673  ptr1);
2674  AH->public.encoding = encoding;
2675  }
2676  else
2677  pg_fatal("invalid ENCODING item: %s",
2678  te->defn);
2679 
2680  free(defn);
2681 }
2682 
2683 static void
2685 {
2686  /* te->defn should have the form SET standard_conforming_strings = 'x'; */
2687  char *ptr1;
2688 
2689  ptr1 = strchr(te->defn, '\'');
2690  if (ptr1 && strncmp(ptr1, "'on'", 4) == 0)
2691  AH->public.std_strings = true;
2692  else if (ptr1 && strncmp(ptr1, "'off'", 5) == 0)
2693  AH->public.std_strings = false;
2694  else
2695  pg_fatal("invalid STDSTRINGS item: %s",
2696  te->defn);
2697 }
2698 
2699 static void
2701 {
2702  /*
2703  * te->defn should contain a command to set search_path. We just copy it
2704  * verbatim for use later.
2705  */
2706  AH->public.searchpath = pg_strdup(te->defn);
2707 }
2708 
2709 static void
2711 {
2712  const char *missing_name;
2713 
2714  Assert(ropt->strict_names);
2715 
2716  if (ropt->schemaNames.head != NULL)
2717  {
2718  missing_name = simple_string_list_not_touched(&ropt->schemaNames);
2719  if (missing_name != NULL)
2720  pg_fatal("schema \"%s\" not found", missing_name);
2721  }
2722 
2723  if (ropt->tableNames.head != NULL)
2724  {
2725  missing_name = simple_string_list_not_touched(&ropt->tableNames);
2726  if (missing_name != NULL)
2727  pg_fatal("table \"%s\" not found", missing_name);
2728  }
2729 
2730  if (ropt->indexNames.head != NULL)
2731  {
2732  missing_name = simple_string_list_not_touched(&ropt->indexNames);
2733  if (missing_name != NULL)
2734  pg_fatal("index \"%s\" not found", missing_name);
2735  }
2736 
2737  if (ropt->functionNames.head != NULL)
2738  {
2739  missing_name = simple_string_list_not_touched(&ropt->functionNames);
2740  if (missing_name != NULL)
2741  pg_fatal("function \"%s\" not found", missing_name);
2742  }
2743 
2744  if (ropt->triggerNames.head != NULL)
2745  {
2746  missing_name = simple_string_list_not_touched(&ropt->triggerNames);
2747  if (missing_name != NULL)
2748  pg_fatal("trigger \"%s\" not found", missing_name);
2749  }
2750 }
2751 
2752 /*
2753  * Determine whether we want to restore this TOC entry.
2754  *
2755  * Returns 0 if entry should be skipped, or some combination of the
2756  * REQ_SCHEMA and REQ_DATA bits if we want to restore schema and/or data
2757  * portions of this TOC entry, or REQ_SPECIAL if it's a special entry.
2758  */
2759 static int
2761 {
2762  int res = REQ_SCHEMA | REQ_DATA;
2763  RestoreOptions *ropt = AH->public.ropt;
2764 
2765  /* These items are treated specially */
2766  if (strcmp(te->desc, "ENCODING") == 0 ||
2767  strcmp(te->desc, "STDSTRINGS") == 0 ||
2768  strcmp(te->desc, "SEARCHPATH") == 0)
2769  return REQ_SPECIAL;
2770 
2771  /*
2772  * DATABASE and DATABASE PROPERTIES also have a special rule: they are
2773  * restored in createDB mode, and not restored otherwise, independently of
2774  * all else.
2775  */
2776  if (strcmp(te->desc, "DATABASE") == 0 ||
2777  strcmp(te->desc, "DATABASE PROPERTIES") == 0)
2778  {
2779  if (ropt->createDB)
2780  return REQ_SCHEMA;
2781  else
2782  return 0;
2783  }
2784 
2785  /*
2786  * Process exclusions that affect certain classes of TOC entries.
2787  */
2788 
2789  /* If it's an ACL, maybe ignore it */
2790  if (ropt->aclsSkip && _tocEntryIsACL(te))
2791  return 0;
2792 
2793  /* If it's a comment, maybe ignore it */
2794  if (ropt->no_comments && strcmp(te->desc, "COMMENT") == 0)
2795  return 0;
2796 
2797  /*
2798  * If it's a publication or a table part of a publication, maybe ignore
2799  * it.
2800  */
2801  if (ropt->no_publications &&
2802  (strcmp(te->desc, "PUBLICATION") == 0 ||
2803  strcmp(te->desc, "PUBLICATION TABLE") == 0 ||
2804  strcmp(te->desc, "PUBLICATION TABLES IN SCHEMA") == 0))
2805  return 0;
2806 
2807  /* If it's a security label, maybe ignore it */
2808  if (ropt->no_security_labels && strcmp(te->desc, "SECURITY LABEL") == 0)
2809  return 0;
2810 
2811  /* If it's a subscription, maybe ignore it */
2812  if (ropt->no_subscriptions && strcmp(te->desc, "SUBSCRIPTION") == 0)
2813  return 0;
2814 
2815  /* Ignore it if section is not to be dumped/restored */
2816  switch (curSection)
2817  {
2818  case SECTION_PRE_DATA:
2819  if (!(ropt->dumpSections & DUMP_PRE_DATA))
2820  return 0;
2821  break;
2822  case SECTION_DATA:
2823  if (!(ropt->dumpSections & DUMP_DATA))
2824  return 0;
2825  break;
2826  case SECTION_POST_DATA:
2827  if (!(ropt->dumpSections & DUMP_POST_DATA))
2828  return 0;
2829  break;
2830  default:
2831  /* shouldn't get here, really, but ignore it */
2832  return 0;
2833  }
2834 
2835  /* Ignore it if rejected by idWanted[] (cf. SortTocFromFile) */
2836  if (ropt->idWanted && !ropt->idWanted[te->dumpId - 1])
2837  return 0;
2838 
2839  /*
2840  * Check options for selective dump/restore.
2841  */
2842  if (strcmp(te->desc, "ACL") == 0 ||
2843  strcmp(te->desc, "COMMENT") == 0 ||
2844  strcmp(te->desc, "SECURITY LABEL") == 0)
2845  {
2846  /* Database properties react to createDB, not selectivity options. */
2847  if (strncmp(te->tag, "DATABASE ", 9) == 0)
2848  {
2849  if (!ropt->createDB)
2850  return 0;
2851  }
2852  else if (ropt->schemaNames.head != NULL ||
2853  ropt->schemaExcludeNames.head != NULL ||
2854  ropt->selTypes)
2855  {
2856  /*
2857  * In a selective dump/restore, we want to restore these dependent
2858  * TOC entry types only if their parent object is being restored.
2859  * Without selectivity options, we let through everything in the
2860  * archive. Note there may be such entries with no parent, eg
2861  * non-default ACLs for built-in objects.
2862  *
2863  * This code depends on the parent having been marked already,
2864  * which should be the case; if it isn't, perhaps due to
2865  * SortTocFromFile rearrangement, skipping the dependent entry
2866  * seems prudent anyway.
2867  *
2868  * Ideally we'd handle, eg, table CHECK constraints this way too.
2869  * But it's hard to tell which of their dependencies is the one to
2870  * consult.
2871  */
2872  if (te->nDeps != 1 ||
2873  TocIDRequired(AH, te->dependencies[0]) == 0)
2874  return 0;
2875  }
2876  }
2877  else
2878  {
2879  /* Apply selective-restore rules for standalone TOC entries. */
2880  if (ropt->schemaNames.head != NULL)
2881  {
2882  /* If no namespace is specified, it means all. */
2883  if (!te->namespace)
2884  return 0;
2885  if (!simple_string_list_member(&ropt->schemaNames, te->namespace))
2886  return 0;
2887  }
2888 
2889  if (ropt->schemaExcludeNames.head != NULL &&
2890  te->namespace &&
2891  simple_string_list_member(&ropt->schemaExcludeNames, te->namespace))
2892  return 0;
2893 
2894  if (ropt->selTypes)
2895  {
2896  if (strcmp(te->desc, "TABLE") == 0 ||
2897  strcmp(te->desc, "TABLE DATA") == 0 ||
2898  strcmp(te->desc, "VIEW") == 0 ||
2899  strcmp(te->desc, "FOREIGN TABLE") == 0 ||
2900  strcmp(te->desc, "MATERIALIZED VIEW") == 0 ||
2901  strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0 ||
2902  strcmp(te->desc, "SEQUENCE") == 0 ||
2903  strcmp(te->desc, "SEQUENCE SET") == 0)
2904  {
2905  if (!ropt->selTable)
2906  return 0;
2907  if (ropt->tableNames.head != NULL &&
2909  return 0;
2910  }
2911  else if (strcmp(te->desc, "INDEX") == 0)
2912  {
2913  if (!ropt->selIndex)
2914  return 0;
2915  if (ropt->indexNames.head != NULL &&
2917  return 0;
2918  }
2919  else if (strcmp(te->desc, "FUNCTION") == 0 ||
2920  strcmp(te->desc, "AGGREGATE") == 0 ||
2921  strcmp(te->desc, "PROCEDURE") == 0)
2922  {
2923  if (!ropt->selFunction)
2924  return 0;
2925  if (ropt->functionNames.head != NULL &&
2927  return 0;
2928  }
2929  else if (strcmp(te->desc, "TRIGGER") == 0)
2930  {
2931  if (!ropt->selTrigger)
2932  return 0;
2933  if (ropt->triggerNames.head != NULL &&
2935  return 0;
2936  }
2937  else
2938  return 0;
2939  }
2940  }
2941 
2942  /*
2943  * Determine whether the TOC entry contains schema and/or data components,
2944  * and mask off inapplicable REQ bits. If it had a dataDumper, assume
2945  * it's both schema and data. Otherwise it's probably schema-only, but
2946  * there are exceptions.
2947  */
2948  if (!te->hadDumper)
2949  {
2950  /*
2951  * Special Case: If 'SEQUENCE SET' or anything to do with BLOBs, then
2952  * it is considered a data entry. We don't need to check for the
2953  * BLOBS entry or old-style BLOB COMMENTS, because they will have
2954  * hadDumper = true ... but we do need to check new-style BLOB ACLs,
2955  * comments, etc.
2956  */
2957  if (strcmp(te->desc, "SEQUENCE SET") == 0 ||
2958  strcmp(te->desc, "BLOB") == 0 ||
2959  (strcmp(te->desc, "ACL") == 0 &&
2960  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
2961  (strcmp(te->desc, "COMMENT") == 0 &&
2962  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
2963  (strcmp(te->desc, "SECURITY LABEL") == 0 &&
2964  strncmp(te->tag, "LARGE OBJECT ", 13) == 0))
2965  res = res & REQ_DATA;
2966  else
2967  res = res & ~REQ_DATA;
2968  }
2969 
2970  /* If there's no definition command, there's no schema component */
2971  if (!te->defn || !te->defn[0])
2972  res = res & ~REQ_SCHEMA;
2973 
2974  /*
2975  * Special case: <Init> type with <Max OID> tag; this is obsolete and we
2976  * always ignore it.
2977  */
2978  if ((strcmp(te->desc, "<Init>") == 0) && (strcmp(te->tag, "Max OID") == 0))
2979  return 0;
2980 
2981  /* Mask it if we only want schema */
2982  if (ropt->schemaOnly)
2983  {
2984  /*
2985  * The sequence_data option overrides schemaOnly for SEQUENCE SET.
2986  *
2987  * In binary-upgrade mode, even with schemaOnly set, we do not mask
2988  * out large objects. (Only large object definitions, comments and
2989  * other metadata should be generated in binary-upgrade mode, not the
2990  * actual data, but that need not concern us here.)
2991  */
2992  if (!(ropt->sequence_data && strcmp(te->desc, "SEQUENCE SET") == 0) &&
2993  !(ropt->binary_upgrade &&
2994  (strcmp(te->desc, "BLOB") == 0 ||
2995  (strcmp(te->desc, "ACL") == 0 &&
2996  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
2997  (strcmp(te->desc, "COMMENT") == 0 &&
2998  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
2999  (strcmp(te->desc, "SECURITY LABEL") == 0 &&
3000  strncmp(te->tag, "LARGE OBJECT ", 13) == 0))))
3001  res = res & REQ_SCHEMA;
3002  }
3003 
3004  /* Mask it if we only want data */
3005  if (ropt->dataOnly)
3006  res = res & REQ_DATA;
3007 
3008  return res;
3009 }
3010 
3011 /*
3012  * Identify which pass we should restore this TOC entry in.
3013  *
3014  * See notes with the RestorePass typedef in pg_backup_archiver.h.
3015  */
3016 static RestorePass
3018 {
3019  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3020  if (strcmp(te->desc, "ACL") == 0 ||
3021  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3022  strcmp(te->desc, "DEFAULT ACL") == 0)
3023  return RESTORE_PASS_ACL;
3024  if (strcmp(te->desc, "EVENT TRIGGER") == 0 ||
3025  strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0)
3026  return RESTORE_PASS_POST_ACL;
3027 
3028  /*
3029  * Comments need to be emitted in the same pass as their parent objects.
3030  * ACLs haven't got comments, and neither do matview data objects, but
3031  * event triggers do. (Fortunately, event triggers haven't got ACLs, or
3032  * we'd need yet another weird special case.)
3033  */
3034  if (strcmp(te->desc, "COMMENT") == 0 &&
3035  strncmp(te->tag, "EVENT TRIGGER ", 14) == 0)
3036  return RESTORE_PASS_POST_ACL;
3037 
3038  /* All else can be handled in the main pass. */
3039  return RESTORE_PASS_MAIN;
3040 }
3041 
3042 /*
3043  * Identify TOC entries that are ACLs.
3044  *
3045  * Note: it seems worth duplicating some code here to avoid a hard-wired
3046  * assumption that these are exactly the same entries that we restore during
3047  * the RESTORE_PASS_ACL phase.
3048  */
3049 static bool
3051 {
3052  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3053  if (strcmp(te->desc, "ACL") == 0 ||
3054  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3055  strcmp(te->desc, "DEFAULT ACL") == 0)
3056  return true;
3057  return false;
3058 }
3059 
3060 /*
3061  * Issue SET commands for parameters that we want to have set the same way
3062  * at all times during execution of a restore script.
3063  */
3064 static void
3066 {
3067  RestoreOptions *ropt = AH->public.ropt;
3068 
3069  /*
3070  * Disable timeouts to allow for slow commands, idle parallel workers, etc
3071  */
3072  ahprintf(AH, "SET statement_timeout = 0;\n");
3073  ahprintf(AH, "SET lock_timeout = 0;\n");
3074  ahprintf(AH, "SET idle_in_transaction_session_timeout = 0;\n");
3075 
3076  /* Select the correct character set encoding */
3077  ahprintf(AH, "SET client_encoding = '%s';\n",
3079 
3080  /* Select the correct string literal syntax */
3081  ahprintf(AH, "SET standard_conforming_strings = %s;\n",
3082  AH->public.std_strings ? "on" : "off");
3083 
3084  /* Select the role to be used during restore */
3085  if (ropt && ropt->use_role)
3086  ahprintf(AH, "SET ROLE %s;\n", fmtId(ropt->use_role));
3087 
3088  /* Select the dump-time search_path */
3089  if (AH->public.searchpath)
3090  ahprintf(AH, "%s", AH->public.searchpath);
3091 
3092  /* Make sure function checking is disabled */
3093  ahprintf(AH, "SET check_function_bodies = false;\n");
3094 
3095  /* Ensure that all valid XML data will be accepted */
3096  ahprintf(AH, "SET xmloption = content;\n");
3097 
3098  /* Avoid annoying notices etc */
3099  ahprintf(AH, "SET client_min_messages = warning;\n");
3100  if (!AH->public.std_strings)
3101  ahprintf(AH, "SET escape_string_warning = off;\n");
3102 
3103  /* Adjust row-security state */
3104  if (ropt && ropt->enable_row_security)
3105  ahprintf(AH, "SET row_security = on;\n");
3106  else
3107  ahprintf(AH, "SET row_security = off;\n");
3108 
3109  ahprintf(AH, "\n");
3110 }
3111 
3112 /*
3113  * Issue a SET SESSION AUTHORIZATION command. Caller is responsible
3114  * for updating state if appropriate. If user is NULL or an empty string,
3115  * the specification DEFAULT will be used.
3116  */
3117 static void
3119 {
3121 
3122  appendPQExpBufferStr(cmd, "SET SESSION AUTHORIZATION ");
3123 
3124  /*
3125  * SQL requires a string literal here. Might as well be correct.
3126  */
3127  if (user && *user)
3128  appendStringLiteralAHX(cmd, user, AH);
3129  else
3130  appendPQExpBufferStr(cmd, "DEFAULT");
3131  appendPQExpBufferChar(cmd, ';');
3132 
3133  if (RestoringToDB(AH))
3134  {
3135  PGresult *res;
3136 
3137  res = PQexec(AH->connection, cmd->data);
3138 
3139  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3140  /* NOT warn_or_exit_horribly... use -O instead to skip this. */
3141  pg_fatal("could not set session user to \"%s\": %s",
3143 
3144  PQclear(res);
3145  }
3146  else
3147  ahprintf(AH, "%s\n\n", cmd->data);
3148 
3149  destroyPQExpBuffer(cmd);
3150 }
3151 
3152 
3153 /*
3154  * Issue the commands to connect to the specified database.
3155  *
3156  * If we're currently restoring right into a database, this will
3157  * actually establish a connection. Otherwise it puts a \connect into
3158  * the script output.
3159  */
3160 static void
3162 {
3163  if (RestoringToDB(AH))
3165  else
3166  {
3167  PQExpBufferData connectbuf;
3168 
3169  initPQExpBuffer(&connectbuf);
3170  appendPsqlMetaConnect(&connectbuf, dbname);
3171  ahprintf(AH, "%s\n", connectbuf.data);
3172  termPQExpBuffer(&connectbuf);
3173  }
3174 
3175  /*
3176  * NOTE: currUser keeps track of what the imaginary session user in our
3177  * script is. It's now effectively reset to the original userID.
3178  */
3179  free(AH->currUser);
3180  AH->currUser = NULL;
3181 
3182  /* don't assume we still know the output schema, tablespace, etc either */
3183  free(AH->currSchema);
3184  AH->currSchema = NULL;
3185 
3186  free(AH->currTableAm);
3187  AH->currTableAm = NULL;
3188 
3189  free(AH->currTablespace);
3190  AH->currTablespace = NULL;
3191 
3192  /* re-establish fixed state */
3194 }
3195 
3196 /*
3197  * Become the specified user, and update state to avoid redundant commands
3198  *
3199  * NULL or empty argument is taken to mean restoring the session default
3200  */
3201 static void
3202 _becomeUser(ArchiveHandle *AH, const char *user)
3203 {
3204  if (!user)
3205  user = ""; /* avoid null pointers */
3206 
3207  if (AH->currUser && strcmp(AH->currUser, user) == 0)
3208  return; /* no need to do anything */
3209 
3210  _doSetSessionAuth(AH, user);
3211 
3212  /*
3213  * NOTE: currUser keeps track of what the imaginary session user in our
3214  * script is
3215  */
3216  free(AH->currUser);
3217  AH->currUser = pg_strdup(user);
3218 }
3219 
3220 /*
3221  * Become the owner of the given TOC entry object. If
3222  * changes in ownership are not allowed, this doesn't do anything.
3223  */
3224 static void
3226 {
3227  RestoreOptions *ropt = AH->public.ropt;
3228 
3229  if (ropt && (ropt->noOwner || !ropt->use_setsessauth))
3230  return;
3231 
3232  _becomeUser(AH, te->owner);
3233 }
3234 
3235 
3236 /*
3237  * Issue the commands to select the specified schema as the current schema
3238  * in the target database.
3239  */
3240 static void
3241 _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
3242 {
3243  PQExpBuffer qry;
3244 
3245  /*
3246  * If there was a SEARCHPATH TOC entry, we're supposed to just stay with
3247  * that search_path rather than switching to entry-specific paths.
3248  * Otherwise, it's an old archive that will not restore correctly unless
3249  * we set the search_path as it's expecting.
3250  */
3251  if (AH->public.searchpath)
3252  return;
3253 
3254  if (!schemaName || *schemaName == '\0' ||
3255  (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
3256  return; /* no need to do anything */
3257 
3258  qry = createPQExpBuffer();
3259 
3260  appendPQExpBuffer(qry, "SET search_path = %s",
3261  fmtId(schemaName));
3262  if (strcmp(schemaName, "pg_catalog") != 0)
3263  appendPQExpBufferStr(qry, ", pg_catalog");
3264 
3265  if (RestoringToDB(AH))
3266  {
3267  PGresult *res;
3268 
3269  res = PQexec(AH->connection, qry->data);
3270 
3271  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3273  "could not set search_path to \"%s\": %s",
3274  schemaName, PQerrorMessage(AH->connection));
3275 
3276  PQclear(res);
3277  }
3278  else
3279  ahprintf(AH, "%s;\n\n", qry->data);
3280 
3281  free(AH->currSchema);
3282  AH->currSchema = pg_strdup(schemaName);
3283 
3284  destroyPQExpBuffer(qry);
3285 }
3286 
3287 /*
3288  * Issue the commands to select the specified tablespace as the current one
3289  * in the target database.
3290  */
3291 static void
3293 {
3294  RestoreOptions *ropt = AH->public.ropt;
3295  PQExpBuffer qry;
3296  const char *want,
3297  *have;
3298 
3299  /* do nothing in --no-tablespaces mode */
3300  if (ropt->noTablespace)
3301  return;
3302 
3303  have = AH->currTablespace;
3304  want = tablespace;
3305 
3306  /* no need to do anything for non-tablespace object */
3307  if (!want)
3308  return;
3309 
3310  if (have && strcmp(want, have) == 0)
3311  return; /* no need to do anything */
3312 
3313  qry = createPQExpBuffer();
3314 
3315  if (strcmp(want, "") == 0)
3316  {
3317  /* We want the tablespace to be the database's default */
3318  appendPQExpBufferStr(qry, "SET default_tablespace = ''");
3319  }
3320  else
3321  {
3322  /* We want an explicit tablespace */
3323  appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
3324  }
3325 
3326  if (RestoringToDB(AH))
3327  {
3328  PGresult *res;
3329 
3330  res = PQexec(AH->connection, qry->data);
3331 
3332  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3334  "could not set default_tablespace to %s: %s",
3335  fmtId(want), PQerrorMessage(AH->connection));
3336 
3337  PQclear(res);
3338  }
3339  else
3340  ahprintf(AH, "%s;\n\n", qry->data);
3341 
3342  free(AH->currTablespace);
3343  AH->currTablespace = pg_strdup(want);
3344 
3345  destroyPQExpBuffer(qry);
3346 }
3347 
3348 /*
3349  * Set the proper default_table_access_method value for the table.
3350  */
3351 static void
3352 _selectTableAccessMethod(ArchiveHandle *AH, const char *tableam)
3353 {
3354  RestoreOptions *ropt = AH->public.ropt;
3355  PQExpBuffer cmd;
3356  const char *want,
3357  *have;
3358 
3359  /* do nothing in --no-table-access-method mode */
3360  if (ropt->noTableAm)
3361  return;
3362 
3363  have = AH->currTableAm;
3364  want = tableam;
3365 
3366  if (!want)
3367  return;
3368 
3369  if (have && strcmp(want, have) == 0)
3370  return;
3371 
3372  cmd = createPQExpBuffer();
3373  appendPQExpBuffer(cmd, "SET default_table_access_method = %s;", fmtId(want));
3374 
3375  if (RestoringToDB(AH))
3376  {
3377  PGresult *res;
3378 
3379  res = PQexec(AH->connection, cmd->data);
3380 
3381  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3383  "could not set default_table_access_method: %s",
3384  PQerrorMessage(AH->connection));
3385 
3386  PQclear(res);
3387  }
3388  else
3389  ahprintf(AH, "%s\n\n", cmd->data);
3390 
3391  destroyPQExpBuffer(cmd);
3392 
3393  free(AH->currTableAm);
3394  AH->currTableAm = pg_strdup(want);
3395 }
3396 
3397 /*
3398  * Extract an object description for a TOC entry, and append it to buf.
3399  *
3400  * This is used for ALTER ... OWNER TO.
3401  *
3402  * If the object type has no owner, do nothing.
3403  */
3404 static void
3406 {
3407  const char *type = te->desc;
3408 
3409  /* objects that don't require special decoration */
3410  if (strcmp(type, "COLLATION") == 0 ||
3411  strcmp(type, "CONVERSION") == 0 ||
3412  strcmp(type, "DOMAIN") == 0 ||
3413  strcmp(type, "FOREIGN TABLE") == 0 ||
3414  strcmp(type, "MATERIALIZED VIEW") == 0 ||
3415  strcmp(type, "SEQUENCE") == 0 ||
3416  strcmp(type, "STATISTICS") == 0 ||
3417  strcmp(type, "TABLE") == 0 ||
3418  strcmp(type, "TEXT SEARCH DICTIONARY") == 0 ||
3419  strcmp(type, "TEXT SEARCH CONFIGURATION") == 0 ||
3420  strcmp(type, "TYPE") == 0 ||
3421  strcmp(type, "VIEW") == 0 ||
3422  /* non-schema-specified objects */
3423  strcmp(type, "DATABASE") == 0 ||
3424  strcmp(type, "PROCEDURAL LANGUAGE") == 0 ||
3425  strcmp(type, "SCHEMA") == 0 ||
3426  strcmp(type, "EVENT TRIGGER") == 0 ||
3427  strcmp(type, "FOREIGN DATA WRAPPER") == 0 ||
3428  strcmp(type, "SERVER") == 0 ||
3429  strcmp(type, "PUBLICATION") == 0 ||
3430  strcmp(type, "SUBSCRIPTION") == 0)
3431  {
3432  appendPQExpBuffer(buf, "%s ", type);
3433  if (te->namespace && *te->namespace)
3434  appendPQExpBuffer(buf, "%s.", fmtId(te->namespace));
3436  }
3437  /* BLOBs just have a name, but it's numeric so must not use fmtId */
3438  else if (strcmp(type, "BLOB") == 0)
3439  {
3440  appendPQExpBuffer(buf, "LARGE OBJECT %s", te->tag);
3441  }
3442  /*
3443  * These object types require additional decoration. Fortunately, the
3444  * information needed is exactly what's in the DROP command.
3445  */
3446  else if (strcmp(type, "AGGREGATE") == 0 ||
3447  strcmp(type, "FUNCTION") == 0 ||
3448  strcmp(type, "OPERATOR") == 0 ||
3449  strcmp(type, "OPERATOR CLASS") == 0 ||
3450  strcmp(type, "OPERATOR FAMILY") == 0 ||
3451  strcmp(type, "PROCEDURE") == 0)
3452  {
3453  /* Chop "DROP " off the front and make a modifiable copy */
3454  char *first = pg_strdup(te->dropStmt + 5);
3455  char *last;
3456 
3457  /* point to last character in string */
3458  last = first + strlen(first) - 1;
3459 
3460  /* Strip off any ';' or '\n' at the end */
3461  while (last >= first && (*last == '\n' || *last == ';'))
3462  last--;
3463  *(last + 1) = '\0';
3464 
3465  appendPQExpBufferStr(buf, first);
3466 
3467  free(first);
3468  return;
3469  }
3470  /* these object types don't have separate owners */
3471  else if (strcmp(type, "CAST") == 0 ||
3472  strcmp(type, "CHECK CONSTRAINT") == 0 ||
3473  strcmp(type, "CONSTRAINT") == 0 ||
3474  strcmp(type, "DATABASE PROPERTIES") == 0 ||
3475  strcmp(type, "DEFAULT") == 0 ||
3476  strcmp(type, "FK CONSTRAINT") == 0 ||
3477  strcmp(type, "INDEX") == 0 ||
3478  strcmp(type, "RULE") == 0 ||
3479  strcmp(type, "TRIGGER") == 0 ||
3480  strcmp(type, "ROW SECURITY") == 0 ||
3481  strcmp(type, "POLICY") == 0 ||
3482  strcmp(type, "USER MAPPING") == 0)
3483  {
3484  /* do nothing */
3485  }
3486  else
3487  pg_fatal("don't know how to set owner for object type \"%s\"", type);
3488 }
3489 
3490 /*
3491  * Emit the SQL commands to create the object represented by a TOC entry
3492  *
3493  * This now also includes issuing an ALTER OWNER command to restore the
3494  * object's ownership, if wanted. But note that the object's permissions
3495  * will remain at default, until the matching ACL TOC entry is restored.
3496  */
3497 static void
3498 _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
3499 {
3500  RestoreOptions *ropt = AH->public.ropt;
3501 
3502  /* Select owner, schema, tablespace and default AM as necessary */
3503  _becomeOwner(AH, te);
3504  _selectOutputSchema(AH, te->namespace);
3505  _selectTablespace(AH, te->tablespace);
3507 
3508  /* Emit header comment for item */
3509  if (!AH->noTocComments)
3510  {
3511  const char *pfx;
3512  char *sanitized_name;
3513  char *sanitized_schema;
3514  char *sanitized_owner;
3515 
3516  if (isData)
3517  pfx = "Data for ";
3518  else
3519  pfx = "";
3520 
3521  ahprintf(AH, "--\n");
3522  if (AH->public.verbose)
3523  {
3524  ahprintf(AH, "-- TOC entry %d (class %u OID %u)\n",
3525  te->dumpId, te->catalogId.tableoid, te->catalogId.oid);
3526  if (te->nDeps > 0)
3527  {
3528  int i;
3529 
3530  ahprintf(AH, "-- Dependencies:");
3531  for (i = 0; i < te->nDeps; i++)
3532  ahprintf(AH, " %d", te->dependencies[i]);
3533  ahprintf(AH, "\n");
3534  }
3535  }
3536 
3537  sanitized_name = sanitize_line(te->tag, false);
3538  sanitized_schema = sanitize_line(te->namespace, true);
3539  sanitized_owner = sanitize_line(ropt->noOwner ? NULL : te->owner, true);
3540 
3541  ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
3542  pfx, sanitized_name, te->desc, sanitized_schema,
3543  sanitized_owner);
3544 
3545  free(sanitized_name);
3546  free(sanitized_schema);
3547  free(sanitized_owner);
3548 
3549  if (te->tablespace && strlen(te->tablespace) > 0 && !ropt->noTablespace)
3550  {
3551  char *sanitized_tablespace;
3552 
3553  sanitized_tablespace = sanitize_line(te->tablespace, false);
3554  ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
3555  free(sanitized_tablespace);
3556  }
3557  ahprintf(AH, "\n");
3558 
3559  if (AH->PrintExtraTocPtr != NULL)
3560  AH->PrintExtraTocPtr(AH, te);
3561  ahprintf(AH, "--\n\n");
3562  }
3563 
3564  /*
3565  * Actually print the definition.
3566  *
3567  * Really crude hack for suppressing AUTHORIZATION clause that old pg_dump
3568  * versions put into CREATE SCHEMA. Don't mutate the variant for schema
3569  * "public" that is a comment. We have to do this when --no-owner mode is
3570  * selected. This is ugly, but I see no other good way ...
3571  */
3572  if (ropt->noOwner &&
3573  strcmp(te->desc, "SCHEMA") == 0 && strncmp(te->defn, "--", 2) != 0)
3574  {
3575  ahprintf(AH, "CREATE SCHEMA %s;\n\n\n", fmtId(te->tag));
3576  }
3577  else
3578  {
3579  if (te->defn && strlen(te->defn) > 0)
3580  ahprintf(AH, "%s\n\n", te->defn);
3581  }
3582 
3583  /*
3584  * If we aren't using SET SESSION AUTH to determine ownership, we must
3585  * instead issue an ALTER OWNER command. Schema "public" is special; when
3586  * a dump emits a comment in lieu of creating it, we use ALTER OWNER even
3587  * when using SET SESSION for all other objects. We assume that anything
3588  * without a DROP command is not a separately ownable object.
3589  */
3590  if (!ropt->noOwner &&
3591  (!ropt->use_setsessauth ||
3592  (strcmp(te->desc, "SCHEMA") == 0 &&
3593  strncmp(te->defn, "--", 2) == 0)) &&
3594  te->owner && strlen(te->owner) > 0 &&
3595  te->dropStmt && strlen(te->dropStmt) > 0)
3596  {
3597  PQExpBufferData temp;
3598 
3599  initPQExpBuffer(&temp);
3600  _getObjectDescription(&temp, te);
3601  /*
3602  * If _getObjectDescription() didn't fill the buffer, then there is no
3603  * owner.
3604  */
3605  if (temp.data[0])
3606  ahprintf(AH, "ALTER %s OWNER TO %s;\n\n", temp.data, fmtId(te->owner));
3607  termPQExpBuffer(&temp);
3608  }
3609 
3610  /*
3611  * If it's an ACL entry, it might contain SET SESSION AUTHORIZATION
3612  * commands, so we can no longer assume we know the current auth setting.
3613  */
3614  if (_tocEntryIsACL(te))
3615  {
3616  free(AH->currUser);
3617  AH->currUser = NULL;
3618  }
3619 }
3620 
3621 /*
3622  * Sanitize a string to be included in an SQL comment or TOC listing, by
3623  * replacing any newlines with spaces. This ensures each logical output line
3624  * is in fact one physical output line, to prevent corruption of the dump
3625  * (which could, in the worst case, present an SQL injection vulnerability
3626  * if someone were to incautiously load a dump containing objects with
3627  * maliciously crafted names).
3628  *
3629  * The result is a freshly malloc'd string. If the input string is NULL,
3630  * return a malloc'ed empty string, unless want_hyphen, in which case return a
3631  * malloc'ed hyphen.
3632  *
3633  * Note that we currently don't bother to quote names, meaning that the name
3634  * fields aren't automatically parseable. "pg_restore -L" doesn't care because
3635  * it only examines the dumpId field, but someday we might want to try harder.
3636  */
3637 static char *
3638 sanitize_line(const char *str, bool want_hyphen)
3639 {
3640  char *result;
3641  char *s;
3642 
3643  if (!str)
3644  return pg_strdup(want_hyphen ? "-" : "");
3645 
3646  result = pg_strdup(str);
3647 
3648  for (s = result; *s != '\0'; s++)
3649  {
3650  if (*s == '\n' || *s == '\r')
3651  *s = ' ';
3652  }
3653 
3654  return result;
3655 }
3656 
3657 /*
3658  * Write the file header for a custom-format archive
3659  */
3660 void
3662 {
3663  struct tm crtm;
3664 
3665  AH->WriteBufPtr(AH, "PGDMP", 5); /* Magic code */
3666  AH->WriteBytePtr(AH, ARCHIVE_MAJOR(AH->version));
3667  AH->WriteBytePtr(AH, ARCHIVE_MINOR(AH->version));
3668  AH->WriteBytePtr(AH, ARCHIVE_REV(AH->version));
3669  AH->WriteBytePtr(AH, AH->intSize);
3670  AH->WriteBytePtr(AH, AH->offSize);
3671  AH->WriteBytePtr(AH, AH->format);
3672  WriteInt(AH, AH->compression);
3673  crtm = *localtime(&AH->createDate);
3674  WriteInt(AH, crtm.tm_sec);
3675  WriteInt(AH, crtm.tm_min);
3676  WriteInt(AH, crtm.tm_hour);
3677  WriteInt(AH, crtm.tm_mday);
3678  WriteInt(AH, crtm.tm_mon);
3679  WriteInt(AH, crtm.tm_year);
3680  WriteInt(AH, crtm.tm_isdst);
3681  WriteStr(AH, PQdb(AH->connection));
3682  WriteStr(AH, AH->public.remoteVersionStr);
3683  WriteStr(AH, PG_VERSION);
3684 }
3685 
3686 void
3688 {
3689  char vmaj,
3690  vmin,
3691  vrev;
3692  int fmt;
3693 
3694  /*
3695  * If we haven't already read the header, do so.
3696  *
3697  * NB: this code must agree with _discoverArchiveFormat(). Maybe find a
3698  * way to unify the cases?
3699  */
3700  if (!AH->readHeader)
3701  {
3702  char tmpMag[7];
3703 
3704  AH->ReadBufPtr(AH, tmpMag, 5);
3705 
3706  if (strncmp(tmpMag, "PGDMP", 5) != 0)
3707  pg_fatal("did not find magic string in file header");
3708  }
3709 
3710  vmaj = AH->ReadBytePtr(AH);
3711  vmin = AH->ReadBytePtr(AH);
3712 
3713  if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */
3714  vrev = AH->ReadBytePtr(AH);
3715  else
3716  vrev = 0;
3717 
3718  AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev);
3719 
3720  if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
3721  pg_fatal("unsupported version (%d.%d) in file header",
3722  vmaj, vmin);
3723 
3724  AH->intSize = AH->ReadBytePtr(AH);
3725  if (AH->intSize > 32)
3726  pg_fatal("sanity check on integer size (%lu) failed",
3727  (unsigned long) AH->intSize);
3728 
3729  if (AH->intSize > sizeof(int))
3730  pg_log_warning("archive was made on a machine with larger integers, some operations might fail");
3731 
3732  if (AH->version >= K_VERS_1_7)
3733  AH->offSize = AH->ReadBytePtr(AH);
3734  else
3735  AH->offSize = AH->intSize;
3736 
3737  fmt = AH->ReadBytePtr(AH);
3738 
3739  if (AH->format != fmt)
3740  pg_fatal("expected format (%d) differs from format found in file (%d)",
3741  AH->format, fmt);
3742 
3743  if (AH->version >= K_VERS_1_2)
3744  {
3745  if (AH->version < K_VERS_1_4)
3746  AH->compression = AH->ReadBytePtr(AH);
3747  else
3748  AH->compression = ReadInt(AH);
3749  }
3750  else
3752 
3753 #ifndef HAVE_LIBZ
3754  if (AH->compression != 0)
3755  pg_log_warning("archive is compressed, but this installation does not support compression -- no data will be available");
3756 #endif
3757 
3758  if (AH->version >= K_VERS_1_4)
3759  {
3760  struct tm crtm;
3761 
3762  crtm.tm_sec = ReadInt(AH);
3763  crtm.tm_min = ReadInt(AH);
3764  crtm.tm_hour = ReadInt(AH);
3765  crtm.tm_mday = ReadInt(AH);
3766  crtm.tm_mon = ReadInt(AH);
3767  crtm.tm_year = ReadInt(AH);
3768  crtm.tm_isdst = ReadInt(AH);
3769 
3770  /*
3771  * Newer versions of glibc have mktime() report failure if tm_isdst is
3772  * inconsistent with the prevailing timezone, e.g. tm_isdst = 1 when
3773  * TZ=UTC. This is problematic when restoring an archive under a
3774  * different timezone setting. If we get a failure, try again with
3775  * tm_isdst set to -1 ("don't know").
3776  *
3777  * XXX with or without this hack, we reconstruct createDate
3778  * incorrectly when the prevailing timezone is different from
3779  * pg_dump's. Next time we bump the archive version, we should flush
3780  * this representation and store a plain seconds-since-the-Epoch
3781  * timestamp instead.
3782  */
3783  AH->createDate = mktime(&crtm);
3784  if (AH->createDate == (time_t) -1)
3785  {
3786  crtm.tm_isdst = -1;
3787  AH->createDate = mktime(&crtm);
3788  if (AH->createDate == (time_t) -1)
3789  pg_log_warning("invalid creation date in header");
3790  }
3791  }
3792 
3793  if (AH->version >= K_VERS_1_4)
3794  {
3795  AH->archdbname = ReadStr(AH);
3796  }
3797 
3798  if (AH->version >= K_VERS_1_10)
3799  {
3800  AH->archiveRemoteVersion = ReadStr(AH);
3801  AH->archiveDumpVersion = ReadStr(AH);
3802  }
3803 }
3804 
3805 
3806 /*
3807  * checkSeek
3808  * check to see if ftell/fseek can be performed.
3809  */
3810 bool
3811 checkSeek(FILE *fp)
3812 {
3813  pgoff_t tpos;
3814 
3815  /* Check that ftello works on this file */
3816  tpos = ftello(fp);
3817  if (tpos < 0)
3818  return false;
3819 
3820  /*
3821  * Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
3822  * this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
3823  * successful no-op even on files that are otherwise unseekable.
3824  */
3825  if (fseeko(fp, tpos, SEEK_SET) != 0)
3826  return false;
3827 
3828  return true;
3829 }
3830 
3831 
3832 /*
3833  * dumpTimestamp
3834  */
3835 static void
3836 dumpTimestamp(ArchiveHandle *AH, const char *msg, time_t tim)
3837 {
3838  char buf[64];
3839 
3840  if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&tim)) != 0)
3841  ahprintf(AH, "-- %s %s\n\n", msg, buf);
3842 }
3843 
3844 /*
3845  * Main engine for parallel restore.
3846  *
3847  * Parallel restore is done in three phases. In this first phase,
3848  * we'll process all SECTION_PRE_DATA TOC entries that are allowed to be
3849  * processed in the RESTORE_PASS_MAIN pass. (In practice, that's all
3850  * PRE_DATA items other than ACLs.) Entries we can't process now are
3851  * added to the pending_list for later phases to deal with.
3852  */
3853 static void
3855 {
3856  bool skipped_some;
3857  TocEntry *next_work_item;
3858 
3859  pg_log_debug("entering restore_toc_entries_prefork");
3860 
3861  /* Adjust dependency information */
3862  fix_dependencies(AH);
3863 
3864  /*
3865  * Do all the early stuff in a single connection in the parent. There's no
3866  * great point in running it in parallel, in fact it will actually run
3867  * faster in a single connection because we avoid all the connection and
3868  * setup overhead. Also, pre-9.2 pg_dump versions were not very good
3869  * about showing all the dependencies of SECTION_PRE_DATA items, so we do
3870  * not risk trying to process them out-of-order.
3871  *
3872  * Stuff that we can't do immediately gets added to the pending_list.
3873  * Note: we don't yet filter out entries that aren't going to be restored.
3874  * They might participate in dependency chains connecting entries that
3875  * should be restored, so we treat them as live until we actually process
3876  * them.
3877  *
3878  * Note: as of 9.2, it should be guaranteed that all PRE_DATA items appear
3879  * before DATA items, and all DATA items before POST_DATA items. That is
3880  * not certain to be true in older archives, though, and in any case use
3881  * of a list file would destroy that ordering (cf. SortTocFromFile). So
3882  * this loop cannot assume that it holds.
3883  */
3885  skipped_some = false;
3886  for (next_work_item = AH->toc->next; next_work_item != AH->toc; next_work_item = next_work_item->next)
3887  {
3888  bool do_now = true;
3889 
3890  if (next_work_item->section != SECTION_PRE_DATA)
3891  {
3892  /* DATA and POST_DATA items are just ignored for now */
3893  if (next_work_item->section == SECTION_DATA ||
3894  next_work_item->section == SECTION_POST_DATA)
3895  {
3896  do_now = false;
3897  skipped_some = true;
3898  }
3899  else
3900  {
3901  /*
3902  * SECTION_NONE items, such as comments, can be processed now
3903  * if we are still in the PRE_DATA part of the archive. Once
3904  * we've skipped any items, we have to consider whether the
3905  * comment's dependencies are satisfied, so skip it for now.
3906  */
3907  if (skipped_some)
3908  do_now = false;
3909  }
3910  }
3911 
3912  /*
3913  * Also skip items that need to be forced into later passes. We need
3914  * not set skipped_some in this case, since by assumption no main-pass
3915  * items could depend on these.
3916  */
3917  if (_tocEntryRestorePass(next_work_item) != RESTORE_PASS_MAIN)
3918  do_now = false;
3919 
3920  if (do_now)
3921  {
3922  /* OK, restore the item and update its dependencies */
3923  pg_log_info("processing item %d %s %s",
3924  next_work_item->dumpId,
3925  next_work_item->desc, next_work_item->tag);
3926 
3927  (void) restore_toc_entry(AH, next_work_item, false);
3928 
3929  /* Reduce dependencies, but don't move anything to ready_list */
3930  reduce_dependencies(AH, next_work_item, NULL);
3931  }
3932  else
3933  {
3934  /* Nope, so add it to pending_list */
3935  pending_list_append(pending_list, next_work_item);
3936  }
3937  }
3938 
3939  /*
3940  * Now close parent connection in prep for parallel steps. We do this
3941  * mainly to ensure that we don't exceed the specified number of parallel
3942  * connections.
3943  */
3944  DisconnectDatabase(&AH->public);
3945 
3946  /* blow away any transient state from the old connection */
3947  free(AH->currUser);
3948  AH->currUser = NULL;
3949  free(AH->currSchema);
3950  AH->currSchema = NULL;
3951  free(AH->currTablespace);
3952  AH->currTablespace = NULL;
3953  free(AH->currTableAm);
3954  AH->currTableAm = NULL;
3955 }
3956 
3957 /*
3958  * Main engine for parallel restore.
3959  *
3960  * Parallel restore is done in three phases. In this second phase,
3961  * we process entries by dispatching them to parallel worker children
3962  * (processes on Unix, threads on Windows), each of which connects
3963  * separately to the database. Inter-entry dependencies are respected,
3964  * and so is the RestorePass multi-pass structure. When we can no longer
3965  * make any entries ready to process, we exit. Normally, there will be
3966  * nothing left to do; but if there is, the third phase will mop up.
3967  */
3968 static void
3970  TocEntry *pending_list)
3971 {
3972  ParallelReadyList ready_list;
3973  TocEntry *next_work_item;
3974 
3975  pg_log_debug("entering restore_toc_entries_parallel");
3976 
3977  /* Set up ready_list with enough room for all known TocEntrys */
3978  ready_list_init(&ready_list, AH->tocCount);
3979 
3980  /*
3981  * The pending_list contains all items that we need to restore. Move all
3982  * items that are available to process immediately into the ready_list.
3983  * After this setup, the pending list is everything that needs to be done
3984  * but is blocked by one or more dependencies, while the ready list
3985  * contains items that have no remaining dependencies and are OK to
3986  * process in the current restore pass.
3987  */
3989  move_to_ready_list(pending_list, &ready_list, AH->restorePass);
3990 
3991  /*
3992  * main parent loop
3993  *
3994  * Keep going until there is no worker still running AND there is no work
3995  * left to be done. Note invariant: at top of loop, there should always
3996  * be at least one worker available to dispatch a job to.
3997  */
3998  pg_log_info("entering main parallel loop");
3999 
4000  for (;;)
4001  {
4002  /* Look for an item ready to be dispatched to a worker */
4003  next_work_item = pop_next_work_item(&ready_list, pstate);
4004  if (next_work_item != NULL)
4005  {
4006  /* If not to be restored, don't waste time launching a worker */
4007  if ((next_work_item->reqs & (REQ_SCHEMA | REQ_DATA)) == 0)
4008  {
4009  pg_log_info("skipping item %d %s %s",
4010  next_work_item->dumpId,
4011  next_work_item->desc, next_work_item->tag);
4012  /* Update its dependencies as though we'd completed it */
4013  reduce_dependencies(AH, next_work_item, &ready_list);
4014  /* Loop around to see if anything else can be dispatched */
4015  continue;
4016  }
4017 
4018  pg_log_info("launching item %d %s %s",
4019  next_work_item->dumpId,
4020  next_work_item->desc, next_work_item->tag);
4021 
4022  /* Dispatch to some worker */
4023  DispatchJobForTocEntry(AH, pstate, next_work_item, ACT_RESTORE,
4024  mark_restore_job_done, &ready_list);
4025  }
4026  else if (IsEveryWorkerIdle(pstate))
4027  {
4028  /*
4029  * Nothing is ready and no worker is running, so we're done with
4030  * the current pass or maybe with the whole process.
4031  */
4032  if (AH->restorePass == RESTORE_PASS_LAST)
4033  break; /* No more parallel processing is possible */
4034 
4035  /* Advance to next restore pass */
4036  AH->restorePass++;
4037  /* That probably allows some stuff to be made ready */
4038  move_to_ready_list(pending_list, &ready_list, AH->restorePass);
4039  /* Loop around to see if anything's now ready */
4040  continue;
4041  }
4042  else
4043  {
4044  /*
4045  * We have nothing ready, but at least one child is working, so
4046  * wait for some subjob to finish.
4047  */
4048  }
4049 
4050  /*
4051  * Before dispatching another job, check to see if anything has
4052  * finished. We should check every time through the loop so as to
4053  * reduce dependencies as soon as possible. If we were unable to
4054  * dispatch any job this time through, wait until some worker finishes
4055  * (and, hopefully, unblocks some pending item). If we did dispatch
4056  * something, continue as soon as there's at least one idle worker.
4057  * Note that in either case, there's guaranteed to be at least one
4058  * idle worker when we return to the top of the loop. This ensures we
4059  * won't block inside DispatchJobForTocEntry, which would be
4060  * undesirable: we'd rather postpone dispatching until we see what's
4061  * been unblocked by finished jobs.
4062  */
4063  WaitForWorkers(AH, pstate,
4064  next_work_item ? WFW_ONE_IDLE : WFW_GOT_STATUS);
4065  }
4066 
4067  /* There should now be nothing in ready_list. */
4068  Assert(ready_list.first_te > ready_list.last_te);
4069 
4070  ready_list_free(&ready_list);
4071 
4072  pg_log_info("finished main parallel loop");
4073 }
4074 
4075 /*
4076  * Main engine for parallel restore.
4077  *
4078  * Parallel restore is done in three phases. In this third phase,
4079  * we mop up any remaining TOC entries by processing them serially.
4080  * This phase normally should have nothing to do, but if we've somehow
4081  * gotten stuck due to circular dependencies or some such, this provides
4082  * at least some chance of completing the restore successfully.
4083  */
4084 static void
4086 {
4087  RestoreOptions *ropt = AH->public.ropt;
4088  TocEntry *te;
4089 
4090  pg_log_debug("entering restore_toc_entries_postfork");
4091 
4092  /*
4093  * Now reconnect the single parent connection.
4094  */
4095  ConnectDatabase((Archive *) AH, &ropt->cparams, true);
4096 
4097  /* re-establish fixed state */
4099 
4100  /*
4101  * Make sure there is no work left due to, say, circular dependencies, or
4102  * some other pathological condition. If so, do it in the single parent
4103  * connection. We don't sweat about RestorePass ordering; it's likely we
4104  * already violated that.
4105  */
4106  for (te = pending_list->pending_next; te != pending_list; te = te->pending_next)
4107  {
4108  pg_log_info("processing missed item %d %s %s",
4109  te->dumpId, te->desc, te->tag);
4110  (void) restore_toc_entry(AH, te, false);
4111  }
4112 }
4113 
4114 /*
4115  * Check if te1 has an exclusive lock requirement for an item that te2 also
4116  * requires, whether or not te2's requirement is for an exclusive lock.
4117  */
4118 static bool
4120 {
4121  int j,
4122  k;
4123 
4124  for (j = 0; j < te1->nLockDeps; j++)
4125  {
4126  for (k = 0; k < te2->nDeps; k++)
4127  {
4128  if (te1->lockDeps[j] == te2->dependencies[k])
4129  return true;
4130  }
4131  }
4132  return false;
4133 }
4134 
4135 
4136 /*
4137  * Initialize the header of the pending-items list.
4138  *
4139  * This is a circular list with a dummy TocEntry as header, just like the
4140  * main TOC list; but we use separate list links so that an entry can be in
4141  * the main TOC list as well as in the pending list.
4142  */
4143 static void
4145 {
4146  l->pending_prev = l->pending_next = l;
4147 }
4148 
4149 /* Append te to the end of the pending-list headed by l */
4150 static void
4152 {
4153  te->pending_prev = l->pending_prev;
4154  l->pending_prev->pending_next = te;
4155  l->pending_prev = te;
4156  te->pending_next = l;
4157 }
4158 
4159 /* Remove te from the pending-list */
4160 static void
4162 {
4165  te->pending_prev = NULL;
4166  te->pending_next = NULL;
4167 }
4168 
4169 
4170 /*
4171  * Initialize the ready_list with enough room for up to tocCount entries.
4172  */
4173 static void
4174 ready_list_init(ParallelReadyList *ready_list, int tocCount)
4175 {
4176  ready_list->tes = (TocEntry **)
4177  pg_malloc(tocCount * sizeof(TocEntry *));
4178  ready_list->first_te = 0;
4179  ready_list->last_te = -1;
4180  ready_list->sorted = false;
4181 }
4182 
4183 /*
4184  * Free storage for a ready_list.
4185  */
4186 static void
4188 {
4189  pg_free(ready_list->tes);
4190 }
4191 
4192 /* Add te to the ready_list */
4193 static void
4195 {
4196  ready_list->tes[++ready_list->last_te] = te;
4197  /* List is (probably) not sorted anymore. */
4198  ready_list->sorted = false;
4199 }
4200 
4201 /* Remove the i'th entry in the ready_list */
4202 static void
4204 {
4205  int f = ready_list->first_te;
4206 
4207  Assert(i >= f && i <= ready_list->last_te);
4208 
4209  /*
4210  * In the typical case where the item to be removed is the first ready
4211  * entry, we need only increment first_te to remove it. Otherwise, move
4212  * the entries before it to compact the list. (This preserves sortedness,
4213  * if any.) We could alternatively move the entries after i, but there
4214  * are typically many more of those.
4215  */
4216  if (i > f)
4217  {
4218  TocEntry **first_te_ptr = &ready_list->tes[f];
4219 
4220  memmove(first_te_ptr + 1, first_te_ptr, (i - f) * sizeof(TocEntry *));
4221  }
4222  ready_list->first_te++;
4223 }
4224 
4225 /* Sort the ready_list into the desired order */
4226 static void
4228 {
4229  if (!ready_list->sorted)
4230  {
4231  int n = ready_list->last_te - ready_list->first_te + 1;
4232 
4233  if (n > 1)
4234  qsort(ready_list->tes + ready_list->first_te, n,
4235  sizeof(TocEntry *),
4237  ready_list->sorted = true;
4238  }
4239 }
4240 
4241 /* qsort comparator for sorting TocEntries by dataLength */
4242 static int
4243 TocEntrySizeCompare(const void *p1, const void *p2)
4244 {
4245  const TocEntry *te1 = *(const TocEntry *const *) p1;
4246  const TocEntry *te2 = *(const TocEntry *const *) p2;
4247 
4248  /* Sort by decreasing dataLength */
4249  if (te1->dataLength > te2->dataLength)
4250  return -1;
4251  if (te1->dataLength < te2->dataLength)
4252  return 1;
4253 
4254  /* For equal dataLengths, sort by dumpId, just to be stable */
4255  if (te1->dumpId < te2->dumpId)
4256  return -1;
4257  if (te1->dumpId > te2->dumpId)
4258  return 1;
4259 
4260  return 0;
4261 }
4262 
4263 
4264 /*
4265  * Move all immediately-ready items from pending_list to ready_list.
4266  *
4267  * Items are considered ready if they have no remaining dependencies and
4268  * they belong in the current restore pass. (See also reduce_dependencies,
4269  * which applies the same logic one-at-a-time.)
4270  */
4271 static void
4273  ParallelReadyList *ready_list,
4274  RestorePass pass)
4275 {
4276  TocEntry *te;
4277  TocEntry *next_te;
4278 
4279  for (te = pending_list->pending_next; te != pending_list; te = next_te)
4280  {
4281  /* must save list link before possibly removing te from list */
4282  next_te = te->pending_next;
4283 
4284  if (te->depCount == 0 &&
4285  _tocEntryRestorePass(te) == pass)
4286  {
4287  /* Remove it from pending_list ... */
4288  pending_list_remove(te);
4289  /* ... and add to ready_list */
4290  ready_list_insert(ready_list, te);
4291  }
4292  }
4293 }
4294 
4295 /*
4296  * Find the next work item (if any) that is capable of being run now,
4297  * and remove it from the ready_list.
4298  *
4299  * Returns the item, or NULL if nothing is runnable.
4300  *
4301  * To qualify, the item must have no remaining dependencies
4302  * and no requirements for locks that are incompatible with
4303  * items currently running. Items in the ready_list are known to have
4304  * no remaining dependencies, but we have to check for lock conflicts.
4305  */
4306 static TocEntry *
4308  ParallelState *pstate)
4309 {
4310  /*
4311  * Sort the ready_list so that we'll tackle larger jobs first.
4312  */
4313  ready_list_sort(ready_list);
4314 
4315  /*
4316  * Search the ready_list until we find a suitable item.
4317  */
4318  for (int i = ready_list->first_te; i <= ready_list->last_te; i++)
4319  {
4320  TocEntry *te = ready_list->tes[i];
4321  bool conflicts = false;
4322 
4323  /*
4324  * Check to see if the item would need exclusive lock on something
4325  * that a currently running item also needs lock on, or vice versa. If
4326  * so, we don't want to schedule them together.
4327  */
4328  for (int k = 0; k < pstate->numWorkers; k++)
4329  {
4330  TocEntry *running_te = pstate->te[k];
4331 
4332  if (running_te == NULL)
4333  continue;
4334  if (has_lock_conflicts(te, running_te) ||
4335  has_lock_conflicts(running_te, te))
4336  {
4337  conflicts = true;
4338  break;
4339  }
4340  }
4341 
4342  if (conflicts)
4343  continue;
4344 
4345  /* passed all tests, so this item can run */
4346  ready_list_remove(ready_list, i);
4347  return te;
4348  }
4349 
4350  pg_log_debug("no item ready");
4351  return NULL;
4352 }
4353 
4354 
4355 /*
4356  * Restore a single TOC item in parallel with others
4357  *
4358  * this is run in the worker, i.e. in a thread (Windows) or a separate process
4359  * (everything else). A worker process executes several such work items during
4360  * a parallel backup or restore. Once we terminate here and report back that
4361  * our work is finished, the leader process will assign us a new work item.
4362  */
4363 int
4365 {
4366  int status;
4367 
4368  Assert(AH->connection != NULL);
4369 
4370  /* Count only errors associated with this TOC entry */
4371  AH->public.n_errors = 0;
4372 
4373  /* Restore the TOC item */
4374  status = restore_toc_entry(AH, te, true);
4375 
4376  return status;
4377 }
4378 
4379 
4380 /*
4381  * Callback function that's invoked in the leader process after a step has
4382  * been parallel restored.
4383  *
4384  * Update status and reduce the dependency count of any dependent items.
4385  */
4386 static void
4388  TocEntry *te,
4389  int status,
4390  void *callback_data)
4391 {
4392  ParallelReadyList *ready_list = (ParallelReadyList *) callback_data;
4393 
4394  pg_log_info("finished item %d %s %s",
4395  te->dumpId, te->desc, te->tag);
4396 
4397  if (status == WORKER_CREATE_DONE)
4398  mark_create_done(AH, te);
4399  else if (status == WORKER_INHIBIT_DATA)
4400  {
4402  AH->public.n_errors++;
4403  }
4404  else if (status == WORKER_IGNORED_ERRORS)
4405  AH->public.n_errors++;
4406  else if (status != 0)
4407  pg_fatal("worker process failed: exit code %d",
4408  status);
4409 
4410  reduce_dependencies(AH, te, ready_list);
4411 }
4412 
4413 
4414 /*
4415  * Process the dependency information into a form useful for parallel restore.
4416  *
4417  * This function takes care of fixing up some missing or badly designed
4418  * dependencies, and then prepares subsidiary data structures that will be
4419  * used in the main parallel-restore logic, including:
4420  * 1. We build the revDeps[] arrays of incoming dependency dumpIds.
4421  * 2. We set up depCount fields that are the number of as-yet-unprocessed
4422  * dependencies for each TOC entry.
4423  *
4424  * We also identify locking dependencies so that we can avoid trying to
4425  * schedule conflicting items at the same time.
4426  */
4427 static void
4429 {
4430  TocEntry *te;
4431  int i;
4432 
4433  /*
4434  * Initialize the depCount/revDeps/nRevDeps fields, and make sure the TOC
4435  * items are marked as not being in any parallel-processing list.
4436  */
4437  for (te = AH->toc->next; te != AH->toc; te = te->next)
4438  {
4439  te->depCount = te->nDeps;
4440  te->revDeps = NULL;
4441  te->nRevDeps = 0;
4442  te->pending_prev = NULL;
4443  te->pending_next = NULL;
4444  }
4445 
4446  /*
4447  * POST_DATA items that are shown as depending on a table need to be
4448  * re-pointed to depend on that table's data, instead. This ensures they
4449  * won't get scheduled until the data has been loaded.
4450  */
4452 
4453  /*
4454  * Pre-8.4 versions of pg_dump neglected to set up a dependency from BLOB
4455  * COMMENTS to BLOBS. Cope. (We assume there's only one BLOBS and only
4456  * one BLOB COMMENTS in such files.)
4457  */
4458  if (AH->version < K_VERS_1_11)
4459  {
4460  for (te = AH->toc->next; te != AH->toc; te = te->next)
4461  {
4462  if (strcmp(te->desc, "BLOB COMMENTS") == 0 && te->nDeps == 0)
4463  {
4464  TocEntry *te2;
4465 
4466  for (te2 = AH->toc->next; te2 != AH->toc; te2 = te2->next)
4467  {
4468  if (strcmp(te2->desc, "BLOBS") == 0)
4469  {
4470  te->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
4471  te->dependencies[0] = te2->dumpId;
4472  te->nDeps++;
4473  te->depCount++;
4474  break;
4475  }
4476  }
4477  break;
4478  }
4479  }
4480  }
4481 
4482  /*
4483  * At this point we start to build the revDeps reverse-dependency arrays,
4484  * so all changes of dependencies must be complete.
4485  */
4486 
4487  /*
4488  * Count the incoming dependencies for each item. Also, it is possible
4489  * that the dependencies list items that are not in the archive at all
4490  * (that should not happen in 9.2 and later, but is highly likely in older
4491  * archives). Subtract such items from the depCounts.
4492  */
4493  for (te = AH->toc->next; te != AH->toc; te = te->next)
4494  {
4495  for (i = 0; i < te->nDeps; i++)
4496  {
4497  DumpId depid = te->dependencies[i];
4498 
4499  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4500  AH->tocsByDumpId[depid]->nRevDeps++;
4501  else
4502  te->depCount--;
4503  }
4504  }
4505 
4506  /*
4507  * Allocate space for revDeps[] arrays, and reset nRevDeps so we can use
4508  * it as a counter below.
4509  */
4510  for (te = AH->toc->next; te != AH->toc; te = te->next)
4511  {
4512  if (te->nRevDeps > 0)
4513  te->revDeps = (DumpId *) pg_malloc(te->nRevDeps * sizeof(DumpId));
4514  te->nRevDeps = 0;
4515  }
4516 
4517  /*
4518  * Build the revDeps[] arrays of incoming-dependency dumpIds. This had
4519  * better agree with the loops above.
4520  */
4521  for (te = AH->toc->next; te != AH->toc; te = te->next)
4522  {
4523  for (i = 0; i < te->nDeps; i++)
4524  {
4525  DumpId depid = te->dependencies[i];
4526 
4527  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4528  {
4529  TocEntry *otherte = AH->tocsByDumpId[depid];
4530 
4531  otherte->revDeps[otherte->nRevDeps++] = te->dumpId;
4532  }
4533  }
4534  }
4535 
4536  /*
4537  * Lastly, work out the locking dependencies.
4538  */
4539  for (te = AH->toc->next; te != AH->toc; te = te->next)
4540  {
4541  te->lockDeps = NULL;
4542  te->nLockDeps = 0;
4544  }
4545 }
4546 
4547 /*
4548  * Change dependencies on table items to depend on table data items instead,
4549  * but only in POST_DATA items.
4550  *
4551  * Also, for any item having such dependency(s), set its dataLength to the
4552  * largest dataLength of the table data items it depends on. This ensures
4553  * that parallel restore will prioritize larger jobs (index builds, FK
4554  * constraint checks, etc) over smaller ones, avoiding situations where we
4555  * end a restore with only one active job working on a large table.
4556  */
4557 static void
4559 {
4560  TocEntry *te;
4561  int i;
4562  DumpId olddep;
4563 
4564  for (te = AH->toc->next; te != AH->toc; te = te->next)
4565  {
4566  if (te->section != SECTION_POST_DATA)
4567  continue;
4568  for (i = 0; i < te->nDeps; i++)
4569  {
4570  olddep = te->dependencies[i];
4571  if (olddep <= AH->maxDumpId &&
4572  AH->tableDataId[olddep] != 0)
4573  {
4574  DumpId tabledataid = AH->tableDataId[olddep];
4575  TocEntry *tabledatate = AH->tocsByDumpId[tabledataid];
4576 
4577  te->dependencies[i] = tabledataid;
4578  te->dataLength = Max(te->dataLength, tabledatate->dataLength);
4579  pg_log_debug("transferring dependency %d -> %d to %d",
4580  te->dumpId, olddep, tabledataid);
4581  }
4582  }
4583  }
4584 }
4585 
4586 /*
4587  * Identify which objects we'll need exclusive lock on in order to restore
4588  * the given TOC entry (*other* than the one identified by the TOC entry
4589  * itself). Record their dump IDs in the entry's lockDeps[] array.
4590  */
4591 static void
4593 {
4594  DumpId *lockids;
4595  int nlockids;
4596  int i;
4597 
4598  /*
4599  * We only care about this for POST_DATA items. PRE_DATA items are not
4600  * run in parallel, and DATA items are all independent by assumption.
4601  */
4602  if (te->section != SECTION_POST_DATA)
4603  return;
4604 
4605  /* Quick exit if no dependencies at all */
4606  if (te->nDeps == 0)
4607  return;
4608 
4609  /*
4610  * Most POST_DATA items are ALTER TABLEs or some moral equivalent of that,
4611  * and hence require exclusive lock. However, we know that CREATE INDEX
4612  * does not. (Maybe someday index-creating CONSTRAINTs will fall in that
4613  * category too ... but today is not that day.)
4614  */
4615  if (strcmp(te->desc, "INDEX") == 0)
4616  return;
4617 
4618  /*
4619  * We assume the entry requires exclusive lock on each TABLE or TABLE DATA
4620  * item listed among its dependencies. Originally all of these would have
4621  * been TABLE items, but repoint_table_dependencies would have repointed
4622  * them to the TABLE DATA items if those are present (which they might not
4623  * be, eg in a schema-only dump). Note that all of the entries we are
4624  * processing here are POST_DATA; otherwise there might be a significant
4625  * difference between a dependency on a table and a dependency on its
4626  * data, so that closer analysis would be needed here.
4627  */
4628  lockids = (DumpId *) pg_malloc(te->nDeps * sizeof(DumpId));
4629  nlockids = 0;
4630  for (i = 0; i < te->nDeps; i++)
4631  {
4632  DumpId depid = te->dependencies[i];
4633 
4634  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL &&
4635  ((strcmp(AH->tocsByDumpId[depid]->desc, "TABLE DATA") == 0) ||
4636  strcmp(AH->tocsByDumpId[depid]->desc, "TABLE") == 0))
4637  lockids[nlockids++] = depid;
4638  }
4639 
4640  if (nlockids == 0)
4641  {
4642  free(lockids);
4643  return;
4644  }
4645 
4646  te->lockDeps = pg_realloc(lockids, nlockids * sizeof(DumpId));
4647  te->nLockDeps = nlockids;
4648 }
4649 
4650 /*
4651  * Remove the specified TOC entry from the depCounts of items that depend on
4652  * it, thereby possibly making them ready-to-run. Any pending item that
4653  * becomes ready should be moved to the ready_list, if that's provided.
4654  */
4655 static void
4657  ParallelReadyList *ready_list)
4658 {
4659  int i;
4660 
4661  pg_log_debug("reducing dependencies for %d", te->dumpId);
4662 
4663  for (i = 0; i < te->nRevDeps; i++)
4664  {
4665  TocEntry *otherte = AH->tocsByDumpId[te->revDeps[i]];
4666 
4667  Assert(otherte->depCount > 0);
4668  otherte->depCount--;
4669 
4670  /*
4671  * It's ready if it has no remaining dependencies, and it belongs in
4672  * the current restore pass, and it is currently a member of the
4673  * pending list (that check is needed to prevent double restore in
4674  * some cases where a list-file forces out-of-order restoring).
4675  * However, if ready_list == NULL then caller doesn't want any list
4676  * memberships changed.
4677  */
4678  if (otherte->depCount == 0 &&
4679  _tocEntryRestorePass(otherte) == AH->restorePass &&
4680  otherte->pending_prev != NULL &&
4681  ready_list != NULL)
4682  {
4683  /* Remove it from pending list ... */
4684  pending_list_remove(otherte);
4685  /* ... and add to ready_list */
4686  ready_list_insert(ready_list, otherte);
4687  }
4688  }
4689 }
4690 
4691 /*
4692  * Set the created flag on the DATA member corresponding to the given
4693  * TABLE member
4694  */
4695 static void
4697 {
4698  if (AH->tableDataId[te->dumpId] != 0)
4699  {
4700  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4701 
4702  ted->created = true;
4703  }
4704 }
4705 
4706 /*
4707  * Mark the DATA member corresponding to the given TABLE member
4708  * as not wanted
4709  */
4710 static void
4712 {
4713  pg_log_info("table \"%s\" could not be created, will not restore its data",
4714  te->tag);
4715 
4716  if (AH->tableDataId[te->dumpId] != 0)
4717  {
4718  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4719 
4720  ted->reqs = 0;
4721  }
4722 }
4723 
4724 /*
4725  * Clone and de-clone routines used in parallel restoration.
4726  *
4727  * Enough of the structure is cloned to ensure that there is no
4728  * conflict between different threads each with their own clone.
4729  */
4730 ArchiveHandle *
4732 {
4733  ArchiveHandle *clone;
4734 
4735  /* Make a "flat" copy */
4736  clone = (ArchiveHandle *) pg_malloc(sizeof(ArchiveHandle));
4737  memcpy(clone, AH, sizeof(ArchiveHandle));
4738 
4739  /* Handle format-independent fields */
4740  memset(&(clone->sqlparse), 0, sizeof(clone->sqlparse));
4741 
4742  /* The clone will have its own connection, so disregard connection state */
4743  clone->connection = NULL;
4744  clone->connCancel = NULL;
4745  clone->currUser = NULL;
4746  clone->currSchema = NULL;
4747  clone->currTableAm = NULL;
4748  clone->currTablespace = NULL;
4749 
4750  /* savedPassword must be local in case we change it while connecting */
4751  if (clone->savedPassword)
4752  clone->savedPassword = pg_strdup(clone->savedPassword);
4753 
4754  /* clone has its own error count, too */
4755  clone->public.n_errors = 0;
4756 
4757  /*
4758  * Connect our new clone object to the database, using the same connection
4759  * parameters used for the original connection.
4760  */
4761  ConnectDatabase((Archive *) clone, &clone->public.ropt->cparams, true);
4762 
4763  /* re-establish fixed state */
4764  if (AH->mode == archModeRead)
4765  _doSetFixedOutputState(clone);
4766  /* in write case, setupDumpWorker will fix up connection state */
4767 
4768  /* Let the format-specific code have a chance too */
4769  clone->ClonePtr(clone);
4770 
4771  Assert(clone->connection != NULL);
4772  return clone;
4773 }
4774 
4775 /*
4776  * Release clone-local storage.
4777  *
4778  * Note: we assume any clone-local connection was already closed.
4779  */
4780 void
4782 {
4783  /* Should not have an open database connection */
4784  Assert(AH->connection == NULL);
4785 
4786  /* Clear format-specific state */
4787  AH->DeClonePtr(AH);
4788 
4789  /* Clear state allocated by CloneArchive */
4790  if (AH->sqlparse.curCmd)
4792 
4793  /* Clear any connection-local state */
4794  free(AH->currUser);
4795  free(AH->currSchema);
4796  free(AH->currTablespace);
4797  free(AH->currTableAm);
4798  free(AH->savedPassword);
4799 
4800  free(AH);
4801 }
int lo_write(int fd, const char *buf, int len)
Definition: be-fsstubs.c:181
void ParallelBackupEnd(ArchiveHandle *AH, ParallelState *pstate)
Definition: parallel.c:1059
void WaitForWorkers(ArchiveHandle *AH, ParallelState *pstate, WFW_WaitOption mode)
Definition: parallel.c:1451
void DispatchJobForTocEntry(ArchiveHandle *AH, ParallelState *pstate, TocEntry *te, T_Action act, ParallelCompletionPtr callback, void *callback_data)
Definition: parallel.c:1205
bool IsEveryWorkerIdle(ParallelState *pstate)
Definition: parallel.c:1268
ParallelState * ParallelBackupStart(ArchiveHandle *AH)
Definition: parallel.c:897
@ WFW_ALL_IDLE
Definition: parallel.h:35
@ WFW_GOT_STATUS
Definition: parallel.h:33
@ WFW_ONE_IDLE
Definition: parallel.h:34
#define PG_BINARY_R
Definition: c.h:1211
#define ngettext(s, p, n)
Definition: c.h:1120
#define PG_BINARY_A
Definition: c.h:1210
#define Max(x, y)
Definition: c.h:931
#define PG_BINARY_W
Definition: c.h:1212
#define PGDUMP_STRFTIME_FMT
Definition: dumputils.h:33
int pg_char_to_encoding(const char *name)
Definition: encnames.c:550
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:588
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:6589
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6743
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3240
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2225
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:96
int lo_open(PGconn *conn, Oid lobjId, int mode)
Definition: fe-lobj.c:57
Oid lo_create(PGconn *conn, Oid lobjId)
Definition: fe-lobj.c:474
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pg_free(void *ptr)
Definition: fe_memutils.c:105
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define free(a)
Definition: header.h:65
int remaining
Definition: informix.c:667
char sign
Definition: informix.c:668
int b
Definition: isn.c:70
return true
Definition: isn.c:126
int j
Definition: isn.c:74
int i
Definition: isn.c:73
@ PGRES_COMMAND_OK
Definition: libpq-fe.h:97
#define INV_WRITE
Definition: libpq-fs.h:21
static void const char * fmt
va_end(args)
Assert(fmt[strlen(fmt) - 1] !='\n')
va_start(args, fmt)
static struct pg_tm tm
Definition: localtime.c:104
void pg_log_generic_v(enum pg_log_level level, enum pg_log_part part, const char *pg_restrict fmt, va_list ap)
Definition: logging.c:216
#define pg_log_info(...)
Definition: logging.h:124
@ PG_LOG_PRIMARY
Definition: logging.h:67
@ PG_LOG_ERROR
Definition: logging.h:43
#define pg_log_debug(...)
Definition: logging.h:133
static AmcheckOptions opts
Definition: pg_amcheck.c:110
void ConnectDatabase(Archive *AHX, const ConnParams *cparams, bool isReconnect)
Definition: pg_backup_db.c:110
@ SECTION_NONE
Definition: pg_backup.h:55
@ SECTION_POST_DATA
Definition: pg_backup.h:58
@ SECTION_PRE_DATA
Definition: pg_backup.h:56
@ SECTION_DATA
Definition: pg_backup.h:57
int DumpId
Definition: pg_backup.h:265
void(* SetupWorkerPtrType)(Archive *AH)
Definition: pg_backup.h:275
enum _archiveFormat ArchiveFormat
@ archModeWrite
Definition: pg_backup.h:49
@ archModeAppend
Definition: pg_backup.h:48
@ archModeRead
Definition: pg_backup.h:50
void DisconnectDatabase(Archive *AHX)
Definition: pg_backup_db.c:225
enum _teSection teSection
@ archUnknown
Definition: pg_backup.h:39
@ archTar
Definition: pg_backup.h:41
@ archCustom
Definition: pg_backup.h:40
@ archDirectory
Definition: pg_backup.h:43
@ archNull
Definition: pg_backup.h:42
static void fix_dependencies(ArchiveHandle *AH)
static void ready_list_insert(ParallelReadyList *ready_list, TocEntry *te)
static void repoint_table_dependencies(ArchiveHandle *AH)
void DeCloneArchive(ArchiveHandle *AH)
static int _discoverArchiveFormat(ArchiveHandle *AH)
#define TEXT_DUMPALL_HEADER
int TocIDRequired(ArchiveHandle *AH, DumpId id)
bool checkSeek(FILE *fp)
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
void warn_or_exit_horribly(ArchiveHandle *AH, const char *fmt,...)
void WriteDataChunksForTocEntry(ArchiveHandle *AH, TocEntry *te)
static void _becomeOwner(ArchiveHandle *AH, TocEntry *te)
void WriteHead(ArchiveHandle *AH)
static void _becomeUser(ArchiveHandle *AH, const char *user)
static void ready_list_free(ParallelReadyList *ready_list)
TocEntry * getTocEntryByDumpId(ArchiveHandle *AH, DumpId id)
static void pending_list_append(TocEntry *l, TocEntry *te)
static void ready_list_sort(ParallelReadyList *ready_list)
size_t WriteInt(ArchiveHandle *AH, int i)
void ProcessArchiveRestoreOptions(Archive *AHX)
static int restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
static void _moveBefore(TocEntry *pos, TocEntry *te)
static bool _tocEntryIsACL(TocEntry *te)
static void _getObjectDescription(PQExpBuffer buf, const TocEntry *te)
static void buildTocEntryArrays(ArchiveHandle *AH)
static void identify_locking_dependencies(ArchiveHandle *AH, TocEntry *te)
struct _outputContext OutputContext
static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te)
static void processSearchPathEntry(ArchiveHandle *AH, TocEntry *te)
int archprintf(Archive *AH, const char *fmt,...)
static void ready_list_remove(ParallelReadyList *ready_list, int i)
static void StrictNamesCheck(RestoreOptions *ropt)
static void mark_restore_job_done(ArchiveHandle *AH, TocEntry *te, int status, void *callback_data)
ArchiveHandle * CloneArchive(ArchiveHandle *AH)
size_t WriteOffset(ArchiveHandle *AH, pgoff_t o, int wasSet)
static OutputContext SaveOutput(ArchiveHandle *AH)
RestoreOptions * NewRestoreOptions(void)
static RestorePass _tocEntryRestorePass(TocEntry *te)
static void setupRestoreWorker(Archive *AHX)
static void _reconnectToDB(ArchiveHandle *AH, const char *dbname)
void StartRestoreBlob(ArchiveHandle *AH, Oid oid, bool drop)
void CloseArchive(Archive *AHX)
static void pending_list_header_init(TocEntry *l)
static void restore_toc_entries_parallel(ArchiveHandle *AH, ParallelState *pstate, TocEntry *pending_list)
static ArchiveHandle * _allocAH(const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupWorkerPtr)
static void mark_create_done(ArchiveHandle *AH, TocEntry *te)
#define TEXT_DUMP_HEADER
static void _selectTableAccessMethod(ArchiveHandle *AH, const char *tableam)
void WriteDataChunks(ArchiveHandle *AH, ParallelState *pstate)
static void dumpTimestamp(ArchiveHandle *AH, const char *msg, time_t tim)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
static void reduce_dependencies(ArchiveHandle *AH, TocEntry *te, ParallelReadyList *ready_list)
static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
static void mark_dump_job_done(ArchiveHandle *AH, TocEntry *te, int status, void *callback_data)
static void _enableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te)
static void SetOutput(ArchiveHandle *AH, const char *filename, int compression)
void SortTocFromFile(Archive *AHX)
int StartBlob(Archive *AHX, Oid oid)
int ReadOffset(ArchiveHandle *AH, pgoff_t *o)
char * ReadStr(ArchiveHandle *AH)
static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
static void inhibit_data_for_failed_table(ArchiveHandle *AH, TocEntry *te)
int ReadInt(ArchiveHandle *AH)
static void restore_toc_entries_prefork(ArchiveHandle *AH, TocEntry *pending_list)
static void restore_toc_entries_postfork(ArchiveHandle *AH, TocEntry *pending_list)
static void RestoreOutput(ArchiveHandle *AH, OutputContext savedContext)
TocEntry * ArchiveEntry(Archive *AHX, CatalogId catalogId, DumpId dumpId, ArchiveOpts *opts)
static void _doSetFixedOutputState(ArchiveHandle *AH)
void PrintTOCSummary(Archive *AHX)
static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te)
void StartRestoreBlobs(ArchiveHandle *AH)
static int RestoringToDB(ArchiveHandle *AH)
void ReadHead(ArchiveHandle *AH)
void SetArchiveOptions(Archive *AH, DumpOptions *dopt, RestoreOptions *ropt)
static void pending_list_remove(TocEntry *te)
static bool has_lock_conflicts(TocEntry *te1, TocEntry *te2)
DumpOptions * NewDumpOptions(void)
void ReadToc(ArchiveHandle *AH)
Archive * CreateArchive(const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupDumpWorker)
static char * sanitize_line(const char *str, bool want_hyphen)
static void _selectTablespace(ArchiveHandle *AH, const char *tablespace)
static int TocEntrySizeCompare(const void *p1, const void *p2)
void RestoreArchive(Archive *AHX)
static void ready_list_init(ParallelReadyList *ready_list, int tocCount)
void WriteToc(ArchiveHandle *AH)
void archputs(const char *s, Archive *AH)
static void move_to_ready_list(TocEntry *pending_list, ParallelReadyList *ready_list, RestorePass pass)
struct _parallelReadyList ParallelReadyList
void EndRestoreBlob(ArchiveHandle *AH, Oid oid)
static TocEntry * pop_next_work_item(ParallelReadyList *ready_list, ParallelState *pstate)
static int _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH)
static void _doSetSessionAuth(ArchiveHandle *AH, const char *user)
Archive * OpenArchive(const char *FileSpec, const ArchiveFormat fmt)
void EndRestoreBlobs(ArchiveHandle *AH)
void InitDumpOptions(DumpOptions *opts)
DumpOptions * dumpOptionsFromRestoreOptions(RestoreOptions *ropt)
static void dump_lo_buf(ArchiveHandle *AH)
void WriteData(Archive *AHX, const void *data, size_t dLen)
int parallel_restore(ArchiveHandle *AH, TocEntry *te)
int EndBlob(Archive *AHX, Oid oid)
size_t WriteStr(ArchiveHandle *AH, const char *c)
static void _disableTriggersIfNecessary(ArchiveHandle *AH, TocEntry *te)
void InitArchiveFmt_Null(ArchiveHandle *AH)
#define WORKER_CREATE_DONE
void DropBlobIfExists(ArchiveHandle *AH, Oid oid)
Definition: pg_backup_db.c:545
#define K_VERS_1_14
#define appendByteaLiteralAHX(buf, str, len, AH)
void struct _archiveOpts ArchiveOpts
void(* EndDataPtrType)(ArchiveHandle *AH, TocEntry *te)
#define K_VERS_SELF
#define K_VERS_1_10
void(* StartDataPtrType)(ArchiveHandle *AH, TocEntry *te)
#define ARCHIVE_MAJOR(version)
#define ARCHIVE_MINOR(version)
#define K_VERS_1_2
#define RESTORE_PASS_LAST
void InitArchiveFmt_Custom(ArchiveHandle *AH)
#define K_OFFSET_NO_DATA
void InitArchiveFmt_Tar(ArchiveHandle *AH)
#define REQ_SCHEMA
#define GZWRITE(p, s, n, fh)
#define K_VERS_1_4
#define appendStringLiteralAHX(buf, str, AH)
#define MAKE_ARCHIVE_VERSION(major, minor, rev)
#define K_VERS_1_5
void ReconnectToServer(ArchiveHandle *AH, const char *dbname)
Definition: pg_backup_db.c:74
#define ARCHIVE_REV(version)
#define WRITE_ERROR_EXIT
bool isValidTarHeader(char *header)
#define WORKER_IGNORED_ERRORS
#define REQ_SPECIAL
#define K_VERS_1_6
@ STAGE_INITIALIZING
@ STAGE_PROCESSING
@ STAGE_NONE
@ STAGE_FINALIZING
@ ACT_RESTORE
@ ACT_DUMP
#define K_VERS_1_0
#define K_OFFSET_POS_NOT_SET
#define K_OFFSET_POS_SET
#define K_VERS_MAX
#define K_VERS_1_8
#define WORKER_OK
@ OUTPUT_COPYDATA
@ OUTPUT_SQLCMDS
@ OUTPUT_OTHERDATA
#define K_VERS_1_12
#define REQ_DATA
#define READ_ERROR_EXIT(fd)
void InitArchiveFmt_Directory(ArchiveHandle *AH)
#define K_VERS_1_11
#define K_VERS_1_9
#define WORKER_INHIBIT_DATA
#define GZCLOSE(fh)
@ RESTORE_PASS_ACL
@ RESTORE_PASS_MAIN
#define Z_DEFAULT_COMPRESSION
#define K_VERS_1_3
#define K_VERS_1_7
void EndDBCopyMode(Archive *AHX, const char *tocEntryTag)
Definition: pg_backup_db.c:500
int ExecuteSqlCommandBuf(Archive *AHX, const char *buf, size_t bufLen)
Definition: pg_backup_db.c:445
#define DUMP_PRE_DATA
#define DUMP_DATA
#define DUMP_UNSECTIONED
#define pg_fatal(...)
#define DUMP_POST_DATA
static PgChecksumMode mode
Definition: pg_checksums.c:65
#define MAXPGPATH
const void size_t len
const void * data
static int sig
Definition: pg_ctl.c:79
int32 encoding
Definition: pg_database.h:41
static bool dosync
Definition: pg_dump.c:101
static void setupDumpWorker(Archive *AH)
Definition: pg_dump.c:1233
#define exit_nicely(code)
Definition: pg_dumpall.c:124
static char * filename
Definition: pg_dumpall.c:119
bool pg_get_line_buf(FILE *stream, StringInfo buf)
Definition: pg_get_line.c:95
static char * user
Definition: pg_regress.c:93
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
static char * buf
Definition: pg_test_fsync.c:67
char * tablespace
Definition: pgbench.c:225
#define pg_log_warning(...)
Definition: pgfnames.c:24
#define sprintf
Definition: port.h:240
#define snprintf
Definition: port.h:238
#define qsort(a, b, c, d)
Definition: port.h:445
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:72
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:114
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
char * c
size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
Definition: psprintf.c:106
bool simple_string_list_member(SimpleStringList *list, const char *val)
Definition: simple_list.c:87
const char * simple_string_list_not_touched(SimpleStringList *list)
Definition: simple_list.c:144
char * dbname
Definition: streamutil.c:51
void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
Definition: string_utils.c:590
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
const char * fmtQualifiedId(const char *schema, const char *id)
Definition: string_utils.c:145
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
int minRemoteVersion
Definition: pg_backup.h:217
char * remoteVersionStr
Definition: pg_backup.h:213
DumpOptions * dopt
Definition: pg_backup.h:209
bool exit_on_error
Definition: pg_backup.h:232
char * searchpath
Definition: pg_backup.h:228
int maxRemoteVersion
Definition: pg_backup.h:218
int n_errors
Definition: pg_backup.h:233
bool std_strings
Definition: pg_backup.h:225
int numWorkers
Definition: pg_backup.h:220
int encoding
Definition: pg_backup.h:224
int verbose
Definition: pg_backup.h:212
RestoreOptions * ropt
Definition: pg_backup.h:210
Oid tableoid
Definition: pg_backup.h:261
TocEntry ** te
Definition: parallel.h:59
int numWorkers
Definition: parallel.h:57
SimpleStringListCell * head
Definition: simple_list.h:42
ArchiverStage stage
RestorePass restorePass
ArchiveFormat format
struct _tocEntry * toc
DeClonePtrType DeClonePtr
struct _tocEntry * lastErrorTE
ReadExtraTocPtrType ReadExtraTocPtr
struct _tocEntry * currentTE
CustomOutPtrType CustomOutPtr
PGcancel *volatile connCancel
EndBlobPtrType EndBlobPtr