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

Variables

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

Macro Definition Documentation

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

Definition at line 44 of file pg_backup_archiver.c.

Referenced by _discoverArchiveFormat().

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

Definition at line 45 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,
ArchiveMode  mode,
SetupWorkerPtr  setupWorkerPtr 
)
static

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

2247 {
2248  ArchiveHandle *AH;
2249 
2250 #if 0
2251  write_msg(modulename, "allocating AH for %s, format %d\n", FileSpec, fmt);
2252 #endif
2253 
2254  AH = (ArchiveHandle *) pg_malloc0(sizeof(ArchiveHandle));
2255 
2256  /* AH->debugLevel = 100; */
2257 
2258  AH->version = K_VERS_SELF;
2259 
2260  /* initialize for backwards compatible string processing */
2261  AH->public.encoding = 0; /* PG_SQL_ASCII */
2262  AH->public.std_strings = false;
2263 
2264  /* sql error handling */
2265  AH->public.exit_on_error = true;
2266  AH->public.n_errors = 0;
2267 
2268  AH->archiveDumpVersion = PG_VERSION;
2269 
2270  AH->createDate = time(NULL);
2271 
2272  AH->intSize = sizeof(int);
2273  AH->offSize = sizeof(pgoff_t);
2274  if (FileSpec)
2275  {
2276  AH->fSpec = pg_strdup(FileSpec);
2277 
2278  /*
2279  * Not used; maybe later....
2280  *
2281  * AH->workDir = pg_strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;
2282  * i--) if (AH->workDir[i-1] == '/')
2283  */
2284  }
2285  else
2286  AH->fSpec = NULL;
2287 
2288  AH->currUser = NULL; /* unknown */
2289  AH->currSchema = NULL; /* ditto */
2290  AH->currTablespace = NULL; /* ditto */
2291  AH->currWithOids = -1; /* force SET */
2292 
2293  AH->toc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2294 
2295  AH->toc->next = AH->toc;
2296  AH->toc->prev = AH->toc;
2297 
2298  AH->mode = mode;
2299  AH->compression = compression;
2300 
2301  memset(&(AH->sqlparse), 0, sizeof(AH->sqlparse));
2302 
2303  /* Open stdout with no compression for AH output handle */
2304  AH->gzOut = 0;
2305  AH->OF = stdout;
2306 
2307  /*
2308  * On Windows, we need to use binary mode to read/write non-text archive
2309  * formats. Force stdin/stdout into binary mode if that is what we are
2310  * using.
2311  */
2312 #ifdef WIN32
2313  if (fmt != archNull &&
2314  (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0))
2315  {
2316  if (mode == archModeWrite)
2317  setmode(fileno(stdout), O_BINARY);
2318  else
2319  setmode(fileno(stdin), O_BINARY);
2320  }
2321 #endif
2322 
2323  AH->SetupWorkerPtr = setupWorkerPtr;
2324 
2325  if (fmt == archUnknown)
2326  AH->format = _discoverArchiveFormat(AH);
2327  else
2328  AH->format = fmt;
2329 
2331 
2332  switch (AH->format)
2333  {
2334  case archCustom:
2336  break;
2337 
2338  case archNull:
2339  InitArchiveFmt_Null(AH);
2340  break;
2341 
2342  case archDirectory:
2344  break;
2345 
2346  case archTar:
2347  InitArchiveFmt_Tar(AH);
2348  break;
2349 
2350  default:
2351  exit_horribly(modulename, "unrecognized file format \"%d\"\n", fmt);
2352  }
2353 
2354  return AH;
2355 }
struct _tocEntry * next
#define K_VERS_SELF
void InitArchiveFmt_Tar(ArchiveHandle *AH)
SetupWorkerPtr SetupWorkerPtr
int n_errors
Definition: pg_backup.h:200
int encoding
Definition: pg_backup.h:194
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
struct _tocEntry * toc
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
sqlparseInfo sqlparse
struct _tocEntry * prev
#define pgoff_t
Definition: win32.h:241
ArchiveFormat format
static int _discoverArchiveFormat(ArchiveHandle *AH)
void InitArchiveFmt_Directory(ArchiveHandle *AH)
void InitArchiveFmt_Null(ArchiveHandle *AH)
void InitArchiveFmt_Custom(ArchiveHandle *AH)
void write_msg(const char *modulename, const char *fmt,...)
#define NULL
Definition: c.h:226
void exit_horribly(const char *modulename, const char *fmt,...)
bool exit_on_error
Definition: pg_backup.h:199
static const char * modulename
bool std_strings
Definition: pg_backup.h:195
static void _becomeOwner ( ArchiveHandle AH,
TocEntry te 
)
static

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

3111 {
3112  RestoreOptions *ropt = AH->public.ropt;
3113 
3114  if (ropt && (ropt->noOwner || !ropt->use_setsessauth))
3115  return;
3116 
3117  _becomeUser(AH, te->owner);
3118 }
RestoreOptions * ropt
Definition: pg_backup.h:179
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 3086 of file pg_backup_archiver.c.

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

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

3087 {
3088  if (!user)
3089  user = ""; /* avoid null pointers */
3090 
3091  if (AH->currUser && strcmp(AH->currUser, user) == 0)
3092  return; /* no need to do anything */
3093 
3094  _doSetSessionAuth(AH, user);
3095 
3096  /*
3097  * NOTE: currUser keeps track of what the imaginary session user in our
3098  * script is
3099  */
3100  if (AH->currUser)
3101  free(AH->currUser);
3102  AH->currUser = pg_strdup(user);
3103 }
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:60
static char * user
Definition: pg_regress.c:90
static void _disableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

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

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

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

