PostgreSQL Source Code  git master
pg_backup_archiver.c File Reference
#include "postgres_fe.h"
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include "parallel.h"
#include "pg_backup_archiver.h"
#include "pg_backup_db.h"
#include "pg_backup_utils.h"
#include "dumputils.h"
#include "fe_utils/string_utils.h"
#include "libpq/libpq-fs.h"
Include dependency graph for pg_backup_archiver.c:

Go to the source code of this file.

Data Structures

struct  _outputContext
 

Macros

#define TEXT_DUMP_HEADER   "--\n-- PostgreSQL database dump\n--\n\n"
 
#define TEXT_DUMPALL_HEADER   "--\n-- PostgreSQL database cluster dump\n--\n\n"
 

Typedefs

typedef struct _outputContext OutputContext
 

Functions

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, ArchiveHandle *AH)
 
static void _printTocEntry (ArchiveHandle *AH, TocEntry *te, bool isData)
 
static char * replace_line_endings (const char *str)
 
static void _doSetFixedOutputState (ArchiveHandle *AH)
 
static void _doSetSessionAuth (ArchiveHandle *AH, const char *user)
 
static void _doSetWithOids (ArchiveHandle *AH, const bool withOids)
 
static void _reconnectToDB (ArchiveHandle *AH, const char *dbname)
 
static void _becomeUser (ArchiveHandle *AH, const char *user)
 
static void _becomeOwner (ArchiveHandle *AH, TocEntry *te)
 
static void _selectOutputSchema (ArchiveHandle *AH, const char *schemaName)
 
static void _selectTablespace (ArchiveHandle *AH, const char *tablespace)
 
static void processEncodingEntry (ArchiveHandle *AH, TocEntry *te)
 
static void processStdStringsEntry (ArchiveHandle *AH, TocEntry *te)
 
static teReqs _tocEntryRequired (TocEntry *te, teSection curSection, RestoreOptions *ropt)
 
static RestorePass _tocEntryRestorePass (TocEntry *te)
 
static bool _tocEntryIsACL (TocEntry *te)
 
static void _disableTriggersIfNecessary (ArchiveHandle *AH, TocEntry *te)
 
static void _enableTriggersIfNecessary (ArchiveHandle *AH, TocEntry *te)
 
static void buildTocEntryArrays (ArchiveHandle *AH)
 
static void _moveBefore (ArchiveHandle *AH, TocEntry *pos, TocEntry *te)
 
static int _discoverArchiveFormat (ArchiveHandle *AH)
 
static int RestoringToDB (ArchiveHandle *AH)
 
static void dump_lo_buf (ArchiveHandle *AH)
 
static void dumpTimestamp (ArchiveHandle *AH, const char *msg, time_t tim)
 
static void SetOutput (ArchiveHandle *AH, const char *filename, int compression)
 
static OutputContext SaveOutput (ArchiveHandle *AH)
 
static void RestoreOutput (ArchiveHandle *AH, OutputContext savedContext)
 
static int restore_toc_entry (ArchiveHandle *AH, TocEntry *te, bool is_parallel)
 
static void restore_toc_entries_prefork (ArchiveHandle *AH, TocEntry *pending_list)
 
static void restore_toc_entries_parallel (ArchiveHandle *AH, ParallelState *pstate, TocEntry *pending_list)
 
static void restore_toc_entries_postfork (ArchiveHandle *AH, TocEntry *pending_list)
 
static void par_list_header_init (TocEntry *l)
 
static void par_list_append (TocEntry *l, TocEntry *te)
 
static void par_list_remove (TocEntry *te)
 
static void move_to_ready_list (TocEntry *pending_list, TocEntry *ready_list, RestorePass pass)
 
static TocEntryget_next_work_item (ArchiveHandle *AH, TocEntry *ready_list, ParallelState *pstate)
 
static void mark_dump_job_done (ArchiveHandle *AH, TocEntry *te, int status, void *callback_data)
 
static void mark_restore_job_done (ArchiveHandle *AH, TocEntry *te, int status, void *callback_data)
 
static void fix_dependencies (ArchiveHandle *AH)
 
static bool has_lock_conflicts (TocEntry *te1, TocEntry *te2)
 
static void repoint_table_dependencies (ArchiveHandle *AH)
 
static void identify_locking_dependencies (ArchiveHandle *AH, TocEntry *te)
 
static void reduce_dependencies (ArchiveHandle *AH, TocEntry *te, TocEntry *ready_list)
 
static void mark_create_done (ArchiveHandle *AH, TocEntry *te)
 
static void inhibit_data_for_failed_table (ArchiveHandle *AH, TocEntry *te)
 
static void StrictNamesCheck (RestoreOptions *ropt)
 
DumpOptionsNewDumpOptions (void)
 
void InitDumpOptions (DumpOptions *opts)
 
DumpOptionsdumpOptionsFromRestoreOptions (RestoreOptions *ropt)
 
static void setupRestoreWorker (Archive *AHX)
 
ArchiveCreateArchive (const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupDumpWorker)
 
ArchiveOpenArchive (const char *FileSpec, const ArchiveFormat fmt)
 
void CloseArchive (Archive *AHX)
 
void SetArchiveOptions (Archive *AH, DumpOptions *dopt, RestoreOptions *ropt)
 
void ProcessArchiveRestoreOptions (Archive *AHX)
 
void RestoreArchive (Archive *AHX)
 
RestoreOptionsNewRestoreOptions (void)
 
void WriteData (Archive *AHX, const void *data, size_t dLen)
 
void ArchiveEntry (Archive *AHX, CatalogId catalogId, DumpId dumpId, const char *tag, const char *namespace, const char *tablespace, const char *owner, bool withOids, const char *desc, teSection section, const char *defn, const char *dropStmt, const char *copyStmt, const DumpId *deps, int nDeps, DataDumperPtr dumpFn, void *dumpArg)
 
void PrintTOCSummary (Archive *AHX)
 
int StartBlob (Archive *AHX, Oid oid)
 
int EndBlob (Archive *AHX, Oid oid)
 
void StartRestoreBlobs (ArchiveHandle *AH)
 
void EndRestoreBlobs (ArchiveHandle *AH)
 
void StartRestoreBlob (ArchiveHandle *AH, Oid oid, bool drop)
 
void EndRestoreBlob (ArchiveHandle *AH, Oid oid)
 
void SortTocFromFile (Archive *AHX)
 
void archputs (const char *s, Archive *AH)
 
int archprintf (Archive *AH, const char *fmt,...)
 
int ahprintf (ArchiveHandle *AH, const char *fmt,...)
 
void ahlog (ArchiveHandle *AH, int level, const char *fmt,...)
 
