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

Variables

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

Macro Definition Documentation

#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,
SetupWorkerPtrType  setupWorkerPtr 
)
static

Definition at line 2301 of file pg_backup_archiver.c.

References _discoverArchiveFormat(), archCustom, archDirectory, _archiveHandle::archiveDumpVersion, archModeWrite, archNull, archTar, archUnknown, _archiveHandle::compression, _archiveHandle::createDate, _archiveHandle::currSchema, _archiveHandle::currTablespace, _archiveHandle::currUser, _archiveHandle::currWithOids, dosync, _archiveHandle::dosync, Archive::encoding, exit_horribly(), Archive::exit_on_error, _archiveHandle::format, _archiveHandle::fSpec, _archiveHandle::gzOut, InitArchiveFmt_Custom(), InitArchiveFmt_Directory(), InitArchiveFmt_Null(), InitArchiveFmt_Tar(), _archiveHandle::intSize, K_VERS_SELF, _archiveHandle::mode, modulename, Archive::n_errors, _tocEntry::next, 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().

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

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

3207 {
3208  RestoreOptions *ropt = AH->public.ropt;
3209 
3210  if (ropt && (ropt->noOwner || !ropt->use_setsessauth))
3211  return;
3212 
3213  _becomeUser(AH, te->owner);
3214 }
RestoreOptions * ropt
Definition: pg_backup.h:182
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 3182 of file pg_backup_archiver.c.

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

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

3183 {
3184  if (!user)
3185  user = ""; /* avoid null pointers */
3186 
3187  if (AH->currUser && strcmp(AH->currUser, user) == 0)
3188  return; /* no need to do anything */
3189 
3190  _doSetSessionAuth(AH, user);
3191 
3192  /*
3193  * NOTE: currUser keeps track of what the imaginary session user in our
3194  * script is
3195  */
3196  if (AH->currUser)
3197  free(AH->currUser);
3198  AH->currUser = pg_strdup(user);
3199 }
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 973 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entry().

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

Definition at line 2096 of file pg_backup_archiver.c.

References archDirectory, archTar, buf, exit_horribly(), _archiveHandle::format, free, fseeko, _archiveHandle::fSpec, _archiveHandle::intSize, isValidTarHeader(), K_VERS_1_7, _archiveHandle::lookahead, _archiveHandle::lookaheadLen, _archiveHandle::lookaheadPos, _archiveHandle::lookaheadSize, MAKE_ARCHIVE_VERSION, MAXPGPATH, modulename, 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().

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

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

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

