PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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, SetupWorkerPtr setupWorkerPtr)
 
static void _getObjectDescription (PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
 
static void _printTocEntry (ArchiveHandle *AH, TocEntry *te, bool isData, bool acl_pass)
 
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 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)
 
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 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, SetupWorkerPtr 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

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

Definition at line 42 of file pg_backup_archiver.c.

Referenced by _discoverArchiveFormat().

#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

Function Documentation

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

Definition at line 2274 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, NULL, _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().

2277 {
2278  ArchiveHandle *AH;
2279 
2280 #if 0
2281  write_msg(modulename, "allocating AH for %s, format %d\n", FileSpec, fmt);
2282 #endif
2283 
2284  AH = (ArchiveHandle *) pg_malloc0(sizeof(ArchiveHandle));
2285 
2286  /* AH->debugLevel = 100; */
2287 
2288  AH->version = K_VERS_SELF;
2289 
2290  /* initialize for backwards compatible string processing */
2291  AH->public.encoding = 0; /* PG_SQL_ASCII */
2292  AH->public.std_strings = false;
2293 
2294  /* sql error handling */
2295  AH->public.exit_on_error = true;
2296  AH->public.n_errors = 0;
2297 
2298  AH->archiveDumpVersion = PG_VERSION;
2299 
2300  AH->createDate = time(NULL);
2301 
2302  AH->intSize = sizeof(int);
2303  AH->offSize = sizeof(pgoff_t);
2304  if (FileSpec)
2305  {
2306  AH->fSpec = pg_strdup(FileSpec);
2307 
2308  /*
2309  * Not used; maybe later....
2310  *
2311  * AH->workDir = pg_strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;
2312  * i--) if (AH->workDir[i-1] == '/')
2313  */
2314  }
2315  else
2316  AH->fSpec = NULL;
2317 
2318  AH->currUser = NULL; /* unknown */
2319  AH->currSchema = NULL; /* ditto */
2320  AH->currTablespace = NULL; /* ditto */
2321  AH->currWithOids = -1; /* force SET */
2322 
2323  AH->toc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2324 
2325  AH->toc->next = AH->toc;
2326  AH->toc->prev = AH->toc;
2327 
2328  AH->mode = mode;
2329  AH->compression = compression;
2330  AH->dosync = dosync;
2331 
2332  memset(&(AH->sqlparse), 0, sizeof(AH->sqlparse));
2333 
2334  /* Open stdout with no compression for AH output handle */
2335  AH->gzOut = 0;
2336  AH->OF = stdout;
2337 
2338  /*
2339  * On Windows, we need to use binary mode to read/write non-text archive
2340  * formats. Force stdin/stdout into binary mode if that is what we are
2341  * using.
2342  */
2343 #ifdef WIN32
2344  if (fmt != archNull &&
2345  (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0))
2346  {
2347  if (mode == archModeWrite)
2348  setmode(fileno(stdout), O_BINARY);
2349  else
2350  setmode(fileno(stdin), O_BINARY);
2351  }
2352 #endif
2353 
2354  AH->SetupWorkerPtr = setupWorkerPtr;
2355 
2356  if (fmt == archUnknown)
2357  AH->format = _discoverArchiveFormat(AH);
2358  else
2359  AH->format = fmt;
2360 
2362 
2363  switch (AH->format)
2364  {
2365  case archCustom:
2367  break;
2368 
2369  case archNull:
2370  InitArchiveFmt_Null(AH);
2371  break;
2372 
2373  case archDirectory:
2375  break;
2376 
2377  case archTar:
2378  InitArchiveFmt_Tar(AH);
2379  break;
2380 
2381  default:
2382  exit_horribly(modulename, "unrecognized file format \"%d\"\n", fmt);
2383  }
2384 
2385  return AH;
2386 }
struct _tocEntry * next
#define K_VERS_SELF
static bool dosync
Definition: pg_dump.c:92
void InitArchiveFmt_Tar(ArchiveHandle *AH)
SetupWorkerPtr SetupWorkerPtr
int n_errors
Definition: pg_backup.h:201
int encoding
Definition: pg_backup.h:195
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
#define pgoff_t
Definition: win32.h:241
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,...)
#define NULL
Definition: c.h:229
void exit_horribly(const char *modulename, const char *fmt,...)
bool exit_on_error
Definition: pg_backup.h:200
static const char * modulename
bool std_strings
Definition: pg_backup.h:196
static void _becomeOwner ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 3149 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().

3150 {
3151  RestoreOptions *ropt = AH->public.ropt;
3152 
3153  if (ropt && (ropt->noOwner || !ropt->use_setsessauth))
3154  return;
3155 
3156  _becomeUser(AH, te->owner);
3157 }
RestoreOptions * ropt
Definition: pg_backup.h:180
static void _becomeUser(ArchiveHandle *AH, const char *user)
int use_setsessauth
Definition: pg_backup.h:68
static void _becomeUser ( ArchiveHandle AH,
const char *  user 
)
static

Definition at line 3125 of file pg_backup_archiver.c.

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

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

3126 {
3127  if (!user)
3128  user = ""; /* avoid null pointers */
3129 
3130  if (AH->currUser && strcmp(AH->currUser, user) == 0)
3131  return; /* no need to do anything */
3132 
3133  _doSetSessionAuth(AH, user);
3134 
3135  /*
3136  * NOTE: currUser keeps track of what the imaginary session user in our
3137  * script is
3138  */
3139  if (AH->currUser)
3140  free(AH->currUser);
3141  AH->currUser = pg_strdup(user);
3142 }
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:92
static void _disableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 946 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().

947 {
948  RestoreOptions *ropt = AH->public.ropt;
949 
950  /* This hack is only needed in a data-only restore */
951  if (!ropt->dataOnly || !ropt->disable_triggers)
952  return;
953 
954  ahlog(AH, 1, "disabling triggers for %s\n", te->tag);
955 
956  /*
957  * Become superuser if possible, since they are the only ones who can
958  * disable constraint triggers. If -S was not given, assume the initial
959  * user identity is a superuser. (XXX would it be better to become the
960  * table owner?)
961  */
962  _becomeUser(AH, ropt->superuser);
963 
964  /*
965  * Disable them.
966  */
967  _selectOutputSchema(AH, te->namespace);
968 
969  ahprintf(AH, "ALTER TABLE %s DISABLE TRIGGER ALL;\n\n",
970  fmtId(te->tag));
971 }
RestoreOptions * ropt
Definition: pg_backup.h:180
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
static int _discoverArchiveFormat ( ArchiveHandle AH)
static

Definition at line 2069 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, NULL, _archiveHandle::offSize, PG_BINARY_R, pg_malloc0(), READ_ERROR_EXIT, _archiveHandle::readHeader, sig, snprintf(), strerror(), TEXT_DUMP_HEADER, TEXT_DUMPALL_HEADER, _archiveHandle::version, and write_msg().

Referenced by _allocAH().

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

Definition at line 2956 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().

