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, bool acl_pass)
 
static char * replace_line_endings (const char *str)
 
static void _doSetFixedOutputState (ArchiveHandle *AH)
 
static void _doSetSessionAuth (ArchiveHandle *AH, const char *user)
 
static void _doSetWithOids (ArchiveHandle *AH, const bool withOids)
 
static void _reconnectToDB (ArchiveHandle *AH, const char *dbname)
 
static void _becomeUser (ArchiveHandle *AH, const char *user)
 
static void _becomeOwner (ArchiveHandle *AH, TocEntry *te)
 
static void _selectOutputSchema (ArchiveHandle *AH, const char *schemaName)
 
static void _selectTablespace (ArchiveHandle *AH, const char *tablespace)
 
static void processEncodingEntry (ArchiveHandle *AH, TocEntry *te)
 
static void processStdStringsEntry (ArchiveHandle *AH, TocEntry *te)
 
static teReqs _tocEntryRequired (TocEntry *te, teSection curSection, RestoreOptions *ropt)
 
static bool _tocEntryIsACL (TocEntry *te)
 
static void _disableTriggersIfNecessary (ArchiveHandle *AH, TocEntry *te)
 
static void _enableTriggersIfNecessary (ArchiveHandle *AH, TocEntry *te)
 
static void buildTocEntryArrays (ArchiveHandle *AH)
 
static void _moveBefore (ArchiveHandle *AH, TocEntry *pos, TocEntry *te)
 
static int _discoverArchiveFormat (ArchiveHandle *AH)
 
static int RestoringToDB (ArchiveHandle *AH)
 
static void dump_lo_buf (ArchiveHandle *AH)
 
static void dumpTimestamp (ArchiveHandle *AH, const char *msg, time_t tim)
 
static void SetOutput (ArchiveHandle *AH, const char *filename, int compression)
 
static OutputContext SaveOutput (ArchiveHandle *AH)
 
static void RestoreOutput (ArchiveHandle *AH, OutputContext savedContext)
 
static int restore_toc_entry (ArchiveHandle *AH, TocEntry *te, bool is_parallel)
 
static void restore_toc_entries_prefork (ArchiveHandle *AH)
 
static void restore_toc_entries_parallel (ArchiveHandle *AH, ParallelState *pstate, TocEntry *pending_list)
 
static void restore_toc_entries_postfork (ArchiveHandle *AH, TocEntry *pending_list)
 
static void par_list_header_init (TocEntry *l)
 
static void par_list_append (TocEntry *l, TocEntry *te)
 
static void par_list_remove (TocEntry *te)
 
static TocEntryget_next_work_item (ArchiveHandle *AH, TocEntry *ready_list, ParallelState *pstate)
 
static void mark_dump_job_done (ArchiveHandle *AH, TocEntry *te, int status, void *callback_data)
 
static void mark_restore_job_done (ArchiveHandle *AH, TocEntry *te, int status, void *callback_data)
 
static void fix_dependencies (ArchiveHandle *AH)
 
static bool has_lock_conflicts (TocEntry *te1, TocEntry *te2)
 
static void repoint_table_dependencies (ArchiveHandle *AH)
 
static void identify_locking_dependencies (ArchiveHandle *AH, TocEntry *te)
 
static void reduce_dependencies (ArchiveHandle *AH, TocEntry *te, TocEntry *ready_list)
 
static void mark_create_done (ArchiveHandle *AH, TocEntry *te)
 
static void inhibit_data_for_failed_table (ArchiveHandle *AH, TocEntry *te)
 
static void StrictNamesCheck (RestoreOptions *ropt)
 
DumpOptionsNewDumpOptions (void)
 
void InitDumpOptions (DumpOptions *opts)
 
DumpOptionsdumpOptionsFromRestoreOptions (RestoreOptions *ropt)
 
static void setupRestoreWorker (Archive *AHX)
 