void ahwrite (const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
 
void warn_or_exit_horribly (ArchiveHandle *AH, const char *modulename, const char *fmt,...)
 
TocEntrygetTocEntryByDumpId (ArchiveHandle *AH, DumpId id)
 
teReqs TocIDRequired (ArchiveHandle *AH, DumpId id)
 
size_t WriteOffset (ArchiveHandle *AH, pgoff_t o, int wasSet)
 
int ReadOffset (ArchiveHandle *AH, pgoff_t *o)
 
size_t WriteInt (ArchiveHandle *AH, int i)
 
int ReadInt (ArchiveHandle *AH)
 
size_t WriteStr (ArchiveHandle *AH, const char *c)
 
char * ReadStr (ArchiveHandle *AH)
 
void WriteDataChunks (ArchiveHandle *AH, ParallelState *pstate)
 
void WriteDataChunksForTocEntry (ArchiveHandle *AH, TocEntry *te)
 
void WriteToc (ArchiveHandle *AH)
 
void ReadToc (ArchiveHandle *AH)
 
static void _setWithOids (ArchiveHandle *AH, TocEntry *te)
 
void WriteHead (ArchiveHandle *AH)
 
void ReadHead (ArchiveHandle *AH)
 
bool checkSeek (FILE *fp)
 
int parallel_restore (ArchiveHandle *AH, TocEntry *te)
 
ArchiveHandleCloneArchive (ArchiveHandle *AH)
 
void DeCloneArchive (ArchiveHandle *AH)
 

Variables

static const char * modulename = gettext_noop("archiver")
 

Macro Definition Documentation

◆ TEXT_DUMP_HEADER

#define TEXT_DUMP_HEADER   "--\n-- PostgreSQL database dump\n--\n\n"

Definition at line 42 of file pg_backup_archiver.c.

Referenced by _discoverArchiveFormat().

◆ TEXT_DUMPALL_HEADER

#define TEXT_DUMPALL_HEADER   "--\n-- PostgreSQL database cluster dump\n--\n\n"

Definition at line 43 of file pg_backup_archiver.c.

Referenced by _discoverArchiveFormat().

Typedef Documentation

◆ OutputContext

Function Documentation

◆ _allocAH()

static ArchiveHandle * _allocAH ( const char *  FileSpec,
const ArchiveFormat  fmt,
const int  compression,
bool  dosync,
ArchiveMode  mode,
SetupWorkerPtrType  setupWorkerPtr 
)
static

Definition at line 2301 of file pg_backup_archiver.c.

References _discoverArchiveFormat(), archCustom, archDirectory, _archiveHandle::archiveDumpVersion, archModeWrite, archNull, archTar, archUnknown, _archiveHandle::compression, _archiveHandle::createDate, _archiveHandle::currSchema, _archiveHandle::currTablespace, _archiveHandle::currUser, _archiveHandle::currWithOids, dosync, _archiveHandle::dosync, Archive::encoding, exit_horribly(), Archive::exit_on_error, _archiveHandle::format, _archiveHandle::fSpec, _archiveHandle::gzOut, InitArchiveFmt_Custom(), InitArchiveFmt_Directory(), InitArchiveFmt_Null(), InitArchiveFmt_Tar(), _archiveHandle::intSize, K_VERS_SELF, _archiveHandle::mode, modulename, Archive::n_errors, _tocEntry::next, _archiveHandle::OF, _archiveHandle::offSize, pg_malloc0(), pg_strdup(), pgoff_t, _tocEntry::prev, _archiveHandle::promptPassword, _archiveHandle::public, _archiveHandle::SetupWorkerPtr, _archiveHandle::sqlparse, Archive::std_strings, _archiveHandle::toc, TRI_DEFAULT, _archiveHandle::version, and write_msg().

Referenced by CreateArchive(), and OpenArchive().

2304 {
2305  ArchiveHandle *AH;
2306 
2307 #if 0
2308  write_msg(modulename, "allocating AH for %s, format %d\n", FileSpec, fmt);
2309 #endif
2310 
2311  AH = (ArchiveHandle *) pg_malloc0(sizeof(ArchiveHandle));
2312 
2313  /* AH->debugLevel = 100; */
2314 
2315  AH->version = K_VERS_SELF;
2316 
2317  /* initialize for backwards compatible string processing */
2318  AH->public.encoding = 0; /* PG_SQL_ASCII */
2319  AH->public.std_strings = false;
2320 
2321  /* sql error handling */
2322  AH->public.exit_on_error = true;
2323  AH->public.n_errors = 0;
2324 
2325  AH->archiveDumpVersion = PG_VERSION;
2326 
2327  AH->createDate = time(NULL);
2328 
2329  AH->intSize = sizeof(int);
2330  AH->offSize = sizeof(pgoff_t);
2331  if (FileSpec)
2332  {
2333  AH->fSpec = pg_strdup(FileSpec);
2334 
2335  /*
2336  * Not used; maybe later....
2337  *
2338  * AH->workDir = pg_strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;
2339  * i--) if (AH->workDir[i-1] == '/')
2340  */
2341  }
2342  else
2343  AH->fSpec = NULL;
2344 
2345  AH->currUser = NULL; /* unknown */
2346  AH->currSchema = NULL; /* ditto */
2347  AH->currTablespace = NULL; /* ditto */
2348  AH->currWithOids = -1; /* force SET */
2349 
2350  AH->toc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2351 
2352  AH->toc->next = AH->toc;
2353  AH->toc->prev = AH->toc;
2354 
2355  AH->mode = mode;
2356  AH->compression = compression;
2357  AH->dosync = dosync;
2358 
2359  memset(&(AH->sqlparse), 0, sizeof(AH->sqlparse));
2360 
2361  /* Open stdout with no compression for AH output handle */
2362  AH->gzOut = 0;
2363  AH->OF = stdout;
2364 
2365  /*
2366  * On Windows, we need to use binary mode to read/write non-text files,
2367  * which include all archive formats as well as compressed plain text.
2368  * Force stdin/stdout into binary mode if that is what we are using.
2369  */
2370 #ifdef WIN32
2371  if ((fmt != archNull || compression != 0) &&
2372  (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0))
2373  {
2374  if (mode == archModeWrite)
2375  _setmode(fileno(stdout), O_BINARY);
2376  else
2377  _setmode(fileno(stdin), O_BINARY);
2378  }
2379 #endif
2380 
2381  AH->SetupWorkerPtr = setupWorkerPtr;
2382 
2383  if (fmt == archUnknown)
2384  AH->format = _discoverArchiveFormat(AH);
2385  else
2386  AH->format = fmt;
2387 
2389 
2390  switch (AH->format)
2391  {
2392  case archCustom:
2394  break;
2395 
2396  case archNull:
2397  InitArchiveFmt_Null(AH);
2398  break;
2399 
2400  case archDirectory:
2402  break;
2403 
2404  case archTar:
2405  InitArchiveFmt_Tar(AH);
2406  break;
2407 
2408  default:
2409  exit_horribly(modulename, "unrecognized file format \"%d\"\n", fmt);
2410  }
2411 
2412  return AH;
2413 }
struct _tocEntry * next
#define K_VERS_SELF
static bool dosync
Definition: pg_dump.c:94
void InitArchiveFmt_Tar(ArchiveHandle *AH)
int n_errors
Definition: pg_backup.h:202
int encoding
Definition: pg_backup.h:196
SetupWorkerPtrType SetupWorkerPtr
#define pgoff_t
Definition: win32_port.h:206
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
struct _tocEntry * toc
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
sqlparseInfo sqlparse
struct _tocEntry * prev
ArchiveFormat format
static int _discoverArchiveFormat(ArchiveHandle *AH)
void InitArchiveFmt_Directory(ArchiveHandle *AH)
void InitArchiveFmt_Null(ArchiveHandle *AH)
void InitArchiveFmt_Custom(ArchiveHandle *AH)
void write_msg(const char *modulename, const char *fmt,...)
void exit_horribly(const char *modulename, const char *fmt,...)
bool exit_on_error
Definition: pg_backup.h:201
static const char * modulename
bool std_strings
Definition: pg_backup.h:197

◆ _becomeOwner()

static void _becomeOwner ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 3207 of file pg_backup_archiver.c.

References _becomeUser(), _restoreOptions::noOwner, _tocEntry::owner, _archiveHandle::public, Archive::ropt, and _restoreOptions::use_setsessauth.

Referenced by _printTocEntry(), restore_toc_entry(), and RestoreArchive().

3208 {
3209  RestoreOptions *ropt = AH->public.ropt;
3210 
3211  if (ropt && (ropt->noOwner || !ropt->use_setsessauth))
3212  return;
3213 
3214  _becomeUser(AH, te->owner);
3215 }
RestoreOptions * ropt
Definition: pg_backup.h:182
static void _becomeUser(ArchiveHandle *AH, const char *user)
int use_setsessauth
Definition: pg_backup.h:68

◆ _becomeUser()

static void _becomeUser ( ArchiveHandle AH,
const char *  user 
)
static

Definition at line 3183 of file pg_backup_archiver.c.

References _doSetSessionAuth(), _archiveHandle::currUser, free, and pg_strdup().

Referenced by _becomeOwner(), _disableTriggersIfNecessary(), and _enableTriggersIfNecessary().

3184 {
3185  if (!user)
3186  user = ""; /* avoid null pointers */
3187 
3188  if (AH->currUser && strcmp(AH->currUser, user) == 0)
3189  return; /* no need to do anything */
3190 
3191  _doSetSessionAuth(AH, user);
3192 
3193  /*
3194  * NOTE: currUser keeps track of what the imaginary session user in our
3195  * script is
3196  */
3197  if (AH->currUser)
3198  free(AH->currUser);
3199  AH->currUser = pg_strdup(user);
3200 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void _doSetSessionAuth(ArchiveHandle *AH, const char *user)
#define free(a)
Definition: header.h:65
static char * user
Definition: pg_regress.c:93

◆ _disableTriggersIfNecessary()

static void _disableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 973 of file pg_backup_archiver.c.

References _becomeUser(), _selectOutputSchema(), ahlog(), ahprintf(), _restoreOptions::dataOnly, _restoreOptions::disable_triggers, fmtId(), _archiveHandle::public, Archive::ropt, _restoreOptions::superuser, and _tocEntry::tag.

Referenced by restore_toc_entry().

974 {
975  RestoreOptions *ropt = AH->public.ropt;
976 
977  /* This hack is only needed in a data-only restore */
978  if (!ropt->dataOnly || !ropt->disable_triggers)
979  return;
980 
981  ahlog(AH, 1, "disabling triggers for %s\n", te->tag);
982 
983  /*
984  * Become superuser if possible, since they are the only ones who can
985  * disable constraint triggers. If -S was not given, assume the initial
986  * user identity is a superuser. (XXX would it be better to become the
987  * table owner?)
988  */
989  _becomeUser(AH, ropt->superuser);
990 
991  /*
992  * Disable them.
993  */
994  _selectOutputSchema(AH, te->namespace);
995 
996  ahprintf(AH, "ALTER TABLE %s DISABLE TRIGGER ALL;\n\n",
997  fmtId(te->tag));
998 }
RestoreOptions * ropt
Definition: pg_backup.h:182
static void _becomeUser(ArchiveHandle *AH, const char *user)
const char * fmtId(const char *rawid)
Definition: string_utils.c:66
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
char * superuser
Definition: pg_backup.h:70
static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
int disable_triggers
Definition: pg_backup.h:66

◆ _discoverArchiveFormat()

static int _discoverArchiveFormat ( ArchiveHandle AH)
static

Definition at line 2096 of file pg_backup_archiver.c.

References archDirectory, archTar, buf, exit_horribly(), _archiveHandle::format, free, fseeko, _archiveHandle::fSpec, _archiveHandle::intSize, isValidTarHeader(), K_VERS_1_7, _archiveHandle::lookahead, _archiveHandle::lookaheadLen, _archiveHandle::lookaheadPos, _archiveHandle::lookaheadSize, MAKE_ARCHIVE_VERSION, MAXPGPATH, modulename, _archiveHandle::offSize, PG_BINARY_R, pg_malloc0(), READ_ERROR_EXIT, _archiveHandle::readHeader, S_ISDIR, S_ISREG, sig, snprintf(), stat, strerror(), TEXT_DUMP_HEADER, TEXT_DUMPALL_HEADER, _archiveHandle::version, and write_msg().

Referenced by _allocAH().

2097 {
2098  FILE *fh;
2099  char sig[6]; /* More than enough */
2100  size_t cnt;
2101  int wantClose = 0;
2102 
2103 #if 0
2104  write_msg(modulename, "attempting to ascertain archive format\n");
2105 #endif
2106 
2107  if (AH->lookahead)
2108  free(AH->lookahead);
2109 
2110  AH->lookaheadSize = 512;
2111  AH->lookahead = pg_malloc0(512);
2112  AH->lookaheadLen = 0;
2113  AH->lookaheadPos = 0;
2114 
2115  if (AH->fSpec)
2116  {
2117  struct stat st;
2118 
2119  wantClose = 1;
2120 
2121  /*
2122  * Check if the specified archive is a directory. If so, check if
2123  * there's a "toc.dat" (or "toc.dat.gz") file in it.
2124  */
2125  if (stat(AH->fSpec, &st) == 0 && S_ISDIR(st.st_mode))
2126  {
2127  char buf[MAXPGPATH];
2128 
2129  if (snprintf(buf, MAXPGPATH, "%s/toc.dat", AH->fSpec) >= MAXPGPATH)
2130  exit_horribly(modulename, "directory name too long: \"%s\"\n",
2131  AH->fSpec);
2132  if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
2133  {
2134  AH->format = archDirectory;
2135  return AH->format;
2136  }
2137 
2138 #ifdef HAVE_LIBZ
2139  if (snprintf(buf, MAXPGPATH, "%s/toc.dat.gz", AH->fSpec) >= MAXPGPATH)
2140  exit_horribly(modulename, "directory name too long: \"%s\"\n",
2141  AH->fSpec);
2142  if (stat(buf, &st) == 0 && S_ISREG(st.st_mode))
2143  {
2144  AH->format = archDirectory;
2145  return AH->format;
2146  }
2147 #endif
2148  exit_horribly(modulename, "directory \"%s\" does not appear to be a valid archive (\"toc.dat\" does not exist)\n",
2149  AH->fSpec);
2150  fh = NULL; /* keep compiler quiet */
2151  }
2152  else
2153  {
2154  fh = fopen(AH->fSpec, PG_BINARY_R);
2155  if (!fh)
2156  exit_horribly(modulename, "could not open input file \"%s\": %s\n",
2157  AH->fSpec, strerror(errno));
2158  }
2159  }
2160  else
2161  {
2162  fh = stdin;
2163  if (!fh)
2164  exit_horribly(modulename, "could not open input file: %s\n",
2165  strerror(errno));
2166  }
2167 
2168  if ((cnt = fread(sig, 1, 5, fh)) != 5)
2169  {
2170  if (ferror(fh))
2171  exit_horribly(modulename, "could not read input file: %s\n", strerror(errno));
2172  else
2173  exit_horribly(modulename, "input file is too short (read %lu, expected 5)\n",
2174  (unsigned long) cnt);
2175  }
2176 
2177  /* Save it, just in case we need it later */
2178  memcpy(&AH->lookahead[0], sig, 5);
2179  AH->lookaheadLen = 5;
2180 
2181  if (strncmp(sig, "PGDMP", 5) == 0)
2182  {
2183  int byteread;
2184  char vmaj,
2185  vmin,
2186  vrev;
2187 
2188  /*
2189  * Finish reading (most of) a custom-format header.
2190  *
2191  * NB: this code must agree with ReadHead().
2192  */
2193  if ((byteread = fgetc(fh)) == EOF)
2194  READ_ERROR_EXIT(fh);
2195 
2196  vmaj = byteread;
2197 
2198  if ((byteread = fgetc(fh)) == EOF)
2199  READ_ERROR_EXIT(fh);
2200 
2201  vmin = byteread;
2202 
2203  /* Save these too... */
2204  AH->lookahead[AH->lookaheadLen++] = vmaj;
2205  AH->lookahead[AH->lookaheadLen++] = vmin;
2206 
2207  /* Check header version; varies from V1.0 */
2208  if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */
2209  {
2210  if ((byteread = fgetc(fh)) == EOF)
2211  READ_ERROR_EXIT(fh);
2212 
2213  vrev = byteread;
2214  AH->lookahead[AH->lookaheadLen++] = vrev;
2215  }
2216  else
2217  vrev = 0;
2218 
2219  AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev);
2220 
2221  if ((AH->intSize = fgetc(fh)) == EOF)
2222  READ_ERROR_EXIT(fh);
2223  AH->lookahead[AH->lookaheadLen++] = AH->intSize;
2224 
2225  if (AH->version >= K_VERS_1_7)
2226  {
2227  if ((AH->offSize = fgetc(fh)) == EOF)
2228  READ_ERROR_EXIT(fh);
2229  AH->lookahead[AH->lookaheadLen++] = AH->offSize;
2230  }
2231  else
2232  AH->offSize = AH->intSize;
2233 
2234  if ((byteread = fgetc(fh)) == EOF)
2235  READ_ERROR_EXIT(fh);
2236 
2237  AH->format = byteread;
2238  AH->lookahead[AH->lookaheadLen++] = AH->format;
2239  }
2240  else
2241  {
2242  /*
2243  * *Maybe* we have a tar archive format file or a text dump ... So,
2244  * read first 512 byte header...
2245  */
2246  cnt = fread(&AH->lookahead[AH->lookaheadLen], 1, 512 - AH->lookaheadLen, fh);
2247  /* read failure is checked below */
2248  AH->lookaheadLen += cnt;
2249 
2250  if (AH->lookaheadLen >= strlen(TEXT_DUMPALL_HEADER) &&
2251  (strncmp(AH->lookahead, TEXT_DUMP_HEADER, strlen(TEXT_DUMP_HEADER)) == 0 ||
2252  strncmp(AH->lookahead, TEXT_DUMPALL_HEADER, strlen(TEXT_DUMPALL_HEADER)) == 0))
2253  {
2254  /*
2255  * looks like it's probably a text format dump. so suggest they
2256  * try psql
2257  */
2258  exit_horribly(modulename, "input file appears to be a text format dump. Please use psql.\n");
2259  }
2260 
2261  if (AH->lookaheadLen != 512)
2262  {
2263  if (feof(fh))
2264  exit_horribly(modulename, "input file does not appear to be a valid archive (too short?)\n");
2265  else
2266  READ_ERROR_EXIT(fh);
2267  }
2268 
2269  if (!isValidTarHeader(AH->lookahead))
2270  exit_horribly(modulename, "input file does not appear to be a valid archive\n");
2271 
2272  AH->format = archTar;
2273  }
2274 
2275  /* If we can't seek, then mark the header as read */
2276  if (fseeko(fh, 0, SEEK_SET) != 0)
2277  {
2278  /*
2279  * NOTE: Formats that use the lookahead buffer can unset this in their
2280  * Init routine.
2281  */
2282  AH->readHeader = 1;
2283  }
2284  else
2285  AH->lookaheadLen = 0; /* Don't bother since we've reset the file */
2286 
2287  /* Close the file */
2288  if (wantClose)
2289  if (fclose(fh) != 0)
2290  exit_horribly(modulename, "could not close input file: %s\n",
2291  strerror(errno));
2292 
2293  return AH->format;
2294 }
#define TEXT_DUMP_HEADER
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
bool isValidTarHeader(char *header)
#define PG_BINARY_R
Definition: c.h:1051
#define K_VERS_1_7
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define MAXPGPATH
#define MAKE_ARCHIVE_VERSION(major, minor, rev)
static char * buf
Definition: pg_test_fsync.c:67
#define S_ISREG(m)
Definition: win32_port.h:310
#define stat(a, b)
Definition: win32_port.h:266
ArchiveFormat format
#define TEXT_DUMPALL_HEADER
static int sig
Definition: pg_ctl.c:80
#define fseeko(stream, offset, origin)
Definition: win32_port.h:212
#define free(a)
Definition: header.h:65
void write_msg(const char *modulename, const char *fmt,...)
#define S_ISDIR(m)
Definition: win32_port.h:307
void exit_horribly(const char *modulename, const char *fmt,...)
const char * strerror(int errnum)
Definition: strerror.c:19
#define READ_ERROR_EXIT(fd)
static const char * modulename

◆ _doSetFixedOutputState()

static void _doSetFixedOutputState ( ArchiveHandle AH)
static

Definition at line 3014 of file pg_backup_archiver.c.

References ahprintf(), _restoreOptions::enable_row_security, Archive::encoding, fmtId(), pg_encoding_to_char(), _archiveHandle::public, Archive::ropt, Archive::std_strings, and _restoreOptions::use_role.

Referenced by _reconnectToDB(), CloneArchive(), restore_toc_entries_postfork(), and RestoreArchive().

3015 {
3016  RestoreOptions *ropt = AH->public.ropt;
3017 
3018  /*
3019  * Disable timeouts to allow for slow commands, idle parallel workers, etc
3020  */
3021  ahprintf(AH, "SET statement_timeout = 0;\n");
3022  ahprintf(AH, "SET lock_timeout = 0;\n");
3023  ahprintf(AH, "SET idle_in_transaction_session_timeout = 0;\n");
3024 
3025  /* Select the correct character set encoding */
3026  ahprintf(AH, "SET client_encoding = '%s';\n",
3028 
3029  /* Select the correct string literal syntax */
3030  ahprintf(AH, "SET standard_conforming_strings = %s;\n",
3031  AH->public.std_strings ? "on" : "off");
3032 
3033  /* Select the role to be used during restore */
3034  if (ropt && ropt->use_role)
3035  ahprintf(AH, "SET ROLE %s;\n", fmtId(ropt->use_role));
3036 
3037  /* Make sure function checking is disabled */
3038  ahprintf(AH, "SET check_function_bodies = false;\n");
3039 
3040  /* Avoid annoying notices etc */
3041  ahprintf(AH, "SET client_min_messages = warning;\n");
3042  if (!AH->public.std_strings)
3043  ahprintf(AH, "SET escape_string_warning = off;\n");
3044 
3045  /* Adjust row-security state */
3046  if (ropt && ropt->enable_row_security)
3047  ahprintf(AH, "SET row_security = on;\n");
3048  else
3049  ahprintf(AH, "SET row_security = off;\n");
3050 
3051  ahprintf(AH, "\n");
3052 }
RestoreOptions * ropt
Definition: pg_backup.h:182
const char * fmtId(const char *rawid)
Definition: string_utils.c:66
char * use_role
Definition: pg_backup.h:71
int encoding
Definition: pg_backup.h:196
int enable_row_security
Definition: pg_backup.h:122
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:607
bool std_strings
Definition: pg_backup.h:197

◆ _doSetSessionAuth()

static void _doSetSessionAuth ( ArchiveHandle AH,
const char *  user 
)
static

Definition at line 3060 of file pg_backup_archiver.c.

References ahprintf(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendStringLiteralAHX, _archiveHandle::connection, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), exit_horribly(), modulename, PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQexec(), PQresultStatus(), and RestoringToDB().

Referenced by _becomeUser().

3061 {
3063 
3064  appendPQExpBufferStr(cmd, "SET SESSION AUTHORIZATION ");
3065 
3066  /*
3067  * SQL requires a string literal here. Might as well be correct.
3068  */
3069  if (user && *user)
3070  appendStringLiteralAHX(cmd, user, AH);
3071  else
3072  appendPQExpBufferStr(cmd, "DEFAULT");
3073  appendPQExpBufferChar(cmd, ';');
3074 
3075  if (RestoringToDB(AH))
3076  {
3077  PGresult *res;
3078 
3079  res = PQexec(AH->connection, cmd->data);
3080 
3081  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3082  /* NOT warn_or_exit_horribly... use -O instead to skip this. */
3083  exit_horribly(modulename, "could not set session user to \"%s\": %s",
3085 
3086  PQclear(res);
3087  }
3088  else
3089  ahprintf(AH, "%s\n\n", cmd->data);
3090 
3091  destroyPQExpBuffer(cmd);
3092 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6115
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
void PQclear(PGresult *res)
Definition: fe-exec.c:671
#define appendStringLiteralAHX(buf, str, AH)
void exit_horribly(const char *modulename, const char *fmt,...)
static char * user
Definition: pg_regress.c:93
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
static const char * modulename

◆ _doSetWithOids()

static void _doSetWithOids ( ArchiveHandle AH,
const bool  withOids 
)
static

Definition at line 3100 of file pg_backup_archiver.c.

References ahprintf(), appendPQExpBuffer(), _archiveHandle::connection, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), modulename, PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQexec(), PQresultStatus(), RestoringToDB(), and warn_or_exit_horribly().

Referenced by _setWithOids().

3101 {
3103 
3104  appendPQExpBuffer(cmd, "SET default_with_oids = %s;", withOids ?
3105  "true" : "false");
3106 
3107  if (RestoringToDB(AH))
3108  {
3109  PGresult *res;
3110 
3111  res = PQexec(AH->connection, cmd->data);
3112 
3113  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3115  "could not set default_with_oids: %s",
3116  PQerrorMessage(AH->connection));
3117 
3118  PQclear(res);
3119  }
3120  else
3121  ahprintf(AH, "%s\n\n", cmd->data);
3122 
3123  destroyPQExpBuffer(cmd);
3124 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6115
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
void warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
void PQclear(PGresult *res)
Definition: fe-exec.c:671
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
static const char * modulename

◆ _enableTriggersIfNecessary()

static void _enableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 1001 of file pg_backup_archiver.c.

References _becomeUser(), _selectOutputSchema(), ahlog(), ahprintf(), _restoreOptions::dataOnly, _restoreOptions::disable_triggers, fmtId(), _archiveHandle::public, Archive::ropt, _restoreOptions::superuser, and _tocEntry::tag.

Referenced by restore_toc_entry().

1002 {
1003  RestoreOptions *ropt = AH->public.ropt;
1004 
1005  /* This hack is only needed in a data-only restore */
1006  if (!ropt->dataOnly || !ropt->disable_triggers)
1007  return;
1008 
1009  ahlog(AH, 1, "enabling triggers for %s\n", te->tag);
1010 
1011  /*
1012  * Become superuser if possible, since they are the only ones who can
1013  * disable constraint triggers. If -S was not given, assume the initial
1014  * user identity is a superuser. (XXX would it be better to become the
1015  * table owner?)
1016  */
1017  _becomeUser(AH, ropt->superuser);
1018 
1019  /*
1020  * Enable them.
1021  */
1022  _selectOutputSchema(AH, te->namespace);
1023 
1024  ahprintf(AH, "ALTER TABLE %s ENABLE TRIGGER ALL;\n\n",
1025  fmtId(te->tag));
1026 }
RestoreOptions * ropt
Definition: pg_backup.h:182
static void _becomeUser(ArchiveHandle *AH, const char *user)
const char * fmtId(const char *rawid)
Definition: string_utils.c:66
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
char * superuser
Definition: pg_backup.h:70
static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
int disable_triggers
Definition: pg_backup.h:66

◆ _getObjectDescription()

static void _getObjectDescription ( PQExpBuffer  buf,
TocEntry te,
ArchiveHandle AH 
)
static

Definition at line 3343 of file pg_backup_archiver.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), _tocEntry::desc, _tocEntry::dropStmt, fmtId(), free, modulename, pg_strdup(), _tocEntry::tag, generate_unaccent_rules::type, and write_msg().

Referenced by _printTocEntry().

3344 {
3345  const char *type = te->desc;
3346 
3347  /* Use ALTER TABLE for views and sequences */
3348  if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0 ||
3349  strcmp(type, "MATERIALIZED VIEW") == 0)
3350  type = "TABLE";
3351 
3352  /* objects that don't require special decoration */
3353  if (strcmp(type, "COLLATION") == 0 ||
3354  strcmp(type, "CONVERSION") == 0 ||
3355  strcmp(type, "DOMAIN") == 0 ||
3356  strcmp(type, "TABLE") == 0 ||
3357  strcmp(type, "TYPE") == 0 ||
3358  strcmp(type, "FOREIGN TABLE") == 0 ||
3359  strcmp(type, "TEXT SEARCH DICTIONARY") == 0 ||
3360  strcmp(type, "TEXT SEARCH CONFIGURATION") == 0 ||
3361  /* non-schema-specified objects */
3362  strcmp(type, "DATABASE") == 0 ||
3363  strcmp(type, "PROCEDURAL LANGUAGE") == 0 ||
3364  strcmp(type, "SCHEMA") == 0 ||
3365  strcmp(type, "EVENT TRIGGER") == 0 ||
3366  strcmp(type, "FOREIGN DATA WRAPPER") == 0 ||
3367  strcmp(type, "SERVER") == 0 ||
3368  strcmp(type, "PUBLICATION") == 0 ||
3369  strcmp(type, "SUBSCRIPTION") == 0 ||
3370  strcmp(type, "USER MAPPING") == 0)
3371  {
3372  /* We already know that search_path was set properly */
3373  appendPQExpBuffer(buf, "%s %s", type, fmtId(te->tag));
3374  return;
3375  }
3376 
3377  /* BLOBs just have a name, but it's numeric so must not use fmtId */
3378  if (strcmp(type, "BLOB") == 0)
3379  {
3380  appendPQExpBuffer(buf, "LARGE OBJECT %s", te->tag);
3381  return;
3382  }
3383 
3384  /*
3385  * These object types require additional decoration. Fortunately, the
3386  * information needed is exactly what's in the DROP command.
3387  */
3388  if (strcmp(type, "AGGREGATE") == 0 ||
3389  strcmp(type, "FUNCTION") == 0 ||
3390  strcmp(type, "OPERATOR") == 0 ||
3391  strcmp(type, "OPERATOR CLASS") == 0 ||
3392  strcmp(type, "OPERATOR FAMILY") == 0 ||
3393  strcmp(type, "PROCEDURE") == 0)
3394  {
3395  /* Chop "DROP " off the front and make a modifiable copy */
3396  char *first = pg_strdup(te->dropStmt + 5);
3397  char *last;
3398 
3399  /* point to last character in string */
3400  last = first + strlen(first) - 1;
3401 
3402  /* Strip off any ';' or '\n' at the end */
3403  while (last >= first && (*last == '\n' || *last == ';'))
3404  last--;
3405  *(last + 1) = '\0';
3406 
3407  appendPQExpBufferStr(buf, first);
3408 
3409  free(first);
3410  return;
3411  }
3412 
3413  write_msg(modulename, "WARNING: don't know how to set owner for object type \"%s\"\n",
3414  type);
3415 }
const char * fmtId(const char *rawid)
Definition: string_utils.c:66
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
#define free(a)
Definition: header.h:65
void write_msg(const char *modulename, const char *fmt,...)
static const char * modulename

◆ _moveBefore()

static void _moveBefore ( ArchiveHandle AH,
TocEntry pos,
TocEntry te 
)
static

Definition at line 1828 of file pg_backup_archiver.c.

References _tocEntry::next, and _tocEntry::prev.

Referenced by SortTocFromFile().

1829 {
1830  /* Unlink te from list */
1831  te->prev->next = te->next;
1832  te->next->prev = te->prev;
1833 
1834  /* and insert it before "pos" */
1835  te->prev = pos->prev;
1836  te->next = pos;
1837  pos->prev->next = te;
1838  pos->prev = te;
1839 }
struct _tocEntry * next
struct _tocEntry * prev

◆ _printTocEntry()

static void _printTocEntry ( ArchiveHandle AH,
TocEntry te,
bool  isData 
)
static

Definition at line 3425 of file pg_backup_archiver.c.

References _becomeOwner(), _getObjectDescription(), _selectOutputSchema(), _selectTablespace(), _setWithOids(), _tocEntryIsACL(), ahprintf(), appendPQExpBuffer(), appendPQExpBufferStr(), _tocEntry::catalogId, _restoreOptions::createDB, createPQExpBuffer(), _archiveHandle::currUser, PQExpBufferData::data, _tocEntry::defn, _tocEntry::dependencies, _tocEntry::desc, destroyPQExpBuffer(), _restoreOptions::dropSchema, _tocEntry::dropStmt, _tocEntry::dumpId, fmtId(), free, i, modulename, _tocEntry::nDeps, _restoreOptions::noOwner, _restoreOptions::noTablespace, _archiveHandle::noTocComments, CatalogId::oid, _tocEntry::owner, pg_strdup(), _archiveHandle::PrintExtraTocPtr, _archiveHandle::public, replace_line_endings(), Archive::ropt, CatalogId::tableoid, _tocEntry::tablespace, _tocEntry::tag, _restoreOptions::use_setsessauth, Archive::verbose, and write_msg().

Referenced by restore_toc_entry().

3426 {
3427  RestoreOptions *ropt = AH->public.ropt;
3428 
3429  /*
3430  * Avoid dumping the public schema, as it will already be created ...
3431  * unless we are using --clean mode (and *not* --create mode), in which
3432  * case we've previously issued a DROP for it so we'd better recreate it.
3433  *
3434  * Likewise for its comment, if any. (We could try issuing the COMMENT
3435  * command anyway; but it'd fail if the restore is done as non-super-user,
3436  * so let's not.)
3437  *
3438  * XXX it looks pretty ugly to hard-wire the public schema like this, but
3439  * it sits in a sort of no-mans-land between being a system object and a
3440  * user object, so it really is special in a way.
3441  */
3442  if (!(ropt->dropSchema && !ropt->createDB))
3443  {
3444  if (strcmp(te->desc, "SCHEMA") == 0 &&
3445  strcmp(te->tag, "public") == 0)
3446  return;
3447  if (strcmp(te->desc, "COMMENT") == 0 &&
3448  strcmp(te->tag, "SCHEMA public") == 0)
3449  return;
3450  }
3451 
3452  /* Select owner, schema, and tablespace as necessary */
3453  _becomeOwner(AH, te);
3454  _selectOutputSchema(AH, te->namespace);
3455  _selectTablespace(AH, te->tablespace);
3456 
3457  /* Set up OID mode too */
3458  if (strcmp(te->desc, "TABLE") == 0)
3459  _setWithOids(AH, te);
3460 
3461  /* Emit header comment for item */
3462  if (!AH->noTocComments)
3463  {
3464  const char *pfx;
3465  char *sanitized_name;
3466  char *sanitized_schema;
3467  char *sanitized_owner;
3468 
3469  if (isData)
3470  pfx = "Data for ";
3471  else
3472  pfx = "";
3473 
3474  ahprintf(AH, "--\n");
3475  if (AH->public.verbose)
3476  {
3477  ahprintf(AH, "-- TOC entry %d (class %u OID %u)\n",
3478  te->dumpId, te->catalogId.tableoid, te->catalogId.oid);
3479  if (te->nDeps > 0)
3480  {
3481  int i;
3482 
3483  ahprintf(AH, "-- Dependencies:");
3484  for (i = 0; i < te->nDeps; i++)
3485  ahprintf(AH, " %d", te->dependencies[i]);
3486  ahprintf(AH, "\n");
3487  }
3488  }
3489 
3490  /*
3491  * Zap any line endings embedded in user-supplied fields, to prevent
3492  * corruption of the dump (which could, in the worst case, present an
3493  * SQL injection vulnerability if someone were to incautiously load a
3494  * dump containing objects with maliciously crafted names).
3495  */
3496  sanitized_name = replace_line_endings(te->tag);
3497  if (te->namespace)
3498  sanitized_schema = replace_line_endings(te->namespace);
3499  else
3500  sanitized_schema = pg_strdup("-");
3501  if (!ropt->noOwner)
3502  sanitized_owner = replace_line_endings(te->owner);
3503  else
3504  sanitized_owner = pg_strdup("-");
3505 
3506  ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
3507  pfx, sanitized_name, te->desc, sanitized_schema,
3508  sanitized_owner);
3509 
3510  free(sanitized_name);
3511  free(sanitized_schema);
3512  free(sanitized_owner);
3513 
3514  if (te->tablespace && strlen(te->tablespace) > 0 && !ropt->noTablespace)
3515  {
3516  char *sanitized_tablespace;
3517 
3518  sanitized_tablespace = replace_line_endings(te->tablespace);
3519  ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
3520  free(sanitized_tablespace);
3521  }
3522  ahprintf(AH, "\n");
3523 
3524  if (AH->PrintExtraTocPtr != NULL)
3525  AH->PrintExtraTocPtr(AH, te);
3526  ahprintf(AH, "--\n\n");
3527  }
3528 
3529  /*
3530  * Actually print the definition.
3531  *
3532  * Really crude hack for suppressing AUTHORIZATION clause that old pg_dump
3533  * versions put into CREATE SCHEMA. We have to do this when --no-owner
3534  * mode is selected. This is ugly, but I see no other good way ...
3535  */
3536  if (ropt->noOwner && strcmp(te->desc, "SCHEMA") == 0)
3537  {
3538  ahprintf(AH, "CREATE SCHEMA %s;\n\n\n", fmtId(te->tag));
3539  }
3540  else
3541  {
3542  if (strlen(te->defn) > 0)
3543  ahprintf(AH, "%s\n\n", te->defn);
3544  }
3545 
3546  /*
3547  * If we aren't using SET SESSION AUTH to determine ownership, we must
3548  * instead issue an ALTER OWNER command. We assume that anything without
3549  * a DROP command is not a separately ownable object. All the categories
3550  * with DROP commands must appear in one list or the other.
3551  */
3552  if (!ropt->noOwner && !ropt->use_setsessauth &&
3553  strlen(te->owner) > 0 && strlen(te->dropStmt) > 0)
3554  {
3555  if (strcmp(te->desc, "AGGREGATE") == 0 ||
3556  strcmp(te->desc, "BLOB") == 0 ||
3557  strcmp(te->desc, "COLLATION") == 0 ||
3558  strcmp(te->desc, "CONVERSION") == 0 ||
3559  strcmp(te->desc, "DATABASE") == 0 ||
3560  strcmp(te->desc, "DOMAIN") == 0 ||
3561  strcmp(te->desc, "FUNCTION") == 0 ||
3562  strcmp(te->desc, "OPERATOR") == 0 ||
3563  strcmp(te->desc, "OPERATOR CLASS") == 0 ||
3564  strcmp(te->desc, "OPERATOR FAMILY") == 0 ||
3565  strcmp(te->desc, "PROCEDURE") == 0 ||
3566  strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 ||
3567  strcmp(te->desc, "SCHEMA") == 0 ||
3568  strcmp(te->desc, "EVENT TRIGGER") == 0 ||
3569  strcmp(te->desc, "TABLE") == 0 ||
3570  strcmp(te->desc, "TYPE") == 0 ||
3571  strcmp(te->desc, "VIEW") == 0 ||
3572  strcmp(te->desc, "MATERIALIZED VIEW") == 0 ||
3573  strcmp(te->desc, "SEQUENCE") == 0 ||
3574  strcmp(te->desc, "FOREIGN TABLE") == 0 ||
3575  strcmp(te->desc, "TEXT SEARCH DICTIONARY") == 0 ||
3576  strcmp(te->desc, "TEXT SEARCH CONFIGURATION") == 0 ||
3577  strcmp(te->desc, "FOREIGN DATA WRAPPER") == 0 ||
3578  strcmp(te->desc, "SERVER") == 0 ||
3579  strcmp(te->desc, "PUBLICATION") == 0 ||
3580  strcmp(te->desc, "SUBSCRIPTION") == 0)
3581  {
3582  PQExpBuffer temp = createPQExpBuffer();
3583 
3584  appendPQExpBufferStr(temp, "ALTER ");
3585  _getObjectDescription(temp, te, AH);
3586  appendPQExpBuffer(temp, " OWNER TO %s;", fmtId(te->owner));
3587  ahprintf(AH, "%s\n\n", temp->data);
3588  destroyPQExpBuffer(temp);
3589  }
3590  else if (strcmp(te->desc, "CAST") == 0 ||
3591  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
3592  strcmp(te->desc, "CONSTRAINT") == 0 ||
3593  strcmp(te->desc, "DEFAULT") == 0 ||
3594  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
3595  strcmp(te->desc, "INDEX") == 0 ||
3596  strcmp(te->desc, "RULE") == 0 ||
3597  strcmp(te->desc, "TRIGGER") == 0 ||
3598  strcmp(te->desc, "ROW SECURITY") == 0 ||
3599  strcmp(te->desc, "POLICY") == 0 ||
3600  strcmp(te->desc, "USER MAPPING") == 0 ||
3601  strcmp(te->desc, "STATISTICS") == 0)
3602  {
3603  /* these object types don't have separate owners */
3604  }
3605  else
3606  {
3607  write_msg(modulename, "WARNING: don't know how to set owner for object type \"%s\"\n",
3608  te->desc);
3609  }
3610  }
3611 
3612  /*
3613  * If it's an ACL entry, it might contain SET SESSION AUTHORIZATION
3614  * commands, so we can no longer assume we know the current auth setting.
3615  */
3616  if (_tocEntryIsACL(te))
3617  {
3618  if (AH->currUser)
3619  free(AH->currUser);
3620  AH->currUser = NULL;
3621  }
3622 }
Oid tableoid
Definition: pg_backup.h:226
RestoreOptions * ropt
Definition: pg_backup.h:182
const char * fmtId(const char *rawid)
Definition: string_utils.c:66
CatalogId catalogId
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
static bool _tocEntryIsACL(TocEntry *te)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * replace_line_endings(const char *str)
DumpId * dependencies
static void _setWithOids(ArchiveHandle *AH, TocEntry *te)
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void _becomeOwner(ArchiveHandle *AH, TocEntry *te)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
int use_setsessauth
Definition: pg_backup.h:68
int verbose
Definition: pg_backup.h:184
#define free(a)
Definition: header.h:65
void write_msg(const char *modulename, const char *fmt,...)
static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
int i
PrintExtraTocPtrType PrintExtraTocPtr
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
static const char * modulename
static void _selectTablespace(ArchiveHandle *AH, const char *tablespace)