2957 {
2958  RestoreOptions *ropt = AH->public.ropt;
2959 
2960  /*
2961  * Disable timeouts to allow for slow commands, idle parallel workers, etc
2962  */
2963  ahprintf(AH, "SET statement_timeout = 0;\n");
2964  ahprintf(AH, "SET lock_timeout = 0;\n");
2965  ahprintf(AH, "SET idle_in_transaction_session_timeout = 0;\n");
2966 
2967  /* Select the correct character set encoding */
2968  ahprintf(AH, "SET client_encoding = '%s';\n",
2970 
2971  /* Select the correct string literal syntax */
2972  ahprintf(AH, "SET standard_conforming_strings = %s;\n",
2973  AH->public.std_strings ? "on" : "off");
2974 
2975  /* Select the role to be used during restore */
2976  if (ropt && ropt->use_role)
2977  ahprintf(AH, "SET ROLE %s;\n", fmtId(ropt->use_role));
2978 
2979  /* Make sure function checking is disabled */
2980  ahprintf(AH, "SET check_function_bodies = false;\n");
2981 
2982  /* Avoid annoying notices etc */
2983  ahprintf(AH, "SET client_min_messages = warning;\n");
2984  if (!AH->public.std_strings)
2985  ahprintf(AH, "SET escape_string_warning = off;\n");
2986 
2987  /* Adjust row-security state */
2988  if (ropt && ropt->enable_row_security)
2989  ahprintf(AH, "SET row_security = on;\n");
2990  else
2991  ahprintf(AH, "SET row_security = off;\n");
2992 
2993  ahprintf(AH, "\n");
2994 }
RestoreOptions * ropt
Definition: pg_backup.h:180
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:195
int enable_row_security
Definition: pg_backup.h:120
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:196
static void _doSetSessionAuth ( ArchiveHandle AH,
const char *  user 
)
static

Definition at line 3002 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().

3003 {
3005 
3006  appendPQExpBufferStr(cmd, "SET SESSION AUTHORIZATION ");
3007 
3008  /*
3009  * SQL requires a string literal here. Might as well be correct.
3010  */
3011  if (user && *user)
3012  appendStringLiteralAHX(cmd, user, AH);
3013  else
3014  appendPQExpBufferStr(cmd, "DEFAULT");
3015  appendPQExpBufferChar(cmd, ';');
3016 
3017  if (RestoringToDB(AH))
3018  {
3019  PGresult *res;
3020 
3021  res = PQexec(AH->connection, cmd->data);
3022 
3023  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3024  /* NOT warn_or_exit_horribly... use -O instead to skip this. */
3025  exit_horribly(modulename, "could not set session user to \"%s\": %s",
3027 
3028  PQclear(res);
3029  }
3030  else
3031  ahprintf(AH, "%s\n\n", cmd->data);
3032 
3033  destroyPQExpBuffer(cmd);
3034 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6011
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
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:650
#define appendStringLiteralAHX(buf, str, AH)
void exit_horribly(const char *modulename, const char *fmt,...)
static char * user
Definition: pg_regress.c:92
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
static const char * modulename
static void _doSetWithOids ( ArchiveHandle AH,
const bool  withOids 
)
static

Definition at line 3042 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().

3043 {
3045 
3046  appendPQExpBuffer(cmd, "SET default_with_oids = %s;", withOids ?
3047  "true" : "false");
3048 
3049  if (RestoringToDB(AH))
3050  {
3051  PGresult *res;
3052 
3053  res = PQexec(AH->connection, cmd->data);
3054 
3055  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3057  "could not set default_with_oids: %s",
3058  PQerrorMessage(AH->connection));
3059 
3060  PQclear(res);
3061  }
3062  else
3063  ahprintf(AH, "%s\n\n", cmd->data);
3064 
3065  destroyPQExpBuffer(cmd);
3066 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6011
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
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:650
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
static const char * modulename
static void _enableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 974 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().

975 {
976  RestoreOptions *ropt = AH->public.ropt;
977 
978  /* This hack is only needed in a data-only restore */
979  if (!ropt->dataOnly || !ropt->disable_triggers)
980  return;
981 
982  ahlog(AH, 1, "enabling triggers for %s\n", te->tag);
983 
984  /*
985  * Become superuser if possible, since they are the only ones who can
986  * disable constraint triggers. If -S was not given, assume the initial
987  * user identity is a superuser. (XXX would it be better to become the
988  * table owner?)
989  */
990  _becomeUser(AH, ropt->superuser);
991 
992  /*
993  * Enable them.
994  */
995  _selectOutputSchema(AH, te->namespace);
996 
997  ahprintf(AH, "ALTER TABLE %s ENABLE TRIGGER ALL;\n\n",
998  fmtId(te->tag));
999 }
RestoreOptions * ropt
Definition: pg_backup.h:180
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
static void _getObjectDescription ( PQExpBuffer  buf,
TocEntry te,
ArchiveHandle AH 
)
static

Definition at line 3285 of file pg_backup_archiver.c.

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

Referenced by _printTocEntry().

3286 {
3287  const char *type = te->desc;
3288 
3289  /* Use ALTER TABLE for views and sequences */
3290  if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0 ||
3291  strcmp(type, "MATERIALIZED VIEW") == 0)
3292  type = "TABLE";
3293 
3294  /* objects that don't require special decoration */
3295  if (strcmp(type, "COLLATION") == 0 ||
3296  strcmp(type, "CONVERSION") == 0 ||
3297  strcmp(type, "DOMAIN") == 0 ||
3298  strcmp(type, "TABLE") == 0 ||
3299  strcmp(type, "TYPE") == 0 ||
3300  strcmp(type, "FOREIGN TABLE") == 0 ||
3301  strcmp(type, "TEXT SEARCH DICTIONARY") == 0 ||
3302  strcmp(type, "TEXT SEARCH CONFIGURATION") == 0 ||
3303  /* non-schema-specified objects */
3304  strcmp(type, "DATABASE") == 0 ||
3305  strcmp(type, "PROCEDURAL LANGUAGE") == 0 ||
3306  strcmp(type, "SCHEMA") == 0 ||
3307  strcmp(type, "FOREIGN DATA WRAPPER") == 0 ||
3308  strcmp(type, "SERVER") == 0 ||
3309  strcmp(type, "PUBLICATION") == 0 ||
3310  strcmp(type, "SUBSCRIPTION") == 0 ||
3311  strcmp(type, "USER MAPPING") == 0)
3312  {
3313  /* We already know that search_path was set properly */
3314  appendPQExpBuffer(buf, "%s %s", type, fmtId(te->tag));
3315  return;
3316  }
3317 
3318  /* BLOBs just have a name, but it's numeric so must not use fmtId */
3319  if (strcmp(type, "BLOB") == 0)
3320  {
3321  appendPQExpBuffer(buf, "LARGE OBJECT %s", te->tag);
3322  return;
3323  }
3324 
3325  /*
3326  * These object types require additional decoration. Fortunately, the
3327  * information needed is exactly what's in the DROP command.
3328  */
3329  if (strcmp(type, "AGGREGATE") == 0 ||
3330  strcmp(type, "FUNCTION") == 0 ||
3331  strcmp(type, "OPERATOR") == 0 ||
3332  strcmp(type, "OPERATOR CLASS") == 0 ||
3333  strcmp(type, "OPERATOR FAMILY") == 0)
3334  {
3335  /* Chop "DROP " off the front and make a modifiable copy */
3336  char *first = pg_strdup(te->dropStmt + 5);
3337  char *last;
3338 
3339  /* point to last character in string */
3340  last = first + strlen(first) - 1;
3341 
3342  /* Strip off any ';' or '\n' at the end */
3343  while (last >= first && (*last == '\n' || *last == ';'))
3344  last--;
3345  *(last + 1) = '\0';
3346 
3347  appendPQExpBufferStr(buf, first);
3348 
3349  free(first);
3350  return;
3351  }
3352 
3353  write_msg(modulename, "WARNING: don't know how to set owner for object type %s\n",
3354  type);
3355 }
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
static void _moveBefore ( ArchiveHandle AH,
TocEntry pos,
TocEntry te 
)
static

Definition at line 1801 of file pg_backup_archiver.c.

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

Referenced by SortTocFromFile().

1802 {
1803  /* Unlink te from list */
1804  te->prev->next = te->next;
1805  te->next->prev = te->prev;
1806 
1807  /* and insert it before "pos" */
1808  te->prev = pos->prev;
1809  te->next = pos;
1810  pos->prev->next = te;
1811  pos->prev = te;
1812 }
struct _tocEntry * next
struct _tocEntry * prev
static void _printTocEntry ( ArchiveHandle AH,
TocEntry te,
bool  isData,
bool  acl_pass 
)
static

Definition at line 3358 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, NULL, 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(), and RestoreArchive().

3359 {
3360  RestoreOptions *ropt = AH->public.ropt;
3361 
3362  /* ACLs are dumped only during acl pass */
3363  if (acl_pass)
3364  {
3365  if (!_tocEntryIsACL(te))
3366  return;
3367  }
3368  else
3369  {
3370  if (_tocEntryIsACL(te))
3371  return;
3372  }
3373 
3374  /*
3375  * Avoid dumping the public schema, as it will already be created ...
3376  * unless we are using --clean mode (and *not* --create mode), in which
3377  * case we've previously issued a DROP for it so we'd better recreate it.
3378  *
3379  * Likewise for its comment, if any. (We could try issuing the COMMENT
3380  * command anyway; but it'd fail if the restore is done as non-super-user,
3381  * so let's not.)
3382  *
3383  * XXX it looks pretty ugly to hard-wire the public schema like this, but
3384  * it sits in a sort of no-mans-land between being a system object and a
3385  * user object, so it really is special in a way.
3386  */
3387  if (!(ropt->dropSchema && !ropt->createDB))
3388  {
3389  if (strcmp(te->desc, "SCHEMA") == 0 &&
3390  strcmp(te->tag, "public") == 0)
3391  return;
3392  if (strcmp(te->desc, "COMMENT") == 0 &&
3393  strcmp(te->tag, "SCHEMA public") == 0)
3394  return;
3395  }
3396 
3397  /* Select owner, schema, and tablespace as necessary */
3398  _becomeOwner(AH, te);
3399  _selectOutputSchema(AH, te->namespace);
3400  _selectTablespace(AH, te->tablespace);
3401 
3402  /* Set up OID mode too */
3403  if (strcmp(te->desc, "TABLE") == 0)
3404  _setWithOids(AH, te);
3405 
3406  /* Emit header comment for item */
3407  if (!AH->noTocComments)
3408  {
3409  const char *pfx;
3410  char *sanitized_name;
3411  char *sanitized_schema;
3412  char *sanitized_owner;
3413 
3414  if (isData)
3415  pfx = "Data for ";
3416  else
3417  pfx = "";
3418 
3419  ahprintf(AH, "--\n");
3420  if (AH->public.verbose)
3421  {
3422  ahprintf(AH, "-- TOC entry %d (class %u OID %u)\n",
3423  te->dumpId, te->catalogId.tableoid, te->catalogId.oid);
3424  if (te->nDeps > 0)
3425  {
3426  int i;
3427 
3428  ahprintf(AH, "-- Dependencies:");
3429  for (i = 0; i < te->nDeps; i++)
3430  ahprintf(AH, " %d", te->dependencies[i]);
3431  ahprintf(AH, "\n");
3432  }
3433  }
3434 
3435  /*
3436  * Zap any line endings embedded in user-supplied fields, to prevent
3437  * corruption of the dump (which could, in the worst case, present an
3438  * SQL injection vulnerability if someone were to incautiously load a
3439  * dump containing objects with maliciously crafted names).
3440  */
3441  sanitized_name = replace_line_endings(te->tag);
3442  if (te->namespace)
3443  sanitized_schema = replace_line_endings(te->namespace);
3444  else
3445  sanitized_schema = pg_strdup("-");
3446  if (!ropt->noOwner)
3447  sanitized_owner = replace_line_endings(te->owner);
3448  else
3449  sanitized_owner = pg_strdup("-");
3450 
3451  ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
3452  pfx, sanitized_name, te->desc, sanitized_schema,
3453  sanitized_owner);
3454 
3455  free(sanitized_name);
3456  free(sanitized_schema);
3457  free(sanitized_owner);
3458 
3459  if (te->tablespace && strlen(te->tablespace) > 0 && !ropt->noTablespace)
3460  {
3461  char *sanitized_tablespace;
3462 
3463  sanitized_tablespace = replace_line_endings(te->tablespace);
3464  ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
3465  free(sanitized_tablespace);
3466  }
3467  ahprintf(AH, "\n");
3468 
3469  if (AH->PrintExtraTocPtr !=NULL)
3470  (*AH->PrintExtraTocPtr) (AH, te);
3471  ahprintf(AH, "--\n\n");
3472  }
3473 
3474  /*
3475  * Actually print the definition.
3476  *
3477  * Really crude hack for suppressing AUTHORIZATION clause that old pg_dump
3478  * versions put into CREATE SCHEMA. We have to do this when --no-owner
3479  * mode is selected. This is ugly, but I see no other good way ...
3480  */
3481  if (ropt->noOwner && strcmp(te->desc, "SCHEMA") == 0)
3482  {
3483  ahprintf(AH, "CREATE SCHEMA %s;\n\n\n", fmtId(te->tag));
3484  }
3485  else
3486  {
3487  if (strlen(te->defn) > 0)
3488  ahprintf(AH, "%s\n\n", te->defn);
3489  }
3490 
3491  /*
3492  * If we aren't using SET SESSION AUTH to determine ownership, we must
3493  * instead issue an ALTER OWNER command. We assume that anything without
3494  * a DROP command is not a separately ownable object. All the categories
3495  * with DROP commands must appear in one list or the other.
3496  */
3497  if (!ropt->noOwner && !ropt->use_setsessauth &&
3498  strlen(te->owner) > 0 && strlen(te->dropStmt) > 0)
3499  {
3500  if (strcmp(te->desc, "AGGREGATE") == 0 ||
3501  strcmp(te->desc, "BLOB") == 0 ||
3502  strcmp(te->desc, "COLLATION") == 0 ||
3503  strcmp(te->desc, "CONVERSION") == 0 ||
3504  strcmp(te->desc, "DATABASE") == 0 ||
3505  strcmp(te->desc, "DOMAIN") == 0 ||
3506  strcmp(te->desc, "FUNCTION") == 0 ||
3507  strcmp(te->desc, "OPERATOR") == 0 ||
3508  strcmp(te->desc, "OPERATOR CLASS") == 0 ||
3509  strcmp(te->desc, "OPERATOR FAMILY") == 0 ||
3510  strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 ||
3511  strcmp(te->desc, "SCHEMA") == 0 ||
3512  strcmp(te->desc, "TABLE") == 0 ||
3513  strcmp(te->desc, "TYPE") == 0 ||
3514  strcmp(te->desc, "VIEW") == 0 ||
3515  strcmp(te->desc, "MATERIALIZED VIEW") == 0 ||
3516  strcmp(te->desc, "SEQUENCE") == 0 ||
3517  strcmp(te->desc, "FOREIGN TABLE") == 0 ||
3518  strcmp(te->desc, "TEXT SEARCH DICTIONARY") == 0 ||
3519  strcmp(te->desc, "TEXT SEARCH CONFIGURATION") == 0 ||
3520  strcmp(te->desc, "FOREIGN DATA WRAPPER") == 0 ||
3521  strcmp(te->desc, "SERVER") == 0 ||
3522  strcmp(te->desc, "PUBLICATION") == 0 ||
3523  strcmp(te->desc, "SUBSCRIPTION") == 0)
3524  {
3525  PQExpBuffer temp = createPQExpBuffer();
3526 
3527  appendPQExpBufferStr(temp, "ALTER ");
3528  _getObjectDescription(temp, te, AH);
3529  appendPQExpBuffer(temp, " OWNER TO %s;", fmtId(te->owner));
3530  ahprintf(AH, "%s\n\n", temp->data);
3531  destroyPQExpBuffer(temp);
3532  }
3533  else if (strcmp(te->desc, "CAST") == 0 ||
3534  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
3535  strcmp(te->desc, "CONSTRAINT") == 0 ||
3536  strcmp(te->desc, "DEFAULT") == 0 ||
3537  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
3538  strcmp(te->desc, "INDEX") == 0 ||
3539  strcmp(te->desc, "RULE") == 0 ||
3540  strcmp(te->desc, "TRIGGER") == 0 ||
3541  strcmp(te->desc, "ROW SECURITY") == 0 ||
3542  strcmp(te->desc, "POLICY") == 0 ||
3543  strcmp(te->desc, "USER MAPPING") == 0 ||
3544  strcmp(te->desc, "STATISTICS") == 0)
3545  {
3546  /* these object types don't have separate owners */
3547  }
3548  else
3549  {
3550  write_msg(modulename, "WARNING: don't know how to set owner for object type %s\n",
3551  te->desc);
3552  }
3553  }
3554 
3555  /*
3556  * If it's an ACL entry, it might contain SET SESSION AUTHORIZATION
3557  * commands, so we can no longer assume we know the current auth setting.
3558  */
3559  if (acl_pass)
3560  {
3561  if (AH->currUser)
3562  free(AH->currUser);
3563  AH->currUser = NULL;
3564  }
3565 }
Oid tableoid
Definition: pg_backup.h:225
RestoreOptions * ropt
Definition: pg_backup.h:180
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
PrintExtraTocPtr PrintExtraTocPtr
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:182
#define free(a)
Definition: header.h:65
void write_msg(const char *modulename, const char *fmt,...)
#define NULL
Definition: c.h:229
static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
int i
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
static const char * modulename
static void _selectTablespace(ArchiveHandle *AH, const char *tablespace)
static void _reconnectToDB ( ArchiveHandle AH,
const char *  dbname 
)
static

Definition at line 3079 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entry().

3080 {
3081  if (RestoringToDB(AH))
3083  else
3084  {
3085  if (dbname)
3086  {
3087  PQExpBufferData connectbuf;
3088 
3089  initPQExpBuffer(&connectbuf);
3090  appendPsqlMetaConnect(&connectbuf, dbname);
3091  ahprintf(AH, "%s\n", connectbuf.data);
3092  termPQExpBuffer(&connectbuf);
3093  }
3094  else
3095  ahprintf(AH, "%s\n", "\\connect -\n");
3096  }
3097 
3098  /*
3099  * NOTE: currUser keeps track of what the imaginary session user in our
3100  * script is. It's now effectively reset to the original userID.
3101  */
3102  if (AH->currUser)
3103  free(AH->currUser);
3104  AH->currUser = NULL;
3105 
3106  /* don't assume we still know the output schema, tablespace, etc either */
3107  if (AH->currSchema)
3108  free(AH->currSchema);
3109  AH->currSchema = NULL;
3110  if (AH->currTablespace)
3111  free(AH->currTablespace);
3112  AH->currTablespace = NULL;
3113  AH->currWithOids = -1;
3114 
3115  /* re-establish fixed state */
3117 }
static int RestoringToDB(ArchiveHandle *AH)
int ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser)
Definition: pg_backup_db.c:88
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
Definition: string_utils.c:581
static void _doSetFixedOutputState(ArchiveHandle *AH)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
char * dbname
Definition: streamutil.c:38
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
static void _selectOutputSchema ( ArchiveHandle AH,
const char *  schemaName 
)
static

