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