◆ _reconnectToDB()

static void _reconnectToDB ( ArchiveHandle AH,
const char *  dbname 
)
static

Definition at line 3137 of file pg_backup_archiver.c.

References _doSetFixedOutputState(), ahprintf(), appendPsqlMetaConnect(), _archiveHandle::currSchema, _archiveHandle::currTablespace, _archiveHandle::currUser, _archiveHandle::currWithOids, PQExpBufferData::data, free, initPQExpBuffer(), ReconnectToServer(), RestoringToDB(), and termPQExpBuffer().

Referenced by restore_toc_entry().

3138 {
3139  if (RestoringToDB(AH))
3140  ReconnectToServer(AH, dbname, NULL);
3141  else
3142  {
3143  if (dbname)
3144  {
3145  PQExpBufferData connectbuf;
3146 
3147  initPQExpBuffer(&connectbuf);
3148  appendPsqlMetaConnect(&connectbuf, dbname);
3149  ahprintf(AH, "%s\n", connectbuf.data);
3150  termPQExpBuffer(&connectbuf);
3151  }
3152  else
3153  ahprintf(AH, "%s\n", "\\connect -\n");
3154  }
3155 
3156  /*
3157  * NOTE: currUser keeps track of what the imaginary session user in our
3158  * script is. It's now effectively reset to the original userID.
3159  */
3160  if (AH->currUser)
3161  free(AH->currUser);
3162  AH->currUser = NULL;
3163 
3164  /* don't assume we still know the output schema, tablespace, etc either */
3165  if (AH->currSchema)
3166  free(AH->currSchema);
3167  AH->currSchema = NULL;
3168  if (AH->currTablespace)
3169  free(AH->currTablespace);
3170  AH->currTablespace = NULL;
3171  AH->currWithOids = -1;
3172 
3173  /* re-establish fixed state */
3175 }
static int RestoringToDB(ArchiveHandle *AH)
int ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser)
Definition: pg_backup_db.c:86
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
Definition: string_utils.c:596
static void _doSetFixedOutputState(ArchiveHandle *AH)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define free(a)
Definition: header.h:65
char * dbname
Definition: streamutil.c:42
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89

◆ _selectOutputSchema()

static void _selectOutputSchema ( ArchiveHandle AH,
const char *  schemaName 
)
static

Definition at line 3237 of file pg_backup_archiver.c.

References ahprintf(), appendPQExpBuffer(), appendPQExpBufferStr(), _archiveHandle::connection, createPQExpBuffer(), _archiveHandle::currSchema, PQExpBufferData::data, destroyPQExpBuffer(), fmtId(), free, modulename, pg_strdup(), PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQexec(), PQresultStatus(), RestoringToDB(), and warn_or_exit_horribly().

Referenced by _disableTriggersIfNecessary(), _enableTriggersIfNecessary(), _printTocEntry(), restore_toc_entry(), and RestoreArchive().