ArchiveCreateArchive (const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, 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 2275 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().

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

3159 {
3160  RestoreOptions *ropt = AH->public.ropt;
3161 
3162  if (ropt && (ropt->noOwner || !ropt->use_setsessauth))
3163  return;
3164 
3165  _becomeUser(AH, te->owner);
3166 }
RestoreOptions * ropt
Definition: pg_backup.h:181
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 3134 of file pg_backup_archiver.c.

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

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

3135 {
3136  if (!user)
3137  user = ""; /* avoid null pointers */
3138 
3139  if (AH->currUser && strcmp(AH->currUser, user) == 0)
3140  return; /* no need to do anything */
3141 
3142  _doSetSessionAuth(AH, user);
3143 
3144  /*
3145  * NOTE: currUser keeps track of what the imaginary session user in our
3146  * script is
3147  */
3148  if (AH->currUser)
3149  free(AH->currUser);
3150  AH->currUser = pg_strdup(user);
3151 }
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 947 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().

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

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

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

2966 {
2967  RestoreOptions *ropt = AH->public.ropt;
2968 
2969  /*
2970  * Disable timeouts to allow for slow commands, idle parallel workers, etc
2971  */
2972  ahprintf(AH, "SET statement_timeout = 0;\n");
2973  ahprintf(AH, "SET lock_timeout = 0;\n");
2974  ahprintf(AH, "SET idle_in_transaction_session_timeout = 0;\n");
2975 
2976  /* Select the correct character set encoding */
2977  ahprintf(AH, "SET client_encoding = '%s';\n",
2979 
2980  /* Select the correct string literal syntax */
2981  ahprintf(AH, "SET standard_conforming_strings = %s;\n",
2982  AH->public.std_strings ? "on" : "off");
2983 
2984  /* Select the role to be used during restore */
2985  if (ropt && ropt->use_role)
2986  ahprintf(AH, "SET ROLE %s;\n", fmtId(ropt->use_role));
2987 
2988  /* Make sure function checking is disabled */
2989  ahprintf(AH, "SET check_function_bodies = false;\n");
2990 
2991  /* Avoid annoying notices etc */
2992  ahprintf(AH, "SET client_min_messages = warning;\n");
2993  if (!AH->public.std_strings)
2994  ahprintf(AH, "SET escape_string_warning = off;\n");
2995 
2996  /* Adjust row-security state */
2997  if (ropt && ropt->enable_row_security)
2998  ahprintf(AH, "SET row_security = on;\n");
2999  else
3000  ahprintf(AH, "SET row_security = off;\n");
3001 
3002  ahprintf(AH, "\n");
3003 }
RestoreOptions * ropt
Definition: pg_backup.h:181
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 3011 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().

3012 {
3014 
3015  appendPQExpBufferStr(cmd, "SET SESSION AUTHORIZATION ");
3016 
3017  /*
3018  * SQL requires a string literal here. Might as well be correct.
3019  */
3020  if (user && *user)
3021  appendStringLiteralAHX(cmd, user, AH);
3022  else
3023  appendPQExpBufferStr(cmd, "DEFAULT");
3024  appendPQExpBufferChar(cmd, ';');
3025 
3026  if (RestoringToDB(AH))
3027  {
3028  PGresult *res;
3029 
3030  res = PQexec(AH->connection, cmd->data);
3031 
3032  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3033  /* NOT warn_or_exit_horribly... use -O instead to skip this. */
3034  exit_horribly(modulename, "could not set session user to \"%s\": %s",
3036 
3037  PQclear(res);
3038  }
3039  else
3040  ahprintf(AH, "%s\n\n", cmd->data);
3041 
3042  destroyPQExpBuffer(cmd);
3043 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5988
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 3051 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().

3052 {
3054 
3055  appendPQExpBuffer(cmd, "SET default_with_oids = %s;", withOids ?
3056  "true" : "false");
3057 
3058  if (RestoringToDB(AH))
3059  {
3060  PGresult *res;
3061 
3062  res = PQexec(AH->connection, cmd->data);
3063 
3064  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3066  "could not set default_with_oids: %s",
3067  PQerrorMessage(AH->connection));
3068 
3069  PQclear(res);
3070  }
3071  else
3072  ahprintf(AH, "%s\n\n", cmd->data);
3073 
3074  destroyPQExpBuffer(cmd);
3075 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5988
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 975 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().

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

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

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

Referenced by SortTocFromFile().

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

Definition at line 3367 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entry(), and RestoreArchive().

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

3089 {
3090  if (RestoringToDB(AH))
3092  else
3093  {
3094  if (dbname)
3095  {
3096  PQExpBufferData connectbuf;
3097 
3098  initPQExpBuffer(&connectbuf);
3099  appendPsqlMetaConnect(&connectbuf, dbname);
3100  ahprintf(AH, "%s\n", connectbuf.data);
3101  termPQExpBuffer(&connectbuf);
3102  }
3103  else
3104  ahprintf(AH, "%s\n", "\\connect -\n");
3105  }
3106 
3107  /*
3108  * NOTE: currUser keeps track of what the imaginary session user in our
3109  * script is. It's now effectively reset to the original userID.
3110  */
3111  if (AH->currUser)
3112  free(AH->currUser);
3113  AH->currUser = NULL;
3114 
3115  /* don't assume we still know the output schema, tablespace, etc either */
3116  if (AH->currSchema)
3117  free(AH->currSchema);
3118  AH->currSchema = NULL;
3119  if (AH->currTablespace)
3120  free(AH->currTablespace);
3121  AH->currTablespace = NULL;
3122  AH->currWithOids = -1;
3123 
3124  /* re-establish fixed state */
3126 }
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:38
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
static void _selectOutputSchema ( ArchiveHandle AH,
const char *  schemaName 
)
static

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

3189 {
3190  PQExpBuffer qry;
3191 
3192  if (!schemaName || *schemaName == '\0' ||
3193  (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
3194  return; /* no need to do anything */
3195 
3196  qry = createPQExpBuffer();
3197 
3198  appendPQExpBuffer(qry, "SET search_path = %s",
3199  fmtId(schemaName));
3200  if (strcmp(schemaName, "pg_catalog") != 0)
3201  appendPQExpBufferStr(qry, ", pg_catalog");
3202 
3203  if (RestoringToDB(AH))
3204  {
3205  PGresult *res;
3206 
3207  res = PQexec(AH->connection, qry->data);
3208 
3209  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3211  "could not set search_path to \"%s\": %s",
3212  schemaName, PQerrorMessage(AH->connection));
3213 
3214  PQclear(res);
3215  }
3216  else
3217  ahprintf(AH, "%s;\n\n", qry->data);
3218 
3219  if (AH->currSchema)
3220  free(AH->currSchema);
3221  AH->currSchema = pg_strdup(schemaName);
3222 
3223  destroyPQExpBuffer(qry);
3224 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5988
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 3231 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().

3232 {
3233  RestoreOptions *ropt = AH->public.ropt;
3234  PQExpBuffer qry;
3235  const char *want,
3236  *have;
3237 
3238  /* do nothing in --no-tablespaces mode */
3239  if (ropt->noTablespace)
3240  return;
3241 
3242  have = AH->currTablespace;
3243  want = tablespace;
3244 
3245  /* no need to do anything for non-tablespace object */
3246  if (!want)
3247  return;
3248 
3249  if (have && strcmp(want, have) == 0)
3250  return; /* no need to do anything */
3251 
3252  qry = createPQExpBuffer();
3253 
3254  if (strcmp(want, "") == 0)
3255  {
3256  /* We want the tablespace to be the database's default */
3257  appendPQExpBufferStr(qry, "SET default_tablespace = ''");
3258  }
3259  else
3260  {
3261  /* We want an explicit tablespace */
3262  appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
3263  }
3264 
3265  if (RestoringToDB(AH))
3266  {
3267  PGresult *res;
3268 
3269  res = PQexec(AH->connection, qry->data);
3270 
3271  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3273  "could not set default_tablespace to %s: %s",
3274  fmtId(want), PQerrorMessage(AH->connection));
3275 
3276  PQclear(res);
3277  }
3278  else
3279  ahprintf(AH, "%s;\n\n", qry->data);
3280 
3281  if (AH->currTablespace)
3282  free(AH->currTablespace);
3283  AH->currTablespace = pg_strdup(want);
3284 
3285  destroyPQExpBuffer(qry);
3286 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5988
RestoreOptions * ropt
Definition: pg_backup.h:181
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 3173 of file pg_backup_archiver.c.

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

Referenced by _printTocEntry().

3174 {
3175  if (AH->currWithOids != te->withOids)
3176  {
3177  _doSetWithOids(AH, te->withOids);
3178  AH->currWithOids = te->withOids;
3179  }
3180 }
static void _doSetWithOids(ArchiveHandle *AH, const bool withOids)
static bool _tocEntryIsACL ( TocEntry te)
static

Definition at line 2950 of file pg_backup_archiver.c.

References _tocEntry::desc.

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

2951 {
2952  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
2953  if (strcmp(te->desc, "ACL") == 0 ||
2954  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
2955  strcmp(te->desc, "DEFAULT ACL") == 0)
2956  return true;
2957  return false;
2958 }
static teReqs _tocEntryRequired ( TocEntry te,
teSection  curSection,
RestoreOptions ropt 
)
static

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

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

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

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

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

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

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

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

References WriteData().

Referenced by dumpTableData_insert().

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

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

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

References fseeko, ftello, and pgoff_t.

Referenced by InitArchiveFmt_Custom(), and InitArchiveFmt_Tar().

3729 {
3730  pgoff_t tpos;
3731 
3732  /*
3733  * If pgoff_t is wider than long, we must have "real" fseeko and not an
3734  * emulation using fseek. Otherwise report no seek capability.
3735  */
3736 #ifndef HAVE_FSEEKO
3737  if (sizeof(pgoff_t) > sizeof(long))
3738  return false;
3739 #endif
3740 
3741  /* Check that ftello works on this file */
3742  tpos = ftello(fp);
3743  if (tpos < 0)
3744  return false;
3745 
3746  /*
3747  * Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
3748  * this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
3749  * successful no-op even on files that are otherwise unseekable.
3750  */
3751  if (fseeko(fp, tpos, SEEK_SET) != 0)
3752  return false;
3753 
3754  return true;
3755 }
#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 4509 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().

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

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

Referenced by main().

230 {
231  int res = 0;
232  ArchiveHandle *AH = (ArchiveHandle *) AHX;
233 
234  (*AH->ClosePtr) (AH);
235 
236  /* Close the output */
237  if (AH->gzOut)
238  res = GZCLOSE(AH->OF);
239  else if (AH->OF != stdout)
240  res = fclose(AH->OF);
241 
242  if (res != 0)
243  exit_horribly(modulename, "could not close output file: %s\n",
244  strerror(errno));
245 }
#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 206 of file pg_backup_archiver.c.

References _allocAH().

Referenced by main().

210 {
211  ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, dosync,
212  mode, setupDumpWorker);
213 
214  return (Archive *) AH;
215 }
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:1147
void DeCloneArchive ( ArchiveHandle AH)

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

4599 {
4600  /* Should not have an open database connection */
4601  Assert(AH->connection == NULL);
4602 
4603  /* Clear format-specific state */
4604  (AH->DeClonePtr) (AH);
4605 
4606  /* Clear state allocated by CloneArchive */
4607  if (AH->sqlparse.curCmd)
4609 
4610  /* Clear any connection-local state */
4611  if (AH->currUser)
4612  free(AH->currUser);
4613  if (AH->currSchema)
4614  free(AH->currSchema);
4615  if (AH->currTablespace)
4616  free(AH->currTablespace);
4617  if (AH->savedPassword)
4618  free(AH->savedPassword);
4619 
4620  free(AH);
4621 }
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 1645 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().

1646 {
1647  if (AH->connection)
1648  {
1649  size_t res;
1650 
1651  res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used);
1652  ahlog(AH, 5, ngettext("wrote %lu byte of large object data (result = %lu)\n",
1653  "wrote %lu bytes of large object data (result = %lu)\n",
1654  AH->lo_buf_used),
1655  (unsigned long) AH->lo_buf_used, (unsigned long) res);
1656  if (res != AH->lo_buf_used)
1658  "could not write to large object (result: %lu, expected: %lu)\n",
1659  (unsigned long) res, (unsigned long) AH->lo_buf_used);
1660  }
1661  else
1662  {
1664 
1666  (const unsigned char *) AH->lo_buf,
1667  AH->lo_buf_used,
1668  AH);
1669 
1670  /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
1671  AH->writingBlob = 0;
1672  ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
1673  AH->writingBlob = 1;
1674 
1675  destroyPQExpBuffer(buf);
1676  }
1677  AH->lo_buf_used = 0;
1678 }
#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 148 of file pg_backup_archiver.c.

References _restoreOptions::aclsSkip, _dumpOptions::aclsSkip, _restoreOptions::column_inserts, _dumpOptions::column_inserts, _restoreOptions::createDB, _restoreOptions::dataOnly, _dumpOptions::dataOnly, _restoreOptions::disable_dollar_quoting, _dumpOptions::disable_dollar_quoting, _restoreOptions::disable_triggers, _dumpOptions::disable_triggers, _restoreOptions::dropSchema, _restoreOptions::dump_inserts, _dumpOptions::dump_inserts, _restoreOptions::dumpSections, _dumpOptions::dumpSections, _restoreOptions::enable_row_security, _dumpOptions::enable_row_security, _restoreOptions::if_exists, _dumpOptions::if_exists, _restoreOptions::include_everything, _dumpOptions::include_everything, _restoreOptions::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().

149 {
150  DumpOptions *dopt = NewDumpOptions();
151 
152  /* this is the inverse of what's at the end of pg_dump.c's main() */
153  dopt->outputClean = ropt->dropSchema;
154  dopt->dataOnly = ropt->dataOnly;
155  dopt->schemaOnly = ropt->schemaOnly;
156  dopt->if_exists = ropt->if_exists;
157  dopt->column_inserts = ropt->column_inserts;
158  dopt->dumpSections = ropt->dumpSections;
159  dopt->aclsSkip = ropt->aclsSkip;
160  dopt->outputSuperuser = ropt->superuser;
161  dopt->outputCreateDB = ropt->createDB;
162  dopt->outputNoOwner = ropt->noOwner;
163  dopt->outputNoTablespaces = ropt->noTablespace;
164  dopt->disable_triggers = ropt->disable_triggers;
165  dopt->use_setsessauth = ropt->use_setsessauth;
166 
168  dopt->dump_inserts = ropt->dump_inserts;
169  dopt->no_publications = ropt->no_publications;
171  dopt->no_subscriptions = ropt->no_subscriptions;
172  dopt->lockWaitTimeout = ropt->lockWaitTimeout;
175  dopt->sequence_data = ropt->sequence_data;
176 
177  return dopt;
178 }
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:171
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:162
char * outputSuperuser
Definition: pg_backup.h:169
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:168
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:165
int outputClean
Definition: pg_backup.h:164
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 3762 of file pg_backup_archiver.c.

References ahprintf(), buf, and PGDUMP_STRFTIME_FMT.

Referenced by RestoreArchive().

3763 {
3764  char buf[64];
3765 
3766  if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&tim)) != 0)
3767  ahprintf(AH, "-- %s %s\n\n", msg, buf);
3768 }
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 1220 of file pg_backup_archiver.c.

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

