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