2918 {
2919  RestoreOptions *ropt = AH->public.ropt;
2920 
2921  /*
2922  * Disable timeouts to allow for slow commands, idle parallel workers, etc
2923  */
2924  ahprintf(AH, "SET statement_timeout = 0;\n");
2925  ahprintf(AH, "SET lock_timeout = 0;\n");
2926  ahprintf(AH, "SET idle_in_transaction_session_timeout = 0;\n");
2927 
2928  /* Select the correct character set encoding */
2929  ahprintf(AH, "SET client_encoding = '%s';\n",
2931 
2932  /* Select the correct string literal syntax */
2933  ahprintf(AH, "SET standard_conforming_strings = %s;\n",
2934  AH->public.std_strings ? "on" : "off");
2935 
2936  /* Select the role to be used during restore */
2937  if (ropt && ropt->use_role)
2938  ahprintf(AH, "SET ROLE %s;\n", fmtId(ropt->use_role));
2939 
2940  /* Make sure function checking is disabled */
2941  ahprintf(AH, "SET check_function_bodies = false;\n");
2942 
2943  /* Avoid annoying notices etc */
2944  ahprintf(AH, "SET client_min_messages = warning;\n");
2945  if (!AH->public.std_strings)
2946  ahprintf(AH, "SET escape_string_warning = off;\n");
2947 
2948  /* Adjust row-security state */
2949  if (ropt && ropt->enable_row_security)
2950  ahprintf(AH, "SET row_security = on;\n");
2951  else
2952  ahprintf(AH, "SET row_security = off;\n");
2953 
2954  ahprintf(AH, "\n");
2955 }
RestoreOptions * ropt
Definition: pg_backup.h:179
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:194
int enable_row_security
Definition: pg_backup.h:120
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:531
bool std_strings
Definition: pg_backup.h:195
static void _doSetSessionAuth ( ArchiveHandle AH,
const char *  user 
)
static

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

2964 {
2966 
2967  appendPQExpBufferStr(cmd, "SET SESSION AUTHORIZATION ");
2968 
2969  /*
2970  * SQL requires a string literal here. Might as well be correct.
2971  */
2972  if (user && *user)
2973  appendStringLiteralAHX(cmd, user, AH);
2974  else
2975  appendPQExpBufferStr(cmd, "DEFAULT");
2976  appendPQExpBufferChar(cmd, ';');
2977 
2978  if (RestoringToDB(AH))
2979  {
2980  PGresult *res;
2981 
2982  res = PQexec(AH->connection, cmd->data);
2983 
2984  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
2985  /* NOT warn_or_exit_horribly... use -O instead to skip this. */
2986  exit_horribly(modulename, "could not set session user to \"%s\": %s",
2988 
2989  PQclear(res);
2990  }
2991  else
2992  ahprintf(AH, "%s\n\n", cmd->data);
2993 
2994  destroyPQExpBuffer(cmd);
2995 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5960
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:90
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 3003 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().

3004 {
3006 
3007  appendPQExpBuffer(cmd, "SET default_with_oids = %s;", withOids ?
3008  "true" : "false");
3009 
3010  if (RestoringToDB(AH))
3011  {
3012  PGresult *res;
3013 
3014  res = PQexec(AH->connection, cmd->data);
3015 
3016  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3018  "could not set default_with_oids: %s",
3019  PQerrorMessage(AH->connection));
3020 
3021  PQclear(res);
3022  }
3023  else
3024  ahprintf(AH, "%s\n\n", cmd->data);
3025 
3026  destroyPQExpBuffer(cmd);
3027 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5960
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 973 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entry().

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

3247 {
3248  const char *type = te->desc;
3249 
3250  /* Use ALTER TABLE for views and sequences */
3251  if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0 ||
3252  strcmp(type, "MATERIALIZED VIEW") == 0)
3253  type = "TABLE";
3254 
3255  /* objects that don't require special decoration */
3256  if (strcmp(type, "COLLATION") == 0 ||
3257  strcmp(type, "CONVERSION") == 0 ||
3258  strcmp(type, "DOMAIN") == 0 ||
3259  strcmp(type, "TABLE") == 0 ||
3260  strcmp(type, "TYPE") == 0 ||
3261  strcmp(type, "FOREIGN TABLE") == 0 ||
3262  strcmp(type, "TEXT SEARCH DICTIONARY") == 0 ||
3263  strcmp(type, "TEXT SEARCH CONFIGURATION") == 0 ||
3264  /* non-schema-specified objects */
3265  strcmp(type, "DATABASE") == 0 ||
3266  strcmp(type, "PROCEDURAL LANGUAGE") == 0 ||
3267  strcmp(type, "SCHEMA") == 0 ||
3268  strcmp(type, "FOREIGN DATA WRAPPER") == 0 ||
3269  strcmp(type, "SERVER") == 0 ||
3270  strcmp(type, "PUBLICATION") == 0 ||
3271  strcmp(type, "SUBSCRIPTION") == 0 ||
3272  strcmp(type, "USER MAPPING") == 0)
3273  {
3274  /* We already know that search_path was set properly */
3275  appendPQExpBuffer(buf, "%s %s", type, fmtId(te->tag));
3276  return;
3277  }
3278 
3279  /* BLOBs just have a name, but it's numeric so must not use fmtId */
3280  if (strcmp(type, "BLOB") == 0)
3281  {
3282  appendPQExpBuffer(buf, "LARGE OBJECT %s", te->tag);
3283  return;
3284  }
3285 
3286  /*
3287  * These object types require additional decoration. Fortunately, the
3288  * information needed is exactly what's in the DROP command.
3289  */
3290  if (strcmp(type, "AGGREGATE") == 0 ||
3291  strcmp(type, "FUNCTION") == 0 ||
3292  strcmp(type, "OPERATOR") == 0 ||
3293  strcmp(type, "OPERATOR CLASS") == 0 ||
3294  strcmp(type, "OPERATOR FAMILY") == 0)
3295  {
3296  /* Chop "DROP " off the front and make a modifiable copy */
3297  char *first = pg_strdup(te->dropStmt + 5);
3298  char *last;
3299 
3300  /* point to last character in string */
3301  last = first + strlen(first) - 1;
3302 
3303  /* Strip off any ';' or '\n' at the end */
3304  while (last >= first && (*last == '\n' || *last == ';'))
3305  last--;
3306  *(last + 1) = '\0';
3307 
3308  appendPQExpBufferStr(buf, first);
3309 
3310  free(first);
3311  return;
3312  }
3313 
3314  write_msg(modulename, "WARNING: don't know how to set owner for object type %s\n",
3315  type);
3316 }
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:60
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 1772 of file pg_backup_archiver.c.

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

Referenced by SortTocFromFile().

1773 {
1774  /* Unlink te from list */
1775  te->prev->next = te->next;
1776  te->next->prev = te->prev;
1777 
1778  /* and insert it before "pos" */
1779  te->prev = pos->prev;
1780  te->next = pos;
1781  pos->prev->next = te;
1782  pos->prev = te;
1783 }
struct _tocEntry * next
struct _tocEntry * prev
static void _printTocEntry ( ArchiveHandle AH,
TocEntry te,
bool  isData,
bool  acl_pass 
)
static

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

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

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

3041 {
3042  if (RestoringToDB(AH))
3044  else
3045  {
3046  if (dbname)
3047  {
3048  PQExpBufferData connectbuf;
3049 
3050  initPQExpBuffer(&connectbuf);
3051  appendPsqlMetaConnect(&connectbuf, dbname);
3052  ahprintf(AH, "%s\n", connectbuf.data);
3053  termPQExpBuffer(&connectbuf);
3054  }
3055  else
3056  ahprintf(AH, "%s\n", "\\connect -\n");
3057  }
3058 
3059  /*
3060  * NOTE: currUser keeps track of what the imaginary session user in our
3061  * script is. It's now effectively reset to the original userID.
3062  */
3063  if (AH->currUser)
3064  free(AH->currUser);
3065  AH->currUser = NULL;
3066 
3067  /* don't assume we still know the output schema, tablespace, etc either */
3068  if (AH->currSchema)
3069  free(AH->currSchema);
3070  AH->currSchema = NULL;
3071  if (AH->currTablespace)
3072  free(AH->currTablespace);
3073  AH->currTablespace = NULL;
3074  AH->currWithOids = -1;
3075 
3076  /* re-establish fixed state */
3078 }
static int RestoringToDB(ArchiveHandle *AH)
int ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser)
Definition: pg_backup_db.c:88
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
Definition: string_utils.c:581
static void _doSetFixedOutputState(ArchiveHandle *AH)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
char * dbname
Definition: streamutil.c:41
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
static void _selectOutputSchema ( ArchiveHandle AH,
const char *  schemaName 
)
static

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

3141 {
3142  PQExpBuffer qry;
3143 
3144  if (!schemaName || *schemaName == '\0' ||
3145  (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
3146  return; /* no need to do anything */
3147 
3148  qry = createPQExpBuffer();
3149 
3150  appendPQExpBuffer(qry, "SET search_path = %s",
3151  fmtId(schemaName));
3152  if (strcmp(schemaName, "pg_catalog") != 0)
3153  appendPQExpBufferStr(qry, ", pg_catalog");
3154 
3155  if (RestoringToDB(AH))
3156  {
3157  PGresult *res;
3158 
3159  res = PQexec(AH->connection, qry->data);
3160 
3161  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3163  "could not set search_path to \"%s\": %s",
3164  schemaName, PQerrorMessage(AH->connection));
3165 
3166  PQclear(res);
3167  }
3168  else
3169  ahprintf(AH, "%s;\n\n", qry->data);
3170 
3171  if (AH->currSchema)
3172  free(AH->currSchema);
3173  AH->currSchema = pg_strdup(schemaName);
3174 
3175  destroyPQExpBuffer(qry);
3176 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5960
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:60
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 3183 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().

3184 {
3185  RestoreOptions *ropt = AH->public.ropt;
3186  PQExpBuffer qry;
3187  const char *want,
3188  *have;
3189 
3190  /* do nothing in --no-tablespaces mode */
3191  if (ropt->noTablespace)
3192  return;
3193 
3194  have = AH->currTablespace;
3195  want = tablespace;
3196 
3197  /* no need to do anything for non-tablespace object */
3198  if (!want)
3199  return;
3200 
3201  if (have && strcmp(want, have) == 0)
3202  return; /* no need to do anything */
3203 
3204  qry = createPQExpBuffer();
3205 
3206  if (strcmp(want, "") == 0)
3207  {
3208  /* We want the tablespace to be the database's default */
3209  appendPQExpBufferStr(qry, "SET default_tablespace = ''");
3210  }
3211  else
3212  {
3213  /* We want an explicit tablespace */
3214  appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
3215  }
3216 
3217  if (RestoringToDB(AH))
3218  {
3219  PGresult *res;
3220 
3221  res = PQexec(AH->connection, qry->data);
3222 
3223  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3225  "could not set default_tablespace to %s: %s",
3226  fmtId(want), PQerrorMessage(AH->connection));
3227 
3228  PQclear(res);
3229  }
3230  else
3231  ahprintf(AH, "%s;\n\n", qry->data);
3232 
3233  if (AH->currTablespace)
3234  free(AH->currTablespace);
3235  AH->currTablespace = pg_strdup(want);
3236 
3237  destroyPQExpBuffer(qry);
3238 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5960
RestoreOptions * ropt
Definition: pg_backup.h:179
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:60
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 3125 of file pg_backup_archiver.c.

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

Referenced by _printTocEntry().

3126 {
3127  if (AH->currWithOids != te->withOids)
3128  {
3129  _doSetWithOids(AH, te->withOids);
3130  AH->currWithOids = te->withOids;
3131  }
3132 }
static void _doSetWithOids(ArchiveHandle *AH, const bool withOids)
static bool _tocEntryIsACL ( TocEntry te)
static

Definition at line 2902 of file pg_backup_archiver.c.

References _tocEntry::desc.

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

2903 {
2904  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
2905  if (strcmp(te->desc, "ACL") == 0 ||
2906  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
2907  strcmp(te->desc, "DEFAULT ACL") == 0)
2908  return true;
2909  return false;
2910 }
static teReqs _tocEntryRequired ( TocEntry te,
teSection  curSection,
RestoreOptions ropt 
)
static

Definition at line 2751 of file pg_backup_archiver.c.

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

Referenced by PrintTOCSummary(), and ProcessArchiveRestoreOptions().

2752 {
2753  teReqs res = REQ_SCHEMA | REQ_DATA;
2754 
2755  /* ENCODING and STDSTRINGS items are treated specially */
2756  if (strcmp(te->desc, "ENCODING") == 0 ||
2757  strcmp(te->desc, "STDSTRINGS") == 0)
2758  return REQ_SPECIAL;
2759 
2760  /* If it's an ACL, maybe ignore it */
2761  if (ropt->aclsSkip && _tocEntryIsACL(te))
2762  return 0;
2763 
2764  /* If it's security labels, maybe ignore it */
2765  if (ropt->no_security_labels && strcmp(te->desc, "SECURITY LABEL") == 0)
2766  return 0;
2767 
2768  /* Ignore it if section is not to be dumped/restored */
2769  switch (curSection)
2770  {
2771  case SECTION_PRE_DATA:
2772  if (!(ropt->dumpSections & DUMP_PRE_DATA))
2773  return 0;
2774  break;
2775  case SECTION_DATA:
2776  if (!(ropt->dumpSections & DUMP_DATA))
2777  return 0;
2778  break;
2779  case SECTION_POST_DATA:
2780  if (!(ropt->dumpSections & DUMP_POST_DATA))
2781  return 0;
2782  break;
2783  default:
2784  /* shouldn't get here, really, but ignore it */
2785  return 0;
2786  }
2787 
2788  /* Check options for selective dump/restore */
2789  if (ropt->schemaNames.head != NULL)
2790  {
2791  /* If no namespace is specified, it means all. */
2792  if (!te->namespace)
2793  return 0;
2794  if (!(simple_string_list_member(&ropt->schemaNames, te->namespace)))
2795  return 0;
2796  }
2797 
2798  if (ropt->schemaExcludeNames.head != NULL &&
2799  te->namespace &&
2800  simple_string_list_member(&ropt->schemaExcludeNames, te->namespace))
2801  return 0;
2802 
2803  if (ropt->selTypes)
2804  {
2805  if (strcmp(te->desc, "TABLE") == 0 ||
2806  strcmp(te->desc, "TABLE DATA") == 0 ||
2807  strcmp(te->desc, "VIEW") == 0 ||
2808  strcmp(te->desc, "FOREIGN TABLE") == 0 ||
2809  strcmp(te->desc, "MATERIALIZED VIEW") == 0 ||
2810  strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0 ||
2811  strcmp(te->desc, "SEQUENCE") == 0 ||
2812  strcmp(te->desc, "SEQUENCE SET") == 0)
2813  {
2814  if (!ropt->selTable)
2815  return 0;
2816  if (ropt->tableNames.head != NULL && (!(simple_string_list_member(&ropt->tableNames, te->tag))))
2817  return 0;
2818  }
2819  else if (strcmp(te->desc, "INDEX") == 0)
2820  {
2821  if (!ropt->selIndex)
2822  return 0;
2823  if (ropt->indexNames.head != NULL && (!(simple_string_list_member(&ropt->indexNames, te->tag))))
2824  return 0;
2825  }
2826  else if (strcmp(te->desc, "FUNCTION") == 0)
2827  {
2828  if (!ropt->selFunction)
2829  return 0;
2830  if (ropt->functionNames.head != NULL && (!(simple_string_list_member(&ropt->functionNames, te->tag))))
2831  return 0;
2832  }
2833  else if (strcmp(te->desc, "TRIGGER") == 0)
2834  {
2835  if (!ropt->selTrigger)
2836  return 0;
2837  if (ropt->triggerNames.head != NULL && (!(simple_string_list_member(&ropt->triggerNames, te->tag))))
2838  return 0;
2839  }
2840  else
2841  return 0;
2842  }
2843 
2844  /*
2845  * Check if we had a dataDumper. Indicates if the entry is schema or data
2846  */
2847  if (!te->hadDumper)
2848  {
2849  /*
2850  * Special Case: If 'SEQUENCE SET' or anything to do with BLOBs, then
2851  * it is considered a data entry. We don't need to check for the
2852  * BLOBS entry or old-style BLOB COMMENTS, because they will have
2853  * hadDumper = true ... but we do need to check new-style BLOB
2854  * comments.
2855  */
2856  if (strcmp(te->desc, "SEQUENCE SET") == 0 ||
2857  strcmp(te->desc, "BLOB") == 0 ||
2858  (strcmp(te->desc, "ACL") == 0 &&
2859  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
2860  (strcmp(te->desc, "COMMENT") == 0 &&
2861  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
2862  (strcmp(te->desc, "SECURITY LABEL") == 0 &&
2863  strncmp(te->tag, "LARGE OBJECT ", 13) == 0))
2864  res = res & REQ_DATA;
2865  else
2866  res = res & ~REQ_DATA;
2867  }
2868 
2869  /*
2870  * Special case: <Init> type with <Max OID> tag; this is obsolete and we
2871  * always ignore it.
2872  */
2873  if ((strcmp(te->desc, "<Init>") == 0) && (strcmp(te->tag, "Max OID") == 0))
2874  return 0;
2875 
2876  /* Mask it if we only want schema */
2877  if (ropt->schemaOnly)
2878  {
2879  if (!(ropt->sequence_data && strcmp(te->desc, "SEQUENCE SET") == 0))
2880  res = res & REQ_SCHEMA;
2881  }
2882 
2883  /* Mask it if we only want data */
2884  if (ropt->dataOnly)
2885  res = res & REQ_DATA;
2886 
2887  /* Mask it if we don't have a schema contribution */
2888  if (!te->defn || strlen(te->defn) == 0)
2889  res = res & ~REQ_SCHEMA;
2890 
2891  /* Finally, if there's a per-ID filter, limit based on that as well */
2892  if (ropt->idWanted && !ropt->idWanted[te->dumpId - 1])
2893  return 0;
2894 
2895  return res;
2896 }
bool simple_string_list_member(SimpleStringList *list, const char *val)
Definition: simple_list.c:87
SimpleStringList triggerNames
Definition: pg_backup.h:103
SimpleStringList schemaNames
Definition: pg_backup.h:101
static bool _tocEntryIsACL(TocEntry *te)
bool * idWanted
Definition: pg_backup.h:119
SimpleStringList tableNames
Definition: pg_backup.h:104
SimpleStringList functionNames
Definition: pg_backup.h:100
int no_security_labels
Definition: pg_backup.h:77
#define NULL
Definition: c.h:226
SimpleStringListCell * head
Definition: simple_list.h:42
SimpleStringList indexNames
Definition: pg_backup.h:99
SimpleStringList schemaExcludeNames
Definition: pg_backup.h:102
void ahlog ( ArchiveHandle AH,
int  level,
const char *  fmt,
  ... 
)
int ahprintf ( ArchiveHandle AH,
const char *  fmt,
  ... 
)

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

1557 {
1558  char *p;
1559  size_t len = 128; /* initial assumption about buffer size */
1560  size_t cnt;
1561 
1562  for (;;)
1563  {
1564  va_list args;
1565 
1566  /* Allocate work buffer. */
1567  p = (char *) pg_malloc(len);
1568 
1569  /* Try to format the data. */
1570  va_start(args, fmt);
1571  cnt = pvsnprintf(p, len, fmt, args);
1572  va_end(args);
1573 
1574  if (cnt < len)
1575  break; /* success */
1576 
1577  /* Release buffer and loop around to try again with larger len. */
1578  free(p);
1579  len = cnt;
1580  }
1581 
1582  ahwrite(p, 1, cnt, AH);
1583  free(p);
1584  return (int) cnt;
1585 }
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:60
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 1658 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().

1659 {
1660  int bytes_written = 0;
1661 
1662  if (AH->writingBlob)
1663  {
1664  size_t remaining = size * nmemb;
1665 
1666  while (AH->lo_buf_used + remaining > AH->lo_buf_size)
1667  {
1668  size_t avail = AH->lo_buf_size - AH->lo_buf_used;
1669 
1670  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, avail);
1671  ptr = (const void *) ((const char *) ptr + avail);
1672  remaining -= avail;
1673  AH->lo_buf_used += avail;
1674  dump_lo_buf(AH);
1675  }
1676 
1677  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
1678  AH->lo_buf_used += remaining;
1679 
1680  bytes_written = size * nmemb;
1681  }
1682  else if (AH->gzOut)
1683  bytes_written = GZWRITE(ptr, size, nmemb, AH->OF);
1684  else if (AH->CustomOutPtr)
1685  bytes_written = AH->CustomOutPtr (AH, ptr, size * nmemb);
1686 
1687  else
1688  {
1689  /*
1690  * If we're doing a restore, and it's direct to DB, and we're
1691  * connected then send it to the DB.
1692  */
1693  if (RestoringToDB(AH))
1694  bytes_written = ExecuteSqlCommandBuf(&AH->public, (const char *) ptr, size * nmemb);
1695  else
1696  bytes_written = fwrite(ptr, size, nmemb, AH->OF) * size;
1697  }
1698 
1699  if (bytes_written != size * nmemb)
1701 
1702  return;
1703 }
int remaining
Definition: informix.c:692
static int RestoringToDB(ArchiveHandle *AH)
int ExecuteSqlCommandBuf(Archive *AHX, const char *buf, size_t bufLen)
Definition: pg_backup_db.c:574
static void dump_lo_buf(ArchiveHandle *AH)
#define GZWRITE(p, s, n, fh)
CustomOutPtr CustomOutPtr
#define WRITE_ERROR_EXIT
void ArchiveEntry ( Archive AHX,
CatalogId  catalogId,
DumpId  dumpId,
const char *  tag,
const char *  namespace,
const char *  tablespace,
const char *  owner,
bool  withOids,
const char *  desc,
teSection  section,
const char *  defn,
const char *  dropStmt,
const char *  copyStmt,
const DumpId deps,
int  nDeps,
DataDumperPtr  dumpFn,
void *  dumpArg 
)

Definition at line 1025 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(), dumpStdStrings(), dumpSubscription(), dumpTableComment(), dumpTableData(), dumpTableSchema(), dumpTableSecLabel(), dumpTransform(), dumpTrigger(), dumpTSConfig(), dumpTSDictionary(), dumpTSParser(), dumpTSTemplate(), dumpUndefinedType(), dumpUserMappings(), and refreshMatViewData().

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

Definition at line 1423 of file pg_backup_archiver.c.

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

1424 {
1425  char *p;
1426  size_t len = 128; /* initial assumption about buffer size */
1427  size_t cnt;
1428 
1429  for (;;)
1430  {
1431  va_list args;
1432 
1433  /* Allocate work buffer. */
1434  p = (char *) pg_malloc(len);
1435 
1436  /* Try to format the data. */
1437  va_start(args, fmt);
1438  cnt = pvsnprintf(p, len, fmt, args);
1439  va_end(args);
1440 
1441  if (cnt < len)
1442  break; /* success */
1443 
1444  /* Release buffer and loop around to try again with larger len. */
1445  free(p);
1446  len = cnt;
1447  }
1448 
1449  WriteData(AH, p, cnt);
1450  free(p);
1451  return (int) cnt;
1452 }
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:60
void archputs ( const char *  s,
Archive AH 
)

Definition at line 1415 of file pg_backup_archiver.c.

References WriteData().

Referenced by dumpTableData_insert().

1416 {
1417  WriteData(AH, s, strlen(s));
1418  return;
1419 }
void WriteData(Archive *AHX, const void *data, size_t dLen)
static void buildTocEntryArrays ( ArchiveHandle AH)
static

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

1798 {
1799  DumpId maxDumpId = AH->maxDumpId;
1800  TocEntry *te;
1801 
1802  AH->tocsByDumpId = (TocEntry **) pg_malloc0((maxDumpId + 1) * sizeof(TocEntry *));
1803  AH->tableDataId = (DumpId *) pg_malloc0((maxDumpId + 1) * sizeof(DumpId));
1804 
1805  for (te = AH->toc->next; te != AH->toc; te = te->next)
1806  {
1807  /* this check is purely paranoia, maxDumpId should be correct */
1808  if (te->dumpId <= 0 || te->dumpId > maxDumpId)
1809  exit_horribly(modulename, "bad dumpId\n");
1810 
1811  /* tocsByDumpId indexes all TOCs by their dump ID */
1812  AH->tocsByDumpId[te->dumpId] = te;
1813 
1814  /*
1815  * tableDataId provides the TABLE DATA item's dump ID for each TABLE
1816  * TOC entry that has a DATA item. We compute this by reversing the
1817  * TABLE DATA item's dependency, knowing that a TABLE DATA item has
1818  * just one dependency and it is the TABLE item.
1819  */
1820  if (strcmp(te->desc, "TABLE DATA") == 0 && te->nDeps > 0)
1821  {
1822  DumpId tableId = te->dependencies[0];
1823 
1824  /*
1825  * The TABLE item might not have been in the archive, if this was
1826  * a data-only dump; but its dump ID should be less than its data
1827  * item's dump ID, so there should be a place for it in the array.
1828  */
1829  if (tableId <= 0 || tableId > maxDumpId)
1830  exit_horribly(modulename, "bad table dumpId for TABLE DATA item\n");
1831 
1832  AH->tableDataId[tableId] = te->dumpId;
1833  }
1834  }
1835 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:228
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 3678 of file pg_backup_archiver.c.

References fseeko, ftello, and pgoff_t.

Referenced by InitArchiveFmt_Custom(), and InitArchiveFmt_Tar().

3679 {
3680  pgoff_t tpos;
3681 
3682  /*
3683  * If pgoff_t is wider than long, we must have "real" fseeko and not an
3684  * emulation using fseek. Otherwise report no seek capability.
3685  */
3686 #ifndef HAVE_FSEEKO
3687  if (sizeof(pgoff_t) > sizeof(long))
3688  return false;
3689 #endif
3690 
3691  /* Check that ftello works on this file */
3692  tpos = ftello(fp);
3693  if (tpos < 0)
3694  return false;
3695 
3696  /*
3697  * Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
3698  * this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
3699  * successful no-op even on files that are otherwise unseekable.
3700  */
3701  if (fseeko(fp, tpos, SEEK_SET) != 0)
3702  return false;
3703 
3704  return true;
3705 }
#define fseeko(stream, offset, origin)
Definition: win32.h:247
#define pgoff_t
Definition: win32.h:241
#define ftello(stream)
Definition: win32.h:250
ArchiveHandle* CloneArchive ( ArchiveHandle AH)

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

4460 {
4461  ArchiveHandle *clone;
4462 
4463  /* Make a "flat" copy */
4464  clone = (ArchiveHandle *) pg_malloc(sizeof(ArchiveHandle));
4465  memcpy(clone, AH, sizeof(ArchiveHandle));
4466 
4467  /* Handle format-independent fields */
4468  memset(&(clone->sqlparse), 0, sizeof(clone->sqlparse));
4469 
4470  /* The clone will have its own connection, so disregard connection state */
4471  clone->connection = NULL;
4472  clone->connCancel = NULL;
4473  clone->currUser = NULL;
4474  clone->currSchema = NULL;
4475  clone->currTablespace = NULL;
4476  clone->currWithOids = -1;
4477 
4478  /* savedPassword must be local in case we change it while connecting */
4479  if (clone->savedPassword)
4480  clone->savedPassword = pg_strdup(clone->savedPassword);
4481 
4482  /* clone has its own error count, too */
4483  clone->public.n_errors = 0;
4484 
4485  /*
4486  * Connect our new clone object to the database: In parallel restore the
4487  * parent is already disconnected, because we can connect the worker
4488  * processes independently to the database (no snapshot sync required). In
4489  * parallel backup we clone the parent's existing connection.
4490  */
4491  if (AH->mode == archModeRead)
4492  {
4493  RestoreOptions *ropt = AH->public.ropt;
4494 
4495  Assert(AH->connection == NULL);
4496 
4497  /* this also sets clone->connection */
4498  ConnectDatabase((Archive *) clone, ropt->dbname,
4499  ropt->pghost, ropt->pgport, ropt->username,
4500  ropt->promptPassword);
4501 
4502  /* re-establish fixed state */
4503  _doSetFixedOutputState(clone);
4504  }
4505  else
4506  {
4508  char *pghost;
4509  char *pgport;
4510  char *username;
4511 
4512  Assert(AH->connection != NULL);
4513 
4514  /*
4515  * Even though we are technically accessing the parent's database
4516  * object here, these functions are fine to be called like that
4517  * because all just return a pointer and do not actually send/receive
4518  * any data to/from the database.
4519  */
4520  initPQExpBuffer(&connstr);
4521  appendPQExpBuffer(&connstr, "dbname=");
4522  appendConnStrVal(&connstr, PQdb(AH->connection));
4523  pghost = PQhost(AH->connection);
4524  pgport = PQport(AH->connection);
4525  username = PQuser(AH->connection);
4526 
4527  /* this also sets clone->connection */
4528  ConnectDatabase((Archive *) clone, connstr.data,
4529  pghost, pgport, username, TRI_NO);
4530 
4531  termPQExpBuffer(&connstr);
4532  /* setupDumpWorker will fix up connection state */
4533  }
4534 
4535  /* Let the format-specific code have a chance too */
4536  (clone->ClonePtr) (clone);
4537 
4538  Assert(clone->connection != NULL);
4539  return clone;
4540 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
RestoreOptions * ropt
Definition: pg_backup.h:179
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
char * username
Definition: pg_backup.h:110
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:536
char * PQport(const PGconn *conn)
Definition: fe-connect.c:5881
int n_errors
Definition: pg_backup.h:200
PGcancel *volatile connCancel
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:5836
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:130
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:5861
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:5828
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
char * pgport
Definition: pgbench.c:181
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
void ConnectDatabase(Archive *AH, const char *dbname, const char *pghost, const char *pgport, const char *username, trivalue prompt_password)
Definition: pg_backup_db.c:248
static char * connstr
Definition: pg_dumpall.c:67
trivalue promptPassword
Definition: pg_backup.h:112
void CloseArchive ( Archive AHX)

Definition at line 227 of file pg_backup_archiver.c.

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

Referenced by main().

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

Definition at line 206 of file pg_backup_archiver.c.

References _allocAH().

Referenced by main().

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

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

4549 {
4550  /* Should not have an open database connection */
4551  Assert(AH->connection == NULL);
4552 
4553  /* Clear format-specific state */
4554  (AH->DeClonePtr) (AH);
4555 
4556  /* Clear state allocated by CloneArchive */
4557  if (AH->sqlparse.curCmd)
4559 
4560  /* Clear any connection-local state */
4561  if (AH->currUser)
4562  free(AH->currUser);
4563  if (AH->currSchema)
4564  free(AH->currSchema);
4565  if (AH->currTablespace)
4566  free(AH->currTablespace);
4567  if (AH->savedPassword)
4568  free(AH->savedPassword);
4569 
4570  free(AH);
4571 }
PQExpBuffer curCmd
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
sqlparseInfo sqlparse
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
static void dump_lo_buf ( ArchiveHandle AH)
static

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

1616 {
1617  if (AH->connection)
1618  {
1619  size_t res;
1620 
1621  res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used);
1622  ahlog(AH, 5, ngettext("wrote %lu byte of large object data (result = %lu)\n",
1623  "wrote %lu bytes of large object data (result = %lu)\n",
1624  AH->lo_buf_used),
1625  (unsigned long) AH->lo_buf_used, (unsigned long) res);
1626  if (res != AH->lo_buf_used)
1628  "could not write to large object (result: %lu, expected: %lu)\n",
1629  (unsigned long) res, (unsigned long) AH->lo_buf_used);
1630  }
1631  else
1632  {
1634 
1636  (const unsigned char *) AH->lo_buf,
1637  AH->lo_buf_used,
1638  AH);
1639 
1640  /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
1641  AH->writingBlob = 0;
1642  ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
1643  AH->writingBlob = 1;
1644 
1645  destroyPQExpBuffer(buf);
1646  }
1647  AH->lo_buf_used = 0;
1648 }
#define appendByteaLiteralAHX(buf, str, len, AH)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:113
static char * buf
Definition: pg_test_fsync.c:65
int lo_write(int fd, const char *buf, int len)
Definition: be-fsstubs.c:189
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define ngettext(s, p, n)
Definition: c.h:127
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
void exit_horribly(const char *modulename, const char *fmt,...)
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
static const char * modulename
DumpOptions* dumpOptionsFromRestoreOptions ( RestoreOptions ropt)

Definition at line 149 of file pg_backup_archiver.c.

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

Referenced by SetArchiveOptions().

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

Definition at line 3712 of file pg_backup_archiver.c.

References ahprintf(), buf, and PGDUMP_STRFTIME_FMT.

Referenced by RestoreArchive().

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

Definition at line 1190 of file pg_backup_archiver.c.

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

Referenced by dumpBlobs().

1191 {
1192  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1193 
1194  if (AH->EndBlobPtr)
1195  (*AH->EndBlobPtr) (AH, AH->currToc, oid);
1196 
1197  return 1;
1198 }
struct _tocEntry * currToc
void EndRestoreBlob ( ArchiveHandle AH,
Oid  oid 
)

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

1295 {
1296  if (AH->lo_buf_used > 0)
1297  {
1298  /* Write remaining bytes from the LO buffer */
1299  dump_lo_buf(AH);
1300  }
1301 
1302  AH->writingBlob = 0;
1303 
1304  if (AH->connection)
1305  {
1306  lo_close(AH->connection, AH->loFd);
1307  AH->loFd = -1;
1308  }
1309  else
1310  {
1311  ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
1312  }
1313 }
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 1227 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().

1228 {
1229  RestoreOptions *ropt = AH->public.ropt;
1230 
1231  if (!ropt->single_txn)
1232  {
1233  if (AH->connection)
1234  CommitTransaction(&AH->public);
1235  else
1236  ahprintf(AH, "COMMIT;\n\n");
1237  }
1238 
1239  ahlog(AH, 1, ngettext("restored %d large object\n",
1240  "restored %d large objects\n",
1241  AH->blobCount),
1242  AH->blobCount);
1243 }
RestoreOptions * ropt
Definition: pg_backup.h:179
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:1938
static void fix_dependencies ( ArchiveHandle AH)
static

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

4189 {
4190  TocEntry *te;
4191  int i;
4192 
4193  /*
4194  * Initialize the depCount/revDeps/nRevDeps fields, and make sure the TOC
4195  * items are marked as not being in any parallel-processing list.
4196  */
4197  for (te = AH->toc->next; te != AH->toc; te = te->next)
4198  {
4199  te->depCount = te->nDeps;
4200  te->revDeps = NULL;
4201  te->nRevDeps = 0;
4202  te->par_prev = NULL;
4203  te->par_next = NULL;
4204  }
4205 
4206  /*
4207  * POST_DATA items that are shown as depending on a table need to be
4208  * re-pointed to depend on that table's data, instead. This ensures they
4209  * won't get scheduled until the data has been loaded.
4210  */
4212 
4213  /*
4214  * Pre-8.4 versions of pg_dump neglected to set up a dependency from BLOB
4215  * COMMENTS to BLOBS. Cope. (We assume there's only one BLOBS and only
4216  * one BLOB COMMENTS in such files.)
4217  */
4218  if (AH->version < K_VERS_1_11)
4219  {
4220  for (te = AH->toc->next; te != AH->toc; te = te->next)
4221  {
4222  if (strcmp(te->desc, "BLOB COMMENTS") == 0 && te->nDeps == 0)
4223  {
4224  TocEntry *te2;
4225 
4226  for (te2 = AH->toc->next; te2 != AH->toc; te2 = te2->next)
4227  {
4228  if (strcmp(te2->desc, "BLOBS") == 0)
4229  {
4230  te->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
4231  te->dependencies[0] = te2->dumpId;
4232  te->nDeps++;
4233  te->depCount++;
4234  break;
4235  }
4236  }
4237  break;
4238  }
4239  }
4240  }
4241 
4242  /*
4243  * At this point we start to build the revDeps reverse-dependency arrays,
4244  * so all changes of dependencies must be complete.
4245  */
4246 
4247  /*
4248  * Count the incoming dependencies for each item. Also, it is possible
4249  * that the dependencies list items that are not in the archive at all
4250  * (that should not happen in 9.2 and later, but is highly likely in older
4251  * archives). Subtract such items from the depCounts.
4252  */
4253  for (te = AH->toc->next; te != AH->toc; te = te->next)
4254  {
4255  for (i = 0; i < te->nDeps; i++)
4256  {
4257  DumpId depid = te->dependencies[i];
4258 
4259  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4260  AH->tocsByDumpId[depid]->nRevDeps++;
4261  else
4262  te->depCount--;
4263  }
4264  }
4265 
4266  /*
4267  * Allocate space for revDeps[] arrays, and reset nRevDeps so we can use
4268  * it as a counter below.
4269  */
4270  for (te = AH->toc->next; te != AH->toc; te = te->next)
4271  {
4272  if (te->nRevDeps > 0)
4273  te->revDeps = (DumpId *) pg_malloc(te->nRevDeps * sizeof(DumpId));
4274  te->nRevDeps = 0;
4275  }
4276 
4277  /*
4278  * Build the revDeps[] arrays of incoming-dependency dumpIds. This had
4279  * better agree with the loops above.
4280  */
4281  for (te = AH->toc->next; te != AH->toc; te = te->next)
4282  {
4283  for (i = 0; i < te->nDeps; i++)
4284  {
4285  DumpId depid = te->dependencies[i];
4286 
4287  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4288  {
4289  TocEntry *otherte = AH->tocsByDumpId[depid];
4290 
4291  otherte->revDeps[otherte->nRevDeps++] = te->dumpId;
4292  }
4293  }
4294  }
4295 
4296  /*
4297  * Lastly, work out the locking dependencies.
4298  */
4299  for (te = AH->toc->next; te != AH->toc; te = te->next)
4300  {
4301  te->lockDeps = NULL;
4302  te->nLockDeps = 0;
4304  }
4305 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:228
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:226
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 4039 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().

4041 {
4042  bool pref_non_data = false; /* or get from AH->ropt */
4043  TocEntry *data_te = NULL;
4044  TocEntry *te;
4045  int i,
4046  k;
4047 
4048  /*
4049  * Bogus heuristics for pref_non_data
4050  */
4051  if (pref_non_data)
4052  {
4053  int count = 0;
4054 
4055  for (k = 0; k < pstate->numWorkers; k++)
4056  {
4057  TocEntry *running_te = pstate->te[k];
4058 
4059  if (running_te != NULL &&
4060  running_te->section == SECTION_DATA)
4061  count++;
4062  }
4063  if (pstate->numWorkers == 0 || count * 4 < pstate->numWorkers)
4064  pref_non_data = false;
4065  }
4066 
4067  /*
4068  * Search the ready_list until we find a suitable item.
4069  */
4070  for (te = ready_list->par_next; te != ready_list; te = te->par_next)
4071  {
4072  bool conflicts = false;
4073 
4074  /*
4075  * Check to see if the item would need exclusive lock on something
4076  * that a currently running item also needs lock on, or vice versa. If
4077  * so, we don't want to schedule them together.
4078  */
4079  for (i = 0; i < pstate->numWorkers; i++)
4080  {
4081  TocEntry *running_te = pstate->te[i];
4082 
4083  if (running_te == NULL)
4084  continue;
4085  if (has_lock_conflicts(te, running_te) ||
4086  has_lock_conflicts(running_te, te))
4087  {
4088  conflicts = true;
4089  break;
4090  }
4091  }
4092 
4093  if (conflicts)
4094  continue;
4095 
4096  if (pref_non_data && te->section == SECTION_DATA)
4097  {
4098  if (data_te == NULL)
4099  data_te = te;
4100  continue;
4101  }
4102 
4103  /* passed all tests, so this item can run */
4104  return te;
4105  }
4106 
4107  if (data_te != NULL)
4108  return data_te;
4109 
4110  ahlog(AH, 2, "no item ready\n");
4111  return NULL;
4112 }
teSection section
struct _tocEntry * par_next
#define NULL
Definition: c.h:226
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 1838 of file pg_backup_archiver.c.

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

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

1839 {
1840  /* build index arrays if we didn't already */
1841  if (AH->tocsByDumpId == NULL)
1842  buildTocEntryArrays(AH);
1843 
1844  if (id > 0 && id <= AH->maxDumpId)
1845  return AH->tocsByDumpId[id];
1846 
1847  return NULL;
1848 }
static void buildTocEntryArrays(ArchiveHandle *AH)
#define NULL
Definition: c.h:226
struct _tocEntry ** tocsByDumpId
static bool has_lock_conflicts ( TocEntry te1,
TocEntry te2 
)
static

Definition at line 3972 of file pg_backup_archiver.c.

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

Referenced by get_next_work_item().

3973 {
3974  int j,
3975  k;
3976 
3977  for (j = 0; j < te1->nLockDeps; j++)
3978  {
3979  for (k = 0; k < te2->nDeps; k++)
3980  {
3981  if (te1->lockDeps[j] == te2->dependencies[k])
3982  return true;
3983  }
3984  }
3985  return false;
3986 }
DumpId * lockDeps
DumpId * dependencies
static void identify_locking_dependencies ( ArchiveHandle AH,
TocEntry te 
)
static

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

4343 {
4344  DumpId *lockids;
4345  int nlockids;
4346  int i;
4347 
4348  /* Quick exit if no dependencies at all */
4349  if (te->nDeps == 0)
4350  return;
4351 
4352  /* Exit if this entry doesn't need exclusive lock on other objects */
4353  if (!(strcmp(te->desc, "CONSTRAINT") == 0 ||
4354  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
4355  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
4356  strcmp(te->desc, "RULE") == 0 ||
4357  strcmp(te->desc, "TRIGGER") == 0))
4358  return;
4359 
4360  /*
4361  * We assume the entry requires exclusive lock on each TABLE or TABLE DATA
4362  * item listed among its dependencies. Originally all of these would have
4363  * been TABLE items, but repoint_table_dependencies would have repointed
4364  * them to the TABLE DATA items if those are present (which they might not
4365  * be, eg in a schema-only dump). Note that all of the entries we are
4366  * processing here are POST_DATA; otherwise there might be a significant
4367  * difference between a dependency on a table and a dependency on its
4368  * data, so that closer analysis would be needed here.
4369  */
4370  lockids = (DumpId *) pg_malloc(te->nDeps * sizeof(DumpId));
4371  nlockids = 0;
4372  for (i = 0; i < te->nDeps; i++)
4373  {
4374  DumpId depid = te->dependencies[i];
4375 
4376  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL &&
4377  ((strcmp(AH->tocsByDumpId[depid]->desc, "TABLE DATA") == 0) ||
4378  strcmp(AH->tocsByDumpId[depid]->desc, "TABLE") == 0))
4379  lockids[nlockids++] = depid;
4380  }
4381 
4382  if (nlockids == 0)
4383  {
4384  free(lockids);
4385  return;
4386  }
4387 
4388  te->lockDeps = pg_realloc(lockids, nlockids * sizeof(DumpId));
4389  te->nLockDeps = nlockids;
4390 }
int DumpId
Definition: pg_backup.h:228
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:60
#define NULL
Definition: c.h:226
struct _tocEntry ** tocsByDumpId
int i
static void inhibit_data_for_failed_table ( ArchiveHandle AH,
TocEntry te 
)
static

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

4440 {
4441  ahlog(AH, 1, "table \"%s\" could not be created, will not restore its data\n",
4442  te->tag);
4443 
4444  if (AH->tableDataId[te->dumpId] != 0)
4445  {
4446  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4447 
4448  ted->reqs = 0;
4449  }
4450 }
struct _tocEntry ** tocsByDumpId
void ahlog(ArchiveHandle *AH, int level, const char *fmt,...)
void InitDumpOptions ( DumpOptions opts)

Definition at line 136 of file pg_backup_archiver.c.

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

Referenced by main(), and NewDumpOptions().

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

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

4425 {
4426  if (AH->tableDataId[te->dumpId] != 0)
4427  {
4428  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4429 
4430  ted->created = true;
4431  }
4432 }
struct _tocEntry ** tocsByDumpId
static void mark_dump_job_done ( ArchiveHandle AH,
TocEntry te,
int  status,
void *  callback_data 
)
static

Definition at line 2401 of file pg_backup_archiver.c.

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

Referenced by WriteDataChunks().

2405 {
2406  ahlog(AH, 1, "finished item %d %s %s\n",
2407  te->dumpId, te->desc, te->tag);
2408 
2409  if (status != 0)
2410  exit_horribly(modulename, "worker process failed: exit code %d\n",
2411  status);
2412 }
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:222
static const char * modulename
static void mark_restore_job_done ( ArchiveHandle AH,
TocEntry te,
int  status,
void *  callback_data 
)
static

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

4151 {
4152  TocEntry *ready_list = (TocEntry *) callback_data;
4153 
4154  ahlog(AH, 1, "finished item %d %s %s\n",
4155  te->dumpId, te->desc, te->tag);
4156 
4157  if (status == WORKER_CREATE_DONE)
4158  mark_create_done(AH, te);
4159  else if (status == WORKER_INHIBIT_DATA)
4160  {
4162  AH->public.n_errors++;
4163  }
4164  else if (status == WORKER_IGNORED_ERRORS)
4165  AH->public.n_errors++;
4166  else if (status != 0)
4167  exit_horribly(modulename, "worker process failed: exit code %d\n",
4168  status);
4169 
4170  reduce_dependencies(AH, te, ready_list);
4171 }
#define WORKER_CREATE_DONE
int n_errors
Definition: pg_backup.h:200
#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:222
static const char * modulename
DumpOptions* NewDumpOptions ( void  )

Definition at line 124 of file pg_backup_archiver.c.

References InitDumpOptions(), and pg_malloc().

Referenced by dumpOptionsFromRestoreOptions().

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

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

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

Definition at line 218 of file pg_backup_archiver.c.

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

Referenced by main().

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

Definition at line 4004 of file pg_backup_archiver.c.

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

Referenced by reduce_dependencies(), and restore_toc_entries_parallel().

4005 {
4006  te->par_prev = l->par_prev;
4007  l->par_prev->par_next = te;
4008  l->par_prev = te;
4009  te->par_next = l;
4010 }
struct _tocEntry * par_prev
struct _tocEntry * par_next
static void par_list_header_init ( TocEntry l)
static

Definition at line 3997 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entries_parallel(), and RestoreArchive().

3998 {
3999  l->par_prev = l->par_next = l;
4000 }
struct _tocEntry * par_prev
struct _tocEntry * par_next
static void par_list_remove ( TocEntry te)
static

Definition at line 4014 of file pg_backup_archiver.c.

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

Referenced by reduce_dependencies(), and restore_toc_entries_parallel().

4015 {
4016  te->par_prev->par_next = te->par_next;
4017  te->par_next->par_prev = te->par_prev;
4018  te->par_prev = NULL;
4019  te->par_next = NULL;
4020 }
struct _tocEntry * par_prev
struct _tocEntry * par_next
#define NULL
Definition: c.h:226
int parallel_restore ( ArchiveHandle AH,
TocEntry te 
)

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

4125 {
4126  int status;
4127 
4128  Assert(AH->connection != NULL);
4129 
4130  /* Count only errors associated with this TOC entry */
4131  AH->public.n_errors = 0;
4132 
4133  /* Restore the TOC item */
4134  status = restore_toc_entry(AH, te, true);
4135 
4136  return status;
4137 }
int n_errors
Definition: pg_backup.h:200
static int restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:670
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:222
void PrintTOCSummary ( Archive AHX)

Definition at line 1089 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, i, _archiveHandle::intSize, _tocEntry::nDeps, _tocEntry::next, _archiveHandle::offSize, CatalogId::oid, _tocEntry::owner, PGDUMP_STRFTIME_FMT, _archiveHandle::public, 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().

1090 {
1091  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1092  RestoreOptions *ropt = AH->public.ropt;
1093  TocEntry *te;
1094  teSection curSection;
1095  OutputContext sav;
1096  const char *fmtName;
1097  char stamp_str[64];
1098 
1099  sav = SaveOutput(AH);
1100  if (ropt->filename)
1101  SetOutput(AH, ropt->filename, 0 /* no compression */ );
1102 
1103  if (strftime(stamp_str, sizeof(stamp_str), PGDUMP_STRFTIME_FMT,
1104  localtime(&AH->createDate)) == 0)
1105  strcpy(stamp_str, "[unknown]");
1106 
1107  ahprintf(AH, ";\n; Archive created at %s\n", stamp_str);
1108  ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n",
1109  AH->archdbname, AH->tocCount, AH->compression);
1110 
1111  switch (AH->format)
1112  {
1113  case archCustom:
1114  fmtName = "CUSTOM";
1115  break;
1116  case archDirectory:
1117  fmtName = "DIRECTORY";
1118  break;
1119  case archTar:
1120  fmtName = "TAR";
1121  break;
1122  default:
1123  fmtName = "UNKNOWN";
1124  }
1125 
1126  ahprintf(AH, "; Dump Version: %d.%d-%d\n",
1128  ahprintf(AH, "; Format: %s\n", fmtName);
1129  ahprintf(AH, "; Integer: %d bytes\n", (int) AH->intSize);
1130  ahprintf(AH, "; Offset: %d bytes\n", (int) AH->offSize);
1131  if (AH->archiveRemoteVersion)
1132  ahprintf(AH, "; Dumped from database version: %s\n",
1133  AH->archiveRemoteVersion);
1134  if (AH->archiveDumpVersion)
1135  ahprintf(AH, "; Dumped by pg_dump version: %s\n",
1136  AH->archiveDumpVersion);
1137 
1138  ahprintf(AH, ";\n;\n; Selected TOC Entries:\n;\n");
1139 
1140  curSection = SECTION_PRE_DATA;
1141  for (te = AH->toc->next; te != AH->toc; te = te->next)
1142  {
1143  if (te->section != SECTION_NONE)
1144  curSection = te->section;
1145  if (ropt->verbose ||
1146  (_tocEntryRequired(te, curSection, ropt) & (REQ_SCHEMA | REQ_DATA)) != 0)
1147  ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
1148  te->catalogId.tableoid, te->catalogId.oid,
1149  te->desc, te->namespace ? te->namespace : "-",
1150  te->tag, te->owner);
1151  if (ropt->verbose && te->nDeps > 0)
1152  {
1153  int i;
1154 
1155  ahprintf(AH, ";\tdepends on:");
1156  for (i = 0; i < te->nDeps; i++)
1157  ahprintf(AH, " %d", te->dependencies[i]);
1158  ahprintf(AH, "\n");
1159  }
1160  }
1161 
1162  /* Enforce strict names checking */
1163  if (ropt->strict_names)
1164  StrictNamesCheck(ropt);
1165 
1166  if (ropt->filename)
1167  RestoreOutput(AH, sav);
1168 }
struct _tocEntry * next
Oid tableoid
Definition: pg_backup.h:224
RestoreOptions * ropt
Definition: pg_backup.h:179
CatalogId catalogId
static void SetOutput(ArchiveHandle *AH, const char *filename, int compression)
teSection section
const char * filename
Definition: pg_backup.h:80
struct _tocEntry * toc
DumpId * dependencies
#define ARCHIVE_REV(version)
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)
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 260 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().

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

2665 {
2666  /* te->defn should have the form SET client_encoding = 'foo'; */
2667  char *defn = pg_strdup(te->defn);
2668  char *ptr1;
2669  char *ptr2 = NULL;
2670  int encoding;
2671 
2672  ptr1 = strchr(defn, '\'');
2673  if (ptr1)
2674  ptr2 = strchr(++ptr1, '\'');
2675  if (ptr2)
2676  {
2677  *ptr2 = '\0';
2678  encoding = pg_char_to_encoding(ptr1);
2679  if (encoding < 0)
2680  exit_horribly(modulename, "unrecognized encoding \"%s\"\n",
2681  ptr1);
2682  AH->public.encoding = encoding;
2683  }
2684  else
2685  exit_horribly(modulename, "invalid ENCODING item: %s\n",
2686  te->defn);
2687 
2688  free(defn);
2689 }
int pg_char_to_encoding(const char *name)
Definition: encnames.c:475
int encoding
Definition: pg_backup.h:194
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static char * encoding
Definition: initdb.c:121
#define free(a)
Definition: header.h:60
#define NULL
Definition: c.h:226
void exit_horribly(const char *modulename, const char *fmt,...)
static const char * modulename
static void processStdStringsEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2692 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

2693 {
2694  /* te->defn should have the form SET standard_conforming_strings = 'x'; */
2695  char *ptr1;
2696 
2697  ptr1 = strchr(te->defn, '\'');
2698  if (ptr1 && strncmp(ptr1, "'on'", 4) == 0)
2699  AH->public.std_strings = true;
2700  else if (ptr1 && strncmp(ptr1, "'off'", 5) == 0)
2701  AH->public.std_strings = false;
2702  else
2703  exit_horribly(modulename, "invalid STDSTRINGS item: %s\n",
2704  te->defn);
2705 }
void exit_horribly(const char *modulename, const char *fmt,...)
static const char * modulename
bool std_strings
Definition: pg_backup.h:195
void ReadHead ( ArchiveHandle AH)

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

3576 {
3577  char tmpMag[7];
3578  int fmt;
3579  struct tm crtm;
3580 
3581  /*
3582  * If we haven't already read the header, do so.
3583  *
3584  * NB: this code must agree with _discoverArchiveFormat(). Maybe find a
3585  * way to unify the cases?
3586  */
3587  if (!AH->readHeader)
3588  {
3589  char vmaj,
3590  vmin,
3591  vrev;
3592 
3593  (*AH->ReadBufPtr) (AH, tmpMag, 5);
3594 
3595  if (strncmp(tmpMag, "PGDMP", 5) != 0)
3596  exit_horribly(modulename, "did not find magic string in file header\n");
3597 
3598  vmaj = (*AH->ReadBytePtr) (AH);
3599  vmin = (*AH->ReadBytePtr) (AH);
3600 
3601  if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */
3602  vrev = (*AH->ReadBytePtr) (AH);
3603  else
3604  vrev = 0;
3605 
3606  AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev);
3607 
3608  if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
3609  exit_horribly(modulename, "unsupported version (%d.%d) in file header\n",
3610  vmaj, vmin);
3611 
3612  AH->intSize = (*AH->ReadBytePtr) (AH);
3613  if (AH->intSize > 32)
3614  exit_horribly(modulename, "sanity check on integer size (%lu) failed\n",
3615  (unsigned long) AH->intSize);
3616 
3617  if (AH->intSize > sizeof(int))
3618  write_msg(modulename, "WARNING: archive was made on a machine with larger integers, some operations might fail\n");
3619 
3620  if (AH->version >= K_VERS_1_7)
3621  AH->offSize = (*AH->ReadBytePtr) (AH);
3622  else
3623  AH->offSize = AH->intSize;
3624 
3625  fmt = (*AH->ReadBytePtr) (AH);
3626 
3627  if (AH->format != fmt)
3628  exit_horribly(modulename, "expected format (%d) differs from format found in file (%d)\n",
3629  AH->format, fmt);
3630  }
3631 
3632  if (AH->version >= K_VERS_1_2)
3633  {
3634  if (AH->version < K_VERS_1_4)
3635  AH->compression = (*AH->ReadBytePtr) (AH);
3636  else
3637  AH->compression = ReadInt(AH);
3638  }
3639  else
3641 
3642 #ifndef HAVE_LIBZ
3643  if (AH->compression != 0)
3644  write_msg(modulename, "WARNING: archive is compressed, but this installation does not support compression -- no data will be available\n");
3645 #endif
3646 
3647  if (AH->version >= K_VERS_1_4)
3648  {
3649  crtm.tm_sec = ReadInt(AH);
3650  crtm.tm_min = ReadInt(AH);
3651  crtm.tm_hour = ReadInt(AH);
3652  crtm.tm_mday = ReadInt(AH);
3653  crtm.tm_mon = ReadInt(AH);
3654  crtm.tm_year = ReadInt(AH);
3655  crtm.tm_isdst = ReadInt(AH);
3656 
3657  AH->archdbname = ReadStr(AH);
3658 
3659  AH->createDate = mktime(&crtm);
3660 
3661  if (AH->createDate == (time_t) -1)
3662  write_msg(modulename, "WARNING: invalid creation date in header\n");
3663  }
3664 
3665  if (AH->version >= K_VERS_1_10)
3666  {
3667  AH->archiveRemoteVersion = ReadStr(AH);
3668  AH->archiveDumpVersion = ReadStr(AH);
3669  }
3670 }
#define Z_DEFAULT_COMPRESSION
#define K_VERS_1_0
int ReadInt(ArchiveHandle *AH)
#define K_VERS_1_4
static struct pg_tm tm
Definition: localtime.c:103
#define K_VERS_1_7
#define MAKE_ARCHIVE_VERSION(major, minor, rev)
#define K_VERS_1_2
#define K_VERS_1_10
ReadBytePtr ReadBytePtr
ArchiveFormat format
#define K_VERS_MAX
void write_msg(const char *modulename, const char *fmt,...)
char * ReadStr(ArchiveHandle *AH)
void exit_horribly(const char *modulename, const char *fmt,...)
static const char * modulename
int ReadInt ( ArchiveHandle AH)

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

