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