3238 {
3239  PQExpBuffer qry;
3240 
3241  if (!schemaName || *schemaName == '\0' ||
3242  (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
3243  return; /* no need to do anything */
3244 
3245  qry = createPQExpBuffer();
3246 
3247  appendPQExpBuffer(qry, "SET search_path = %s",
3248  fmtId(schemaName));
3249  if (strcmp(schemaName, "pg_catalog") != 0)
3250  appendPQExpBufferStr(qry, ", pg_catalog");
3251 
3252  if (RestoringToDB(AH))
3253  {
3254  PGresult *res;
3255 
3256  res = PQexec(AH->connection, qry->data);
3257 
3258  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3260  "could not set search_path to \"%s\": %s",
3261  schemaName, PQerrorMessage(AH->connection));
3262 
3263  PQclear(res);
3264  }
3265  else
3266  ahprintf(AH, "%s;\n\n", qry->data);
3267 
3268  if (AH->currSchema)
3269  free(AH->currSchema);
3270  AH->currSchema = pg_strdup(schemaName);
3271 
3272  destroyPQExpBuffer(qry);
3273 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6115
const char * fmtId(const char *rawid)
Definition: string_utils.c:66
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
void warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
void PQclear(PGresult *res)
Definition: fe-exec.c:671
#define free(a)
Definition: header.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
static const char * modulename

◆ _selectTablespace()

static void _selectTablespace ( ArchiveHandle AH,
const char *  tablespace 
)
static

Definition at line 3280 of file pg_backup_archiver.c.

References ahprintf(), appendPQExpBuffer(), appendPQExpBufferStr(), _archiveHandle::connection, createPQExpBuffer(), _archiveHandle::currTablespace, PQExpBufferData::data, destroyPQExpBuffer(), fmtId(), free, modulename, _restoreOptions::noTablespace, pg_strdup(), PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQexec(), PQresultStatus(), _archiveHandle::public, RestoringToDB(), Archive::ropt, tablespace, and warn_or_exit_horribly().

Referenced by _printTocEntry().

3281 {
3282  RestoreOptions *ropt = AH->public.ropt;
3283  PQExpBuffer qry;
3284  const char *want,
3285  *have;
3286 
3287  /* do nothing in --no-tablespaces mode */
3288  if (ropt->noTablespace)
3289  return;
3290 
3291  have = AH->currTablespace;
3292  want = tablespace;
3293 
3294  /* no need to do anything for non-tablespace object */
3295  if (!want)
3296  return;
3297 
3298  if (have && strcmp(want, have) == 0)
3299  return; /* no need to do anything */
3300 
3301  qry = createPQExpBuffer();
3302 
3303  if (strcmp(want, "") == 0)
3304  {
3305  /* We want the tablespace to be the database's default */
3306  appendPQExpBufferStr(qry, "SET default_tablespace = ''");
3307  }
3308  else
3309  {
3310  /* We want an explicit tablespace */
3311  appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
3312  }
3313 
3314  if (RestoringToDB(AH))
3315  {
3316  PGresult *res;
3317 
3318  res = PQexec(AH->connection, qry->data);
3319 
3320  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3322  "could not set default_tablespace to %s: %s",
3323  fmtId(want), PQerrorMessage(AH->connection));
3324 
3325  PQclear(res);
3326  }
3327  else
3328  ahprintf(AH, "%s;\n\n", qry->data);
3329 
3330  if (AH->currTablespace)
3331  free(AH->currTablespace);
3332  AH->currTablespace = pg_strdup(want);
3333 
3334  destroyPQExpBuffer(qry);
3335 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6115
RestoreOptions * ropt
Definition: pg_backup.h:182
const char * fmtId(const char *rawid)
Definition: string_utils.c:66
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
void warn_or_exit_horribly(ArchiveHandle *AH, const char *modulename, const char *fmt,...)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
char * tablespace
Definition: pgbench.c:146
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
void PQclear(PGresult *res)
Definition: fe-exec.c:671
#define free(a)
Definition: header.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
static const char * modulename

◆ _setWithOids()

static void _setWithOids ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 3222 of file pg_backup_archiver.c.

References _doSetWithOids(), _archiveHandle::currWithOids, and _tocEntry::withOids.

Referenced by _printTocEntry().

3223 {
3224  if (AH->currWithOids != te->withOids)
3225  {
3226  _doSetWithOids(AH, te->withOids);
3227  AH->currWithOids = te->withOids;
3228  }
3229 }
static void _doSetWithOids(ArchiveHandle *AH, const bool withOids)

◆ _tocEntryIsACL()

static bool _tocEntryIsACL ( TocEntry te)
static

Definition at line 2999 of file pg_backup_archiver.c.

References _tocEntry::desc.

Referenced by _printTocEntry(), and _tocEntryRequired().

3000 {
3001  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3002  if (strcmp(te->desc, "ACL") == 0 ||
3003  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3004  strcmp(te->desc, "DEFAULT ACL") == 0)
3005  return true;
3006  return false;
3007 }

◆ _tocEntryRequired()

static teReqs _tocEntryRequired ( TocEntry te,
teSection  curSection,
RestoreOptions ropt 
)
static

Definition at line 2809 of file pg_backup_archiver.c.

References _tocEntryIsACL(), _restoreOptions::aclsSkip, _restoreOptions::binary_upgrade, _restoreOptions::dataOnly, _tocEntry::defn, _tocEntry::desc, DUMP_DATA, DUMP_POST_DATA, DUMP_PRE_DATA, _tocEntry::dumpId, _restoreOptions::dumpSections, _restoreOptions::functionNames, _tocEntry::hadDumper, SimpleStringList::head, _restoreOptions::idWanted, _restoreOptions::indexNames, _restoreOptions::no_publications, _restoreOptions::no_security_labels, _restoreOptions::no_subscriptions, REQ_DATA, REQ_SCHEMA, REQ_SPECIAL, _restoreOptions::schemaExcludeNames, _restoreOptions::schemaNames, _restoreOptions::schemaOnly, SECTION_DATA, SECTION_POST_DATA, SECTION_PRE_DATA, _restoreOptions::selFunction, _restoreOptions::selIndex, _restoreOptions::selTable, _restoreOptions::selTrigger, _restoreOptions::selTypes, _restoreOptions::sequence_data, simple_string_list_member(), _restoreOptions::tableNames, _tocEntry::tag, and _restoreOptions::triggerNames.

Referenced by PrintTOCSummary(), and ProcessArchiveRestoreOptions().

2810 {
2811  teReqs res = REQ_SCHEMA | REQ_DATA;
2812 
2813  /* ENCODING and STDSTRINGS items are treated specially */
2814  if (strcmp(te->desc, "ENCODING") == 0 ||
2815  strcmp(te->desc, "STDSTRINGS") == 0)
2816  return REQ_SPECIAL;
2817 
2818  /* If it's an ACL, maybe ignore it */
2819  if (ropt->aclsSkip && _tocEntryIsACL(te))
2820  return 0;
2821 
2822  /* If it's a publication, maybe ignore it */
2823  if (ropt->no_publications && strcmp(te->desc, "PUBLICATION") == 0)
2824  return 0;
2825 
2826  /* If it's security labels, maybe ignore it */
2827  if (ropt->no_security_labels && strcmp(te->desc, "SECURITY LABEL") == 0)
2828  return 0;
2829 
2830  /* If it's a subcription, maybe ignore it */
2831  if (ropt->no_subscriptions && strcmp(te->desc, "SUBSCRIPTION") == 0)
2832  return 0;
2833 
2834  /* Ignore it if section is not to be dumped/restored */
2835  switch (curSection)
2836  {
2837  case SECTION_PRE_DATA:
2838  if (!(ropt->dumpSections & DUMP_PRE_DATA))
2839  return 0;
2840  break;
2841  case SECTION_DATA:
2842  if (!(ropt->dumpSections & DUMP_DATA))
2843  return 0;
2844  break;
2845  case SECTION_POST_DATA:
2846  if (!(ropt->dumpSections & DUMP_POST_DATA))
2847  return 0;
2848  break;
2849  default:
2850  /* shouldn't get here, really, but ignore it */
2851  return 0;
2852  }
2853 
2854  /* Check options for selective dump/restore */
2855  if (ropt->schemaNames.head != NULL)
2856  {
2857  /* If no namespace is specified, it means all. */
2858  if (!te->namespace)
2859  return 0;
2860  if (!(simple_string_list_member(&ropt->schemaNames, te->namespace)))
2861  return 0;
2862  }
2863 
2864  if (ropt->schemaExcludeNames.head != NULL &&
2865  te->namespace &&
2866  simple_string_list_member(&ropt->schemaExcludeNames, te->namespace))
2867  return 0;
2868 
2869  if (ropt->selTypes)
2870  {
2871  if (strcmp(te->desc, "TABLE") == 0 ||
2872  strcmp(te->desc, "TABLE DATA") == 0 ||
2873  strcmp(te->desc, "VIEW") == 0 ||
2874  strcmp(te->desc, "FOREIGN TABLE") == 0 ||
2875  strcmp(te->desc, "MATERIALIZED VIEW") == 0 ||
2876  strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0 ||
2877  strcmp(te->desc, "SEQUENCE") == 0 ||
2878  strcmp(te->desc, "SEQUENCE SET") == 0)
2879  {
2880  if (!ropt->selTable)
2881  return 0;
2882  if (ropt->tableNames.head != NULL && (!(simple_string_list_member(&ropt->tableNames, te->tag))))
2883  return 0;
2884  }
2885  else if (strcmp(te->desc, "INDEX") == 0)
2886  {
2887  if (!ropt->selIndex)
2888  return 0;
2889  if (ropt->indexNames.head != NULL && (!(simple_string_list_member(&ropt->indexNames, te->tag))))
2890  return 0;
2891  }
2892  else if (strcmp(te->desc, "FUNCTION") == 0 ||
2893  strcmp(te->desc, "PROCEDURE") == 0)
2894  {
2895  if (!ropt->selFunction)
2896  return 0;
2897  if (ropt->functionNames.head != NULL && (!(simple_string_list_member(&ropt->functionNames, te->tag))))
2898  return 0;
2899  }
2900  else if (strcmp(te->desc, "TRIGGER") == 0)
2901  {
2902  if (!ropt->selTrigger)
2903  return 0;
2904  if (ropt->triggerNames.head != NULL && (!(simple_string_list_member(&ropt->triggerNames, te->tag))))
2905  return 0;
2906  }
2907  else
2908  return 0;
2909  }
2910 
2911  /*
2912  * Check if we had a dataDumper. Indicates if the entry is schema or data
2913  */
2914  if (!te->hadDumper)
2915  {
2916  /*
2917  * Special Case: If 'SEQUENCE SET' or anything to do with BLOBs, then
2918  * it is considered a data entry. We don't need to check for the
2919  * BLOBS entry or old-style BLOB COMMENTS, because they will have
2920  * hadDumper = true ... but we do need to check new-style BLOB
2921  * comments.
2922  */
2923  if (strcmp(te->desc, "SEQUENCE SET") == 0 ||
2924  strcmp(te->desc, "BLOB") == 0 ||
2925  (strcmp(te->desc, "ACL") == 0 &&
2926  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
2927  (strcmp(te->desc, "COMMENT") == 0 &&
2928  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
2929  (strcmp(te->desc, "SECURITY LABEL") == 0 &&
2930  strncmp(te->tag, "LARGE OBJECT ", 13) == 0))
2931  res = res & REQ_DATA;
2932  else
2933  res = res & ~REQ_DATA;
2934  }
2935 
2936  /*
2937  * Special case: <Init> type with <Max OID> tag; this is obsolete and we
2938  * always ignore it.
2939  */
2940  if ((strcmp(te->desc, "<Init>") == 0) && (strcmp(te->tag, "Max OID") == 0))
2941  return 0;
2942 
2943  /* Mask it if we only want schema */
2944  if (ropt->schemaOnly)
2945  {
2946  /*
2947  * In binary-upgrade mode, even with schema-only set, we do not mask
2948  * out large objects. Only large object definitions, comments and
2949  * other information should be generated in binary-upgrade mode (not
2950  * the actual data).
2951  */
2952  if (!(ropt->sequence_data && strcmp(te->desc, "SEQUENCE SET") == 0) &&
2953  !(ropt->binary_upgrade && strcmp(te->desc, "BLOB") == 0) &&
2954  !(ropt->binary_upgrade && strncmp(te->tag, "LARGE OBJECT ", 13) == 0))
2955  res = res & REQ_SCHEMA;
2956  }
2957 
2958  /* Mask it if we only want data */
2959  if (ropt->dataOnly)
2960  res = res & REQ_DATA;
2961 
2962  /* Mask it if we don't have a schema contribution */
2963  if (!te->defn || strlen(te->defn) == 0)
2964  res = res & ~REQ_SCHEMA;
2965 
2966  /* Finally, if there's a per-ID filter, limit based on that as well */
2967  if (ropt->idWanted && !ropt->idWanted[te->dumpId - 1])
2968  return 0;
2969 
2970  return res;
2971 }
bool simple_string_list_member(SimpleStringList *list, const char *val)
Definition: simple_list.c:87
SimpleStringList triggerNames
Definition: pg_backup.h:105
SimpleStringList schemaNames
Definition: pg_backup.h:103
static bool _tocEntryIsACL(TocEntry *te)
bool * idWanted
Definition: pg_backup.h:121
SimpleStringList tableNames
Definition: pg_backup.h:106
SimpleStringList functionNames
Definition: pg_backup.h:102
int no_security_labels
Definition: pg_backup.h:78
int no_subscriptions
Definition: pg_backup.h:79
SimpleStringListCell * head
Definition: simple_list.h:42
SimpleStringList indexNames
Definition: pg_backup.h:101
int no_publications
Definition: pg_backup.h:77
SimpleStringList schemaExcludeNames
Definition: pg_backup.h:104

◆ _tocEntryRestorePass()

static RestorePass _tocEntryRestorePass ( TocEntry te)
static

Definition at line 2979 of file pg_backup_archiver.c.

References _tocEntry::desc, RESTORE_PASS_ACL, and RESTORE_PASS_MAIN.

Referenced by move_to_ready_list(), reduce_dependencies(), restore_toc_entries_prefork(), and RestoreArchive().

2980 {
2981  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
2982  if (strcmp(te->desc, "ACL") == 0 ||
2983  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
2984  strcmp(te->desc, "DEFAULT ACL") == 0)
2985  return RESTORE_PASS_ACL;
2986  if (strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0)
2987  return RESTORE_PASS_REFRESH;
2988  return RESTORE_PASS_MAIN;
2989 }

◆ ahlog()

void ahlog ( ArchiveHandle AH,
int  level,
const char *  fmt,
  ... 
)

◆ ahprintf()

int ahprintf ( ArchiveHandle AH,
const char *  fmt,
  ... 
)

Definition at line 1612 of file pg_backup_archiver.c.

References ahwrite(), generate_unaccent_rules::args, free, pg_malloc(), and pvsnprintf().

Referenced by _disableTriggersIfNecessary(), _doSetFixedOutputState(), _doSetSessionAuth(), _doSetWithOids(), _enableTriggersIfNecessary(), _EndBlob(), _EndBlobs(), _EndData(), _PrintExtraToc(), _PrintTocData(), _printTocEntry(), _reconnectToDB(), _selectOutputSchema(), _selectTablespace(), _StartBlob(), _StartBlobs(), _WriteBlobData(), DropBlobIfExists(), dump_lo_buf(), dumpTimestamp(), EndRestoreBlob(), EndRestoreBlobs(), PrintTOCSummary(), restore_toc_entry(), RestoreArchive(), StartRestoreBlob(), and StartRestoreBlobs().

1613 {
1614  char *p;
1615  size_t len = 128; /* initial assumption about buffer size */
1616  size_t cnt;
1617 
1618  for (;;)
1619  {
1620  va_list args;
1621 
1622  /* Allocate work buffer. */
1623  p = (char *) pg_malloc(len);
1624 
1625  /* Try to format the data. */
1626  va_start(args, fmt);
1627  cnt = pvsnprintf(p, len, fmt, args);
1628  va_end(args);
1629 
1630  if (cnt < len)
1631  break; /* success */
1632 
1633  /* Release buffer and loop around to try again with larger len. */
1634  free(p);
1635  len = cnt;
1636  }
1637 
1638  ahwrite(p, 1, cnt, AH);
1639  free(p);
1640  return (int) cnt;
1641 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
Definition: psprintf.c:104
#define free(a)
Definition: header.h:65
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)

◆ ahwrite()

void ahwrite ( const void *  ptr,
size_t  size,
size_t  nmemb,
ArchiveHandle AH 
)

Definition at line 1714 of file pg_backup_archiver.c.

References _archiveHandle::CustomOutPtr, dump_lo_buf(), ExecuteSqlCommandBuf(), _archiveHandle::gzOut, GZWRITE, _archiveHandle::lo_buf, _archiveHandle::lo_buf_size, _archiveHandle::lo_buf_used, _archiveHandle::OF, _archiveHandle::public, remaining, RestoringToDB(), WRITE_ERROR_EXIT, and _archiveHandle::writingBlob.

Referenced by _LoadBlobs(), _PrintFileData(), _PrintTocData(), _WriteData(), ahprintf(), EndCompressor(), and ReadDataFromArchiveNone().

1715 {
1716  int bytes_written = 0;
1717 
1718  if (AH->writingBlob)
1719  {
1720  size_t remaining = size * nmemb;
1721 
1722  while (AH->lo_buf_used + remaining > AH->lo_buf_size)
1723  {
1724  size_t avail = AH->lo_buf_size - AH->lo_buf_used;
1725 
1726  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, avail);
1727  ptr = (const void *) ((const char *) ptr + avail);
1728  remaining -= avail;
1729  AH->lo_buf_used += avail;
1730  dump_lo_buf(AH);
1731  }
1732 
1733  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
1734  AH->lo_buf_used += remaining;
1735 
1736  bytes_written = size * nmemb;
1737  }
1738  else if (AH->gzOut)
1739  bytes_written = GZWRITE(ptr, size, nmemb, AH->OF);
1740  else if (AH->CustomOutPtr)
1741  bytes_written = AH->CustomOutPtr(AH, ptr, size * nmemb);
1742 
1743  else
1744  {
1745  /*
1746  * If we're doing a restore, and it's direct to DB, and we're
1747  * connected then send it to the DB.
1748  */
1749  if (RestoringToDB(AH))
1750  bytes_written = ExecuteSqlCommandBuf(&AH->public, (const char *) ptr, size * nmemb);
1751  else
1752  bytes_written = fwrite(ptr, size, nmemb, AH->OF) * size;
1753  }
1754 
1755  if (bytes_written != size * nmemb)
1757 
1758  return;
1759 }
int remaining
Definition: informix.c:692
static int RestoringToDB(ArchiveHandle *AH)
int ExecuteSqlCommandBuf(Archive *AHX, const char *buf, size_t bufLen)
Definition: pg_backup_db.c:563
static void dump_lo_buf(ArchiveHandle *AH)
#define GZWRITE(p, s, n, fh)
CustomOutPtrType CustomOutPtr
#define WRITE_ERROR_EXIT

◆ ArchiveEntry()

void ArchiveEntry ( Archive AHX,
CatalogId  catalogId,
DumpId  dumpId,
const char *  tag,
const char *  namespace,
const char *  tablespace,
const char *  owner,
bool  withOids,
const char *  desc,
teSection  section,
const char *  defn,
const char *  dropStmt,
const char *  copyStmt,
const DumpId deps,
int  nDeps,
DataDumperPtr  dumpFn,
void *  dumpArg 
)

Definition at line 1053 of file pg_backup_archiver.c.

References _archiveHandle::ArchiveEntryPtr, _tocEntry::catalogId, _tocEntry::dataDumper, _tocEntry::dataDumperArg, _tocEntry::dependencies, _tocEntry::dumpId, _tocEntry::formatData, _tocEntry::hadDumper, _archiveHandle::maxDumpId, _tocEntry::nDeps, _tocEntry::next, pg_malloc(), pg_malloc0(), pg_strdup(), _tocEntry::prev, _tocEntry::section, _tocEntry::tag, _archiveHandle::toc, _archiveHandle::tocCount, and true.

Referenced by dumpAccessMethod(), dumpACL(), dumpAgg(), dumpAttrDef(), dumpBaseType(), dumpBlob(), dumpCast(), dumpCollation(), dumpComment(), dumpCompositeType(), dumpCompositeTypeColComments(), dumpConstraint(), dumpConversion(), dumpDatabase(), dumpDefaultACL(), dumpDomain(), dumpDumpableObject(), dumpEncoding(), dumpEnumType(), dumpEventTrigger(), dumpExtension(), dumpForeignDataWrapper(), dumpForeignServer(), dumpFunc(), dumpIndex(), dumpNamespace(), dumpOpclass(), dumpOpfamily(), dumpOpr(), dumpPolicy(), dumpProcLang(), dumpPublication(), dumpPublicationTable(), dumpRangeType(), dumpRule(), dumpSecLabel(), dumpSequence(), dumpSequenceData(), dumpShellType(), dumpStatisticsExt(), dumpStdStrings(), dumpSubscription(), dumpTableComment(), dumpTableData(), dumpTableSchema(), dumpTableSecLabel(), dumpTransform(), dumpTrigger(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), dumpTSTemplate(), dumpUndefinedType(), dumpUserMappings(), and refreshMatViewData().

1064 {
1065  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1066  TocEntry *newToc;
1067 
1068  newToc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
1069 
1070  AH->tocCount++;
1071  if (dumpId > AH->maxDumpId)
1072  AH->maxDumpId = dumpId;
1073 
1074  newToc->prev = AH->toc->prev;
1075  newToc->next = AH->toc;
1076  AH->toc->prev->next = newToc;
1077  AH->toc->prev = newToc;
1078 
1079  newToc->catalogId = catalogId;
1080  newToc->dumpId = dumpId;
1081  newToc->section = section;
1082 
1083  newToc->tag = pg_strdup(tag);
1084  newToc->namespace = namespace ? pg_strdup(namespace) : NULL;
1085  newToc->tablespace = tablespace ? pg_strdup(tablespace) : NULL;
1086  newToc->owner = pg_strdup(owner);
1087  newToc->withOids = withOids;
1088  newToc->desc = pg_strdup(desc);
1089  newToc->defn = pg_strdup(defn);
1090  newToc->dropStmt = pg_strdup(dropStmt);
1091  newToc->copyStmt = copyStmt ? pg_strdup(copyStmt) : NULL;
1092 
1093  if (nDeps > 0)
1094  {
1095  newToc->dependencies = (DumpId *) pg_malloc(nDeps * sizeof(DumpId));
1096  memcpy(newToc->dependencies, deps, nDeps * sizeof(DumpId));
1097  newToc->nDeps = nDeps;
1098  }
1099  else
1100  {
1101  newToc->dependencies = NULL;
1102  newToc->nDeps = 0;
1103  }
1104 
1105  newToc->dataDumper = dumpFn;
1106  newToc->dataDumperArg = dumpArg;
1107  newToc->hadDumper = dumpFn ? true : false;
1108 
1109  newToc->formatData = NULL;
1110 
1111  if (AH->ArchiveEntryPtr != NULL)
1112  AH->ArchiveEntryPtr(AH, newToc);
1113 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:230
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
CatalogId catalogId
void * dataDumperArg
DataDumperPtr dataDumper
teSection section
#define true
Definition: c.h:261
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
struct _tocEntry * toc
DumpId * dependencies
char * tablespace
Definition: pgbench.c:146
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
struct _tocEntry * prev
ArchiveEntryPtrType ArchiveEntryPtr

◆ archprintf()

int archprintf ( Archive AH,
const char *  fmt,
  ... 
)

Definition at line 1479 of file pg_backup_archiver.c.

References generate_unaccent_rules::args, free, pg_malloc(), pvsnprintf(), and WriteData().

1480 {
1481  char *p;
1482  size_t len = 128; /* initial assumption about buffer size */
1483  size_t cnt;
1484 
1485  for (;;)
1486  {
1487  va_list args;
1488 
1489  /* Allocate work buffer. */
1490  p = (char *) pg_malloc(len);
1491 
1492  /* Try to format the data. */
1493  va_start(args, fmt);
1494  cnt = pvsnprintf(p, len, fmt, args);
1495  va_end(args);
1496 
1497  if (cnt < len)
1498  break; /* success */
1499 
1500  /* Release buffer and loop around to try again with larger len. */
1501  free(p);
1502  len = cnt;
1503  }
1504 
1505  WriteData(AH, p, cnt);
1506  free(p);
1507  return (int) cnt;
1508 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
Definition: psprintf.c:104
void WriteData(Archive *AHX, const void *data, size_t dLen)
#define free(a)
Definition: header.h:65

◆ archputs()

void archputs ( const char *  s,
Archive AH 
)

Definition at line 1471 of file pg_backup_archiver.c.

References WriteData().

Referenced by dumpTableData_insert().

1472 {
1473  WriteData(AH, s, strlen(s));
1474  return;
1475 }
void WriteData(Archive *AHX, const void *data, size_t dLen)

◆ buildTocEntryArrays()

static void buildTocEntryArrays ( ArchiveHandle AH)
static

Definition at line 1853 of file pg_backup_archiver.c.

References _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dumpId, exit_horribly(), _archiveHandle::maxDumpId, modulename, _tocEntry::nDeps, _tocEntry::next, pg_malloc0(), _archiveHandle::tableDataId, _archiveHandle::toc, and _archiveHandle::tocsByDumpId.

Referenced by getTocEntryByDumpId(), and RestoreArchive().

1854 {
1855  DumpId maxDumpId = AH->maxDumpId;
1856  TocEntry *te;
1857 
1858  AH->tocsByDumpId = (TocEntry **) pg_malloc0((maxDumpId + 1) * sizeof(TocEntry *));
1859  AH->tableDataId = (DumpId *) pg_malloc0((maxDumpId + 1) * sizeof(DumpId));
1860 
1861  for (te = AH->toc->next; te != AH->toc; te = te->next)
1862  {
1863  /* this check is purely paranoia, maxDumpId should be correct */
1864  if (te->dumpId <= 0 || te->dumpId > maxDumpId)
1865  exit_horribly(modulename, "bad dumpId\n");
1866 
1867  /* tocsByDumpId indexes all TOCs by their dump ID */
1868  AH->tocsByDumpId[te->dumpId] = te;
1869 
1870  /*
1871  * tableDataId provides the TABLE DATA item's dump ID for each TABLE
1872  * TOC entry that has a DATA item. We compute this by reversing the
1873  * TABLE DATA item's dependency, knowing that a TABLE DATA item has
1874  * just one dependency and it is the TABLE item.
1875  */
1876  if (strcmp(te->desc, "TABLE DATA") == 0 && te->nDeps > 0)
1877  {
1878  DumpId tableId = te->dependencies[0];
1879 
1880  /*
1881  * The TABLE item might not have been in the archive, if this was
1882  * a data-only dump; but its dump ID should be less than its data
1883  * item's dump ID, so there should be a place for it in the array.
1884  */
1885  if (tableId <= 0 || tableId > maxDumpId)
1886  exit_horribly(modulename, "bad table dumpId for TABLE DATA item\n");
1887 
1888  AH->tableDataId[tableId] = te->dumpId;
1889  }
1890  }
1891 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:230
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
struct _tocEntry * toc
DumpId * dependencies
struct _tocEntry ** tocsByDumpId
void exit_horribly(const char *modulename, const char *fmt,...)
static const char * modulename

◆ checkSeek()

bool checkSeek ( FILE *  fp)

Definition at line 3779 of file pg_backup_archiver.c.

References fseeko, ftello, and pgoff_t.

Referenced by InitArchiveFmt_Custom(), and InitArchiveFmt_Tar().

3780 {
3781  pgoff_t tpos;
3782 
3783  /*
3784  * If pgoff_t is wider than long, we must have "real" fseeko and not an
3785  * emulation using fseek. Otherwise report no seek capability.
3786  */
3787 #ifndef HAVE_FSEEKO
3788  if (sizeof(pgoff_t) > sizeof(long))
3789  return false;
3790 #endif
3791 
3792  /* Check that ftello works on this file */
3793  tpos = ftello(fp);
3794  if (tpos < 0)
3795  return false;
3796 
3797  /*
3798  * Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
3799  * this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
3800  * successful no-op even on files that are otherwise unseekable.
3801  */
3802  if (fseeko(fp, tpos, SEEK_SET) != 0)
3803  return false;
3804 
3805  return true;
3806 }
#define pgoff_t
Definition: win32_port.h:206
#define ftello(stream)
Definition: win32_port.h:215
#define fseeko(stream, offset, origin)
Definition: win32_port.h:212

◆ CloneArchive()

ArchiveHandle* CloneArchive ( ArchiveHandle AH)

Definition at line 4629 of file pg_backup_archiver.c.

References _doSetFixedOutputState(), appendConnStrVal(), appendPQExpBuffer(), archModeRead, Assert, _archiveHandle::ClonePtr, _archiveHandle::connCancel, ConnectDatabase(), _archiveHandle::connection, connstr, _archiveHandle::currSchema, _archiveHandle::currTablespace, _archiveHandle::currUser, _archiveHandle::currWithOids, PQExpBufferData::data, _restoreOptions::dbname, initPQExpBuffer(), _archiveHandle::mode, Archive::n_errors, pg_malloc(), pg_strdup(), _restoreOptions::pghost, pghost, _restoreOptions::pgport, pgport, PQdb(), PQhost(), PQport(), PQuser(), _restoreOptions::promptPassword, _archiveHandle::public, Archive::ropt, _archiveHandle::savedPassword, _archiveHandle::sqlparse, termPQExpBuffer(), TRI_NO, _restoreOptions::username, and username.

Referenced by RunWorker().

4630 {
4631  ArchiveHandle *clone;
4632 
4633  /* Make a "flat" copy */
4634  clone = (ArchiveHandle *) pg_malloc(sizeof(ArchiveHandle));
4635  memcpy(clone, AH, sizeof(ArchiveHandle));
4636 
4637  /* Handle format-independent fields */
4638  memset(&(clone->sqlparse), 0, sizeof(clone->sqlparse));
4639 
4640  /* The clone will have its own connection, so disregard connection state */
4641  clone->connection = NULL;
4642  clone->connCancel = NULL;
4643  clone->currUser = NULL;
4644  clone->currSchema = NULL;
4645  clone->currTablespace = NULL;
4646  clone->currWithOids = -1;
4647 
4648  /* savedPassword must be local in case we change it while connecting */
4649  if (clone->savedPassword)
4650  clone->savedPassword = pg_strdup(clone->savedPassword);
4651 
4652  /* clone has its own error count, too */
4653  clone->public.n_errors = 0;
4654 
4655  /*
4656  * Connect our new clone object to the database: In parallel restore the
4657  * parent is already disconnected, because we can connect the worker
4658  * processes independently to the database (no snapshot sync required). In
4659  * parallel backup we clone the parent's existing connection.
4660  */
4661  if (AH->mode == archModeRead)
4662  {
4663  RestoreOptions *ropt = AH->public.ropt;
4664 
4665  Assert(AH->connection == NULL);
4666 
4667  /* this also sets clone->connection */
4668  ConnectDatabase((Archive *) clone, ropt->dbname,
4669  ropt->pghost, ropt->pgport, ropt->username,
4670  ropt->promptPassword);
4671 
4672  /* re-establish fixed state */
4673  _doSetFixedOutputState(clone);
4674  }
4675  else
4676  {
4678  char *pghost;
4679  char *pgport;
4680  char *username;
4681 
4682  Assert(AH->connection != NULL);
4683 
4684  /*
4685  * Even though we are technically accessing the parent's database
4686  * object here, these functions are fine to be called like that
4687  * because all just return a pointer and do not actually send/receive
4688  * any data to/from the database.
4689  */
4690  initPQExpBuffer(&connstr);
4691  appendPQExpBuffer(&connstr, "dbname=");
4692  appendConnStrVal(&connstr, PQdb(AH->connection));
4693  pghost = PQhost(AH->connection);
4694  pgport = PQport(AH->connection);
4695  username = PQuser(AH->connection);
4696 
4697  /* this also sets clone->connection */
4698  ConnectDatabase((Archive *) clone, connstr.data,
4699  pghost, pgport, username, TRI_NO);
4700 
4701  termPQExpBuffer(&connstr);
4702  /* setupDumpWorker will fix up connection state */
4703  }
4704 
4705  /* Let the format-specific code have a chance too */
4706  clone->ClonePtr(clone);
4707 
4708  Assert(clone->connection != NULL);
4709  return clone;
4710 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
RestoreOptions * ropt
Definition: pg_backup.h:182
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
char * username
Definition: pg_backup.h:112
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:551
char * PQport(const PGconn *conn)
Definition: fe-connect.c:6036
int n_errors
Definition: pg_backup.h:202
PGcancel *volatile connCancel
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:5991
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void _doSetFixedOutputState(ArchiveHandle *AH)
sqlparseInfo sqlparse
char * pghost
Definition: pgbench.c:180
static char * username
Definition: initdb.c:132
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:6016
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:5983
#define Assert(condition)
Definition: c.h:680
ClonePtrType ClonePtr
char * pgport
Definition: pgbench.c:181
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
void ConnectDatabase(Archive *AH, const char *dbname, const char *pghost, const char *pgport, const char *username, trivalue prompt_password)
Definition: pg_backup_db.c:246
static char * connstr
Definition: pg_dumpall.c:64
trivalue promptPassword
Definition: pg_backup.h:114

◆ CloseArchive()

void CloseArchive ( Archive AHX)

Definition at line 235 of file pg_backup_archiver.c.

References _archiveHandle::ClosePtr, exit_horribly(), GZCLOSE, _archiveHandle::gzOut, modulename, _archiveHandle::OF, and strerror().

Referenced by main().

236 {
237  int res = 0;
238  ArchiveHandle *AH = (ArchiveHandle *) AHX;
239 
240  AH->ClosePtr(AH);
241 
242  /* Close the output */
243  if (AH->gzOut)
244  res = GZCLOSE(AH->OF);
245  else if (AH->OF != stdout)
246  res = fclose(AH->OF);
247 
248  if (res != 0)
249  exit_horribly(modulename, "could not close output file: %s\n",
250  strerror(errno));
251 }
#define GZCLOSE(fh)
void exit_horribly(const char *modulename, const char *fmt,...)
const char * strerror(int errnum)
Definition: strerror.c:19
ClosePtrType ClosePtr
static const char * modulename

◆ CreateArchive()

Archive* CreateArchive ( const char *  FileSpec,
const ArchiveFormat  fmt,
const int  compression,
bool  dosync,
ArchiveMode  mode,
SetupWorkerPtrType  setupDumpWorker 
)

Definition at line 212 of file pg_backup_archiver.c.

References _allocAH().

Referenced by main().

216 {
217  ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, dosync,
218  mode, setupDumpWorker);
219 
220  return (Archive *) AH;
221 }
static ArchiveHandle * _allocAH(const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupWorkerPtr)
static bool dosync
Definition: pg_dump.c:94
static void setupDumpWorker(Archive *AHX)
Definition: pg_dump.c:1153

◆ DeCloneArchive()

void DeCloneArchive ( ArchiveHandle AH)

Definition at line 4718 of file pg_backup_archiver.c.

References Assert, _archiveHandle::connection, sqlparseInfo::curCmd, _archiveHandle::currSchema, _archiveHandle::currTablespace, _archiveHandle::currUser, _archiveHandle::DeClonePtr, destroyPQExpBuffer(), free, _archiveHandle::savedPassword, and _archiveHandle::sqlparse.

Referenced by RunWorker().

4719 {
4720  /* Should not have an open database connection */
4721  Assert(AH->connection == NULL);
4722 
4723  /* Clear format-specific state */
4724  AH->DeClonePtr(AH);
4725 
4726  /* Clear state allocated by CloneArchive */
4727  if (AH->sqlparse.curCmd)
4729 
4730  /* Clear any connection-local state */
4731  if (AH->currUser)
4732  free(AH->currUser);
4733  if (AH->currSchema)
4734  free(AH->currSchema);
4735  if (AH->currTablespace)
4736  free(AH->currTablespace);
4737  if (AH->savedPassword)
4738  free(AH->savedPassword);
4739 
4740  free(AH);
4741 }
PQExpBuffer curCmd
DeClonePtrType DeClonePtr
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
sqlparseInfo sqlparse
#define free(a)
Definition: header.h:65
#define Assert(condition)
Definition: c.h:680

◆ dump_lo_buf()

static void dump_lo_buf ( ArchiveHandle AH)
static

Definition at line 1671 of file pg_backup_archiver.c.

References ahlog(), ahprintf(), appendByteaLiteralAHX, buf, _archiveHandle::connection, createPQExpBuffer(), PQExpBufferData::data, destroyPQExpBuffer(), exit_horribly(), _archiveHandle::lo_buf, _archiveHandle::lo_buf_used, lo_write(), _archiveHandle::loFd, modulename, ngettext, and _archiveHandle::writingBlob.

Referenced by ahwrite(), and EndRestoreBlob().

1672 {
1673  if (AH->connection)
1674  {
1675  size_t res;
1676 
1677  res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used);
1678  ahlog(AH, 5, ngettext("wrote %lu byte of large object data (result = %lu)\n",
1679  "wrote %lu bytes of large object data (result = %lu)\n",
1680  AH->lo_buf_used),
1681  (unsigned long) AH->lo_buf_used, (unsigned long) res);
1682  if (res != AH->lo_buf_used)
1684  "could not write to large object (result: %lu, expected: %lu)\n",
1685  (unsigned long) res, (unsigned long) AH->lo_buf_used);
1686  }
1687  else
1688  {
1690 
1692  (const unsigned char *) AH->lo_buf,
1693  AH->lo_buf_used,
1694  AH);
1695 
1696  /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
1697  AH->writingBlob = 0;
1698  ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
1699  AH->writingBlob = 1;
1700 
1701  destroyPQExpBuffer(buf);
1702  }
1703  AH->lo_buf_used = 0;
1704 }
#define appendByteaLiteralAHX(buf, str, len, AH)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
static char * buf
Definition: pg_test_fsync.c:67
int lo_write(int fd, const char *buf, int len)
Definition: be-fsstubs.c:170
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define ngettext(s, p, n)
Definition: c.h:991
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
void exit_horribly(const char *modulename, const char *fmt,...)
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
static const char * modulename

◆ dumpOptionsFromRestoreOptions()

DumpOptions* dumpOptionsFromRestoreOptions ( RestoreOptions ropt)

Definition at line 154 of file pg_backup_archiver.c.

References _restoreOptions::aclsSkip, _dumpOptions::aclsSkip, _restoreOptions::column_inserts, _dumpOptions::column_inserts, _restoreOptions::createDB, _restoreOptions::dataOnly, _dumpOptions::dataOnly, _restoreOptions::disable_dollar_quoting, _dumpOptions::disable_dollar_quoting, _restoreOptions::disable_triggers, _dumpOptions::disable_triggers, _restoreOptions::dropSchema, _restoreOptions::dump_inserts, _dumpOptions::dump_inserts, _restoreOptions::dumpSections, _dumpOptions::dumpSections, _restoreOptions::enable_row_security, _dumpOptions::enable_row_security, _restoreOptions::if_exists, _dumpOptions::if_exists, _restoreOptions::include_everything, _dumpOptions::include_everything, _restoreOptions::lockWaitTimeout, _dumpOptions::lockWaitTimeout, NewDumpOptions(), _restoreOptions::no_publications, _dumpOptions::no_publications, _restoreOptions::no_security_labels, _dumpOptions::no_security_labels, _restoreOptions::no_subscriptions, _dumpOptions::no_subscriptions, _restoreOptions::noOwner, _restoreOptions::noTablespace, _dumpOptions::outputClean, _dumpOptions::outputCreateDB, _dumpOptions::outputNoOwner, _dumpOptions::outputNoTablespaces, _dumpOptions::outputSuperuser, _restoreOptions::schemaOnly, _dumpOptions::schemaOnly, _restoreOptions::sequence_data, _dumpOptions::sequence_data, _restoreOptions::superuser, _restoreOptions::use_setsessauth, and _dumpOptions::use_setsessauth.

Referenced by SetArchiveOptions().

155 {
156  DumpOptions *dopt = NewDumpOptions();
157 
158  /* this is the inverse of what's at the end of pg_dump.c's main() */
159  dopt->outputClean = ropt->dropSchema;
160  dopt->dataOnly = ropt->dataOnly;
161  dopt->schemaOnly = ropt->schemaOnly;
162  dopt->if_exists = ropt->if_exists;
163  dopt->column_inserts = ropt->column_inserts;
164  dopt->dumpSections = ropt->dumpSections;
165  dopt->aclsSkip = ropt->aclsSkip;
166  dopt->outputSuperuser = ropt->superuser;
167  dopt->outputCreateDB = ropt->createDB;
168  dopt->outputNoOwner = ropt->noOwner;
169  dopt->outputNoTablespaces = ropt->noTablespace;
170  dopt->disable_triggers = ropt->disable_triggers;
171  dopt->use_setsessauth = ropt->use_setsessauth;
172 
174  dopt->dump_inserts = ropt->dump_inserts;
175  dopt->no_publications = ropt->no_publications;
177  dopt->no_subscriptions = ropt->no_subscriptions;
178  dopt->lockWaitTimeout = ropt->lockWaitTimeout;
181  dopt->sequence_data = ropt->sequence_data;
182 
183  return dopt;
184 }
int column_inserts
Definition: pg_backup.h:147
int disable_triggers
Definition: pg_backup.h:156
int disable_dollar_quoting
Definition: pg_backup.h:73
bool schemaOnly
Definition: pg_backup.h:138
int no_subscriptions
Definition: pg_backup.h:151
int no_publications
Definition: pg_backup.h:150
DumpOptions * NewDumpOptions(void)
int sequence_data
Definition: pg_backup.h:172
const char * lockWaitTimeout
Definition: pg_backup.h:88
int use_setsessauth
Definition: pg_backup.h:158
int disable_dollar_quoting
Definition: pg_backup.h:145
int column_inserts
Definition: pg_backup.h:75
const char * lockWaitTimeout
Definition: pg_backup.h:142
bool dataOnly
Definition: pg_backup.h:139
bool include_everything
Definition: pg_backup.h:163
char * outputSuperuser
Definition: pg_backup.h:170
int include_everything
Definition: pg_backup.h:89
int no_security_labels
Definition: pg_backup.h:78
int dumpSections
Definition: pg_backup.h:140
int enable_row_security
Definition: pg_backup.h:122
int dump_inserts
Definition: pg_backup.h:146
int outputNoOwner
Definition: pg_backup.h:169
int no_security_labels
Definition: pg_backup.h:149
int no_subscriptions
Definition: pg_backup.h:79
char * superuser
Definition: pg_backup.h:70
bool aclsSkip
Definition: pg_backup.h:141
int use_setsessauth
Definition: pg_backup.h:68
int enable_row_security
Definition: pg_backup.h:159
int outputCreateDB
Definition: pg_backup.h:166
int outputClean
Definition: pg_backup.h:165
int outputNoTablespaces
Definition: pg_backup.h:157
int no_publications
Definition: pg_backup.h:77
int disable_triggers
Definition: pg_backup.h:66

◆ dumpTimestamp()

static void dumpTimestamp ( ArchiveHandle AH,
const char *  msg,
time_t  tim 
)
static

Definition at line 3813 of file pg_backup_archiver.c.

References ahprintf(), buf, and PGDUMP_STRFTIME_FMT.

Referenced by RestoreArchive().

3814 {
3815  char buf[64];
3816 
3817  if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&tim)) != 0)
3818  ahprintf(AH, "-- %s %s\n\n", msg, buf);
3819 }
static char * buf
Definition: pg_test_fsync.c:67
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define PGDUMP_STRFTIME_FMT
Definition: dumputils.h:33