3060 {
3062 
3063  appendPQExpBufferStr(cmd, "SET SESSION AUTHORIZATION ");
3064 
3065  /*
3066  * SQL requires a string literal here. Might as well be correct.
3067  */
3068  if (user && *user)
3069  appendStringLiteralAHX(cmd, user, AH);
3070  else
3071  appendPQExpBufferStr(cmd, "DEFAULT");
3072  appendPQExpBufferChar(cmd, ';');
3073 
3074  if (RestoringToDB(AH))
3075  {
3076  PGresult *res;
3077 
3078  res = PQexec(AH->connection, cmd->data);
3079 
3080  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3081  /* NOT warn_or_exit_horribly... use -O instead to skip this. */
3082  exit_horribly(modulename, "could not set session user to \"%s\": %s",
3084 
3085  PQclear(res);
3086  }
3087  else
3088  ahprintf(AH, "%s\n\n", cmd->data);
3089 
3090  destroyPQExpBuffer(cmd);
3091 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6097
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 3099 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().

3100 {
3102 
3103  appendPQExpBuffer(cmd, "SET default_with_oids = %s;", withOids ?
3104  "true" : "false");
3105 
3106  if (RestoringToDB(AH))
3107  {
3108  PGresult *res;
3109 
3110  res = PQexec(AH->connection, cmd->data);
3111 
3112  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3114  "could not set default_with_oids: %s",
3115  PQerrorMessage(AH->connection));
3116 
3117  PQclear(res);
3118  }
3119  else
3120  ahprintf(AH, "%s\n\n", cmd->data);
3121 
3122  destroyPQExpBuffer(cmd);
3123 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6097
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 1001 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entry().

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

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

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

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

Referenced by SortTocFromFile().

1829 {
1830  /* Unlink te from list */
1831  te->prev->next = te->next;
1832  te->next->prev = te->prev;
1833 
1834  /* and insert it before "pos" */
1835  te->prev = pos->prev;
1836  te->next = pos;
1837  pos->prev->next = te;
1838  pos->prev = te;
1839 }
struct _tocEntry * next
struct _tocEntry * prev
static void _printTocEntry ( ArchiveHandle AH,
TocEntry te,
bool  isData 
)
static

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

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

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

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

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

3237 {
3238  PQExpBuffer qry;
3239 
3240  if (!schemaName || *schemaName == '\0' ||
3241  (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
3242  return; /* no need to do anything */
3243 
3244  qry = createPQExpBuffer();
3245 
3246  appendPQExpBuffer(qry, "SET search_path = %s",
3247  fmtId(schemaName));
3248  if (strcmp(schemaName, "pg_catalog") != 0)
3249  appendPQExpBufferStr(qry, ", pg_catalog");
3250 
3251  if (RestoringToDB(AH))
3252  {
3253  PGresult *res;
3254 
3255  res = PQexec(AH->connection, qry->data);
3256 
3257  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3259  "could not set search_path to \"%s\": %s",
3260  schemaName, PQerrorMessage(AH->connection));
3261 
3262  PQclear(res);
3263  }
3264  else
3265  ahprintf(AH, "%s;\n\n", qry->data);
3266 
3267  if (AH->currSchema)
3268  free(AH->currSchema);
3269  AH->currSchema = pg_strdup(schemaName);
3270 
3271  destroyPQExpBuffer(qry);
3272 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6097
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 3279 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().

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

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

Referenced by _printTocEntry().

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

Definition at line 2998 of file pg_backup_archiver.c.

References _tocEntry::desc.

Referenced by _printTocEntry(), and _tocEntryRequired().

2999 {
3000  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3001  if (strcmp(te->desc, "ACL") == 0 ||
3002  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3003  strcmp(te->desc, "DEFAULT ACL") == 0)
3004  return true;
3005  return false;
3006 }
static teReqs _tocEntryRequired ( TocEntry te,
teSection  curSection,
RestoreOptions ropt 
)
static

Definition at line 2809 of file pg_backup_archiver.c.

References _tocEntryIsACL(), _restoreOptions::aclsSkip, _restoreOptions::binary_upgrade, _restoreOptions::dataOnly, _tocEntry::defn, _tocEntry::desc, DUMP_DATA, DUMP_POST_DATA, DUMP_PRE_DATA, _tocEntry::dumpId, _restoreOptions::dumpSections, _restoreOptions::functionNames, _tocEntry::hadDumper, SimpleStringList::head, _restoreOptions::idWanted, _restoreOptions::indexNames, _restoreOptions::no_publications, _restoreOptions::no_security_labels, _restoreOptions::no_subscriptions, 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().

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

Definition at line 2978 of file pg_backup_archiver.c.

References _tocEntry::desc, RESTORE_PASS_ACL, and RESTORE_PASS_MAIN.

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

2979 {
2980  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
2981  if (strcmp(te->desc, "ACL") == 0 ||
2982  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
2983  strcmp(te->desc, "DEFAULT ACL") == 0)
2984  return RESTORE_PASS_ACL;
2985  if (strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0)
2986  return RESTORE_PASS_REFRESH;
2987  return RESTORE_PASS_MAIN;
2988 }
void ahlog ( ArchiveHandle AH,
int  level,
const char *  fmt,
  ... 
)
int ahprintf ( ArchiveHandle AH,
const char *  fmt,
  ... 
)

Definition at line 1612 of file pg_backup_archiver.c.

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

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

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

Definition at line 1714 of file pg_backup_archiver.c.

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

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

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

Definition at line 1053 of file pg_backup_archiver.c.

References _archiveHandle::ArchiveEntryPtr, _tocEntry::catalogId, _tocEntry::dataDumper, _tocEntry::dataDumperArg, _tocEntry::dependencies, _tocEntry::dumpId, _tocEntry::formatData, _tocEntry::hadDumper, _archiveHandle::maxDumpId, _tocEntry::nDeps, _tocEntry::next, 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().

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

Definition at line 1479 of file pg_backup_archiver.c.

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

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

Definition at line 1471 of file pg_backup_archiver.c.

References WriteData().

Referenced by dumpTableData_insert().

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

Definition at line 1853 of file pg_backup_archiver.c.

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

Referenced by getTocEntryByDumpId(), and RestoreArchive().

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

Definition at line 3776 of file pg_backup_archiver.c.

References fseeko, ftello, and pgoff_t.

Referenced by InitArchiveFmt_Custom(), and InitArchiveFmt_Tar().

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

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

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

Definition at line 235 of file pg_backup_archiver.c.

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

Referenced by main().

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

Definition at line 212 of file pg_backup_archiver.c.

References _allocAH().

Referenced by main().

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

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

4711 {
4712  /* Should not have an open database connection */
4713  Assert(AH->connection == NULL);
4714 
4715  /* Clear format-specific state */
4716  (AH->DeClonePtr) (AH);
4717 
4718  /* Clear state allocated by CloneArchive */
4719  if (AH->sqlparse.curCmd)
4721 
4722  /* Clear any connection-local state */
4723  if (AH->currUser)
4724  free(AH->currUser);
4725  if (AH->currSchema)
4726  free(AH->currSchema);
4727  if (AH->currTablespace)
4728  free(AH->currTablespace);
4729  if (AH->savedPassword)
4730  free(AH->savedPassword);
4731 
4732  free(AH);
4733 }
PQExpBuffer curCmd
DeClonePtrType DeClonePtr
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 1671 of file pg_backup_archiver.c.

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

Referenced by ahwrite(), and EndRestoreBlob().

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

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

Referenced by SetArchiveOptions().

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

Definition at line 3810 of file pg_backup_archiver.c.

References ahprintf(), buf, and PGDUMP_STRFTIME_FMT.

Referenced by RestoreArchive().

3811 {
3812  char buf[64];
3813 
3814  if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&tim)) != 0)
3815  ahprintf(AH, "-- %s %s\n\n", msg, buf);
3816 }
static char * buf
Definition: pg_test_fsync.c:66
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define PGDUMP_STRFTIME_FMT
Definition: dumputils.h:33
int EndBlob ( Archive AHX,
Oid  oid 
)

Definition at line 1246 of file pg_backup_archiver.c.

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

Referenced by dumpBlobs().

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

Definition at line 1350 of file pg_backup_archiver.c.

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

Referenced by _LoadBlobs().

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

Definition at line 1283 of file pg_backup_archiver.c.

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

Referenced by _LoadBlobs().

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

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

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

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

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

1895 {
1896  /* build index arrays if we didn't already */
1897  if (AH->tocsByDumpId == NULL)
1898  buildTocEntryArrays(AH);
1899 
1900  if (id > 0 && id <= AH->maxDumpId)
1901  return AH->tocsByDumpId[id];
1902 
1903  return NULL;
1904 }
static void buildTocEntryArrays(ArchiveHandle *AH)
#define NULL
Definition: c.h:229
struct _tocEntry ** tocsByDumpId
static bool has_lock_conflicts ( TocEntry te1,
TocEntry te2 
)
static

Definition at line 4095 of file pg_backup_archiver.c.

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

Referenced by get_next_work_item().

4096 {
4097  int j,
4098  k;
4099 
4100  for (j = 0; j < te1->nLockDeps; j++)
4101  {
4102  for (k = 0; k < te2->nDeps; k++)
4103  {
4104  if (te1->lockDeps[j] == te2->dependencies[k])
4105  return true;
4106  }
4107  }
4108  return false;
4109 }
DumpId * lockDeps
DumpId * dependencies
static void identify_locking_dependencies ( ArchiveHandle AH,
TocEntry te 
)
static

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

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

4602 {
4603  ahlog(AH, 1, "table \"%s\" could not be created, will not restore its data\n",
4604  te->tag);
4605 
4606  if (AH->tableDataId[te->dumpId] != 0)
4607  {
4608  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4609 
4610  ted->reqs = 0;
4611  }
4612 }
struct _tocEntry ** tocsByDumpId
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
void InitDumpOptions ( DumpOptions opts)

Definition at line 141 of file pg_backup_archiver.c.

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

Referenced by main(), and NewDumpOptions().

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

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

4587 {
4588  if (AH->tableDataId[te->dumpId] != 0)
4589  {
4590  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4591 
4592  ted->created = true;
4593  }
4594 }
struct _tocEntry ** tocsByDumpId
static void mark_dump_job_done ( ArchiveHandle AH,
TocEntry te,
int  status,
void *  callback_data 
)
static

Definition at line 2459 of file pg_backup_archiver.c.

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

Referenced by WriteDataChunks().

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

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

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

Definition at line 4154 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entries_parallel().

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

Definition at line 129 of file pg_backup_archiver.c.

References InitDumpOptions(), and pg_malloc().

Referenced by dumpOptionsFromRestoreOptions().

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

Definition at line 958 of file pg_backup_archiver.c.

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

Referenced by _CloseArchive(), and main().

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

Definition at line 226 of file pg_backup_archiver.c.

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

Referenced by main().

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

Definition at line 4127 of file pg_backup_archiver.c.

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

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

4128 {
4129  te->par_prev = l->par_prev;
4130  l->par_prev->par_next = te;
4131  l->par_prev = te;
4132  te->par_next = l;
4133 }
struct _tocEntry * par_prev
struct _tocEntry * par_next
static void par_list_header_init ( TocEntry l)
static

Definition at line 4120 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entries_parallel(), and RestoreArchive().

4121 {
4122  l->par_prev = l->par_next = l;
4123 }
struct _tocEntry * par_prev
struct _tocEntry * par_next
static void par_list_remove ( TocEntry te)
static

Definition at line 4137 of file pg_backup_archiver.c.

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

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

4138 {
4139  te->par_prev->par_next = te->par_next;
4140  te->par_next->par_prev = te->par_prev;
4141  te->par_prev = NULL;
4142  te->par_next = NULL;
4143 }
struct _tocEntry * par_prev
struct _tocEntry * par_next
#define NULL
Definition: c.h:229
int parallel_restore ( ArchiveHandle AH,
TocEntry te 
)

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

4278 {
4279  int status;
4280 
4281  Assert(AH->connection != NULL);
4282 
4283  /* Count only errors associated with this TOC entry */
4284  AH->public.n_errors = 0;
4285 
4286  /* Restore the TOC item */
4287  status = restore_toc_entry(AH, te, true);
4288 
4289  return status;
4290 }
int n_errors
Definition: pg_backup.h:202
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 1117 of file pg_backup_archiver.c.

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

Referenced by main().

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

Definition at line 268 of file pg_backup_archiver.c.

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

Referenced by main().

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

Definition at line 2722 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

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

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

Referenced by ReadToc().

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

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

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

Definition at line 2030 of file pg_backup_archiver.c.

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

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

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

Definition at line 1935 of file pg_backup_archiver.c.

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

Referenced by _ReadExtraToc().

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

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

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

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

Definition at line 2565 of file pg_backup_archiver.c.

References ahlog(), _tocEntry::catalogId, _tocEntry::copyStmt, _tocEntry::defn, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dropStmt, _tocEntry::dumpId, exit_horribly(), free, _tocEntry::hadDumper, i, InvalidOid, K_VERS_1_10, K_VERS_1_11, K_VERS_1_3, K_VERS_1_5, K_VERS_1_6, K_VERS_1_8, K_VERS_1_9, _archiveHandle::maxDumpId, modulename, _tocEntry::nDeps, _tocEntry::next, 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().

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

Definition at line 4551 of file pg_backup_archiver.c.

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

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

4552 {
4553  int i;
4554 
4555  ahlog(AH, 2, "reducing dependencies for %d\n", te->dumpId);
4556 
4557  for (i = 0; i < te->nRevDeps; i++)
4558  {
4559  TocEntry *otherte = AH->tocsByDumpId[te->revDeps[i]];
4560 
4561  Assert(otherte->depCount > 0);
4562  otherte->depCount--;
4563 
4564  /*
4565  * It's ready if it has no remaining dependencies and it belongs in
4566  * the current restore pass. However, don't move it if it has not yet
4567  * been put into the pending list.
4568  */
4569  if (otherte->depCount == 0 &&
4570  _tocEntryRestorePass(otherte) == AH->restorePass &&
4571  otherte->par_prev != NULL)
4572  {
4573  /* It must be in the pending list, so remove it ... */
4574  par_list_remove(otherte);
4575  /* ... and add to ready_list */
4576  par_list_append(ready_list, otherte);
4577  }
4578  }
4579 }
RestorePass restorePass
static RestorePass _tocEntryRestorePass(TocEntry *te)
struct _tocEntry * par_prev
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
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 3627 of file pg_backup_archiver.c.

References pg_strdup(), and result.

Referenced by _printTocEntry(), and PrintTOCSummary().

3628 {
3629  char *result;
3630  char *s;
3631 
3632  result = pg_strdup(str);
3633 
3634  for (s = result; *s != '\0'; s++)
3635  {
3636  if (*s == '\n' || *s == '\r')
3637  *s = ' ';
3638  }
3639 
3640  return result;
3641 }
return result
Definition: formatting.c:1633
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void repoint_table_dependencies ( ArchiveHandle AH)
static

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

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