Definition at line 3179 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().

3180 {
3181  PQExpBuffer qry;
3182 
3183  if (!schemaName || *schemaName == '\0' ||
3184  (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
3185  return; /* no need to do anything */
3186 
3187  qry = createPQExpBuffer();
3188 
3189  appendPQExpBuffer(qry, "SET search_path = %s",
3190  fmtId(schemaName));
3191  if (strcmp(schemaName, "pg_catalog") != 0)
3192  appendPQExpBufferStr(qry, ", pg_catalog");
3193 
3194  if (RestoringToDB(AH))
3195  {
3196  PGresult *res;
3197 
3198  res = PQexec(AH->connection, qry->data);
3199 
3200  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3202  "could not set search_path to \"%s\": %s",
3203  schemaName, PQerrorMessage(AH->connection));
3204 
3205  PQclear(res);
3206  }
3207  else
3208  ahprintf(AH, "%s;\n\n", qry->data);
3209 
3210  if (AH->currSchema)
3211  free(AH->currSchema);
3212  AH->currSchema = pg_strdup(schemaName);
3213 
3214  destroyPQExpBuffer(qry);
3215 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6011
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:2596
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:650
#define free(a)
Definition: header.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
static const char * modulename
static void _selectTablespace ( ArchiveHandle AH,
const char *  tablespace 
)
static

Definition at line 3222 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().

3223 {
3224  RestoreOptions *ropt = AH->public.ropt;
3225  PQExpBuffer qry;
3226  const char *want,
3227  *have;
3228 
3229  /* do nothing in --no-tablespaces mode */
3230  if (ropt->noTablespace)
3231  return;
3232 
3233  have = AH->currTablespace;
3234  want = tablespace;
3235 
3236  /* no need to do anything for non-tablespace object */
3237  if (!want)
3238  return;
3239 
3240  if (have && strcmp(want, have) == 0)
3241  return; /* no need to do anything */
3242 
3243  qry = createPQExpBuffer();
3244 
3245  if (strcmp(want, "") == 0)
3246  {
3247  /* We want the tablespace to be the database's default */
3248  appendPQExpBufferStr(qry, "SET default_tablespace = ''");
3249  }
3250  else
3251  {
3252  /* We want an explicit tablespace */
3253  appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
3254  }
3255 
3256  if (RestoringToDB(AH))
3257  {
3258  PGresult *res;
3259 
3260  res = PQexec(AH->connection, qry->data);
3261 
3262  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3264  "could not set default_tablespace to %s: %s",
3265  fmtId(want), PQerrorMessage(AH->connection));
3266 
3267  PQclear(res);
3268  }
3269  else
3270  ahprintf(AH, "%s;\n\n", qry->data);
3271 
3272  if (AH->currTablespace)
3273  free(AH->currTablespace);
3274  AH->currTablespace = pg_strdup(want);
3275 
3276  destroyPQExpBuffer(qry);
3277 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6011
RestoreOptions * ropt
Definition: pg_backup.h:180
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:2596
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:650
#define free(a)
Definition: header.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
static const char * modulename
static void _setWithOids ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 3164 of file pg_backup_archiver.c.

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

Referenced by _printTocEntry().

3165 {
3166  if (AH->currWithOids != te->withOids)
3167  {
3168  _doSetWithOids(AH, te->withOids);
3169  AH->currWithOids = te->withOids;
3170  }
3171 }
static void _doSetWithOids(ArchiveHandle *AH, const bool withOids)
static bool _tocEntryIsACL ( TocEntry te)
static

Definition at line 2941 of file pg_backup_archiver.c.

References _tocEntry::desc.

Referenced by _printTocEntry(), _tocEntryRequired(), restore_toc_entries_parallel(), and restore_toc_entry().

2942 {
2943  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
2944  if (strcmp(te->desc, "ACL") == 0 ||
2945  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
2946  strcmp(te->desc, "DEFAULT ACL") == 0)
2947  return true;
2948  return false;
2949 }
static teReqs _tocEntryRequired ( TocEntry te,
teSection  curSection,
RestoreOptions ropt 
)
static

Definition at line 2782 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_security_labels, NULL, 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().

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

Definition at line 1585 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().

1586 {
1587  char *p;
1588  size_t len = 128; /* initial assumption about buffer size */
1589  size_t cnt;
1590 
1591  for (;;)
1592  {
1593  va_list args;
1594 
1595  /* Allocate work buffer. */
1596  p = (char *) pg_malloc(len);
1597 
1598  /* Try to format the data. */
1599  va_start(args, fmt);
1600  cnt = pvsnprintf(p, len, fmt, args);
1601  va_end(args);
1602 
1603  if (cnt < len)
1604  break; /* success */
1605 
1606  /* Release buffer and loop around to try again with larger len. */
1607  free(p);
1608  len = cnt;
1609  }
1610 
1611  ahwrite(p, 1, cnt, AH);
1612  free(p);
1613  return (int) cnt;
1614 }
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)
void ahwrite ( const void *  ptr,
size_t  size,
size_t  nmemb,
ArchiveHandle AH 
)

Definition at line 1687 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(), and ReadDataFromArchiveNone().

1688 {
1689  int bytes_written = 0;
1690 
1691  if (AH->writingBlob)
1692  {
1693  size_t remaining = size * nmemb;
1694 
1695  while (AH->lo_buf_used + remaining > AH->lo_buf_size)
1696  {
1697  size_t avail = AH->lo_buf_size - AH->lo_buf_used;
1698 
1699  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, avail);
1700  ptr = (const void *) ((const char *) ptr + avail);
1701  remaining -= avail;
1702  AH->lo_buf_used += avail;
1703  dump_lo_buf(AH);
1704  }
1705 
1706  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
1707  AH->lo_buf_used += remaining;
1708 
1709  bytes_written = size * nmemb;
1710  }
1711  else if (AH->gzOut)
1712  bytes_written = GZWRITE(ptr, size, nmemb, AH->OF);
1713  else if (AH->CustomOutPtr)
1714  bytes_written = AH->CustomOutPtr (AH, ptr, size * nmemb);
1715 
1716  else
1717  {
1718  /*
1719  * If we're doing a restore, and it's direct to DB, and we're
1720  * connected then send it to the DB.
1721  */
1722  if (RestoringToDB(AH))
1723  bytes_written = ExecuteSqlCommandBuf(&AH->public, (const char *) ptr, size * nmemb);
1724  else
1725  bytes_written = fwrite(ptr, size, nmemb, AH->OF) * size;
1726  }
1727 
1728  if (bytes_written != size * nmemb)
1730 
1731  return;
1732 }
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:574
static void dump_lo_buf(ArchiveHandle *AH)
#define GZWRITE(p, s, n, fh)
CustomOutPtr CustomOutPtr
#define WRITE_ERROR_EXIT
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 1026 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, NULL, pg_malloc(), pg_malloc0(), pg_strdup(), _tocEntry::prev, _tocEntry::section, _tocEntry::tag, _archiveHandle::toc, and _archiveHandle::tocCount.

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().

