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