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