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