Referenced by dumpBlobs().

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

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

1325 {
1326  if (AH->lo_buf_used > 0)
1327  {
1328  /* Write remaining bytes from the LO buffer */
1329  dump_lo_buf(AH);
1330  }
1331 
1332  AH->writingBlob = 0;
1333 
1334  if (AH->connection)
1335  {
1336  lo_close(AH->connection, AH->loFd);
1337  AH->loFd = -1;
1338  }
1339  else
1340  {
1341  ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
1342  }
1343 }
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 1257 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().

1258 {
1259  RestoreOptions *ropt = AH->public.ropt;
1260 
1261  if (!ropt->single_txn)
1262  {
1263  if (AH->connection)
1264  CommitTransaction(&AH->public);
1265  else
1266  ahprintf(AH, "COMMIT;\n\n");
1267  }
1268 
1269  ahlog(AH, 1, ngettext("restored %d large object\n",
1270  "restored %d large objects\n",
1271  AH->blobCount),
1272  AH->blobCount);
1273 }
RestoreOptions * ropt
Definition: pg_backup.h:181
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 4238 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().

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

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

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

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

1869 {
1870  /* build index arrays if we didn't already */
1871  if (AH->tocsByDumpId == NULL)
1872  buildTocEntryArrays(AH);
1873 
1874  if (id > 0 && id <= AH->maxDumpId)
1875  return AH->tocsByDumpId[id];
1876 
1877  return NULL;
1878 }
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 4022 of file pg_backup_archiver.c.

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