◆ EndBlob()

int EndBlob ( Archive AHX,
Oid  oid 
)

Definition at line 1246 of file pg_backup_archiver.c.

References _archiveHandle::currToc, and _archiveHandle::EndBlobPtr.

Referenced by dumpBlobs().

1247 {
1248  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1249 
1250  if (AH->EndBlobPtr)
1251  AH->EndBlobPtr(AH, AH->currToc, oid);
1252 
1253  return 1;
1254 }
struct _tocEntry * currToc
EndBlobPtrType EndBlobPtr

◆ EndRestoreBlob()

void EndRestoreBlob ( ArchiveHandle AH,
Oid  oid 
)

Definition at line 1350 of file pg_backup_archiver.c.

References ahprintf(), _archiveHandle::connection, dump_lo_buf(), _archiveHandle::lo_buf_used, lo_close(), _archiveHandle::loFd, and _archiveHandle::writingBlob.

Referenced by _LoadBlobs().

1351 {
1352  if (AH->lo_buf_used > 0)
1353  {
1354  /* Write remaining bytes from the LO buffer */
1355  dump_lo_buf(AH);
1356  }
1357 
1358  AH->writingBlob = 0;
1359 
1360  if (AH->connection)
1361  {
1362  lo_close(AH->connection, AH->loFd);
1363  AH->loFd = -1;
1364  }
1365  else
1366  {
1367  ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
1368  }
1369 }
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:99
static void dump_lo_buf(ArchiveHandle *AH)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)