1975 {
1976  int res = 0;
1977  int bv,
1978  b;
1979  int sign = 0; /* Default positive */
1980  int bitShift = 0;
1981 
1982  if (AH->version > K_VERS_1_0)
1983  /* Read a sign byte */
1984  sign = (*AH->ReadBytePtr) (AH);
1985 
1986  for (b = 0; b < AH->intSize; b++)
1987  {
1988  bv = (*AH->ReadBytePtr) (AH) & 0xFF;
1989  if (bv != 0)
1990  res = res + (bv << bitShift);
1991  bitShift += 8;
1992  }
1993 
1994  if (sign)
1995  res = -res;
1996 
1997  return res;
1998 }
#define K_VERS_1_0
char sign
Definition: informix.c:693
ReadBytePtr ReadBytePtr
int ReadOffset ( ArchiveHandle AH,
pgoff_t o 
)

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

1880 {
1881  int i;
1882  int off;
1883  int offsetFlg;
1884 
1885  /* Initialize to zero */
1886  *o = 0;
1887 
1888  /* Check for old version */
1889  if (AH->version < K_VERS_1_7)
1890  {
1891  /* Prior versions wrote offsets using WriteInt */
1892  i = ReadInt(AH);
1893  /* -1 means not set */
1894  if (i < 0)
1895  return K_OFFSET_POS_NOT_SET;
1896  else if (i == 0)
1897  return K_OFFSET_NO_DATA;
1898 
1899  /* Cast to pgoff_t because it was written as an int. */
1900  *o = (pgoff_t) i;
1901  return K_OFFSET_POS_SET;
1902  }
1903 
1904  /*
1905  * Read the flag indicating the state of the data pointer. Check if valid
1906  * and die if not.
1907  *
1908  * This used to be handled by a negative or zero pointer, now we use an
1909  * extra byte specifically for the state.
1910  */
1911  offsetFlg = (*AH->ReadBytePtr) (AH) & 0xFF;
1912 
1913  switch (offsetFlg)
1914  {
1915  case K_OFFSET_POS_NOT_SET:
1916  case K_OFFSET_NO_DATA:
1917  case K_OFFSET_POS_SET:
1918 
1919  break;
1920 
1921  default:
1922  exit_horribly(modulename, "unexpected data offset flag %d\n", offsetFlg);
1923  }
1924 
1925  /*
1926  * Read the bytes
1927  */
1928  for (off = 0; off < AH->offSize; off++)
1929  {
1930  if (off < sizeof(pgoff_t))
1931  *o |= ((pgoff_t) ((*AH->ReadBytePtr) (AH))) << (off * 8);
1932  else
1933  {
1934  if ((*AH->ReadBytePtr) (AH) != 0)
1935  exit_horribly(modulename, "file offset in dump file is too large\n");
1936  }
1937  }
1938 
1939  return offsetFlg;
1940 }
int ReadInt(ArchiveHandle *AH)
#define K_VERS_1_7
ReadBytePtr ReadBytePtr
#define K_OFFSET_NO_DATA
#define pgoff_t
Definition: win32.h:241
void exit_horribly(const char *modulename, const char *fmt,...)
#define K_OFFSET_POS_SET
int i
static const char * modulename
#define K_OFFSET_POS_NOT_SET
char* ReadStr ( ArchiveHandle AH)

