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