Referenced by get_next_work_item().

4023 {
4024  int j,
4025  k;
4026 
4027  for (j = 0; j < te1->nLockDeps; j++)
4028  {
4029  for (k = 0; k < te2->nDeps; k++)
4030  {
4031  if (te1->lockDeps[j] == te2->dependencies[k])
4032  return true;
4033  }
4034  }
4035  return false;
4036 }
DumpId * lockDeps
DumpId * dependencies
static void identify_locking_dependencies ( ArchiveHandle AH,
TocEntry te 
)
static

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

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

4490 {
4491  ahlog(AH, 1, "table \"%s\" could not be created, will not restore its data\n",
4492  te->tag);
4493 
4494  if (AH->tableDataId[te->dumpId] != 0)
4495  {
4496  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4497 
4498  ted->reqs = 0;
4499  }
4500 }
struct _tocEntry ** tocsByDumpId
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
void InitDumpOptions ( DumpOptions opts)

Definition at line 135 of file pg_backup_archiver.c.

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

Referenced by main(), and NewDumpOptions().

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

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

4475 {
4476  if (AH->tableDataId[te->dumpId] != 0)
4477  {
4478  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4479 
4480  ted->created = true;
4481  }
4482 }
struct _tocEntry ** tocsByDumpId
static void mark_dump_job_done ( ArchiveHandle AH,
TocEntry te,
int  status,
void *  callback_data 
)
static