1037 {
1038  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1039  TocEntry *newToc;
1040 
1041  newToc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
1042 
1043  AH->tocCount++;
1044  if (dumpId > AH->maxDumpId)
1045  AH->maxDumpId = dumpId;
1046 
1047  newToc->prev = AH->toc->prev;
1048  newToc->next = AH->toc;
1049  AH->toc->prev->next = newToc;
1050  AH->toc->prev = newToc;
1051 
1052  newToc->catalogId = catalogId;
1053  newToc->dumpId = dumpId;
1054  newToc->section = section;
1055 
1056  newToc->tag = pg_strdup(tag);
1057  newToc->namespace = namespace ? pg_strdup(namespace) : NULL;
1058  newToc->tablespace = tablespace ? pg_strdup(tablespace) : NULL;
1059  newToc->owner = pg_strdup(owner);
1060  newToc->withOids = withOids;
1061  newToc->desc = pg_strdup(desc);
1062  newToc->defn = pg_strdup(defn);
1063  newToc->dropStmt = pg_strdup(dropStmt);
1064  newToc->copyStmt = copyStmt ? pg_strdup(copyStmt) : NULL;
1065 
1066  if (nDeps > 0)
1067  {
1068  newToc->dependencies = (DumpId *) pg_malloc(nDeps * sizeof(DumpId));
1069  memcpy(newToc->dependencies, deps, nDeps * sizeof(DumpId));
1070  newToc->nDeps = nDeps;
1071  }
1072  else
1073  {
1074  newToc->dependencies = NULL;
1075  newToc->nDeps = 0;
1076  }
1077 
1078  newToc->dataDumper = dumpFn;
1079  newToc->dataDumperArg = dumpArg;
1080  newToc->hadDumper = dumpFn ? true : false;
1081 
1082  newToc->formatData = NULL;
1083 
1084  if (AH->ArchiveEntryPtr !=NULL)
1085  (*AH->ArchiveEntryPtr) (AH, newToc);
1086 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:229
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
CatalogId catalogId
void * dataDumperArg
DataDumperPtr dataDumper
teSection section
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
ArchiveEntryPtr ArchiveEntryPtr
struct _tocEntry * prev
#define NULL
Definition: c.h:229
int archprintf ( Archive AH,
const char *  fmt,
  ... 
)

Definition at line 1452 of file pg_backup_archiver.c.

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

1453 {
1454  char *p;
1455  size_t len = 128; /* initial assumption about buffer size */
1456  size_t cnt;
1457 
1458  for (;;)
1459  {
1460  va_list args;
1461 
1462  /* Allocate work buffer. */
1463  p = (char *) pg_malloc(len);
1464 
1465  /* Try to format the data. */
1466  va_start(args, fmt);
1467  cnt = pvsnprintf(p, len, fmt, args);
1468  va_end(args);
1469 
1470  if (cnt < len)
1471  break; /* success */
1472 
1473  /* Release buffer and loop around to try again with larger len. */
1474  free(p);
1475  len = cnt;
1476  }
1477 
1478  WriteData(AH, p, cnt);
1479  free(p);
1480  return (int) cnt;
1481 }
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
void archputs ( const char *  s,
Archive AH 
)

Definition at line 1444 of file pg_backup_archiver.c.

References WriteData().

Referenced by dumpTableData_insert().

1445 {
1446  WriteData(AH, s, strlen(s));
1447  return;
1448 }
void WriteData(Archive *AHX, const void *data, size_t dLen)
static void buildTocEntryArrays ( ArchiveHandle AH)
static

Definition at line 1826 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().

1827 {
1828  DumpId maxDumpId = AH->maxDumpId;
1829  TocEntry *te;
1830 
1831  AH->tocsByDumpId = (TocEntry **) pg_malloc0((maxDumpId + 1) * sizeof(TocEntry *));
1832  AH->tableDataId = (DumpId *) pg_malloc0((maxDumpId + 1) * sizeof(DumpId));
1833 
1834  for (te = AH->toc->next; te != AH->toc; te = te->next)
1835  {
1836  /* this check is purely paranoia, maxDumpId should be correct */
1837  if (te->dumpId <= 0 || te->dumpId > maxDumpId)
1838  exit_horribly(modulename, "bad dumpId\n");
1839 
1840  /* tocsByDumpId indexes all TOCs by their dump ID */
1841  AH->tocsByDumpId[te->dumpId] = te;
1842 
1843  /*
1844  * tableDataId provides the TABLE DATA item's dump ID for each TABLE
1845  * TOC entry that has a DATA item. We compute this by reversing the
1846  * TABLE DATA item's dependency, knowing that a TABLE DATA item has
1847  * just one dependency and it is the TABLE item.
1848  */
1849  if (strcmp(te->desc, "TABLE DATA") == 0 && te->nDeps > 0)
1850  {
1851  DumpId tableId = te->dependencies[0];
1852 
1853  /*
1854  * The TABLE item might not have been in the archive, if this was
1855  * a data-only dump; but its dump ID should be less than its data
1856  * item's dump ID, so there should be a place for it in the array.
1857  */
1858  if (tableId <= 0 || tableId > maxDumpId)
1859  exit_horribly(modulename, "bad table dumpId for TABLE DATA item\n");
1860 
1861  AH->tableDataId[tableId] = te->dumpId;
1862  }
1863  }
1864 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:229
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
bool checkSeek ( FILE *  fp)

Definition at line 3719 of file pg_backup_archiver.c.

References fseeko, ftello, and pgoff_t.

Referenced by InitArchiveFmt_Custom(), and InitArchiveFmt_Tar().

3720 {
3721  pgoff_t tpos;
3722 
3723  /*
3724  * If pgoff_t is wider than long, we must have "real" fseeko and not an
3725  * emulation using fseek. Otherwise report no seek capability.
3726  */
3727 #ifndef HAVE_FSEEKO
3728  if (sizeof(pgoff_t) > sizeof(long))
3729  return false;
3730 #endif
3731 
3732  /* Check that ftello works on this file */
3733  tpos = ftello(fp);
3734  if (tpos < 0)
3735  return false;
3736 
3737  /*
3738  * Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
3739  * this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
3740  * successful no-op even on files that are otherwise unseekable.
3741  */
3742  if (fseeko(fp, tpos, SEEK_SET) != 0)
3743  return false;
3744 
3745  return true;
3746 }
#define fseeko(stream, offset, origin)
Definition: win32.h:247
#define pgoff_t
Definition: win32.h:241
#define ftello(stream)
Definition: win32.h:250
ArchiveHandle* CloneArchive ( ArchiveHandle AH)

Definition at line 4500 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, NULL, 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().

4501 {
4502  ArchiveHandle *clone;
4503 
4504  /* Make a "flat" copy */
4505  clone = (ArchiveHandle *) pg_malloc(sizeof(ArchiveHandle));
4506  memcpy(clone, AH, sizeof(ArchiveHandle));
4507 
4508  /* Handle format-independent fields */
4509  memset(&(clone->sqlparse), 0, sizeof(clone->sqlparse));
4510 
4511  /* The clone will have its own connection, so disregard connection state */
4512  clone->connection = NULL;
4513  clone->connCancel = NULL;
4514  clone->currUser = NULL;
4515  clone->currSchema = NULL;
4516  clone->currTablespace = NULL;
4517  clone->currWithOids = -1;
4518 
4519  /* savedPassword must be local in case we change it while connecting */
4520  if (clone->savedPassword)
4521  clone->savedPassword = pg_strdup(clone->savedPassword);
4522 
4523  /* clone has its own error count, too */
4524  clone->public.n_errors = 0;
4525 
4526  /*
4527  * Connect our new clone object to the database: In parallel restore the
4528  * parent is already disconnected, because we can connect the worker
4529  * processes independently to the database (no snapshot sync required). In
4530  * parallel backup we clone the parent's existing connection.
4531  */
4532  if (AH->mode == archModeRead)
4533  {
4534  RestoreOptions *ropt = AH->public.ropt;
4535 
4536  Assert(AH->connection == NULL);
4537 
4538  /* this also sets clone->connection */
4539  ConnectDatabase((Archive *) clone, ropt->dbname,
4540  ropt->pghost, ropt->pgport, ropt->username,
4541  ropt->promptPassword);
4542 
4543  /* re-establish fixed state */
4544  _doSetFixedOutputState(clone);
4545  }
4546  else
4547  {
4549  char *pghost;
4550  char *pgport;
4551  char *username;
4552 
4553  Assert(AH->connection != NULL);
4554 
4555  /*
4556  * Even though we are technically accessing the parent's database
4557  * object here, these functions are fine to be called like that
4558  * because all just return a pointer and do not actually send/receive
4559  * any data to/from the database.
4560  */
4561  initPQExpBuffer(&connstr);
4562  appendPQExpBuffer(&connstr, "dbname=");
4563  appendConnStrVal(&connstr, PQdb(AH->connection));
4564  pghost = PQhost(AH->connection);
4565  pgport = PQport(AH->connection);
4566  username = PQuser(AH->connection);
4567 
4568  /* this also sets clone->connection */
4569  ConnectDatabase((Archive *) clone, connstr.data,
4570  pghost, pgport, username, TRI_NO);
4571 
4572  termPQExpBuffer(&connstr);
4573  /* setupDumpWorker will fix up connection state */
4574  }
4575 
4576  /* Let the format-specific code have a chance too */
4577  (clone->ClonePtr) (clone);
4578 
4579  Assert(clone->connection != NULL);
4580  return clone;
4581 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
RestoreOptions * ropt
Definition: pg_backup.h:180
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
char * username
Definition: pg_backup.h:110
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:536
char * PQport(const PGconn *conn)
Definition: fe-connect.c:5932
int n_errors
Definition: pg_backup.h:201
PGcancel *volatile connCancel
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:5887
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:131
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:5912
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:5879
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
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:248
static char * connstr
Definition: pg_dumpall.c:64
trivalue promptPassword
Definition: pg_backup.h:112
void CloseArchive ( Archive AHX)

Definition at line 228 of file pg_backup_archiver.c.

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

Referenced by main().

229 {
230  int res = 0;
231  ArchiveHandle *AH = (ArchiveHandle *) AHX;
232 
233  (*AH->ClosePtr) (AH);
234 
235  /* Close the output */
236  if (AH->gzOut)
237  res = GZCLOSE(AH->OF);
238  else if (AH->OF != stdout)
239  res = fclose(AH->OF);
240 
241  if (res != 0)
242  exit_horribly(modulename, "could not close output file: %s\n",
243  strerror(errno));
244 }
#define GZCLOSE(fh)
void exit_horribly(const char *modulename, const char *fmt,...)
const char * strerror(int errnum)
Definition: strerror.c:19
static const char * modulename
Archive* CreateArchive ( const char *  FileSpec,
const ArchiveFormat  fmt,
const int  compression,
bool  dosync,
ArchiveMode  mode,
SetupWorkerPtr  setupDumpWorker 
)

Definition at line 205 of file pg_backup_archiver.c.

References _allocAH().

Referenced by main().

209 {
210  ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, dosync,
211  mode, setupDumpWorker);
212 
213  return (Archive *) AH;
214 }
static ArchiveHandle * _allocAH(const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtr setupWorkerPtr)
static bool dosync
Definition: pg_dump.c:92
static void setupDumpWorker(Archive *AHX)
Definition: pg_dump.c:1146
void DeCloneArchive ( ArchiveHandle AH)

Definition at line 4589 of file pg_backup_archiver.c.

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

Referenced by RunWorker().

4590 {
4591  /* Should not have an open database connection */
4592  Assert(AH->connection == NULL);
4593 
4594  /* Clear format-specific state */
4595  (AH->DeClonePtr) (AH);
4596 
4597  /* Clear state allocated by CloneArchive */
4598  if (AH->sqlparse.curCmd)
4600 
4601  /* Clear any connection-local state */
4602  if (AH->currUser)
4603  free(AH->currUser);
4604  if (AH->currSchema)
4605  free(AH->currSchema);
4606  if (AH->currTablespace)
4607  free(AH->currTablespace);
4608  if (AH->savedPassword)
4609  free(AH->savedPassword);
4610 
4611  free(AH);
4612 }
PQExpBuffer curCmd
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
sqlparseInfo sqlparse
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
static void dump_lo_buf ( ArchiveHandle AH)
static

Definition at line 1644 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().

1645 {
1646  if (AH->connection)
1647  {
1648  size_t res;
1649 
1650  res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used);
1651  ahlog(AH, 5, ngettext("wrote %lu byte of large object data (result = %lu)\n",
1652  "wrote %lu bytes of large object data (result = %lu)\n",
1653  AH->lo_buf_used),
1654  (unsigned long) AH->lo_buf_used, (unsigned long) res);
1655  if (res != AH->lo_buf_used)
1657  "could not write to large object (result: %lu, expected: %lu)\n",
1658  (unsigned long) res, (unsigned long) AH->lo_buf_used);
1659  }
1660  else
1661  {
1663 
1665  (const unsigned char *) AH->lo_buf,
1666  AH->lo_buf_used,
1667  AH);
1668 
1669  /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
1670  AH->writingBlob = 0;
1671  ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
1672  AH->writingBlob = 1;
1673 
1674  destroyPQExpBuffer(buf);
1675  }
1676  AH->lo_buf_used = 0;
1677 }
#define appendByteaLiteralAHX(buf, str, len, AH)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
static char * buf
Definition: pg_test_fsync.c:65
int lo_write(int fd, const char *buf, int len)
Definition: be-fsstubs.c:189
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define ngettext(s, p, n)
Definition: c.h:127
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
DumpOptions* dumpOptionsFromRestoreOptions ( RestoreOptions ropt)

Definition at line 148 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::include_subscriptions, _dumpOptions::include_subscriptions, _restoreOptions::lockWaitTimeout, _dumpOptions::lockWaitTimeout, NewDumpOptions(), _restoreOptions::no_security_labels, _dumpOptions::no_security_labels, _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().