◆ EndRestoreBlobs()

void EndRestoreBlobs ( ArchiveHandle AH)

Definition at line 1283 of file pg_backup_archiver.c.

References ahlog(), ahprintf(), _archiveHandle::blobCount, CommitTransaction(), _archiveHandle::connection, ngettext, _archiveHandle::public, Archive::ropt, and _restoreOptions::single_txn.

Referenced by _LoadBlobs().

1284 {
1285  RestoreOptions *ropt = AH->public.ropt;
1286 
1287  if (!ropt->single_txn)
1288  {
1289  if (AH->connection)
1290  CommitTransaction(&AH->public);
1291  else
1292  ahprintf(AH, "COMMIT;\n\n");
1293  }
1294 
1295  ahlog(AH, 1, ngettext("restored %d large object\n",
1296  "restored %d large objects\n",
1297  AH->blobCount),
1298  AH->blobCount);
1299 }
RestoreOptions * ropt
Definition: pg_backup.h:182
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define ngettext(s, p, n)
Definition: c.h:991
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
static void CommitTransaction(void)
Definition: xact.c:1934

◆ fix_dependencies()

static void fix_dependencies ( ArchiveHandle AH)
static

Definition at line 4345 of file pg_backup_archiver.c.

References _tocEntry::depCount, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dumpId, i, identify_locking_dependencies(), K_VERS_1_11, _tocEntry::lockDeps, _tocEntry::nDeps, _tocEntry::next, _tocEntry::nLockDeps, _tocEntry::nRevDeps, _tocEntry::par_next, _tocEntry::par_prev, pg_malloc(), repoint_table_dependencies(), _tocEntry::revDeps, _archiveHandle::toc, _archiveHandle::tocsByDumpId, and _archiveHandle::version.

Referenced by restore_toc_entries_prefork().

4346 {
4347  TocEntry *te;
4348  int i;
4349 
4350  /*
4351  * Initialize the depCount/revDeps/nRevDeps fields, and make sure the TOC
4352  * items are marked as not being in any parallel-processing list.
4353  */
4354  for (te = AH->toc->next; te != AH->toc; te = te->next)
4355  {
4356  te->depCount = te->nDeps;
4357  te->revDeps = NULL;
4358  te->nRevDeps = 0;
4359  te->par_prev = NULL;
4360  te->par_next = NULL;
4361  }
4362 
4363  /*
4364  * POST_DATA items that are shown as depending on a table need to be
4365  * re-pointed to depend on that table's data, instead. This ensures they
4366  * won't get scheduled until the data has been loaded.
4367  */
4369 
4370  /*
4371  * Pre-8.4 versions of pg_dump neglected to set up a dependency from BLOB
4372  * COMMENTS to BLOBS. Cope. (We assume there's only one BLOBS and only
4373  * one BLOB COMMENTS in such files.)
4374  */
4375  if (AH->version < K_VERS_1_11)
4376  {
4377  for (te = AH->toc->next; te != AH->toc; te = te->next)
4378  {
4379  if (strcmp(te->desc, "BLOB COMMENTS") == 0 && te->nDeps == 0)
4380  {
4381  TocEntry *te2;
4382 
4383  for (te2 = AH->toc->next; te2 != AH->toc; te2 = te2->next)
4384  {
4385  if (strcmp(te2->desc, "BLOBS") == 0)
4386  {
4387  te->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
4388  te->dependencies[0] = te2->dumpId;
4389  te->nDeps++;
4390  te->depCount++;
4391  break;
4392  }
4393  }
4394  break;
4395  }
4396  }
4397  }
4398 
4399  /*
4400  * At this point we start to build the revDeps reverse-dependency arrays,
4401  * so all changes of dependencies must be complete.
4402  */
4403 
4404  /*
4405  * Count the incoming dependencies for each item. Also, it is possible
4406  * that the dependencies list items that are not in the archive at all
4407  * (that should not happen in 9.2 and later, but is highly likely in older
4408  * archives). Subtract such items from the depCounts.
4409  */
4410  for (te = AH->toc->next; te != AH->toc; te = te->next)
4411  {
4412  for (i = 0; i < te->nDeps; i++)
4413  {
4414  DumpId depid = te->dependencies[i];
4415 
4416  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4417  AH->tocsByDumpId[depid]->nRevDeps++;
4418  else
4419  te->depCount--;
4420  }
4421  }
4422 
4423  /*
4424  * Allocate space for revDeps[] arrays, and reset nRevDeps so we can use
4425  * it as a counter below.
4426  */
4427  for (te = AH->toc->next; te != AH->toc; te = te->next)
4428  {
4429  if (te->nRevDeps > 0)
4430  te->revDeps = (DumpId *) pg_malloc(te->nRevDeps * sizeof(DumpId));
4431  te->nRevDeps = 0;
4432  }
4433 
4434  /*
4435  * Build the revDeps[] arrays of incoming-dependency dumpIds. This had
4436  * better agree with the loops above.
4437  */
4438  for (te = AH->toc->next; te != AH->toc; te = te->next)
4439  {
4440  for (i = 0; i < te->nDeps; i++)
4441  {
4442  DumpId depid = te->dependencies[i];
4443 
4444  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4445  {
4446  TocEntry *otherte = AH->tocsByDumpId[depid];
4447 
4448  otherte->revDeps[otherte->nRevDeps++] = te->dumpId;
4449  }
4450  }
4451  }
4452 
4453  /*
4454  * Lastly, work out the locking dependencies.
4455  */
4456  for (te = AH->toc->next; te != AH->toc; te = te->next)
4457  {
4458  te->lockDeps = NULL;
4459  te->nLockDeps = 0;
4461  }
4462 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:230
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
DumpId * lockDeps
struct _tocEntry * toc
DumpId * dependencies
struct _tocEntry * par_prev
struct _tocEntry * par_next
DumpId * revDeps
struct _tocEntry ** tocsByDumpId
static void identify_locking_dependencies(ArchiveHandle *AH, TocEntry *te)
int i
#define K_VERS_1_11
static void repoint_table_dependencies(ArchiveHandle *AH)

◆ get_next_work_item()

static TocEntry * get_next_work_item ( ArchiveHandle AH,
TocEntry ready_list,
ParallelState pstate 
)
static

Definition at line 4196 of file pg_backup_archiver.c.

References ahlog(), has_lock_conflicts(), i, ParallelState::numWorkers, _tocEntry::par_next, _tocEntry::section, SECTION_DATA, and ParallelState::te.

Referenced by restore_toc_entries_parallel().

4198 {
4199  bool pref_non_data = false; /* or get from AH->ropt */
4200  TocEntry *data_te = NULL;
4201  TocEntry *te;
4202  int i,
4203  k;
4204 
4205  /*
4206  * Bogus heuristics for pref_non_data
4207  */
4208  if (pref_non_data)
4209  {
4210  int count = 0;
4211 
4212  for (k = 0; k < pstate->numWorkers; k++)
4213  {
4214  TocEntry *running_te = pstate->te[k];
4215 
4216  if (running_te != NULL &&
4217  running_te->section == SECTION_DATA)
4218  count++;
4219  }
4220  if (pstate->numWorkers == 0 || count * 4 < pstate->numWorkers)
4221  pref_non_data = false;
4222  }
4223 
4224  /*
4225  * Search the ready_list until we find a suitable item.
4226  */
4227  for (te = ready_list->par_next; te != ready_list; te = te->par_next)
4228  {
4229  bool conflicts = false;
4230 
4231  /*
4232  * Check to see if the item would need exclusive lock on something
4233  * that a currently running item also needs lock on, or vice versa. If
4234  * so, we don't want to schedule them together.
4235  */
4236  for (i = 0; i < pstate->numWorkers; i++)
4237  {
4238  TocEntry *running_te = pstate->te[i];
4239 
4240  if (running_te == NULL)
4241  continue;
4242  if (has_lock_conflicts(te, running_te) ||
4243  has_lock_conflicts(running_te, te))
4244  {
4245  conflicts = true;
4246  break;
4247  }
4248  }
4249 
4250  if (conflicts)
4251  continue;
4252 
4253  if (pref_non_data && te->section == SECTION_DATA)
4254  {
4255  if (data_te == NULL)
4256  data_te = te;
4257  continue;
4258  }
4259 
4260  /* passed all tests, so this item can run */
4261  return te;
4262  }
4263 
4264  if (data_te != NULL)
4265  return data_te;
4266 
4267  ahlog(AH, 2, "no item ready\n");
4268  return NULL;
4269 }
teSection section
struct _tocEntry * par_next
TocEntry ** te
Definition: parallel.h:44
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
int i
static bool has_lock_conflicts(TocEntry *te1, TocEntry *te2)
int numWorkers
Definition: parallel.h:42

◆ getTocEntryByDumpId()

TocEntry* getTocEntryByDumpId ( ArchiveHandle AH,
DumpId  id 
)

Definition at line 1894 of file pg_backup_archiver.c.

References buildTocEntryArrays(), and _archiveHandle::tocsByDumpId.

Referenced by parseWorkerCommand(), SortTocFromFile(), and TocIDRequired().

1895 {
1896  /* build index arrays if we didn't already */
1897  if (AH->tocsByDumpId == NULL)
1898  buildTocEntryArrays(AH);
1899 
1900  if (id > 0 && id <= AH->maxDumpId)
1901  return AH->tocsByDumpId[id];
1902 
1903  return NULL;
1904 }
static void buildTocEntryArrays(ArchiveHandle *AH)
struct _tocEntry ** tocsByDumpId

◆ has_lock_conflicts()

static bool has_lock_conflicts ( TocEntry te1,
TocEntry te2 
)
static

Definition at line 4099 of file pg_backup_archiver.c.

References _tocEntry::dependencies, _tocEntry::lockDeps, _tocEntry::nDeps, and _tocEntry::nLockDeps.

Referenced by get_next_work_item().

4100 {
4101  int j,
4102  k;
4103 
4104  for (j = 0; j < te1->nLockDeps; j++)
4105  {
4106  for (k = 0; k < te2->nDeps; k++)
4107  {
4108  if (te1->lockDeps[j] == te2->dependencies[k])
4109  return true;
4110  }
4111  }
4112  return false;
4113 }
DumpId * lockDeps
DumpId * dependencies

◆ identify_locking_dependencies()

static void identify_locking_dependencies ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4499 of file pg_backup_archiver.c.

References _tocEntry::dependencies, _tocEntry::desc, free, i, _tocEntry::lockDeps, _tocEntry::nDeps, _tocEntry::nLockDeps, pg_malloc(), pg_realloc(), and _archiveHandle::tocsByDumpId.

Referenced by fix_dependencies().

4500 {
4501  DumpId *lockids;
4502  int nlockids;
4503  int i;
4504 
4505  /* Quick exit if no dependencies at all */
4506  if (te->nDeps == 0)
4507  return;
4508 
4509  /* Exit if this entry doesn't need exclusive lock on other objects */
4510  if (!(strcmp(te->desc, "CONSTRAINT") == 0 ||
4511  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
4512  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
4513  strcmp(te->desc, "RULE") == 0 ||
4514  strcmp(te->desc, "TRIGGER") == 0))
4515  return;
4516 
4517  /*
4518  * We assume the entry requires exclusive lock on each TABLE or TABLE DATA
4519  * item listed among its dependencies. Originally all of these would have
4520  * been TABLE items, but repoint_table_dependencies would have repointed
4521  * them to the TABLE DATA items if those are present (which they might not
4522  * be, eg in a schema-only dump). Note that all of the entries we are
4523  * processing here are POST_DATA; otherwise there might be a significant
4524  * difference between a dependency on a table and a dependency on its
4525  * data, so that closer analysis would be needed here.
4526  */
4527  lockids = (DumpId *) pg_malloc(te->nDeps * sizeof(DumpId));
4528  nlockids = 0;
4529  for (i = 0; i < te->nDeps; i++)
4530  {
4531  DumpId depid = te->dependencies[i];
4532 
4533  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL &&
4534  ((strcmp(AH->tocsByDumpId[depid]->desc, "TABLE DATA") == 0) ||
4535  strcmp(AH->tocsByDumpId[depid]->desc, "TABLE") == 0))
4536  lockids[nlockids++] = depid;
4537  }
4538 
4539  if (nlockids == 0)
4540  {
4541  free(lockids);
4542  return;
4543  }
4544 
4545  te->lockDeps = pg_realloc(lockids, nlockids * sizeof(DumpId));
4546  te->nLockDeps = nlockids;
4547 }
int DumpId
Definition: pg_backup.h:230
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
DumpId * lockDeps
DumpId * dependencies
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
#define free(a)
Definition: header.h:65
struct _tocEntry ** tocsByDumpId
int i

◆ inhibit_data_for_failed_table()

static void inhibit_data_for_failed_table ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4609 of file pg_backup_archiver.c.

References ahlog(), _tocEntry::dumpId, _tocEntry::reqs, _archiveHandle::tableDataId, _tocEntry::tag, and _archiveHandle::tocsByDumpId.

Referenced by mark_restore_job_done(), and restore_toc_entry().

4610 {
4611  ahlog(AH, 1, "table \"%s\" could not be created, will not restore its data\n",
4612  te->tag);
4613 
4614  if (AH->tableDataId[te->dumpId] != 0)
4615  {
4616  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4617 
4618  ted->reqs = 0;
4619  }
4620 }
struct _tocEntry ** tocsByDumpId
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)

◆ InitDumpOptions()

void InitDumpOptions ( DumpOptions opts)

Definition at line 141 of file pg_backup_archiver.c.

References DUMP_UNSECTIONED, _dumpOptions::dumpSections, and _dumpOptions::include_everything.

Referenced by main(), and NewDumpOptions().

142 {
143  memset(opts, 0, sizeof(DumpOptions));
144  /* set any fields that shouldn't default to zeroes */
145  opts->include_everything = true;
147 }
bool include_everything
Definition: pg_backup.h:163
int dumpSections
Definition: pg_backup.h:140

◆ mark_create_done()

static void mark_create_done ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4594 of file pg_backup_archiver.c.

References _tocEntry::created, _tocEntry::dumpId, _archiveHandle::tableDataId, and _archiveHandle::tocsByDumpId.

Referenced by mark_restore_job_done(), and restore_toc_entry().

4595 {
4596  if (AH->tableDataId[te->dumpId] != 0)
4597  {
4598  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4599 
4600  ted->created = true;
4601  }
4602 }
struct _tocEntry ** tocsByDumpId

◆ mark_dump_job_done()

static void mark_dump_job_done ( ArchiveHandle AH,
TocEntry te,
int  status,
void *  callback_data 
)
static

Definition at line 2459 of file pg_backup_archiver.c.

References ahlog(), _tocEntry::desc, _tocEntry::dumpId, exit_horribly(), modulename, and _tocEntry::tag.

Referenced by WriteDataChunks().

2463 {
2464  ahlog(AH, 1, "finished item %d %s %s\n",
2465  te->dumpId, te->desc, te->tag);
2466 
2467  if (status != 0)
2468  exit_horribly(modulename, "worker process failed: exit code %d\n",
2469  status);
2470 }
void exit_horribly(const char *modulename, const char *fmt,...)
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
static const char * modulename

◆ mark_restore_job_done()

static void mark_restore_job_done ( ArchiveHandle AH,
TocEntry te,
int  status,
void *  callback_data 
)
static

Definition at line 4304 of file pg_backup_archiver.c.

References ahlog(), _tocEntry::desc, _tocEntry::dumpId, exit_horribly(), inhibit_data_for_failed_table(), mark_create_done(), modulename, Archive::n_errors, _archiveHandle::public, reduce_dependencies(), _tocEntry::tag, WORKER_CREATE_DONE, WORKER_IGNORED_ERRORS, and WORKER_INHIBIT_DATA.

Referenced by restore_toc_entries_parallel().

4308 {
4309  TocEntry *ready_list = (TocEntry *) callback_data;
4310 
4311  ahlog(AH, 1, "finished item %d %s %s\n",
4312  te->dumpId, te->desc, te->tag);
4313 
4314  if (status == WORKER_CREATE_DONE)
4315  mark_create_done(AH, te);
4316  else if (status == WORKER_INHIBIT_DATA)
4317  {
4319  AH->public.n_errors++;
4320  }
4321  else if (status == WORKER_IGNORED_ERRORS)
4322  AH->public.n_errors++;
4323  else if (status != 0)
4324  exit_horribly(modulename, "worker process failed: exit code %d\n",
4325  status);
4326 
4327  reduce_dependencies(AH, te, ready_list);
4328 }
#define WORKER_CREATE_DONE
int n_errors
Definition: pg_backup.h:202
#define WORKER_IGNORED_ERRORS
static void inhibit_data_for_failed_table(ArchiveHandle *AH, TocEntry *te)
#define WORKER_INHIBIT_DATA
static void mark_create_done(ArchiveHandle *AH, TocEntry *te)
static void reduce_dependencies(ArchiveHandle *AH, TocEntry *te, TocEntry *ready_list)
void exit_horribly(const char *modulename, const char *fmt,...)
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
static const char * modulename