Definition at line 2433 of file pg_backup_archiver.c.

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

Referenced by WriteDataChunks().

2437 {
2438  ahlog(AH, 1, "finished item %d %s %s\n",
2439  te->dumpId, te->desc, te->tag);
2440 
2441  if (status != 0)
2442  exit_horribly(modulename, "worker process failed: exit code %d\n",
2443  status);
2444 }
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 4197 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().

4201 {
4202  TocEntry *ready_list = (TocEntry *) callback_data;
4203 
4204  ahlog(AH, 1, "finished item %d %s %s\n",
4205  te->dumpId, te->desc, te->tag);
4206 
4207  if (status == WORKER_CREATE_DONE)
4208  mark_create_done(AH, te);
4209  else if (status == WORKER_INHIBIT_DATA)
4210  {
4212  AH->public.n_errors++;
4213  }
4214  else if (status == WORKER_IGNORED_ERRORS)
4215  AH->public.n_errors++;
4216  else if (status != 0)
4217  exit_horribly(modulename, "worker process failed: exit code %d\n",
4218  status);
4219 
4220  reduce_dependencies(AH, te, ready_list);
4221 }
#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
DumpOptions* NewDumpOptions ( void  )

Definition at line 123 of file pg_backup_archiver.c.

References InitDumpOptions(), and pg_malloc().