149 {
150  DumpOptions *dopt = NewDumpOptions();
151 
152  /* this is the inverse of what's at the end of pg_dump.c's main() */
153  dopt->outputClean = ropt->dropSchema;
154  dopt->dataOnly = ropt->dataOnly;
155  dopt->schemaOnly = ropt->schemaOnly;
156  dopt->if_exists = ropt->if_exists;
157  dopt->column_inserts = ropt->column_inserts;
158  dopt->dumpSections = ropt->dumpSections;
159  dopt->aclsSkip = ropt->aclsSkip;
160  dopt->outputSuperuser = ropt->superuser;
161  dopt->outputCreateDB = ropt->createDB;
162  dopt->outputNoOwner = ropt->noOwner;
163  dopt->outputNoTablespaces = ropt->noTablespace;
164  dopt->disable_triggers = ropt->disable_triggers;
165  dopt->use_setsessauth = ropt->use_setsessauth;
166 
168  dopt->dump_inserts = ropt->dump_inserts;
170  dopt->lockWaitTimeout = ropt->lockWaitTimeout;
173  dopt->sequence_data = ropt->sequence_data;
175 
176  return dopt;
177 }
int column_inserts
Definition: pg_backup.h:146
int disable_triggers
Definition: pg_backup.h:153
int disable_dollar_quoting
Definition: pg_backup.h:73
bool schemaOnly
Definition: pg_backup.h:137
DumpOptions * NewDumpOptions(void)
int sequence_data
Definition: pg_backup.h:170
int include_subscriptions
Definition: pg_backup.h:157
const char * lockWaitTimeout
Definition: pg_backup.h:86
int use_setsessauth
Definition: pg_backup.h:155
int disable_dollar_quoting
Definition: pg_backup.h:144
int column_inserts
Definition: pg_backup.h:75
const char * lockWaitTimeout
Definition: pg_backup.h:141
bool dataOnly
Definition: pg_backup.h:138
bool include_everything
Definition: pg_backup.h:161
char * outputSuperuser
Definition: pg_backup.h:168
int include_everything
Definition: pg_backup.h:87
int no_security_labels
Definition: pg_backup.h:77
int dumpSections
Definition: pg_backup.h:139
int enable_row_security
Definition: pg_backup.h:120
int dump_inserts
Definition: pg_backup.h:145
int outputNoOwner
Definition: pg_backup.h:167
int no_security_labels
Definition: pg_backup.h:148
char * superuser
Definition: pg_backup.h:70
bool aclsSkip
Definition: pg_backup.h:140
int use_setsessauth
Definition: pg_backup.h:68
int enable_row_security
Definition: pg_backup.h:156
int outputCreateDB
Definition: pg_backup.h:164
int outputClean
Definition: pg_backup.h:163
int include_subscriptions
Definition: pg_backup.h:122
int outputNoTablespaces
Definition: pg_backup.h:154
int disable_triggers
Definition: pg_backup.h:66
static void dumpTimestamp ( ArchiveHandle AH,
const char *  msg,
time_t  tim 
)
static

Definition at line 3753 of file pg_backup_archiver.c.

References ahprintf(), buf, and PGDUMP_STRFTIME_FMT.

Referenced by RestoreArchive().

3754 {
3755  char buf[64];
3756 
3757  if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&tim)) != 0)
3758  ahprintf(AH, "-- %s %s\n\n", msg, buf);
3759 }
static char * buf
Definition: pg_test_fsync.c:65
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define PGDUMP_STRFTIME_FMT
Definition: dumputils.h:33
int EndBlob ( Archive AHX,
Oid  oid 
)

Definition at line 1219 of file pg_backup_archiver.c.

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

Referenced by dumpBlobs().

1220 {
1221  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1222 
1223  if (AH->EndBlobPtr)
1224  (*AH->EndBlobPtr) (AH, AH->currToc, oid);
1225 
1226  return 1;
1227 }
struct _tocEntry * currToc
void EndRestoreBlob ( ArchiveHandle AH,
Oid  oid 
)

Definition at line 1323 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().

1324 {
1325  if (AH->lo_buf_used > 0)
1326  {
1327  /* Write remaining bytes from the LO buffer */
1328  dump_lo_buf(AH);
1329  }
1330 
1331  AH->writingBlob = 0;
1332 
1333  if (AH->connection)
1334  {
1335  lo_close(AH->connection, AH->loFd);
1336  AH->loFd = -1;
1337  }
1338  else
1339  {
1340  ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
1341  }
1342 }
int lo_close(PGconn *conn, int fd)
Definition: fe-lobj.c:100
static void dump_lo_buf(ArchiveHandle *AH)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
void EndRestoreBlobs ( ArchiveHandle AH)

Definition at line 1256 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().

1257 {
1258  RestoreOptions *ropt = AH->public.ropt;
1259 
1260  if (!ropt->single_txn)
1261  {
1262  if (AH->connection)
1263  CommitTransaction(&AH->public);
1264  else
1265  ahprintf(AH, "COMMIT;\n\n");
1266  }
1267 
1268  ahlog(AH, 1, ngettext("restored %d large object\n",
1269  "restored %d large objects\n",
1270  AH->blobCount),
1271  AH->blobCount);
1272 }
RestoreOptions * ropt
Definition: pg_backup.h:180
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define ngettext(s, p, n)
Definition: c.h:127
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
static void CommitTransaction(void)
Definition: xact.c:1940
static void fix_dependencies ( ArchiveHandle AH)
static

Definition at line 4229 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, NULL, _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().

4230 {
4231  TocEntry *te;
4232  int i;
4233 
4234  /*
4235  * Initialize the depCount/revDeps/nRevDeps fields, and make sure the TOC
4236  * items are marked as not being in any parallel-processing list.
4237  */
4238  for (te = AH->toc->next; te != AH->toc; te = te->next)
4239  {
4240  te->depCount = te->nDeps;
4241  te->revDeps = NULL;
4242  te->nRevDeps = 0;
4243  te->par_prev = NULL;
4244  te->par_next = NULL;
4245  }
4246 
4247  /*
4248  * POST_DATA items that are shown as depending on a table need to be
4249  * re-pointed to depend on that table's data, instead. This ensures they
4250  * won't get scheduled until the data has been loaded.
4251  */
4253 
4254  /*
4255  * Pre-8.4 versions of pg_dump neglected to set up a dependency from BLOB
4256  * COMMENTS to BLOBS. Cope. (We assume there's only one BLOBS and only
4257  * one BLOB COMMENTS in such files.)
4258  */
4259  if (AH->version < K_VERS_1_11)
4260  {
4261  for (te = AH->toc->next; te != AH->toc; te = te->next)
4262  {
4263  if (strcmp(te->desc, "BLOB COMMENTS") == 0 && te->nDeps == 0)
4264  {
4265  TocEntry *te2;
4266 
4267  for (te2 = AH->toc->next; te2 != AH->toc; te2 = te2->next)
4268  {
4269  if (strcmp(te2->desc, "BLOBS") == 0)
4270  {
4271  te->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
4272  te->dependencies[0] = te2->dumpId;
4273  te->nDeps++;
4274  te->depCount++;
4275  break;
4276  }
4277  }
4278  break;
4279  }
4280  }
4281  }
4282 
4283  /*
4284  * At this point we start to build the revDeps reverse-dependency arrays,
4285  * so all changes of dependencies must be complete.
4286  */
4287 
4288  /*
4289  * Count the incoming dependencies for each item. Also, it is possible
4290  * that the dependencies list items that are not in the archive at all
4291  * (that should not happen in 9.2 and later, but is highly likely in older
4292  * archives). Subtract such items from the depCounts.
4293  */
4294  for (te = AH->toc->next; te != AH->toc; te = te->next)
4295  {
4296  for (i = 0; i < te->nDeps; i++)
4297  {
4298  DumpId depid = te->dependencies[i];
4299 
4300  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4301  AH->tocsByDumpId[depid]->nRevDeps++;
4302  else
4303  te->depCount--;
4304  }
4305  }
4306 
4307  /*
4308  * Allocate space for revDeps[] arrays, and reset nRevDeps so we can use
4309  * it as a counter below.
4310  */
4311  for (te = AH->toc->next; te != AH->toc; te = te->next)
4312  {
4313  if (te->nRevDeps > 0)
4314  te->revDeps = (DumpId *) pg_malloc(te->nRevDeps * sizeof(DumpId));
4315  te->nRevDeps = 0;
4316  }
4317 
4318  /*
4319  * Build the revDeps[] arrays of incoming-dependency dumpIds. This had
4320  * better agree with the loops above.
4321  */
4322  for (te = AH->toc->next; te != AH->toc; te = te->next)
4323  {
4324  for (i = 0; i < te->nDeps; i++)
4325  {
4326  DumpId depid = te->dependencies[i];
4327 
4328  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4329  {
4330  TocEntry *otherte = AH->tocsByDumpId[depid];
4331 
4332  otherte->revDeps[otherte->nRevDeps++] = te->dumpId;
4333  }
4334  }
4335  }
4336 
4337  /*
4338  * Lastly, work out the locking dependencies.
4339  */
4340  for (te = AH->toc->next; te != AH->toc; te = te->next)
4341  {
4342  te->lockDeps = NULL;
4343  te->nLockDeps = 0;
4345  }
4346 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:229
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
#define NULL
Definition: c.h:229
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)
static TocEntry * get_next_work_item ( ArchiveHandle AH,
TocEntry ready_list,
ParallelState pstate 
)
static

Definition at line 4080 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entries_parallel().

4082 {
4083  bool pref_non_data = false; /* or get from AH->ropt */
4084  TocEntry *data_te = NULL;
4085  TocEntry *te;
4086  int i,
4087  k;
4088 
4089  /*
4090  * Bogus heuristics for pref_non_data
4091  */
4092  if (pref_non_data)
4093  {
4094  int count = 0;
4095 
4096  for (k = 0; k < pstate->numWorkers; k++)
4097  {
4098  TocEntry *running_te = pstate->te[k];
4099 
4100  if (running_te != NULL &&
4101  running_te->section == SECTION_DATA)
4102  count++;
4103  }
4104  if (pstate->numWorkers == 0 || count * 4 < pstate->numWorkers)
4105  pref_non_data = false;
4106  }
4107 
4108  /*
4109  * Search the ready_list until we find a suitable item.
4110  */
4111  for (te = ready_list->par_next; te != ready_list; te = te->par_next)
4112  {
4113  bool conflicts = false;
4114 
4115  /*
4116  * Check to see if the item would need exclusive lock on something
4117  * that a currently running item also needs lock on, or vice versa. If
4118  * so, we don't want to schedule them together.
4119  */
4120  for (i = 0; i < pstate->numWorkers; i++)
4121  {
4122  TocEntry *running_te = pstate->te[i];
4123 
4124  if (running_te == NULL)
4125  continue;
4126  if (has_lock_conflicts(te, running_te) ||
4127  has_lock_conflicts(running_te, te))
4128  {
4129  conflicts = true;
4130  break;
4131  }
4132  }
4133 
4134  if (conflicts)
4135  continue;
4136 
4137  if (pref_non_data && te->section == SECTION_DATA)
4138  {
4139  if (data_te == NULL)
4140  data_te = te;
4141  continue;
4142  }
4143 
4144  /* passed all tests, so this item can run */
4145  return te;
4146  }
4147 
4148  if (data_te != NULL)
4149  return data_te;
4150 
4151  ahlog(AH, 2, "no item ready\n");
4152  return NULL;
4153 }
teSection section
struct _tocEntry * par_next
#define NULL
Definition: c.h:229
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
TocEntry* getTocEntryByDumpId ( ArchiveHandle AH,
DumpId  id 
)

Definition at line 1867 of file pg_backup_archiver.c.

References buildTocEntryArrays(), NULL, and _archiveHandle::tocsByDumpId.

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