◆ move_to_ready_list()

static void move_to_ready_list ( TocEntry pending_list,
TocEntry ready_list,
RestorePass  pass 
)
static

Definition at line 4158 of file pg_backup_archiver.c.

References _tocEntryRestorePass(), _tocEntry::depCount, par_list_append(), par_list_remove(), and _tocEntry::par_next.

Referenced by restore_toc_entries_parallel().

4160 {
4161  TocEntry *te;
4162  TocEntry *next_te;
4163 
4164  for (te = pending_list->par_next; te != pending_list; te = next_te)
4165  {
4166  /* must save list link before possibly moving te to other list */
4167  next_te = te->par_next;
4168 
4169  if (te->depCount == 0 &&
4170  _tocEntryRestorePass(te) == pass)
4171  {
4172  /* Remove it from pending_list ... */
4173  par_list_remove(te);
4174  /* ... and add to ready_list */
4175  par_list_append(ready_list, te);
4176  }
4177  }
4178 }
static RestorePass _tocEntryRestorePass(TocEntry *te)
struct _tocEntry * par_next
static void par_list_append(TocEntry *l, TocEntry *te)
static void par_list_remove(TocEntry *te)

◆ NewDumpOptions()

DumpOptions* NewDumpOptions ( void  )

Definition at line 129 of file pg_backup_archiver.c.

References InitDumpOptions(), and pg_malloc().

Referenced by dumpOptionsFromRestoreOptions().

130 {
131  DumpOptions *opts = (DumpOptions *) pg_malloc(sizeof(DumpOptions));
132 
133  InitDumpOptions(opts);
134  return opts;
135 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
void InitDumpOptions(DumpOptions *opts)

◆ NewRestoreOptions()

RestoreOptions* NewRestoreOptions ( void  )

Definition at line 958 of file pg_backup_archiver.c.

References archUnknown, DUMP_UNSECTIONED, _restoreOptions::dumpSections, _restoreOptions::format, pg_malloc0(), _restoreOptions::promptPassword, and TRI_DEFAULT.

Referenced by _CloseArchive(), and main().

959 {
960  RestoreOptions *opts;
961 
962  opts = (RestoreOptions *) pg_malloc0(sizeof(RestoreOptions));
963 
964  /* set any fields that shouldn't default to zeroes */
965  opts->format = archUnknown;
966  opts->promptPassword = TRI_DEFAULT;
968 
969  return opts;
970 }
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
trivalue promptPassword
Definition: pg_backup.h:114

◆ OpenArchive()

Archive* OpenArchive ( const char *  FileSpec,
const ArchiveFormat  fmt 
)

Definition at line 226 of file pg_backup_archiver.c.

References _allocAH(), archModeRead, and setupRestoreWorker().

Referenced by main().

227 {
228  ArchiveHandle *AH = _allocAH(FileSpec, fmt, 0, true, archModeRead, setupRestoreWorker);
229 
230  return (Archive *) AH;
231 }
static ArchiveHandle * _allocAH(const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupWorkerPtr)
static void setupRestoreWorker(Archive *AHX)

◆ par_list_append()

static void par_list_append ( TocEntry l,
TocEntry te 
)
static

Definition at line 4131 of file pg_backup_archiver.c.

References _tocEntry::par_next, and _tocEntry::par_prev.

Referenced by move_to_ready_list(), reduce_dependencies(), and restore_toc_entries_prefork().

4132 {
4133  te->par_prev = l->par_prev;
4134  l->par_prev->par_next = te;
4135  l->par_prev = te;
4136  te->par_next = l;
4137 }
struct _tocEntry * par_prev
struct _tocEntry * par_next

◆ par_list_header_init()

static void par_list_header_init ( TocEntry l)
static

Definition at line 4124 of file pg_backup_archiver.c.

References _tocEntry::par_next, and _tocEntry::par_prev.

Referenced by restore_toc_entries_parallel(), and RestoreArchive().

4125 {
4126  l->par_prev = l->par_next = l;
4127 }
struct _tocEntry * par_prev
struct _tocEntry * par_next

◆ par_list_remove()

static void par_list_remove ( TocEntry te)
static

Definition at line 4141 of file pg_backup_archiver.c.

References _tocEntry::par_next, and _tocEntry::par_prev.

Referenced by move_to_ready_list(), reduce_dependencies(), and restore_toc_entries_parallel().

4142 {
4143  te->par_prev->par_next = te->par_next;
4144  te->par_next->par_prev = te->par_prev;
4145  te->par_prev = NULL;
4146  te->par_next = NULL;
4147 }
struct _tocEntry * par_prev
struct _tocEntry * par_next

◆ parallel_restore()

int parallel_restore ( ArchiveHandle AH,
TocEntry te 
)

Definition at line 4281 of file pg_backup_archiver.c.

References Assert, _archiveHandle::connection, Archive::n_errors, _archiveHandle::public, restore_toc_entry(), and status().

Referenced by _WorkerJobRestoreCustom(), and _WorkerJobRestoreDirectory().

4282 {
4283  int status;
4284 
4285  Assert(AH->connection != NULL);
4286 
4287  /* Count only errors associated with this TOC entry */
4288  AH->public.n_errors = 0;
4289 
4290  /* Restore the TOC item */
4291  status = restore_toc_entry(AH, te, true);
4292 
4293  return status;
4294 }
int n_errors
Definition: pg_backup.h:202
static int restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
#define Assert(condition)
Definition: c.h:680
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225

◆ PrintTOCSummary()

void PrintTOCSummary ( Archive AHX)

Definition at line 1117 of file pg_backup_archiver.c.

References _tocEntryRequired(), ahprintf(), archCustom, _archiveHandle::archdbname, archDirectory, ARCHIVE_MAJOR, ARCHIVE_MINOR, ARCHIVE_REV, _archiveHandle::archiveDumpVersion, _archiveHandle::archiveRemoteVersion, archTar, _tocEntry::catalogId, _archiveHandle::compression, _archiveHandle::createDate, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dumpId, _restoreOptions::filename, _archiveHandle::format, free, i, _archiveHandle::intSize, _tocEntry::nDeps, _tocEntry::next, _archiveHandle::offSize, CatalogId::oid, _tocEntry::owner, pg_strdup(), PGDUMP_STRFTIME_FMT, _archiveHandle::public, replace_line_endings(), REQ_DATA, REQ_SCHEMA, RestoreOutput(), Archive::ropt, SaveOutput(), _tocEntry::section, SECTION_NONE, SECTION_PRE_DATA, SetOutput(), _restoreOptions::strict_names, StrictNamesCheck(), CatalogId::tableoid, _tocEntry::tag, _archiveHandle::toc, _archiveHandle::tocCount, _restoreOptions::verbose, and _archiveHandle::version.

Referenced by main().

1118 {
1119  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1120  RestoreOptions *ropt = AH->public.ropt;
1121  TocEntry *te;
1122  teSection curSection;
1123  OutputContext sav;
1124  const char *fmtName;
1125  char stamp_str[64];
1126 
1127  sav = SaveOutput(AH);
1128  if (ropt->filename)
1129  SetOutput(AH, ropt->filename, 0 /* no compression */ );
1130 
1131  if (strftime(stamp_str, sizeof(stamp_str), PGDUMP_STRFTIME_FMT,
1132  localtime(&AH->createDate)) == 0)
1133  strcpy(stamp_str, "[unknown]");
1134 
1135  ahprintf(AH, ";\n; Archive created at %s\n", stamp_str);
1136  ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n",
1138  AH->tocCount, AH->compression);
1139 
1140  switch (AH->format)
1141  {
1142  case archCustom:
1143  fmtName = "CUSTOM";
1144  break;
1145  case archDirectory:
1146  fmtName = "DIRECTORY";
1147  break;
1148  case archTar:
1149  fmtName = "TAR";
1150  break;
1151  default:
1152  fmtName = "UNKNOWN";
1153  }
1154 
1155  ahprintf(AH, "; Dump Version: %d.%d-%d\n",
1157  ahprintf(AH, "; Format: %s\n", fmtName);
1158  ahprintf(AH, "; Integer: %d bytes\n", (int) AH->intSize);
1159  ahprintf(AH, "; Offset: %d bytes\n", (int) AH->offSize);
1160  if (AH->archiveRemoteVersion)
1161  ahprintf(AH, "; Dumped from database version: %s\n",
1162  AH->archiveRemoteVersion);
1163  if (AH->archiveDumpVersion)
1164  ahprintf(AH, "; Dumped by pg_dump version: %s\n",
1165  AH->archiveDumpVersion);
1166 
1167  ahprintf(AH, ";\n;\n; Selected TOC Entries:\n;\n");
1168 
1169  curSection = SECTION_PRE_DATA;
1170  for (te = AH->toc->next; te != AH->toc; te = te->next)
1171  {
1172  if (te->section != SECTION_NONE)
1173  curSection = te->section;
1174  if (ropt->verbose ||
1175  (_tocEntryRequired(te, curSection, ropt) & (REQ_SCHEMA | REQ_DATA)) != 0)
1176  {
1177  char *sanitized_name;
1178  char *sanitized_schema;
1179  char *sanitized_owner;
1180 
1181  /*
1182  * As in _printTocEntry(), sanitize strings that might contain
1183  * newlines, to ensure that each logical output line is in fact
1184  * one physical output line. This prevents confusion when the
1185  * file is read by "pg_restore -L". Note that we currently don't
1186  * bother to quote names, meaning that the name fields aren't
1187  * automatically parseable. "pg_restore -L" doesn't care because
1188  * it only examines the dumpId field, but someday we might want to
1189  * try harder.
1190  */
1191  sanitized_name = replace_line_endings(te->tag);
1192  if (te->namespace)
1193  sanitized_schema = replace_line_endings(te->namespace);
1194  else
1195  sanitized_schema = pg_strdup("-");
1196  sanitized_owner = replace_line_endings(te->owner);
1197 
1198  ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
1199  te->catalogId.tableoid, te->catalogId.oid,
1200  te->desc, sanitized_schema, sanitized_name,
1201  sanitized_owner);
1202 
1203  free(sanitized_name);
1204  free(sanitized_schema);
1205  free(sanitized_owner);
1206  }
1207  if (ropt->verbose && te->nDeps > 0)
1208  {
1209  int i;
1210 
1211  ahprintf(AH, ";\tdepends on:");
1212  for (i = 0; i < te->nDeps; i++)
1213  ahprintf(AH, " %d", te->dependencies[i]);
1214  ahprintf(AH, "\n");
1215  }
1216  }
1217 
1218  /* Enforce strict names checking */
1219  if (ropt->strict_names)
1220  StrictNamesCheck(ropt);
1221 
1222  if (ropt->filename)
1223  RestoreOutput(AH, sav);
1224 }
struct _tocEntry * next
Oid tableoid
Definition: pg_backup.h:226
RestoreOptions * ropt
Definition: pg_backup.h:182
CatalogId catalogId
static void SetOutput(ArchiveHandle *AH, const char *filename, int compression)
teSection section
const char * filename
Definition: pg_backup.h:82
static char * replace_line_endings(const char *str)
struct _tocEntry * toc
DumpId * dependencies
#define ARCHIVE_REV(version)
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define ARCHIVE_MINOR(version)
ArchiveFormat format
static void StrictNamesCheck(RestoreOptions *ropt)
#define ARCHIVE_MAJOR(version)
static OutputContext SaveOutput(ArchiveHandle *AH)
#define free(a)
Definition: header.h:65
enum _teSection teSection
#define PGDUMP_STRFTIME_FMT
Definition: dumputils.h:33
static void RestoreOutput(ArchiveHandle *AH, OutputContext savedContext)
static teReqs _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
int i

◆ ProcessArchiveRestoreOptions()

void ProcessArchiveRestoreOptions ( Archive AHX)

Definition at line 268 of file pg_backup_archiver.c.

References _tocEntryRequired(), archModeRead, exit_horribly(), _archiveHandle::mode, modulename, _tocEntry::next, _archiveHandle::public, _tocEntry::reqs, Archive::ropt, _tocEntry::section, SECTION_DATA, SECTION_NONE, SECTION_POST_DATA, SECTION_PRE_DATA, _restoreOptions::strict_names, StrictNamesCheck(), _archiveHandle::toc, and write_msg().

Referenced by main().

269 {
270  ArchiveHandle *AH = (ArchiveHandle *) AHX;
271  RestoreOptions *ropt = AH->public.ropt;
272  TocEntry *te;
273  teSection curSection;
274 
275  /* Decide which TOC entries will be dumped/restored, and mark them */
276  curSection = SECTION_PRE_DATA;
277  for (te = AH->toc->next; te != AH->toc; te = te->next)
278  {
279  /*
280  * When writing an archive, we also take this opportunity to check
281  * that we have generated the entries in a sane order that respects
282  * the section divisions. When reading, don't complain, since buggy
283  * old versions of pg_dump might generate out-of-order archives.
284  */
285  if (AH->mode != archModeRead)
286  {
287  switch (te->section)
288  {
289  case SECTION_NONE:
290  /* ok to be anywhere */
291  break;
292  case SECTION_PRE_DATA:
293  if (curSection != SECTION_PRE_DATA)
295  "WARNING: archive items not in correct section order\n");
296  break;
297  case SECTION_DATA:
298  if (curSection == SECTION_POST_DATA)
300  "WARNING: archive items not in correct section order\n");
301  break;
302  case SECTION_POST_DATA:
303  /* ok no matter which section we were in */
304  break;
305  default:
306  exit_horribly(modulename, "unexpected section code %d\n",
307  (int) te->section);
308  break;
309  }
310  }
311 
312  if (te->section != SECTION_NONE)
313  curSection = te->section;
314 
315  te->reqs = _tocEntryRequired(te, curSection, ropt);
316  }
317 
318  /* Enforce strict names checking */
319  if (ropt->strict_names)
320  StrictNamesCheck(ropt);
321 }
struct _tocEntry * next
RestoreOptions * ropt
Definition: pg_backup.h:182
teSection section
struct _tocEntry * toc
static void StrictNamesCheck(RestoreOptions *ropt)
enum _teSection teSection
void write_msg(const char *modulename, const char *fmt,...)
void exit_horribly(const char *modulename, const char *fmt,...)
static teReqs _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
static const char * modulename

◆ processEncodingEntry()

static void processEncodingEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2722 of file pg_backup_archiver.c.

References _tocEntry::defn, encoding, Archive::encoding, exit_horribly(), free, modulename, pg_char_to_encoding(), pg_strdup(), and _archiveHandle::public.

Referenced by ReadToc().

2723 {
2724  /* te->defn should have the form SET client_encoding = 'foo'; */
2725  char *defn = pg_strdup(te->defn);
2726  char *ptr1;
2727  char *ptr2 = NULL;
2728  int encoding;
2729 
2730  ptr1 = strchr(defn, '\'');
2731  if (ptr1)
2732  ptr2 = strchr(++ptr1, '\'');
2733  if (ptr2)
2734  {
2735  *ptr2 = '\0';
2736  encoding = pg_char_to_encoding(ptr1);
2737  if (encoding < 0)
2738  exit_horribly(modulename, "unrecognized encoding \"%s\"\n",
2739  ptr1);
2740  AH->public.encoding = encoding;
2741  }
2742  else
2743  exit_horribly(modulename, "invalid ENCODING item: %s\n",
2744  te->defn);
2745 
2746  free(defn);
2747 }
int pg_char_to_encoding(const char *name)
Definition: encnames.c:551
int encoding
Definition: pg_backup.h:196
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static char * encoding
Definition: initdb.c:123
#define free(a)
Definition: header.h:65
void exit_horribly(const char *modulename, const char *fmt,...)
static const char * modulename

◆ processStdStringsEntry()

static void processStdStringsEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2750 of file pg_backup_archiver.c.

References _tocEntry::defn, exit_horribly(), modulename, _archiveHandle::public, and Archive::std_strings.

Referenced by ReadToc().

2751 {
2752  /* te->defn should have the form SET standard_conforming_strings = 'x'; */
2753  char *ptr1;
2754 
2755  ptr1 = strchr(te->defn, '\'');
2756  if (ptr1 && strncmp(ptr1, "'on'", 4) == 0)
2757  AH->public.std_strings = true;
2758  else if (ptr1 && strncmp(ptr1, "'off'", 5) == 0)
2759  AH->public.std_strings = false;
2760  else
2761  exit_horribly(modulename, "invalid STDSTRINGS item: %s\n",
2762  te->defn);
2763 }
void exit_horribly(const char *modulename, const char *fmt,...)
static const char * modulename
bool std_strings
Definition: pg_backup.h:197

◆ ReadHead()

void ReadHead ( ArchiveHandle AH)

Definition at line 3676 of file pg_backup_archiver.c.

References _archiveHandle::archdbname, _archiveHandle::archiveDumpVersion, _archiveHandle::archiveRemoteVersion, _archiveHandle::compression, _archiveHandle::createDate, exit_horribly(), _archiveHandle::format, _archiveHandle::intSize, K_VERS_1_0, K_VERS_1_10, K_VERS_1_2, K_VERS_1_4, K_VERS_1_7, K_VERS_MAX, MAKE_ARCHIVE_VERSION, modulename, _archiveHandle::offSize, _archiveHandle::ReadBufPtr, _archiveHandle::ReadBytePtr, _archiveHandle::readHeader, ReadInt(), ReadStr(), tm, _archiveHandle::version, write_msg(), and Z_DEFAULT_COMPRESSION.

Referenced by InitArchiveFmt_Custom(), InitArchiveFmt_Directory(), and InitArchiveFmt_Tar().