Definition at line 2020 of file pg_backup_archiver.c.

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

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

2021 {
2022  char *buf;
2023  int l;
2024 
2025  l = ReadInt(AH);
2026  if (l < 0)
2027  buf = NULL;
2028  else
2029  {
2030  buf = (char *) pg_malloc(l + 1);
2031  (*AH->ReadBufPtr) (AH, (void *) buf, l);
2032 
2033  buf[l] = '\0';
2034  }
2035 
2036  return buf;
2037 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
int ReadInt(ArchiveHandle *AH)
static char * buf
Definition: pg_test_fsync.c:65
#define NULL
Definition: c.h:226
void ReadToc ( ArchiveHandle AH)

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

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

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

4399 {
4400  int i;
4401 
4402  ahlog(AH, 2, "reducing dependencies for %d\n", te->dumpId);
4403 
4404  for (i = 0; i < te->nRevDeps; i++)
4405  {
4406  TocEntry *otherte = AH->tocsByDumpId[te->revDeps[i]];
4407 
4408  otherte->depCount--;
4409  if (otherte->depCount == 0 && otherte->par_prev != NULL)
4410  {
4411  /* It must be in the pending list, so remove it ... */
4412  par_list_remove(otherte);
4413  /* ... and add to ready_list */
4414  par_list_append(ready_list, otherte);
4415  }
4416  }
4417 }
struct _tocEntry * par_prev
#define NULL
Definition: c.h:226
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 3532 of file pg_backup_archiver.c.

References pg_strdup().

Referenced by _printTocEntry().

3533 {
3534  char *result;
3535  char *s;
3536 
3537  result = pg_strdup(str);
3538 
3539  for (s = result; *s != '\0'; s++)
3540  {
3541  if (*s == '\n' || *s == '\r')
3542  *s = ' ';
3543  }
3544 
3545  return result;
3546 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void repoint_table_dependencies ( ArchiveHandle AH)
static

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

4313 {
4314  TocEntry *te;
4315  int i;
4316  DumpId olddep;
4317 
4318  for (te = AH->toc->next; te != AH->toc; te = te->next)
4319  {
4320  if (te->section != SECTION_POST_DATA)
4321  continue;
4322  for (i = 0; i < te->nDeps; i++)
4323  {
4324  olddep = te->dependencies[i];
4325  if (olddep <= AH->maxDumpId &&
4326  AH->tableDataId[olddep] != 0)
4327  {
4328  te->dependencies[i] = AH->tableDataId[olddep];
4329  ahlog(AH, 2, "transferring dependency %d -> %d to %d\n",
4330  te->dumpId, olddep, AH->tableDataId[olddep]);
4331  }
4332  }
4333  }
4334 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:228
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 3824 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().

3826 {
3827  bool skipped_some;
3828  TocEntry ready_list;
3829  TocEntry *next_work_item;
3830 
3831  ahlog(AH, 2, "entering restore_toc_entries_parallel\n");
3832 
3833  /*
3834  * Initialize the lists of ready items, the list for pending items has
3835  * already been initialized in the caller. After this setup, the pending
3836  * list is everything that needs to be done but is blocked by one or more
3837  * dependencies, while the ready list contains items that have no
3838  * remaining dependencies. Note: we don't yet filter out entries that
3839  * aren't going to be restored. They might participate in dependency
3840  * chains connecting entries that should be restored, so we treat them as
3841  * live until we actually process them.
3842  */
3843  par_list_header_init(&ready_list);
3844  skipped_some = false;
3845  for (next_work_item = AH->toc->next; next_work_item != AH->toc; next_work_item = next_work_item->next)
3846  {
3847  /* NB: process-or-continue logic must be the inverse of loop above */
3848  if (next_work_item->section == SECTION_PRE_DATA)
3849  {
3850  /* All PRE_DATA items were dealt with above */
3851  continue;
3852  }
3853  if (next_work_item->section == SECTION_DATA ||
3854  next_work_item->section == SECTION_POST_DATA)
3855  {
3856  /* set this flag at same point that previous loop did */
3857  skipped_some = true;
3858  }
3859  else
3860  {
3861  /* SECTION_NONE items must be processed if previous loop didn't */
3862  if (!skipped_some)
3863  continue;
3864  }
3865 
3866  if (next_work_item->depCount > 0)
3867  par_list_append(pending_list, next_work_item);
3868  else
3869  par_list_append(&ready_list, next_work_item);
3870  }
3871 
3872  /*
3873  * main parent loop
3874  *
3875  * Keep going until there is no worker still running AND there is no work
3876  * left to be done.
3877  */
3878 
3879  ahlog(AH, 1, "entering main parallel loop\n");
3880 
3881  while ((next_work_item = get_next_work_item(AH, &ready_list, pstate)) != NULL ||
3882  !IsEveryWorkerIdle(pstate))
3883  {
3884  if (next_work_item != NULL)
3885  {
3886  /* If not to be restored, don't waste time launching a worker */
3887  if ((next_work_item->reqs & (REQ_SCHEMA | REQ_DATA)) == 0 ||
3888  _tocEntryIsACL(next_work_item))
3889  {
3890  ahlog(AH, 1, "skipping item %d %s %s\n",
3891  next_work_item->dumpId,
3892  next_work_item->desc, next_work_item->tag);
3893 
3894  par_list_remove(next_work_item);
3895  reduce_dependencies(AH, next_work_item, &ready_list);
3896 
3897  continue;
3898  }
3899 
3900  ahlog(AH, 1, "launching item %d %s %s\n",
3901  next_work_item->dumpId,
3902  next_work_item->desc, next_work_item->tag);
3903 
3904  par_list_remove(next_work_item);
3905 
3906  DispatchJobForTocEntry(AH, pstate, next_work_item, ACT_RESTORE,
3907  mark_restore_job_done, &ready_list);
3908  }
3909  else
3910  {
3911  /* at least one child is working and we have nothing ready. */
3912  }
3913 
3914  /*
3915  * Before dispatching another job, check to see if anything has
3916  * finished. We should check every time through the loop so as to
3917  * reduce dependencies as soon as possible. If we were unable to
3918  * dispatch any job this time through, wait until some worker finishes
3919  * (and, hopefully, unblocks some pending item). If we did dispatch
3920  * something, continue as soon as there's at least one idle worker.
3921  * Note that in either case, there's guaranteed to be at least one
3922  * idle worker when we return to the top of the loop. This ensures we
3923  * won't block inside DispatchJobForTocEntry, which would be
3924  * undesirable: we'd rather postpone dispatching until we see what's
3925  * been unblocked by finished jobs.
3926  */
3927  WaitForWorkers(AH, pstate,
3928  next_work_item ? WFW_ONE_IDLE : WFW_GOT_STATUS);
3929  }
3930 
3931  ahlog(AH, 1, "finished main parallel loop\n");
3932 }
struct _tocEntry * next
static void mark_restore_job_done(ArchiveHandle *AH, TocEntry *te, int status, void *callback_data)
void DispatchJobForTocEntry(ArchiveHandle *AH, ParallelState *pstate, TocEntry *te, T_Action act, ParallelCompletionPtr callback, void *callback_data)
Definition: parallel.c:1229
bool IsEveryWorkerIdle(ParallelState *pstate)
Definition: parallel.c:1292
static bool _tocEntryIsACL(TocEntry *te)
teSection section
struct _tocEntry * toc
static void par_list_header_init(TocEntry *l)
void WaitForWorkers(ArchiveHandle *AH, ParallelState *pstate, WFW_WaitOption mode)
Definition: parallel.c:1477
static void reduce_dependencies(ArchiveHandle *AH, TocEntry *te, TocEntry *ready_list)
#define NULL
Definition: c.h:226
static void par_list_append(TocEntry *l, TocEntry *te)
char * tag
Defin