1868 {
1869  /* build index arrays if we didn't already */
1870  if (AH->tocsByDumpId == NULL)
1871  buildTocEntryArrays(AH);
1872 
1873  if (id > 0 && id <= AH->maxDumpId)
1874  return AH->tocsByDumpId[id];
1875 
1876  return NULL;
1877 }
static void buildTocEntryArrays(ArchiveHandle *AH)
#define NULL
Definition: c.h:229
struct _tocEntry ** tocsByDumpId
static bool has_lock_conflicts ( TocEntry te1,
TocEntry te2 
)
static

Definition at line 4013 of file pg_backup_archiver.c.

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

Referenced by get_next_work_item().

4014 {
4015  int j,
4016  k;
4017 
4018  for (j = 0; j < te1->nLockDeps; j++)
4019  {
4020  for (k = 0; k < te2->nDeps; k++)
4021  {
4022  if (te1->lockDeps[j] == te2->dependencies[k])
4023  return true;
4024  }
4025  }
4026  return false;
4027 }
DumpId * lockDeps
DumpId * dependencies
static void identify_locking_dependencies ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4383 of file pg_backup_archiver.c.

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

Referenced by fix_dependencies().

4384 {
4385  DumpId *lockids;
4386  int nlockids;
4387  int i;
4388 
4389  /* Quick exit if no dependencies at all */
4390  if (te->nDeps == 0)
4391  return;
4392 
4393  /* Exit if this entry doesn't need exclusive lock on other objects */
4394  if (!(strcmp(te->desc, "CONSTRAINT") == 0 ||
4395  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
4396  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
4397  strcmp(te->desc, "RULE") == 0 ||
4398  strcmp(te->desc, "TRIGGER") == 0))
4399  return;
4400 
4401  /*
4402  * We assume the entry requires exclusive lock on each TABLE or TABLE DATA
4403  * item listed among its dependencies. Originally all of these would have
4404  * been TABLE items, but repoint_table_dependencies would have repointed
4405  * them to the TABLE DATA items if those are present (which they might not
4406  * be, eg in a schema-only dump). Note that all of the entries we are
4407  * processing here are POST_DATA; otherwise there might be a significant
4408  * difference between a dependency on a table and a dependency on its
4409  * data, so that closer analysis would be needed here.
4410  */
4411  lockids = (DumpId *) pg_malloc(te->nDeps * sizeof(DumpId));
4412  nlockids = 0;
4413  for (i = 0; i < te->nDeps; i++)
4414  {
4415  DumpId depid = te->dependencies[i];
4416 
4417  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL &&
4418  ((strcmp(AH->tocsByDumpId[depid]->desc, "TABLE DATA") == 0) ||
4419  strcmp(AH->tocsByDumpId[depid]->desc, "TABLE") == 0))
4420  lockids[nlockids++] = depid;
4421  }
4422 
4423  if (nlockids == 0)
4424  {
4425  free(lockids);
4426  return;
4427  }
4428 
4429  te->lockDeps = pg_realloc(lockids, nlockids * sizeof(DumpId));
4430  te->nLockDeps = nlockids;
4431 }
int DumpId
Definition: pg_backup.h:229
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
#define NULL
Definition: c.h:229
struct _tocEntry ** tocsByDumpId
int i
static void inhibit_data_for_failed_table ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4480 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().

4481 {
4482  ahlog(AH, 1, "table \"%s\" could not be created, will not restore its data\n",
4483  te->tag);
4484 
4485  if (AH->tableDataId[te->dumpId] != 0)
4486  {
4487  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4488 
4489  ted->reqs = 0;
4490  }
4491 }
struct _tocEntry ** tocsByDumpId
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
void InitDumpOptions ( DumpOptions opts)

Definition at line 135 of file pg_backup_archiver.c.

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

Referenced by main(), and NewDumpOptions().

136 {
137  memset(opts, 0, sizeof(DumpOptions));
138  /* set any fields that shouldn't default to zeroes */
139  opts->include_everything = true;
141 }
bool include_everything
Definition: pg_backup.h:161
int dumpSections
Definition: pg_backup.h:139
static void mark_create_done ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4465 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().

4466 {
4467  if (AH->tableDataId[te->dumpId] != 0)
4468  {
4469  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4470 
4471  ted->created = true;
4472  }
4473 }
struct _tocEntry ** tocsByDumpId
static void mark_dump_job_done ( ArchiveHandle AH,
TocEntry te,
int  status,
void *  callback_data 
)
static

Definition at line 2432 of file pg_backup_archiver.c.

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

Referenced by WriteDataChunks().

2436 {
2437  ahlog(AH, 1, "finished item %d %s %s\n",
2438  te->dumpId, te->desc, te->tag);
2439 
2440  if (status != 0)
2441  exit_horribly(modulename, "worker process failed: exit code %d\n",
2442  status);
2443 }
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:224
static const char * modulename
static void mark_restore_job_done ( ArchiveHandle AH,
TocEntry te,
int  status,
void *  callback_data 
)
static

Definition at line 4188 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().

4192 {
4193  TocEntry *ready_list = (TocEntry *) callback_data;
4194 
4195  ahlog(AH, 1, "finished item %d %s %s\n",
4196  te->dumpId, te->desc, te->tag);
4197 
4198  if (status == WORKER_CREATE_DONE)
4199  mark_create_done(AH, te);
4200  else if (status == WORKER_INHIBIT_DATA)
4201  {
4203  AH->public.n_errors++;
4204  }
4205  else if (status == WORKER_IGNORED_ERRORS)
4206  AH->public.n_errors++;
4207  else if (status != 0)
4208  exit_horribly(modulename, "worker process failed: exit code %d\n",
4209  status);
4210 
4211  reduce_dependencies(AH, te, ready_list);
4212 }
#define WORKER_CREATE_DONE
int n_errors
Definition: pg_backup.h:201
#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:224
static const char * modulename
DumpOptions* NewDumpOptions ( void  )

Definition at line 123 of file pg_backup_archiver.c.

References InitDumpOptions(), and pg_malloc().

Referenced by dumpOptionsFromRestoreOptions().

124 {
125  DumpOptions *opts = (DumpOptions *) pg_malloc(sizeof(DumpOptions));
126 
127  InitDumpOptions(opts);
128  return opts;
129 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
void InitDumpOptions(DumpOptions *opts)
RestoreOptions* NewRestoreOptions ( void  )

Definition at line 931 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().

932 {
933  RestoreOptions *opts;
934 
935  opts = (RestoreOptions *) pg_malloc0(sizeof(RestoreOptions));
936 
937  /* set any fields that shouldn't default to zeroes */
938  opts->format = archUnknown;
939  opts->promptPassword = TRI_DEFAULT;
941 
942  return opts;
943 }
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
trivalue promptPassword
Definition: pg_backup.h:112
Archive* OpenArchive ( const char *  FileSpec,
const ArchiveFormat  fmt 
)

Definition at line 219 of file pg_backup_archiver.c.

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

Referenced by main().

220 {
221  ArchiveHandle *AH = _allocAH(FileSpec, fmt, 0, true, archModeRead, setupRestoreWorker);
222 
223  return (Archive *) AH;
224 }
static ArchiveHandle * _allocAH(const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtr setupWorkerPtr)
static void setupRestoreWorker(Archive *AHX)
static void par_list_append ( TocEntry l,
TocEntry te 
)
static

Definition at line 4045 of file pg_backup_archiver.c.

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

Referenced by reduce_dependencies(), and restore_toc_entries_parallel().

4046 {
4047  te->par_prev = l->par_prev;
4048  l->par_prev->par_next = te;
4049  l->par_prev = te;
4050  te->par_next = l;
4051 }
struct _tocEntry * par_prev
struct _tocEntry * par_next
static void par_list_header_init ( TocEntry l)
static

Definition at line 4038 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entries_parallel(), and RestoreArchive().

4039 {
4040  l->par_prev = l->par_next = l;
4041 }
struct _tocEntry * par_prev
struct _tocEntry * par_next
static void par_list_remove ( TocEntry te)
static

Definition at line 4055 of file pg_backup_archiver.c.

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

Referenced by reduce_dependencies(), and restore_toc_entries_parallel().

4056 {
4057  te->par_prev->par_next = te->par_next;
4058  te->par_next->par_prev = te->par_prev;
4059  te->par_prev = NULL;
4060  te->par_next = NULL;
4061 }
struct _tocEntry * par_prev
struct _tocEntry * par_next
#define NULL
Definition: c.h:229
int parallel_restore ( ArchiveHandle AH,
TocEntry te 
)

Definition at line 4165 of file pg_backup_archiver.c.

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

Referenced by _WorkerJobRestoreCustom(), and _WorkerJobRestoreDirectory().

4166 {
4167  int status;
4168 
4169  Assert(AH->connection != NULL);
4170 
4171  /* Count only errors associated with this TOC entry */
4172  AH->public.n_errors = 0;
4173 
4174  /* Restore the TOC item */
4175  status = restore_toc_entry(AH, te, true);
4176 
4177  return status;
4178 }
int n_errors
Definition: pg_backup.h:201
static int restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
void PrintTOCSummary ( Archive AHX)

Definition at line 1090 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().

1091 {
1092  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1093  RestoreOptions *ropt = AH->public.ropt;
1094  TocEntry *te;
1095  teSection curSection;
1096  OutputContext sav;
1097  const char *fmtName;
1098  char stamp_str[64];
1099 
1100  sav = SaveOutput(AH);
1101  if (ropt->filename)
1102  SetOutput(AH, ropt->filename, 0 /* no compression */ );
1103 
1104  if (strftime(stamp_str, sizeof(stamp_str), PGDUMP_STRFTIME_FMT,
1105  localtime(&AH->createDate)) == 0)
1106  strcpy(stamp_str, "[unknown]");
1107 
1108  ahprintf(AH, ";\n; Archive created at %s\n", stamp_str);
1109  ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n",
1111  AH->tocCount, AH->compression);
1112 
1113  switch (AH->format)
1114  {
1115  case archCustom:
1116  fmtName = "CUSTOM";
1117  break;
1118  case archDirectory:
1119  fmtName = "DIRECTORY";
1120  break;
1121  case archTar:
1122  fmtName = "TAR";
1123  break;
1124  default:
1125  fmtName = "UNKNOWN";
1126  }
1127 
1128  ahprintf(AH, "; Dump Version: %d.%d-%d\n",
1130  ahprintf(AH, "; Format: %s\n", fmtName);
1131  ahprintf(AH, "; Integer: %d bytes\n", (int) AH->intSize);
1132  ahprintf(AH, "; Offset: %d bytes\n", (int) AH->offSize);
1133  if (AH->archiveRemoteVersion)
1134  ahprintf(AH, "; Dumped from database version: %s\n",
1135  AH->archiveRemoteVersion);
1136  if (AH->archiveDumpVersion)
1137  ahprintf(AH, "; Dumped by pg_dump version: %s\n",
1138  AH->archiveDumpVersion);
1139 
1140  ahprintf(AH, ";\n;\n; Selected TOC Entries:\n;\n");
1141 
1142  curSection = SECTION_PRE_DATA;
1143  for (te = AH->toc->next; te != AH->toc; te = te->next)
1144  {
1145  if (te->section != SECTION_NONE)
1146  curSection = te->section;
1147  if (ropt->verbose ||
1148  (_tocEntryRequired(te, curSection, ropt) & (REQ_SCHEMA | REQ_DATA)) != 0)
1149  {
1150  char *sanitized_name;
1151  char *sanitized_schema;
1152  char *sanitized_owner;
1153 
1154  /*
1155  * As in _printTocEntry(), sanitize strings that might contain
1156  * newlines, to ensure that each logical output line is in fact
1157  * one physical output line. This prevents confusion when the
1158  * file is read by "pg_restore -L". Note that we currently don't
1159  * bother to quote names, meaning that the name fields aren't
1160  * automatically parseable. "pg_restore -L" doesn't care because
1161  * it only examines the dumpId field, but someday we might want to
1162  * try harder.
1163  */
1164  sanitized_name = replace_line_endings(te->tag);
1165  if (te->namespace)
1166  sanitized_schema = replace_line_endings(te->namespace);
1167  else
1168  sanitized_schema = pg_strdup("-");
1169  sanitized_owner = replace_line_endings(te->owner);
1170 
1171  ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
1172  te->catalogId.tableoid, te->catalogId.oid,
1173  te->desc, sanitized_schema, sanitized_name,
1174  sanitized_owner);
1175 
1176  free(sanitized_name);
1177  free(sanitized_schema);
1178  free(sanitized_owner);
1179  }
1180  if (ropt->verbose && te->nDeps > 0)
1181  {
1182  int i;
1183 
1184  ahprintf(AH, ";\tdepends on:");
1185  for (i = 0; i < te->nDeps; i++)
1186  ahprintf(AH, " %d", te->dependencies[i]);
1187  ahprintf(AH, "\n");
1188  }
1189  }
1190 
1191  /* Enforce strict names checking */
1192  if (ropt->strict_names)
1193  StrictNamesCheck(ropt);
1194 
1195  if (ropt->filename)
1196  RestoreOutput(AH, sav);
1197 }
struct _tocEntry * next
Oid tableoid
Definition: pg_backup.h:225
RestoreOptions * ropt
Definition: pg_backup.h:180
CatalogId catalogId
static void SetOutput(ArchiveHandle *AH, const char *filename, int compression)
teSection section
const char * filename
Definition: pg_backup.h:80
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
void ProcessArchiveRestoreOptions ( Archive AHX)