3677 {
3678  char tmpMag[7];
3679  int fmt;
3680  struct tm crtm;
3681 
3682  /*
3683  * If we haven't already read the header, do so.
3684  *
3685  * NB: this code must agree with _discoverArchiveFormat(). Maybe find a
3686  * way to unify the cases?
3687  */
3688  if (!AH->readHeader)
3689  {
3690  char vmaj,
3691  vmin,
3692  vrev;
3693 
3694  AH->ReadBufPtr(AH, tmpMag, 5);
3695 
3696  if (strncmp(tmpMag, "PGDMP", 5) != 0)
3697  exit_horribly(modulename, "did not find magic string in file header\n");
3698 
3699  vmaj = AH->ReadBytePtr(AH);
3700  vmin = AH->ReadBytePtr(AH);
3701 
3702  if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */
3703  vrev = AH->ReadBytePtr(AH);
3704  else
3705  vrev = 0;
3706 
3707  AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev);
3708 
3709  if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
3710  exit_horribly(modulename, "unsupported version (%d.%d) in file header\n",
3711  vmaj, vmin);
3712 
3713  AH->intSize = AH->ReadBytePtr(AH);
3714  if (AH->intSize > 32)
3715  exit_horribly(modulename, "sanity check on integer size (%lu) failed\n",
3716  (unsigned long) AH->intSize);
3717 
3718  if (AH->intSize > sizeof(int))
3719  write_msg(modulename, "WARNING: archive was made on a machine with larger integers, some operations might fail\n");
3720 
3721  if (AH->version >= K_VERS_1_7)
3722  AH->offSize = AH->ReadBytePtr(AH);
3723  else
3724  AH->offSize = AH->intSize;
3725 
3726  fmt = AH->ReadBytePtr(AH);
3727 
3728  if (AH->format != fmt)
3729  exit_horribly(modulename, "expected format (%d) differs from format found in file (%d)\n",
3730  AH->format, fmt);
3731  }
3732 
3733  if (AH->version >= K_VERS_1_2)
3734  {
3735  if (AH->version < K_VERS_1_4)
3736  AH->compression = AH->ReadBytePtr(AH);
3737  else
3738  AH->compression = ReadInt(AH);
3739  }
3740  else
3742 
3743 #ifndef HAVE_LIBZ
3744  if (AH->compression != 0)
3745  write_msg(modulename, "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n");
3746 #endif
3747 
3748  if (AH->version >= K_VERS_1_4)
3749  {
3750  crtm.tm_sec = ReadInt(AH);
3751  crtm.tm_min = ReadInt(AH);
3752  crtm.tm_hour = ReadInt(AH);
3753  crtm.tm_mday = ReadInt(AH);
3754  crtm.tm_mon = ReadInt(AH);
3755  crtm.tm_year = ReadInt(AH);
3756  crtm.tm_isdst = ReadInt(AH);
3757 
3758  AH->archdbname = ReadStr(AH);
3759 
3760  AH->createDate = mktime(&crtm);
3761 
3762  if (AH->createDate == (time_t) -1)
3763  write_msg(modulename, "WARNING: invalid creation date in header\n");
3764  }
3765 
3766  if (AH->version >= K_VERS_1_10)
3767  {
3768  AH->archiveRemoteVersion = ReadStr(AH);
3769  AH->archiveDumpVersion = ReadStr(AH);
3770  }
3771 }
ReadBufPtrType ReadBufPtr
#define Z_DEFAULT_COMPRESSION
#define K_VERS_1_0
int ReadInt(ArchiveHandle *AH)
#define K_VERS_1_4
ReadBytePtrType ReadBytePtr
static struct pg_tm tm
Definition: localtime.c:107
#define K_VERS_1_7
#define MAKE_ARCHIVE_VERSION(major, minor, rev)
#define K_VERS_1_2
#define K_VERS_1_10
ArchiveFormat format
#define K_VERS_MAX
void write_msg(const char *modulename, const char *fmt,...)
char * ReadStr(ArchiveHandle *AH)
void exit_horribly(const char *modulename, const char *fmt,...)
static const char * modulename

◆ ReadInt()

int ReadInt ( ArchiveHandle AH)

Definition at line 2030 of file pg_backup_archiver.c.

References _archiveHandle::intSize, K_VERS_1_0, _archiveHandle::ReadBytePtr, sign, and _archiveHandle::version.

Referenced by _CustomReadFunc(), _LoadBlobs(), _readBlockHeader(), _ReadExtraToc(), _skipBlobs(), _skipData(), ReadHead(), ReadOffset(), ReadStr(), and ReadToc().

2031 {
2032  int res = 0;
2033  int bv,
2034  b;
2035  int sign = 0; /* Default positive */
2036  int bitShift = 0;
2037 
2038  if (AH->version > K_VERS_1_0)
2039  /* Read a sign byte */
2040  sign = AH->ReadBytePtr(AH);
2041 
2042  for (b = 0; b < AH->intSize; b++)
2043  {
2044  bv = AH->ReadBytePtr(AH) & 0xFF;
2045  if (bv != 0)
2046  res = res + (bv << bitShift);
2047  bitShift += 8;
2048  }
2049 
2050  if (sign)
2051  res = -res;
2052 
2053  return res;
2054 }
#define K_VERS_1_0
ReadBytePtrType ReadBytePtr
char sign
Definition: informix.c:693

◆ ReadOffset()

int ReadOffset ( ArchiveHandle AH,
pgoff_t o 
)

Definition at line 1935 of file pg_backup_archiver.c.

References exit_horribly(), i, K_OFFSET_NO_DATA, K_OFFSET_POS_NOT_SET, K_OFFSET_POS_SET, K_VERS_1_7, modulename, _archiveHandle::offSize, pgoff_t, _archiveHandle::ReadBytePtr, ReadInt(), and _archiveHandle::version.

Referenced by _ReadExtraToc().

1936 {
1937  int i;
1938  int off;
1939  int offsetFlg;
1940 
1941  /* Initialize to zero */
1942  *o = 0;
1943 
1944  /* Check for old version */
1945  if (AH->version < K_VERS_1_7)
1946  {
1947  /* Prior versions wrote offsets using WriteInt */
1948  i = ReadInt(AH);
1949  /* -1 means not set */
1950  if (i < 0)
1951  return K_OFFSET_POS_NOT_SET;
1952  else if (i == 0)
1953  return K_OFFSET_NO_DATA;
1954 
1955  /* Cast to pgoff_t because it was written as an int. */
1956  *o = (pgoff_t) i;
1957  return K_OFFSET_POS_SET;
1958  }
1959 
1960  /*
1961  * Read the flag indicating the state of the data pointer. Check if valid
1962  * and die if not.
1963  *
1964  * This used to be handled by a negative or zero pointer, now we use an
1965  * extra byte specifically for the state.
1966  */
1967  offsetFlg = AH->ReadBytePtr(AH) & 0xFF;
1968 
1969  switch (offsetFlg)
1970  {
1971  case K_OFFSET_POS_NOT_SET:
1972  case K_OFFSET_NO_DATA:
1973  case K_OFFSET_POS_SET:
1974 
1975  break;
1976 
1977  default:
1978  exit_horribly(modulename, "unexpected data offset flag %d\n", offsetFlg);
1979  }
1980 
1981  /*
1982  * Read the bytes
1983  */
1984  for (off = 0; off < AH->offSize; off++)
1985  {
1986  if (off < sizeof(pgoff_t))
1987  *o |= ((pgoff_t) (AH->ReadBytePtr(AH))) << (off * 8);
1988  else
1989  {
1990  if (AH->ReadBytePtr(AH) != 0)
1991  exit_horribly(modulename, "file offset in dump file is too large\n");
1992  }
1993  }
1994 
1995  return offsetFlg;
1996 }
int ReadInt(ArchiveHandle *AH)
ReadBytePtrType ReadBytePtr
#define K_VERS_1_7
#define pgoff_t
Definition: win32_port.h:206
#define K_OFFSET_NO_DATA
void exit_horribly(const char *modulename, const char *fmt,...)
#define K_OFFSET_POS_SET
int i
static const char * modulename
#define K_OFFSET_POS_NOT_SET

◆ ReadStr()

char* ReadStr ( ArchiveHandle AH)

Definition at line 2076 of file pg_backup_archiver.c.

References buf, pg_malloc(), _archiveHandle::ReadBufPtr, and ReadInt().

Referenced by _ReadExtraToc(), ReadHead(), and ReadToc().

2077 {
2078  char *buf;
2079  int l;
2080 
2081  l = ReadInt(AH);
2082  if (l < 0)
2083  buf = NULL;
2084  else
2085  {
2086  buf = (char *) pg_malloc(l + 1);
2087  AH->ReadBufPtr(AH, (void *) buf, l);
2088 
2089  buf[l] = '\0';
2090  }
2091 
2092  return buf;
2093 }
ReadBufPtrType ReadBufPtr
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
int ReadInt(ArchiveHandle *AH)
static char * buf
Definition: pg_test_fsync.c:67

◆ ReadToc()

void ReadToc ( ArchiveHandle AH)

Definition at line 2565 of file pg_backup_archiver.c.

References ahlog(), _tocEntry::catalogId, _tocEntry::copyStmt, _tocEntry::defn, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dropStmt, _tocEntry::dumpId, exit_horribly(), free, _tocEntry::hadDumper, i, InvalidOid, K_VERS_1_10, K_VERS_1_11, K_VERS_1_3, K_VERS_1_5, K_VERS_1_6, K_VERS_1_8, K_VERS_1_9, _archiveHandle::maxDumpId, modulename, _tocEntry::nDeps, _tocEntry::next, CatalogId::oid, _tocEntry::owner, pg_malloc(), pg_malloc0(), pg_realloc(), _tocEntry::prev, processEncodingEntry(), processStdStringsEntry(), _archiveHandle::ReadExtraTocPtr, ReadInt(), ReadStr(), _tocEntry::section, SECTION_DATA, SECTION_NONE, SECTION_POST_DATA, SECTION_PRE_DATA, CatalogId::tableoid, _tocEntry::tablespace, _tocEntry::tag, _archiveHandle::toc, _archiveHandle::tocCount, _archiveHandle::version, and _tocEntry::withOids.

Referenced by InitArchiveFmt_Custom(), InitArchiveFmt_Directory(), and InitArchiveFmt_Tar().

2566 {
2567  int i;
2568  char *tmp;
2569  DumpId *deps;
2570  int depIdx;
2571  int depSize;
2572  TocEntry *te;
2573 
2574  AH->tocCount = ReadInt(AH);
2575  AH->maxDumpId = 0;
2576 
2577  for (i = 0; i < AH->tocCount; i++)
2578  {
2579  te = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2580  te->dumpId = ReadInt(AH);
2581 
2582  if (te->dumpId > AH->maxDumpId)
2583  AH->maxDumpId = te->dumpId;
2584 
2585  /* Sanity check */
2586  if (te->dumpId <= 0)
2588  "entry ID %d out of range -- perhaps a corrupt TOC\n",
2589  te->dumpId);
2590 
2591  te->hadDumper = ReadInt(AH);
2592 
2593  if (AH->version >= K_VERS_1_8)
2594  {
2595  tmp = ReadStr(AH);
2596  sscanf(tmp, "%u", &te->catalogId.tableoid);
2597  free(tmp);
2598  }
2599  else
2601  tmp = ReadStr(AH);
2602  sscanf(tmp, "%u", &te->catalogId.oid);
2603  free(tmp);
2604 
2605  te->tag = ReadStr(AH);
2606  te->desc = ReadStr(AH);
2607 
2608  if (AH->version >= K_VERS_1_11)
2609  {
2610  te->section = ReadInt(AH);
2611  }
2612  else
2613  {
2614  /*
2615  * Rules for pre-8.4 archives wherein pg_dump hasn't classified
2616  * the entries into sections. This list need not cover entry
2617  * types added later than 8.4.
2618  */
2619  if (strcmp(te->desc, "COMMENT") == 0 ||
2620  strcmp(te->desc, "ACL") == 0 ||
2621  strcmp(te->desc, "ACL LANGUAGE") == 0)
2622  te->section = SECTION_NONE;
2623  else if (strcmp(te->desc, "TABLE DATA") == 0 ||
2624  strcmp(te->desc, "BLOBS") == 0 ||
2625  strcmp(te->desc, "BLOB COMMENTS") == 0)
2626  te->section = SECTION_DATA;
2627  else if (strcmp(te->desc, "CONSTRAINT") == 0 ||
2628  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
2629  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
2630  strcmp(te->desc, "INDEX") == 0 ||
2631  strcmp(te->desc, "RULE") == 0 ||
2632  strcmp(te->desc, "TRIGGER") == 0)
2633  te->section = SECTION_POST_DATA;
2634  else
2635  te->section = SECTION_PRE_DATA;
2636  }
2637 
2638  te->defn = ReadStr(AH);
2639  te->dropStmt = ReadStr(AH);
2640 
2641  if (AH->version >= K_VERS_1_3)
2642  te->copyStmt = ReadStr(AH);
2643 
2644  if (AH->version >= K_VERS_1_6)
2645  te->namespace = ReadStr(AH);
2646 
2647  if (AH->version >= K_VERS_1_10)
2648  te->tablespace = ReadStr(AH);
2649 
2650  te->owner = ReadStr(AH);
2651  if (AH->version >= K_VERS_1_9)
2652  {
2653  if (strcmp(ReadStr(AH), "true") == 0)
2654  te->withOids = true;
2655  else
2656  te->withOids = false;
2657  }
2658  else
2659  te->withOids = true;
2660 
2661  /* Read TOC entry dependencies */
2662  if (AH->version >= K_VERS_1_5)
2663  {
2664  depSize = 100;
2665  deps = (DumpId *) pg_malloc(sizeof(DumpId) * depSize);
2666  depIdx = 0;
2667  for (;;)
2668  {
2669  tmp = ReadStr(AH);
2670  if (!tmp)
2671  break; /* end of list */
2672  if (depIdx >= depSize)
2673  {
2674  depSize *= 2;
2675  deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depSize);
2676  }
2677  sscanf(tmp, "%d", &deps[depIdx]);
2678  free(tmp);
2679  depIdx++;
2680  }
2681 
2682  if (depIdx > 0) /* We have a non-null entry */
2683  {
2684  deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depIdx);
2685  te->dependencies = deps;
2686  te->nDeps = depIdx;
2687  }
2688  else
2689  {
2690  free(deps);
2691  te->dependencies = NULL;
2692  te->nDeps = 0;
2693  }
2694  }
2695  else
2696  {
2697  te->dependencies = NULL;
2698  te->nDeps = 0;
2699  }
2700 
2701  if (AH->ReadExtraTocPtr)
2702  AH->ReadExtraTocPtr(AH, te);
2703 
2704  ahlog(AH, 3, "read TOC entry %d (ID %d) for %s %s\n",
2705  i, te->dumpId, te->desc, te->tag);
2706 
2707  /* link completed entry into TOC circular list */
2708  te->prev = AH->toc->prev;
2709  AH->toc->prev->next = te;
2710  AH->toc->prev = te;
2711  te->next = AH->toc;
2712 
2713  /* special processing immediately upon read for some items */
2714  if (strcmp(te->desc, "ENCODING") == 0)
2715  processEncodingEntry(AH, te);
2716  else if (strcmp(te->desc, "STDSTRINGS") == 0)
2717  processStdStringsEntry(AH, te);
2718  }
2719 }
struct _tocEntry * next
static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te)
int DumpId
Definition: pg_backup.h:230
Oid tableoid
Definition: pg_backup.h:226
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
CatalogId catalogId
#define K_VERS_1_9
int ReadInt(ArchiveHandle *AH)
static void processStdStringsEntry(ArchiveHandle *AH, TocEntry *te)
teSection section
#define K_VERS_1_5
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
struct _tocEntry * toc
DumpId * dependencies
#define K_VERS_1_8
#define K_VERS_1_10
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
#define K_VERS_1_3
struct _tocEntry * prev
#define InvalidOid
Definition: postgres_ext.h:36
#define free(a)
Definition: header.h:65
char * ReadStr(ArchiveHandle *AH)
void exit_horribly(const char *modulename, const char *fmt,...)
#define K_VERS_1_6
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
int i
#define K_VERS_1_11
static const char * modulename
ReadExtraTocPtrType ReadExtraTocPtr

◆ reduce_dependencies()

static void reduce_dependencies ( ArchiveHandle AH,
TocEntry te,
TocEntry ready_list 
)
static

Definition at line 4555 of file pg_backup_archiver.c.

References _tocEntryRestorePass(), ahlog(), Assert, _tocEntry::depCount, _tocEntry::dumpId, i, _tocEntry::nRevDeps, par_list_append(), par_list_remove(), _tocEntry::par_prev, _archiveHandle::restorePass, _tocEntry::revDeps, and _archiveHandle::tocsByDumpId.

Referenced by mark_restore_job_done(), restore_toc_entries_parallel(), and restore_toc_entries_prefork().

4556 {
4557  int i;
4558 
4559  ahlog(AH, 2, "reducing dependencies for %d\n", te->dumpId);
4560 
4561  for (i = 0; i < te->nRevDeps; i++)
4562  {
4563  TocEntry *otherte = AH->tocsByDumpId[te->revDeps[i]];
4564 
4565  Assert(otherte->depCount > 0);
4566  otherte->depCount--;
4567 
4568  /*
4569  * It's ready if it has no remaining dependencies, and it belongs in
4570  * the current restore pass, and it is currently a member of the
4571  * pending list (that check is needed to prevent double restore in
4572  * some cases where a list-file forces out-of-order restoring).
4573  * However, if ready_list == NULL then caller doesn't want any list
4574  * memberships changed.
4575  */
4576  if (otherte->depCount == 0 &&
4577  _tocEntryRestorePass(otherte) == AH->restorePass &&
4578  otherte->par_prev != NULL &&
4579  ready_list != NULL)
4580  {
4581  /* Remove it from pending list ... */
4582  par_list_remove(otherte);
4583  /* ... and add to ready_list */
4584  par_list_append(ready_list, otherte);
4585  }
4586  }
4587 }
RestorePass restorePass
static RestorePass _tocEntryRestorePass(TocEntry *te)
struct _tocEntry * par_prev
#define Assert(condition)
Definition: c.h:680
DumpId * revDeps
static void par_list_append(TocEntry *l, TocEntry *te)
struct _tocEntry ** tocsByDumpId
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
int i
static void par_list_remove(TocEntry *te)

◆ replace_line_endings()

static char * replace_line_endings ( const char *  str)
static

Definition at line 3630 of file pg_backup_archiver.c.

References pg_strdup().

Referenced by _printTocEntry(), and PrintTOCSummary().

3631 {
3632  char *result;
3633  char *s;
3634 
3635  result = pg_strdup(str);
3636 
3637  for (s = result; *s != '\0'; s++)
3638  {
3639  if (*s == '\n' || *s == '\r')
3640  *s = ' ';
3641  }
3642 
3643  return result;
3644 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85

◆ repoint_table_dependencies()

static void repoint_table_dependencies ( ArchiveHandle AH)
static

Definition at line 4469 of file pg_backup_archiver.c.

References ahlog(), _tocEntry::dependencies, _tocEntry::dumpId, i, _tocEntry::nDeps, _tocEntry::next, _tocEntry::section, SECTION_POST_DATA, _archiveHandle::tableDataId, and _archiveHandle::toc.

Referenced by fix_dependencies().

4470 {
4471  TocEntry *te;
4472  int i;
4473  DumpId olddep;
4474 
4475  for (te = AH->toc->next; te != AH->toc; te = te->next)
4476  {
4477  if (te->section != SECTION_POST_DATA)
4478  continue;
4479  for (i = 0; i < te->nDeps; i++)
4480  {
4481  olddep = te->dependencies[i];
4482  if (olddep <= AH->maxDumpId &&
4483  AH->tableDataId[olddep] != 0)
4484  {
4485  te->dependencies[i] = AH->tableDataId[olddep];
4486  ahlog(AH, 2, "transferring dependency %d -> %d to %d\n",
4487  te->dumpId, olddep, AH->tableDataId[olddep]);
4488  }
4489  }
4490  }
4491 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:230
teSection section
struct _tocEntry * toc
DumpId * dependencies
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
int i

◆ restore_toc_entries_parallel()

static void restore_toc_entries_parallel ( ArchiveHandle AH,