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