Definition at line 261 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().

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

Definition at line 2695 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

2696 {
2697  /* te->defn should have the form SET client_encoding = 'foo'; */
2698  char *defn = pg_strdup(te->defn);
2699  char *ptr1;
2700  char *ptr2 = NULL;
2701  int encoding;
2702 
2703  ptr1 = strchr(defn, '\'');
2704  if (ptr1)
2705  ptr2 = strchr(++ptr1, '\'');
2706  if (ptr2)
2707  {
2708  *ptr2 = '\0';
2709  encoding = pg_char_to_encoding(ptr1);
2710  if (encoding < 0)
2711  exit_horribly(modulename, "unrecognized encoding \"%s\"\n",
2712  ptr1);
2713  AH->public.encoding = encoding;
2714  }
2715  else
2716  exit_horribly(modulename, "invalid ENCODING item: %s\n",
2717  te->defn);
2718 
2719  free(defn);
2720 }
int pg_char_to_encoding(const char *name)
Definition: encnames.c:551
int encoding
Definition: pg_backup.h:195
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static char * encoding
Definition: initdb.c:122
#define free(a)
Definition: header.h:65
#define NULL
Definition: c.h:229
void exit_horribly(const char *modulename, const char *fmt,...)
static const char * modulename
static void processStdStringsEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2723 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

2724 {
2725  /* te->defn should have the form SET standard_conforming_strings = 'x'; */
2726  char *ptr1;
2727 
2728  ptr1 = strchr(te->defn, '\'');
2729  if (ptr1 && strncmp(ptr1, "'on'", 4) == 0)
2730  AH->public.std_strings = true;
2731  else if (ptr1 && strncmp(ptr1, "'off'", 5) == 0)
2732  AH->public.std_strings = false;
2733  else
2734  exit_horribly(modulename, "invalid STDSTRINGS item: %s\n",
2735  te->defn);
2736 }
void exit_horribly(const char *modulename, const char *fmt,...)
static const char * modulename
bool std_strings
Definition: pg_backup.h:196
void ReadHead ( ArchiveHandle AH)

Definition at line 3616 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().

3617 {
3618  char tmpMag[7];
3619  int fmt;
3620  struct tm crtm;
3621 
3622  /*
3623  * If we haven't already read the header, do so.
3624  *
3625  * NB: this code must agree with _discoverArchiveFormat(). Maybe find a
3626  * way to unify the cases?
3627  */
3628  if (!AH->readHeader)
3629  {
3630  char vmaj,
3631  vmin,
3632  vrev;
3633 
3634  (*AH->ReadBufPtr) (AH, tmpMag, 5);
3635 
3636  if (strncmp(tmpMag, "PGDMP", 5) != 0)
3637  exit_horribly(modulename, "did not find magic string in file header\n");
3638 
3639  vmaj = (*AH->ReadBytePtr) (AH);
3640  vmin = (*AH->ReadBytePtr) (AH);
3641 
3642  if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */
3643  vrev = (*AH->ReadBytePtr) (AH);
3644  else
3645  vrev = 0;
3646 
3647  AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev);
3648 
3649  if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
3650  exit_horribly(modulename, "unsupported version (%d.%d) in file header\n",
3651  vmaj, vmin);
3652 
3653  AH->intSize = (*AH->ReadBytePtr) (AH);
3654  if (AH->intSize > 32)
3655  exit_horribly(modulename, "sanity check on integer size (%lu) failed\n",
3656  (unsigned long) AH->intSize);
3657 
3658  if (AH->intSize > sizeof(int))
3659  write_msg(modulename, "WARNING: archive was made on a machine with larger integers, some operations might fail\n");
3660 
3661  if (AH->version >= K_VERS_1_7)
3662  AH->offSize = (*AH->ReadBytePtr) (AH);
3663  else
3664  AH->offSize = AH->intSize;
3665 
3666  fmt = (*AH->ReadBytePtr) (AH);
3667 
3668  if (AH->format != fmt)
3669  exit_horribly(modulename, "expected format (%d) differs from format found in file (%d)\n",
3670  AH->format, fmt);
3671  }
3672 
3673  if (AH->version >= K_VERS_1_2)
3674  {
3675  if (AH->version < K_VERS_1_4)
3676  AH->compression = (*AH->ReadBytePtr) (AH);
3677  else
3678  AH->compression = ReadInt(AH);
3679  }
3680  else
3682 
3683 #ifndef HAVE_LIBZ
3684  if (AH->compression != 0)
3685  write_msg(modulename, "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n");
3686 #endif
3687 
3688  if (AH->version >= K_VERS_1_4)
3689  {
3690  crtm.tm_sec = ReadInt(AH);
3691  crtm.tm_min = ReadInt(AH);
3692  crtm.tm_hour = ReadInt(AH);
3693  crtm.tm_mday = ReadInt(AH);
3694  crtm.tm_mon = ReadInt(AH);
3695  crtm.tm_year = ReadInt(AH);
3696  crtm.tm_isdst = ReadInt(AH);
3697 
3698  AH->archdbname = ReadStr(AH);
3699 
3700  AH->createDate = mktime(&crtm);
3701 
3702  if (AH->createDate == (time_t) -1)
3703  write_msg(modulename, "WARNING: invalid creation date in header\n");
3704  }
3705 
3706  if (AH->version >= K_VERS_1_10)
3707  {
3708  AH->archiveRemoteVersion = ReadStr(AH);
3709  AH->archiveDumpVersion = ReadStr(AH);
3710  }
3711 }
#define Z_DEFAULT_COMPRESSION
#define K_VERS_1_0
int ReadInt(ArchiveHandle *AH)
#define K_VERS_1_4
static struct pg_tm tm
Definition: localtime.c:103
#define K_VERS_1_7
#define MAKE_ARCHIVE_VERSION(major, minor, rev)
#define K_VERS_1_2
#define K_VERS_1_10
ReadBytePtr ReadBytePtr
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
int ReadInt ( ArchiveHandle AH)

Definition at line 2003 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().

2004 {
2005  int res = 0;
2006  int bv,
2007  b;
2008  int sign = 0; /* Default positive */
2009  int bitShift = 0;
2010 
2011  if (AH->version > K_VERS_1_0)
2012  /* Read a sign byte */
2013  sign = (*AH->ReadBytePtr) (AH);
2014 
2015  for (b = 0; b < AH->intSize; b++)
2016  {
2017  bv = (*AH->ReadBytePtr) (AH) & 0xFF;
2018  if (bv != 0)
2019  res = res + (bv << bitShift);
2020  bitShift += 8;
2021  }
2022 
2023  if (sign)
2024  res = -res;
2025 
2026  return res;
2027 }
#define K_VERS_1_0
char sign
Definition: informix.c:693
ReadBytePtr ReadBytePtr
int ReadOffset ( ArchiveHandle AH,
pgoff_t o 
)

Definition at line 1908 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().

1909 {
1910  int i;
1911  int off;
1912  int offsetFlg;
1913 
1914  /* Initialize to zero */
1915  *o = 0;
1916 
1917  /* Check for old version */
1918  if (AH->version < K_VERS_1_7)
1919  {
1920  /* Prior versions wrote offsets using WriteInt */
1921  i = ReadInt(AH);
1922  /* -1 means not set */
1923  if (i < 0)
1924  return K_OFFSET_POS_NOT_SET;
1925  else if (i == 0)
1926  return K_OFFSET_NO_DATA;
1927 
1928  /* Cast to pgoff_t because it was written as an int. */
1929  *o = (pgoff_t) i;
1930  return K_OFFSET_POS_SET;
1931  }
1932 
1933  /*
1934  * Read the flag indicating the state of the data pointer. Check if valid
1935  * and die if not.
1936  *
1937  * This used to be handled by a negative or zero pointer, now we use an
1938  * extra byte specifically for the state.
1939  */
1940  offsetFlg = (*AH->ReadBytePtr) (AH) & 0xFF;
1941 
1942  switch (offsetFlg)
1943  {
1944  case K_OFFSET_POS_NOT_SET:
1945  case K_OFFSET_NO_DATA:
1946  case K_OFFSET_POS_SET:
1947 
1948  break;
1949 
1950  default:
1951  exit_horribly(modulename, "unexpected data offset flag %d\n", offsetFlg);
1952  }
1953 
1954  /*
1955  * Read the bytes
1956  */
1957  for (off = 0; off < AH->offSize; off++)
1958  {
1959  if (off < sizeof(pgoff_t))
1960  *o |= ((pgoff_t) ((*AH->ReadBytePtr) (AH))) << (off * 8);
1961  else
1962  {
1963  if ((*AH->ReadBytePtr) (AH) != 0)
1964  exit_horribly(modulename, "file offset in dump file is too large\n");
1965  }
1966  }
1967 
1968  return offsetFlg;
1969 }
int ReadInt(ArchiveHandle *AH)
#define K_VERS_1_7
ReadBytePtr ReadBytePtr
#define K_OFFSET_NO_DATA
#define pgoff_t
Definition: win32.h:241
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
char* ReadStr ( ArchiveHandle AH)

Definition at line 2049 of file pg_backup_archiver.c.

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

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