Referenced by dumpOptionsFromRestoreOptions().

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

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

933 {
934  RestoreOptions *opts;
935 
936  opts = (RestoreOptions *) pg_malloc0(sizeof(RestoreOptions));
937 
938  /* set any fields that shouldn't default to zeroes */
939  opts->format = archUnknown;
940  opts->promptPassword = TRI_DEFAULT;
942 
943  return opts;
944 }
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 220 of file pg_backup_archiver.c.

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

Referenced by main().

221 {
222  ArchiveHandle *AH = _allocAH(FileSpec, fmt, 0, true, archModeRead, setupRestoreWorker);
223 
224  return (Archive *) AH;
225 }
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 4054 of file pg_backup_archiver.c.

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

Referenced by reduce_dependencies(), and restore_toc_entries_parallel().

4055 {
4056  te->par_prev = l->par_prev;
4057  l->par_prev->par_next = te;
4058  l->par_prev = te;
4059  te->par_next = l;
4060 }
struct _tocEntry * par_prev
struct _tocEntry * par_next
static void par_list_header_init ( TocEntry l)
static

Definition at line 4047 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entries_parallel(), and RestoreArchive().

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

Definition at line 4064 of file pg_backup_archiver.c.

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

Referenced by reduce_dependencies(), and restore_toc_entries_parallel().

4065 {
4066  te->par_prev->par_next = te->par_next;
4067  te->par_next->par_prev = te->par_prev;
4068  te->par_prev = NULL;
4069  te->par_next = NULL;
4070 }
struct _tocEntry * par_prev
struct _tocEntry * par_next
#define NULL
Definition: c.h:229
int parallel_restore ( ArchiveHandle AH,
TocEntry te 
)

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

4175 {
4176  int status;
4177 
4178  Assert(AH->connection != NULL);
4179 
4180  /* Count only errors associated with this TOC entry */
4181  AH->public.n_errors = 0;
4182 
4183  /* Restore the TOC item */
4184  status = restore_toc_entry(AH, te, true);
4185 
4186  return status;
4187 }
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 1091 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().

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

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