2050 {
2051  char *buf;
2052  int l;
2053 
2054  l = ReadInt(AH);
2055  if (l < 0)
2056  buf = NULL;
2057  else
2058  {
2059  buf = (char *) pg_malloc(l + 1);
2060  (*AH->ReadBufPtr) (AH, (void *) buf, l);
2061 
2062  buf[l] = '\0';
2063  }
2064 
2065  return buf;
2066 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
int ReadInt(ArchiveHandle *AH)
static char * buf
Definition: pg_test_fsync.c:65
#define NULL
Definition: c.h:229
void ReadToc ( ArchiveHandle AH)

Definition at line 2538 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, NULL, 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().

2539 {
2540  int i;
2541  char *tmp;
2542  DumpId *deps;
2543  int depIdx;
2544  int depSize;
2545  TocEntry *te;
2546 
2547  AH->tocCount = ReadInt(AH);
2548  AH->maxDumpId = 0;
2549 
2550  for (i = 0; i < AH->tocCount; i++)
2551  {
2552  te = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2553  te->dumpId = ReadInt(AH);
2554 
2555  if (te->dumpId > AH->maxDumpId)
2556  AH->maxDumpId = te->dumpId;
2557 
2558  /* Sanity check */
2559  if (te->dumpId <= 0)
2561  "entry ID %d out of range -- perhaps a corrupt TOC\n",
2562  te->dumpId);
2563 
2564  te->hadDumper = ReadInt(AH);
2565 
2566  if (AH->version >= K_VERS_1_8)
2567  {
2568  tmp = ReadStr(AH);
2569  sscanf(tmp, "%u", &te->catalogId.tableoid);
2570  free(tmp);
2571  }
2572  else
2574  tmp = ReadStr(AH);
2575  sscanf(tmp, "%u", &te->catalogId.oid);
2576  free(tmp);
2577 
2578  te->tag = ReadStr(AH);
2579  te->desc = ReadStr(AH);
2580 
2581  if (AH->version >= K_VERS_1_11)
2582  {
2583  te->section = ReadInt(AH);
2584  }
2585  else
2586  {
2587  /*
2588  * Rules for pre-8.4 archives wherein pg_dump hasn't classified
2589  * the entries into sections. This list need not cover entry
2590  * types added later than 8.4.
2591  */
2592  if (strcmp(te->desc, "COMMENT") == 0 ||
2593  strcmp(te->desc, "ACL") == 0 ||
2594  strcmp(te->desc, "ACL LANGUAGE") == 0)
2595  te->section = SECTION_NONE;
2596  else if (strcmp(te->desc, "TABLE DATA") == 0 ||
2597  strcmp(te->desc, "BLOBS") == 0 ||
2598  strcmp(te->desc, "BLOB COMMENTS") == 0)
2599  te->section = SECTION_DATA;
2600  else if (strcmp(te->desc, "CONSTRAINT") == 0 ||
2601  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
2602  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
2603  strcmp(te->desc, "INDEX") == 0 ||
2604  strcmp(te->desc, "RULE") == 0 ||
2605  strcmp(te->desc, "TRIGGER") == 0)
2606  te->section = SECTION_POST_DATA;
2607  else
2608  te->section = SECTION_PRE_DATA;
2609  }
2610 
2611  te->defn = ReadStr(AH);
2612  te->dropStmt = ReadStr(AH);
2613 
2614  if (AH->version >= K_VERS_1_3)
2615  te->copyStmt = ReadStr(AH);
2616 
2617  if (AH->version >= K_VERS_1_6)
2618  te->namespace = ReadStr(AH);
2619 
2620  if (AH->version >= K_VERS_1_10)
2621  te->tablespace = ReadStr(AH);
2622 
2623  te->owner = ReadStr(AH);
2624  if (AH->version >= K_VERS_1_9)
2625  {
2626  if (strcmp(ReadStr(AH), "true") == 0)
2627  te->withOids = true;
2628  else
2629  te->withOids = false;
2630  }
2631  else
2632  te->withOids = true;
2633 
2634  /* Read TOC entry dependencies */
2635  if (AH->version >= K_VERS_1_5)
2636  {
2637  depSize = 100;
2638  deps = (DumpId *) pg_malloc(sizeof(DumpId) * depSize);
2639  depIdx = 0;
2640  for (;;)
2641  {
2642  tmp = ReadStr(AH);
2643  if (!tmp)
2644  break; /* end of list */
2645  if (depIdx >= depSize)
2646  {
2647  depSize *= 2;
2648  deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depSize);
2649  }
2650  sscanf(tmp, "%d", &deps[depIdx]);
2651  free(tmp);
2652  depIdx++;
2653  }
2654 
2655  if (depIdx > 0) /* We have a non-null entry */
2656  {
2657  deps = (DumpId *) pg_realloc(deps, sizeof(DumpId) * depIdx);
2658  te->dependencies = deps;
2659  te->nDeps = depIdx;
2660  }
2661  else
2662  {
2663  free(deps);
2664  te->dependencies = NULL;
2665  te->nDeps = 0;
2666  }
2667  }
2668  else
2669  {
2670  te->dependencies = NULL;
2671  te->nDeps = 0;
2672  }
2673 
2674  if (AH->ReadExtraTocPtr)
2675  (*AH->ReadExtraTocPtr) (AH, te);
2676 
2677  ahlog(AH, 3, "read TOC entry %d (ID %d) for %s %s\n",
2678  i, te->dumpId, te->desc, te->tag);
2679 
2680  /* link completed entry into TOC circular list */
2681  te->prev = AH->toc->prev;
2682  AH->toc->prev->next = te;
2683  AH->toc->prev = te;
2684  te->next = AH->toc;
2685 
2686  /* special processing immediately upon read for some items */
2687  if (strcmp(te->desc, "ENCODING") == 0)
2688  processEncodingEntry(AH, te);
2689  else if (strcmp(te->desc, "STDSTRINGS") == 0)
2690  processStdStringsEntry(AH, te);
2691  }
2692 }
struct _tocEntry * next
static void processEncodingEntry(ArchiveHandle *AH, TocEntry *te)
int DumpId
Definition: pg_backup.h:229
Oid tableoid
Definition: pg_backup.h:225
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
#define NULL
Definition: c.h:229
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
ReadExtraTocPtr ReadExtraTocPtr
static void reduce_dependencies ( ArchiveHandle AH,
TocEntry te,
TocEntry ready_list 
)
static

Definition at line 4439 of file pg_backup_archiver.c.

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

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

4440 {
4441  int i;
4442 
4443  ahlog(AH, 2, "reducing dependencies for %d\n", te->dumpId);
4444 
4445  for (i = 0; i < te->nRevDeps; i++)
4446  {
4447  TocEntry *otherte = AH->tocsByDumpId[te->revDeps[i]];
4448 
4449  otherte->depCount--;
4450  if (otherte->depCount == 0 && otherte->par_prev != NULL)
4451  {
4452  /* It must be in the pending list, so remove it ... */
4453  par_list_remove(otherte);
4454  /* ... and add to ready_list */
4455  par_list_append(ready_list, otherte);
4456  }
4457  }
4458 }
struct _tocEntry * par_prev
#define NULL
Definition: c.h:229
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)
static char * replace_line_endings ( const char *  str)
static

Definition at line 3573 of file pg_backup_archiver.c.

References pg_strdup(), and result.

Referenced by _printTocEntry(), and PrintTOCSummary().

3574 {
3575  char *result;
3576  char *s;
3577 
3578  result = pg_strdup(str);
3579 
3580  for (s = result; *s != '\0'; s++)
3581  {
3582  if (*s == '\n' || *s == '\r')
3583  *s = ' ';
3584  }
3585 
3586  return result;
3587 }
return result
Definition: formatting.c:1618
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void repoint_table_dependencies ( ArchiveHandle AH)
static

Definition at line 4353 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().

4354 {
4355  TocEntry *te;
4356  int i;
4357  DumpId olddep;
4358 
4359  for (te = AH->toc->next; te != AH->toc; te = te->next)
4360  {
4361  if (te->section != SECTION_POST_DATA)
4362  continue;
4363  for (i = 0; i < te->nDeps; i++)
4364  {
4365  olddep = te->dependencies[i];
4366  if (olddep <= AH->maxDumpId &&
4367  AH->tableDataId[olddep] != 0)
4368  {
4369  te->dependencies[i] = AH->tableDataId[olddep];
4370  ahlog(AH, 2, "transferring dependency %d -> %d to %d\n",
4371  te->dumpId, olddep, AH->tableDataId[olddep]);
4372  }
4373  }
4374  }
4375 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:229
teSection section
struct _tocEntry * toc
DumpId * dependencies
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
int i
static void restore_toc_entries_parallel ( ArchiveHandle AH,
ParallelState pstate,
TocEntry pending_list 
)
static

Definition at line 3865 of file pg_backup_archiver.c.

References _tocEntryIsACL(), ACT_RESTORE, ahlog(), _tocEntry::depCount, _tocEntry::desc, DispatchJobForTocEntry(), _tocEntry::dumpId, get_next_work_item(), IsEveryWorkerIdle(), mark_restore_job_done(), _tocEntry::next, NULL, par_list_append(), par_list_header_init(), par_list_remove(), reduce_dependencies(), REQ_DATA, REQ_SCHEMA, _tocEntry::reqs, _tocEntry::section, SECTION_DATA, SECTION_POST_DATA, SECTION_PRE_DATA, _tocEntry::tag, _archiveHandle::toc, WaitForWorkers(), WFW_GOT_STATUS, and WFW_ONE_IDLE.

Referenced by RestoreArchive().

3867 {
3868  bool skipped_some;
3869  TocEntry ready_list;
3870  TocEntry *next_work_item;
3871 
3872  ahlog(AH, 2, "entering restore_toc_entries_parallel\n");
3873 
3874  /*
3875  * Initialize the lists of ready items, the list for pending items has
3876  * already been initialized in the caller. After this setup, the pending
3877  * list is everything that needs to be done but is blocked by one or more
3878  * dependencies, while the ready list contains items that have no
3879  * remaining dependencies. Note: we don't yet filter out entries that
3880  * aren't going to be restored. They might participate in dependency
3881  * chains connecting entries that should be restored, so we treat them as
3882  * live until we actually process them.
3883  */
3884  par_list_header_init(&ready_list);
3885  skipped_some = false;
3886  for (next_work_item = AH->toc->next; next_work_item != AH->toc; next_work_item = next_work_item->next)
3887  {
3888  /* NB: process-or-continue logic must be the inverse of loop above */
3889  if (next_work_item->section == SECTION_PRE_DATA)
3890  {
3891  /* All PRE_DATA items were dealt with above */
3892  continue;
3893  }
3894  if (next_work_item->section == SECTION_DATA ||
3895  next_work_item->section == SECTION_POST_DATA)
3896  {
3897  /* set this flag at same point that previous loop did */
3898  skipped_some = true;
3899  }
3900  else
3901  {
3902  /* SECTION_NONE items must be processed if previous loop didn't */
3903  if (!skipped_some)
3904  continue;
3905  }
3906 
3907  if (next_work_item->depCount > 0)
3908  par_list_append(pending_list, next_work_item);
3909  else
3910  par_list_append(&ready_list, next_work_item);
3911  }
3912 
3913  /*
3914  * main parent loop
3915  *
3916  * Keep going until there is no worker still running AND there is no work
3917  * left to be done.
3918  */
3919 
3920  ahlog(AH, 1, "entering main parallel loop\n");
3921 
3922  while ((next_work_item = get_next_work_item(AH, &ready_list, pstate)) != NULL ||
3923  !IsEveryWorkerIdle(pstate))
3924  {
3925  if (next_work_item != NULL)
3926  {
3927  /* If not to be restored, don't waste time launching a worker */
3928  if ((next_work_item->reqs & (REQ_SCHEMA | REQ_DATA)) == 0 ||
3929  _tocEntryIsACL(next_work_item))
3930  {
3931  ahlog(AH, 1, "skipping item %d %s %s\n",
3932  next_work_item->dumpId,
3933  next_work_item->desc, next_work_item->tag);
3934 
3935  par_list_remove(next_work_item);
3936  reduce_dependencies(AH, next_work_item, &ready_list);
3937 
3938  continue;
3939  }
3940 
3941  ahlog(AH, 1, "launching item %d %s %s\n",
3942  next_work_item->dumpId,
3943  next_work_item->desc, next_work_item->tag);
3944 
3945  par_list_remove(next_work_item);
3946 
3947  DispatchJobForTocEntry(AH, pstate, next_work_item, ACT_RESTORE,
3948  mark_restore_job_done, &ready_list);
3949  }
3950  else
3951  {
3952  /* at least one child is working and we have nothing ready. */
3953  }
3954 
3955  /*
3956  * Before dispatching another job, check to see if anything has
3957  * finished. We should check every time through the loop so as to
3958  * reduce dependencies as soon as possible. If we were unable to
3959  * dispatch any job this time through, wait until some worker finishes
3960