2697 {
2698  /* te->defn should have the form SET client_encoding = 'foo'; */
2699  char *defn = pg_strdup(te->defn);
2700  char *ptr1;
2701  char *ptr2 = NULL;
2702  int encoding;
2703 
2704  ptr1 = strchr(defn, '\'');
2705  if (ptr1)
2706  ptr2 = strchr(++ptr1, '\'');
2707  if (ptr2)
2708  {
2709  *ptr2 = '\0';
2710  encoding = pg_char_to_encoding(ptr1);
2711  if (encoding < 0)
2712  exit_horribly(modulename, "unrecognized encoding \"%s\"\n",
2713  ptr1);
2714  AH->public.encoding = encoding;
2715  }
2716  else
2717  exit_horribly(modulename, "invalid ENCODING item: %s\n",
2718  te->defn);
2719 
2720  free(defn);
2721 }
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 2724 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

2725 {
2726  /* te->defn should have the form SET standard_conforming_strings = 'x'; */
2727  char *ptr1;
2728 
2729  ptr1 = strchr(te->defn, '\'');
2730  if (ptr1 && strncmp(ptr1, "'on'", 4) == 0)
2731  AH->public.std_strings = true;
2732  else if (ptr1 && strncmp(ptr1, "'off'", 5) == 0)
2733  AH->public.std_strings = false;
2734  else
2735  exit_horribly(modulename, "invalid STDSTRINGS item: %s\n",
2736  te->defn);
2737 }
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 3625 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().

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

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

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

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

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

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

2051 {
2052  char *buf;
2053  int l;
2054 
2055  l = ReadInt(AH);
2056  if (l < 0)
2057  buf = NULL;
2058  else
2059  {
2060  buf = (char *) pg_malloc(l + 1);
2061  (*AH->ReadBufPtr) (AH, (void *) buf, l);
2062 
2063  buf[l] = '\0';
2064  }
2065 
2066  return buf;
2067 }
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 2539 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().

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

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

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

4449 {
4450  int i;
4451 
4452  ahlog(AH, 2, "reducing dependencies for %d\n", te->dumpId);
4453 
4454  for (i = 0; i < te->nRevDeps; i++)
4455  {
4456  TocEntry *otherte = AH->tocsByDumpId[te->revDeps[i]];
4457 
4458  otherte->depCount--;
4459  if (otherte->depCount == 0 && otherte->par_prev != NULL)
4460  {
4461  /* It must be in the pending list, so remove it ... */
4462  par_list_remove(otherte);
4463  /* ... and add to ready_list */
4464  par_list_append(ready_list, otherte);
4465  }
4466  }
4467 }
struct _tocEntry * par_prev
#define NULL
Definition: c.h:229
DumpId * revDeps
static void par_list_append(TocEntry *l, TocEntry *te)
struct _tocEntry ** tocsByDumpId
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
int i
static void par_list_remove(TocEntry *te)
static char * replace_line_endings ( const char *  str)
static

Definition at line 3582 of file pg_backup_archiver.c.

References pg_strdup(), and result.

Referenced by _printTocEntry(), and PrintTOCSummary().

3583 {
3584  char *result;
3585  char *s;
3586 
3587  result = pg_strdup(str);
3588 
3589  for (s = result; *s != '\0'; s++)
3590  {
3591  if (*s == '\n' || *s == '\r')
3592  *s = ' ';
3593  }
3594 
3595  return result;
3596 }
return result
Definition: formatting.c:1632
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void repoint_table_dependencies ( ArchiveHandle AH)
static

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

4363 {
4364  TocEntry *te;
4365  int i;
4366  DumpId olddep;
4367 
4368  for (te = AH->toc->next; te != AH->toc; te = te->next)
4369  {
4370  if (te->section != SECTION_POST_DATA)
4371  continue;
4372  for (i = 0; i < te->nDeps; i++)
4373  {
4374  olddep = te->dependencies[i];
4375  if (olddep <= AH->maxDumpId &&
4376  AH->tableDataId[olddep] != 0)
4377  {
4378  te->dependencies[i] = AH->tableDataId[olddep];
4379  ahlog(AH, 2, "transferring dependency %d -> %d to %d\n",
4380  te->dumpId, olddep, AH->tableDataId[olddep]);
4381  }
4382  }
4383  }
4384 }
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

Definition at line 3874 of file pg_backup_archiver.c.

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

Referenced by RestoreArchive().

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