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

Go to the source code of this file.

Data Structures

struct  _outputContext
 
struct  _parallelReadyList
 

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
 
typedef struct _parallelReadyList ParallelReadyList
 

Functions

static ArchiveHandle_allocAH (const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupWorkerPtr)
 
static void _getObjectDescription (PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
 
static void _printTocEntry (ArchiveHandle *AH, TocEntry *te, bool isData)
 
static char * sanitize_line (const char *str, bool want_hyphen)
 
static void _doSetFixedOutputState (ArchiveHandle *AH)
 
static void _doSetSessionAuth (ArchiveHandle *AH, const char *user)
 
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 _selectTableAccessMethod (ArchiveHandle *AH, const char *tableam)
 
static void processEncodingEntry (ArchiveHandle *AH, TocEntry *te)
 
static void processStdStringsEntry (ArchiveHandle *AH, TocEntry *te)
 
static void processSearchPathEntry (ArchiveHandle *AH, TocEntry *te)
 
static teReqs _tocEntryRequired (TocEntry *te, teSection curSection, ArchiveHandle *AH)
 
static RestorePass _tocEntryRestorePass (TocEntry *te)
 
static bool _tocEntryIsACL (TocEntry *te)
 
static void _disableTriggersIfNecessary (ArchiveHandle *AH, TocEntry *te)
 
static void _enableTriggersIfNecessary (ArchiveHandle *AH, TocEntry *te)
 
static void buildTocEntryArrays (ArchiveHandle *AH)
 
static void _moveBefore (ArchiveHandle *AH, TocEntry *pos, TocEntry *te)
 
static int _discoverArchiveFormat (ArchiveHandle *AH)
 
static int RestoringToDB (ArchiveHandle *AH)
 
static void dump_lo_buf (ArchiveHandle *AH)
 
static void dumpTimestamp (ArchiveHandle *AH, const char *msg, time_t tim)
 
static void SetOutput (ArchiveHandle *AH, const char *filename, int compression)
 
static OutputContext SaveOutput (ArchiveHandle *AH)
 
static void RestoreOutput (ArchiveHandle *AH, OutputContext savedContext)
 
static int restore_toc_entry (ArchiveHandle *AH, TocEntry *te, bool is_parallel)
 
static void restore_toc_entries_prefork (ArchiveHandle *AH, TocEntry *pending_list)
 
static void restore_toc_entries_parallel (ArchiveHandle *AH, ParallelState *pstate, TocEntry *pending_list)
 
static void restore_toc_entries_postfork (ArchiveHandle *AH, TocEntry *pending_list)
 
static void pending_list_header_init (TocEntry *l)
 
static void pending_list_append (TocEntry *l, TocEntry *te)
 
static void pending_list_remove (TocEntry *te)
 
static void ready_list_init (ParallelReadyList *ready_list, int tocCount)
 
static void ready_list_free (ParallelReadyList *ready_list)
 
static void ready_list_insert (ParallelReadyList *ready_list, TocEntry *te)
 
static void ready_list_remove (ParallelReadyList *ready_list, int i)
 
static void ready_list_sort (ParallelReadyList *ready_list)
 
static int TocEntrySizeCompare (const void *p1, const void *p2)
 
static void move_to_ready_list (TocEntry *pending_list, ParallelReadyList *ready_list, RestorePass pass)
 
static TocEntrypop_next_work_item (ArchiveHandle *AH, ParallelReadyList *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, ParallelReadyList *ready_list)
 
static void mark_create_done (ArchiveHandle *AH, TocEntry *te)
 
static void inhibit_data_for_failed_table (ArchiveHandle *AH, TocEntry *te)
 
static void StrictNamesCheck (RestoreOptions *ropt)
 
DumpOptionsNewDumpOptions (void)
 
void InitDumpOptions (DumpOptions *opts)
 
DumpOptionsdumpOptionsFromRestoreOptions (RestoreOptions *ropt)
 
static void setupRestoreWorker (Archive *AHX)
 
ArchiveCreateArchive (const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupDumpWorker)
 
ArchiveOpenArchive (const char *FileSpec, const ArchiveFormat fmt)
 
void CloseArchive (Archive *AHX)
 
void SetArchiveOptions (Archive *AH, DumpOptions *dopt, RestoreOptions *ropt)
 
void ProcessArchiveRestoreOptions (Archive *AHX)
 
void RestoreArchive (Archive *AHX)
 
RestoreOptionsNewRestoreOptions (void)
 
void WriteData (Archive *AHX, const void *data, size_t dLen)
 
TocEntryArchiveEntry (Archive *AHX, CatalogId catalogId, DumpId dumpId, ArchiveOpts *opts)
 
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 ahwrite (const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
 
void warn_or_exit_horribly (ArchiveHandle *AH, 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)
 
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)
 

Macro Definition Documentation

◆ TEXT_DUMP_HEADER

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

Definition at line 41 of file pg_backup_archiver.c.

Referenced by _discoverArchiveFormat().

◆ TEXT_DUMPALL_HEADER

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

Definition at line 42 of file pg_backup_archiver.c.

Referenced by _discoverArchiveFormat().

Typedef Documentation

◆ OutputContext

typedef struct _outputContext OutputContext

◆ ParallelReadyList

Function Documentation

◆ _allocAH()

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

Definition at line 2280 of file pg_backup_archiver.c.

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

Referenced by CreateArchive(), and OpenArchive().

2283 {
2284  ArchiveHandle *AH;
2285 
2286  pg_log_debug("allocating AH for %s, format %d", FileSpec, fmt);
2287 
2288  AH = (ArchiveHandle *) pg_malloc0(sizeof(ArchiveHandle));
2289 
2290  AH->version = K_VERS_SELF;
2291 
2292  /* initialize for backwards compatible string processing */
2293  AH->public.encoding = 0; /* PG_SQL_ASCII */
2294  AH->public.std_strings = false;
2295 
2296  /* sql error handling */
2297  AH->public.exit_on_error = true;
2298  AH->public.n_errors = 0;
2299 
2300  AH->archiveDumpVersion = PG_VERSION;
2301 
2302  AH->createDate = time(NULL);
2303 
2304  AH->intSize = sizeof(int);
2305  AH->offSize = sizeof(pgoff_t);
2306  if (FileSpec)
2307  {
2308  AH->fSpec = pg_strdup(FileSpec);
2309 
2310  /*
2311  * Not used; maybe later....
2312  *
2313  * AH->workDir = pg_strdup(FileSpec); for(i=strlen(FileSpec) ; i > 0 ;
2314  * i--) if (AH->workDir[i-1] == '/')
2315  */
2316  }
2317  else
2318  AH->fSpec = NULL;
2319 
2320  AH->currUser = NULL; /* unknown */
2321  AH->currSchema = NULL; /* ditto */
2322  AH->currTablespace = NULL; /* ditto */
2323  AH->currTableAm = NULL; /* ditto */
2324 
2325  AH->toc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
2326 
2327  AH->toc->next = AH->toc;
2328  AH->toc->prev = AH->toc;
2329 
2330  AH->mode = mode;
2331  AH->compression = compression;
2332  AH->dosync = dosync;
2333 
2334  memset(&(AH->sqlparse), 0, sizeof(AH->sqlparse));
2335 
2336  /* Open stdout with no compression for AH output handle */
2337  AH->gzOut = 0;
2338  AH->OF = stdout;
2339 
2340  /*
2341  * On Windows, we need to use binary mode to read/write non-text files,
2342  * which include all archive formats as well as compressed plain text.
2343  * Force stdin/stdout into binary mode if that is what we are using.
2344  */
2345 #ifdef WIN32
2346  if ((fmt != archNull || compression != 0) &&
2347  (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0))
2348  {
2349  if (mode == archModeWrite)
2350  _setmode(fileno(stdout), O_BINARY);
2351  else
2352  _setmode(fileno(stdin), O_BINARY);
2353  }
2354 #endif
2355 
2356  AH->SetupWorkerPtr = setupWorkerPtr;
2357 
2358  if (fmt == archUnknown)
2359  AH->format = _discoverArchiveFormat(AH);
2360  else
2361  AH->format = fmt;
2362 
2364 
2365  switch (AH->format)
2366  {
2367  case archCustom:
2369  break;
2370 
2371  case archNull:
2372  InitArchiveFmt_Null(AH);
2373  break;
2374 
2375  case archDirectory:
2377  break;
2378 
2379  case archTar:
2380  InitArchiveFmt_Tar(AH);
2381  break;
2382 
2383  default:
2384  fatal("unrecognized file format \"%d\"", fmt);
2385  }
2386 
2387  return AH;
2388 }
struct _tocEntry * next
static PgChecksumMode mode
Definition: pg_checksums.c:61
#define K_VERS_SELF
static bool dosync
Definition: pg_dump.c:92
void InitArchiveFmt_Tar(ArchiveHandle *AH)
int n_errors
Definition: pg_backup.h:206
int encoding
Definition: pg_backup.h:197
SetupWorkerPtrType SetupWorkerPtr
#define pgoff_t
Definition: win32_port.h:195
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#define pg_log_debug(...)
Definition: logging.h:91
struct _tocEntry * toc
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
sqlparseInfo sqlparse
struct _tocEntry * prev
ArchiveFormat format
static int _discoverArchiveFormat(ArchiveHandle *AH)
void InitArchiveFmt_Directory(ArchiveHandle *AH)
void InitArchiveFmt_Null(ArchiveHandle *AH)
void InitArchiveFmt_Custom(ArchiveHandle *AH)
#define fatal(...)
bool exit_on_error
Definition: pg_backup.h:205
bool std_strings
Definition: pg_backup.h:198

◆ _becomeOwner()

static void _becomeOwner ( ArchiveHandle AH,
TocEntry te 
)
static

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

3286 {
3287  RestoreOptions *ropt = AH->public.ropt;
3288 
3289  if (ropt && (ropt->noOwner || !ropt->use_setsessauth))
3290  return;
3291 
3292  _becomeUser(AH, te->owner);
3293 }
RestoreOptions * ropt
Definition: pg_backup.h:183
static void _becomeUser(ArchiveHandle *AH, const char *user)
int use_setsessauth
Definition: pg_backup.h:68

◆ _becomeUser()

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

Definition at line 3261 of file pg_backup_archiver.c.

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

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

3262 {
3263  if (!user)
3264  user = ""; /* avoid null pointers */
3265 
3266  if (AH->currUser && strcmp(AH->currUser, user) == 0)
3267  return; /* no need to do anything */
3268 
3269  _doSetSessionAuth(AH, user);
3270 
3271  /*
3272  * NOTE: currUser keeps track of what the imaginary session user in our
3273  * script is
3274  */
3275  if (AH->currUser)
3276  free(AH->currUser);
3277  AH->currUser = pg_strdup(user);
3278 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void _doSetSessionAuth(ArchiveHandle *AH, const char *user)
#define free(a)
Definition: header.h:65
static char * user
Definition: pg_regress.c:94

◆ _disableTriggersIfNecessary()

static void _disableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 983 of file pg_backup_archiver.c.

References _becomeUser(), ahprintf(), _restoreOptions::dataOnly, _restoreOptions::disable_triggers, fmtQualifiedId(), pg_log_info, _archiveHandle::public, Archive::ropt, _restoreOptions::superuser, and _tocEntry::tag.

Referenced by restore_toc_entry().

984 {
985  RestoreOptions *ropt = AH->public.ropt;
986 
987  /* This hack is only needed in a data-only restore */
988  if (!ropt->dataOnly || !ropt->disable_triggers)
989  return;
990 
991  pg_log_info("disabling triggers for %s", te->tag);
992 
993  /*
994  * Become superuser if possible, since they are the only ones who can
995  * disable constraint triggers. If -S was not given, assume the initial
996  * user identity is a superuser. (XXX would it be better to become the
997  * table owner?)
998  */
999  _becomeUser(AH, ropt->superuser);
1000 
1001  /*
1002  * Disable them.
1003  */
1004  ahprintf(AH, "ALTER TABLE %s DISABLE TRIGGER ALL;\n\n",
1005  fmtQualifiedId(te->namespace, te->tag));
1006 }
RestoreOptions * ropt
Definition: pg_backup.h:183
static void _becomeUser(ArchiveHandle *AH, const char *user)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
char * superuser
Definition: pg_backup.h:70
const char * fmtQualifiedId(const char *schema, const char *id)
Definition: string_utils.c:145
#define pg_log_info(...)
Definition: logging.h:87
int disable_triggers
Definition: pg_backup.h:66

◆ _discoverArchiveFormat()

static int _discoverArchiveFormat ( ArchiveHandle AH)
static

Definition at line 2080 of file pg_backup_archiver.c.

References archDirectory, archTar, buf, fatal, _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, _archiveHandle::offSize, PG_BINARY_R, pg_log_debug, pg_malloc0(), READ_ERROR_EXIT, _archiveHandle::readHeader, S_ISDIR, S_ISREG, sig, snprintf, stat, TEXT_DUMP_HEADER, TEXT_DUMPALL_HEADER, and _archiveHandle::version.

Referenced by _allocAH().

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

◆ _doSetFixedOutputState()

static void _doSetFixedOutputState ( ArchiveHandle AH)
static

Definition at line 3118 of file pg_backup_archiver.c.

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

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

3119 {
3120  RestoreOptions *ropt = AH->public.ropt;
3121 
3122  /*
3123  * Disable timeouts to allow for slow commands, idle parallel workers, etc
3124  */
3125  ahprintf(AH, "SET statement_timeout = 0;\n");
3126  ahprintf(AH, "SET lock_timeout = 0;\n");
3127  ahprintf(AH, "SET idle_in_transaction_session_timeout = 0;\n");
3128 
3129  /* Select the correct character set encoding */
3130  ahprintf(AH, "SET client_encoding = '%s';\n",
3132 
3133  /* Select the correct string literal syntax */
3134  ahprintf(AH, "SET standard_conforming_strings = %s;\n",
3135  AH->public.std_strings ? "on" : "off");
3136 
3137  /* Select the role to be used during restore */
3138  if (ropt && ropt->use_role)
3139  ahprintf(AH, "SET ROLE %s;\n", fmtId(ropt->use_role));
3140 
3141  /* Select the dump-time search_path */
3142  if (AH->public.searchpath)
3143  ahprintf(AH, "%s", AH->public.searchpath);
3144 
3145  /* Make sure function checking is disabled */
3146  ahprintf(AH, "SET check_function_bodies = false;\n");
3147 
3148  /* Ensure that all valid XML data will be accepted */
3149  ahprintf(AH, "SET xmloption = content;\n");
3150 
3151  /* Avoid annoying notices etc */
3152  ahprintf(AH, "SET client_min_messages = warning;\n");
3153  if (!AH->public.std_strings)
3154  ahprintf(AH, "SET escape_string_warning = off;\n");
3155 
3156  /* Adjust row-security state */
3157  if (ropt && ropt->enable_row_security)
3158  ahprintf(AH, "SET row_security = on;\n");
3159  else
3160  ahprintf(AH, "SET row_security = off;\n");
3161 
3162  ahprintf(AH, "\n");
3163 }
RestoreOptions * ropt
Definition: pg_backup.h:183
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
char * use_role
Definition: pg_backup.h:71
int encoding
Definition: pg_backup.h:197
int enable_row_security
Definition: pg_backup.h:123
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
char * searchpath
Definition: pg_backup.h:201
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:607
bool std_strings
Definition: pg_backup.h:198

◆ _doSetSessionAuth()

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

Definition at line 3171 of file pg_backup_archiver.c.

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

Referenced by _becomeUser().

3172 {
3174 
3175  appendPQExpBufferStr(cmd, "SET SESSION AUTHORIZATION ");
3176 
3177  /*
3178  * SQL requires a string literal here. Might as well be correct.
3179  */
3180  if (user && *user)
3181  appendStringLiteralAHX(cmd, user, AH);
3182  else
3183  appendPQExpBufferStr(cmd, "DEFAULT");
3184  appendPQExpBufferChar(cmd, ';');
3185 
3186  if (RestoringToDB(AH))
3187  {
3188  PGresult *res;
3189 
3190  res = PQexec(AH->connection, cmd->data);
3191 
3192  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3193  /* NOT warn_or_exit_horribly... use -O instead to skip this. */
3194  fatal("could not set session user to \"%s\": %s",
3196 
3197  PQclear(res);
3198  }
3199  else
3200  ahprintf(AH, "%s\n\n", cmd->data);
3201 
3202  destroyPQExpBuffer(cmd);
3203 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define fatal(...)
#define appendStringLiteralAHX(buf, str, AH)
static char * user
Definition: pg_regress.c:94
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939

◆ _enableTriggersIfNecessary()

static void _enableTriggersIfNecessary ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 1009 of file pg_backup_archiver.c.

References _becomeUser(), ahprintf(), _restoreOptions::dataOnly, _restoreOptions::disable_triggers, fmtQualifiedId(), pg_log_info, _archiveHandle::public, Archive::ropt, _restoreOptions::superuser, and _tocEntry::tag.

Referenced by restore_toc_entry().

1010 {
1011  RestoreOptions *ropt = AH->public.ropt;
1012 
1013  /* This hack is only needed in a data-only restore */
1014  if (!ropt->dataOnly || !ropt->disable_triggers)
1015  return;
1016 
1017  pg_log_info("enabling triggers for %s", te->tag);
1018 
1019  /*
1020  * Become superuser if possible, since they are the only ones who can
1021  * disable constraint triggers. If -S was not given, assume the initial
1022  * user identity is a superuser. (XXX would it be better to become the
1023  * table owner?)
1024  */
1025  _becomeUser(AH, ropt->superuser);
1026 
1027  /*
1028  * Enable them.
1029  */
1030  ahprintf(AH, "ALTER TABLE %s ENABLE TRIGGER ALL;\n\n",
1031  fmtQualifiedId(te->namespace, te->tag));
1032 }
RestoreOptions * ropt
Definition: pg_backup.h:183
static void _becomeUser(ArchiveHandle *AH, const char *user)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
char * superuser
Definition: pg_backup.h:70
const char * fmtQualifiedId(const char *schema, const char *id)
Definition: string_utils.c:145
#define pg_log_info(...)
Definition: logging.h:87
int disable_triggers
Definition: pg_backup.h:66

◆ _getObjectDescription()

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

Definition at line 3459 of file pg_backup_archiver.c.

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

Referenced by _printTocEntry().

3460 {
3461  const char *type = te->desc;
3462 
3463  /* Use ALTER TABLE for views and sequences */
3464  if (strcmp(type, "VIEW") == 0 || strcmp(type, "SEQUENCE") == 0 ||
3465  strcmp(type, "MATERIALIZED VIEW") == 0)
3466  type = "TABLE";
3467 
3468  /* objects that don't require special decoration */
3469  if (strcmp(type, "COLLATION") == 0 ||
3470  strcmp(type, "CONVERSION") == 0 ||
3471  strcmp(type, "DOMAIN") == 0 ||
3472  strcmp(type, "TABLE") == 0 ||
3473  strcmp(type, "TYPE") == 0 ||
3474  strcmp(type, "FOREIGN TABLE") == 0 ||
3475  strcmp(type, "TEXT SEARCH DICTIONARY") == 0 ||
3476  strcmp(type, "TEXT SEARCH CONFIGURATION") == 0 ||
3477  strcmp(type, "STATISTICS") == 0 ||
3478  /* non-schema-specified objects */
3479  strcmp(type, "DATABASE") == 0 ||
3480  strcmp(type, "PROCEDURAL LANGUAGE") == 0 ||
3481  strcmp(type, "SCHEMA") == 0 ||
3482  strcmp(type, "EVENT TRIGGER") == 0 ||
3483  strcmp(type, "FOREIGN DATA WRAPPER") == 0 ||
3484  strcmp(type, "SERVER") == 0 ||
3485  strcmp(type, "PUBLICATION") == 0 ||
3486  strcmp(type, "SUBSCRIPTION") == 0 ||
3487  strcmp(type, "USER MAPPING") == 0)
3488  {
3489  appendPQExpBuffer(buf, "%s ", type);
3490  if (te->namespace && *te->namespace)
3491  appendPQExpBuffer(buf, "%s.", fmtId(te->namespace));
3492  appendPQExpBufferStr(buf, fmtId(te->tag));
3493  return;
3494  }
3495 
3496  /* BLOBs just have a name, but it's numeric so must not use fmtId */
3497  if (strcmp(type, "BLOB") == 0)
3498  {
3499  appendPQExpBuffer(buf, "LARGE OBJECT %s", te->tag);
3500  return;
3501  }
3502 
3503  /*
3504  * These object types require additional decoration. Fortunately, the
3505  * information needed is exactly what's in the DROP command.
3506  */
3507  if (strcmp(type, "AGGREGATE") == 0 ||
3508  strcmp(type, "FUNCTION") == 0 ||
3509  strcmp(type, "OPERATOR") == 0 ||
3510  strcmp(type, "OPERATOR CLASS") == 0 ||
3511  strcmp(type, "OPERATOR FAMILY") == 0 ||
3512  strcmp(type, "PROCEDURE") == 0)
3513  {
3514  /* Chop "DROP " off the front and make a modifiable copy */
3515  char *first = pg_strdup(te->dropStmt + 5);
3516  char *last;
3517 
3518  /* point to last character in string */
3519  last = first + strlen(first) - 1;
3520 
3521  /* Strip off any ';' or '\n' at the end */
3522  while (last >= first && (*last == '\n' || *last == ';'))
3523  last--;
3524  *(last + 1) = '\0';
3525 
3526  appendPQExpBufferStr(buf, first);
3527 
3528  free(first);
3529  return;
3530  }
3531 
3532  pg_log_warning("don't know how to set owner for object type \"%s\"",
3533  type);
3534 }
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
#define free(a)
Definition: header.h:65
#define pg_log_warning(...)
Definition: pgfnames.c:24

◆ _moveBefore()

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

Definition at line 1812 of file pg_backup_archiver.c.

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

Referenced by SortTocFromFile().

1813 {
1814  /* Unlink te from list */
1815  te->prev->next = te->next;
1816  te->next->prev = te->prev;
1817 
1818  /* and insert it before "pos" */
1819  te->prev = pos->prev;
1820  te->next = pos;
1821  pos->prev->next = te;
1822  pos->prev = te;
1823 }
struct _tocEntry * next
struct _tocEntry * prev

◆ _printTocEntry()

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

Definition at line 3544 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entry().

3545 {
3546  RestoreOptions *ropt = AH->public.ropt;
3547 
3548  /* Select owner, schema, tablespace and default AM as necessary */
3549  _becomeOwner(AH, te);
3550  _selectOutputSchema(AH, te->namespace);
3551  _selectTablespace(AH, te->tablespace);
3553 
3554  /* Emit header comment for item */
3555  if (!AH->noTocComments)
3556  {
3557  const char *pfx;
3558  char *sanitized_name;
3559  char *sanitized_schema;
3560  char *sanitized_owner;
3561 
3562  if (isData)
3563  pfx = "Data for ";
3564  else
3565  pfx = "";
3566 
3567  ahprintf(AH, "--\n");
3568  if (AH->public.verbose)
3569  {
3570  ahprintf(AH, "-- TOC entry %d (class %u OID %u)\n",
3571  te->dumpId, te->catalogId.tableoid, te->catalogId.oid);
3572  if (te->nDeps > 0)
3573  {
3574  int i;
3575 
3576  ahprintf(AH, "-- Dependencies:");
3577  for (i = 0; i < te->nDeps; i++)
3578  ahprintf(AH, " %d", te->dependencies[i]);
3579  ahprintf(AH, "\n");
3580  }
3581  }
3582 
3583  sanitized_name = sanitize_line(te->tag, false);
3584  sanitized_schema = sanitize_line(te->namespace, true);
3585  sanitized_owner = sanitize_line(ropt->noOwner ? NULL : te->owner, true);
3586 
3587  ahprintf(AH, "-- %sName: %s; Type: %s; Schema: %s; Owner: %s",
3588  pfx, sanitized_name, te->desc, sanitized_schema,
3589  sanitized_owner);
3590 
3591  free(sanitized_name);
3592  free(sanitized_schema);
3593  free(sanitized_owner);
3594 
3595  if (te->tablespace && strlen(te->tablespace) > 0 && !ropt->noTablespace)
3596  {
3597  char *sanitized_tablespace;
3598 
3599  sanitized_tablespace = sanitize_line(te->tablespace, false);
3600  ahprintf(AH, "; Tablespace: %s", sanitized_tablespace);
3601  free(sanitized_tablespace);
3602  }
3603  ahprintf(AH, "\n");
3604 
3605  if (AH->PrintExtraTocPtr != NULL)
3606  AH->PrintExtraTocPtr(AH, te);
3607  ahprintf(AH, "--\n\n");
3608  }
3609 
3610  /*
3611  * Actually print the definition.
3612  *
3613  * Really crude hack for suppressing AUTHORIZATION clause that old pg_dump
3614  * versions put into CREATE SCHEMA. We have to do this when --no-owner
3615  * mode is selected. This is ugly, but I see no other good way ...
3616  */
3617  if (ropt->noOwner && strcmp(te->desc, "SCHEMA") == 0)
3618  {
3619  ahprintf(AH, "CREATE SCHEMA %s;\n\n\n", fmtId(te->tag));
3620  }
3621  else
3622  {
3623  if (te->defn && strlen(te->defn) > 0)
3624  ahprintf(AH, "%s\n\n", te->defn);
3625  }
3626 
3627  /*
3628  * If we aren't using SET SESSION AUTH to determine ownership, we must
3629  * instead issue an ALTER OWNER command. We assume that anything without
3630  * a DROP command is not a separately ownable object. All the categories
3631  * with DROP commands must appear in one list or the other.
3632  */
3633  if (!ropt->noOwner && !ropt->use_setsessauth &&
3634  te->owner && strlen(te->owner) > 0 &&
3635  te->dropStmt && strlen(te->dropStmt) > 0)
3636  {
3637  if (strcmp(te->desc, "AGGREGATE") == 0 ||
3638  strcmp(te->desc, "BLOB") == 0 ||
3639  strcmp(te->desc, "COLLATION") == 0 ||
3640  strcmp(te->desc, "CONVERSION") == 0 ||
3641  strcmp(te->desc, "DATABASE") == 0 ||
3642  strcmp(te->desc, "DOMAIN") == 0 ||
3643  strcmp(te->desc, "FUNCTION") == 0 ||
3644  strcmp(te->desc, "OPERATOR") == 0 ||
3645  strcmp(te->desc, "OPERATOR CLASS") == 0 ||
3646  strcmp(te->desc, "OPERATOR FAMILY") == 0 ||
3647  strcmp(te->desc, "PROCEDURE") == 0 ||
3648  strcmp(te->desc, "PROCEDURAL LANGUAGE") == 0 ||
3649  strcmp(te->desc, "SCHEMA") == 0 ||
3650  strcmp(te->desc, "EVENT TRIGGER") == 0 ||
3651  strcmp(te->desc, "TABLE") == 0 ||
3652  strcmp(te->desc, "TYPE") == 0 ||
3653  strcmp(te->desc, "VIEW") == 0 ||
3654  strcmp(te->desc, "MATERIALIZED VIEW") == 0 ||
3655  strcmp(te->desc, "SEQUENCE") == 0 ||
3656  strcmp(te->desc, "FOREIGN TABLE") == 0 ||
3657  strcmp(te->desc, "TEXT SEARCH DICTIONARY") == 0 ||
3658  strcmp(te->desc, "TEXT SEARCH CONFIGURATION") == 0 ||
3659  strcmp(te->desc, "FOREIGN DATA WRAPPER") == 0 ||
3660  strcmp(te->desc, "SERVER") == 0 ||
3661  strcmp(te->desc, "STATISTICS") == 0 ||
3662  strcmp(te->desc, "PUBLICATION") == 0 ||
3663  strcmp(te->desc, "SUBSCRIPTION") == 0)
3664  {
3665  PQExpBuffer temp = createPQExpBuffer();
3666 
3667  appendPQExpBufferStr(temp, "ALTER ");
3668  _getObjectDescription(temp, te, AH);
3669  appendPQExpBuffer(temp, " OWNER TO %s;", fmtId(te->owner));
3670  ahprintf(AH, "%s\n\n", temp->data);
3671  destroyPQExpBuffer(temp);
3672  }
3673  else if (strcmp(te->desc, "CAST") == 0 ||
3674  strcmp(te->desc, "CHECK CONSTRAINT") == 0 ||
3675  strcmp(te->desc, "CONSTRAINT") == 0 ||
3676  strcmp(te->desc, "DATABASE PROPERTIES") == 0 ||
3677  strcmp(te->desc, "DEFAULT") == 0 ||
3678  strcmp(te->desc, "FK CONSTRAINT") == 0 ||
3679  strcmp(te->desc, "INDEX") == 0 ||
3680  strcmp(te->desc, "RULE") == 0 ||
3681  strcmp(te->desc, "TRIGGER") == 0 ||
3682  strcmp(te->desc, "ROW SECURITY") == 0 ||
3683  strcmp(te->desc, "POLICY") == 0 ||
3684  strcmp(te->desc, "USER MAPPING") == 0)
3685  {
3686  /* these object types don't have separate owners */
3687  }
3688  else
3689  {
3690  pg_log_warning("don't know how to set owner for object type \"%s\"",
3691  te->desc);
3692  }
3693  }
3694 
3695  /*
3696  * If it's an ACL entry, it might contain SET SESSION AUTHORIZATION
3697  * commands, so we can no longer assume we know the current auth setting.
3698  */
3699  if (_tocEntryIsACL(te))
3700  {
3701  if (AH->currUser)
3702  free(AH->currUser);
3703  AH->currUser = NULL;
3704  }
3705 }
Oid tableoid
Definition: pg_backup.h:230
RestoreOptions * ropt
Definition: pg_backup.h:183
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
CatalogId catalogId
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
static bool _tocEntryIsACL(TocEntry *te)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
DumpId * dependencies
static void _selectTableAccessMethod(ArchiveHandle *AH, const char *tableam)
static void _becomeOwner(ArchiveHandle *AH, TocEntry *te)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
int use_setsessauth
Definition: pg_backup.h:68
int verbose
Definition: pg_backup.h:185
#define free(a)
Definition: header.h:65
static void _selectOutputSchema(ArchiveHandle *AH, const char *schemaName)
int i
static char * sanitize_line(const char *str, bool want_hyphen)
PrintExtraTocPtrType PrintExtraTocPtr
static void _getObjectDescription(PQExpBuffer buf, TocEntry *te, ArchiveHandle *AH)
#define pg_log_warning(...)
Definition: pgfnames.c:24
static void _selectTablespace(ArchiveHandle *AH, const char *tablespace)

◆ _reconnectToDB()

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

Definition at line 3216 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entry().

3217 {
3218  if (RestoringToDB(AH))
3219  ReconnectToServer(AH, dbname, NULL);
3220  else
3221  {
3222  if (dbname)
3223  {
3224  PQExpBufferData connectbuf;
3225 
3226  initPQExpBuffer(&connectbuf);
3227  appendPsqlMetaConnect(&connectbuf, dbname);
3228  ahprintf(AH, "%s\n", connectbuf.data);
3229  termPQExpBuffer(&connectbuf);
3230  }
3231  else
3232  ahprintf(AH, "%s\n", "\\connect -\n");
3233  }
3234 
3235  /*
3236  * NOTE: currUser keeps track of what the imaginary session user in our
3237  * script is. It's now effectively reset to the original userID.
3238  */
3239  if (AH->currUser)
3240  free(AH->currUser);
3241  AH->currUser = NULL;
3242 
3243  /* don't assume we still know the output schema, tablespace, etc either */
3244  if (AH->currSchema)
3245  free(AH->currSchema);
3246  AH->currSchema = NULL;
3247  if (AH->currTablespace)
3248  free(AH->currTablespace);
3249  AH->currTablespace = NULL;
3250 
3251  /* re-establish fixed state */
3253 }
static int RestoringToDB(ArchiveHandle *AH)
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void ReconnectToServer(ArchiveHandle *AH, const char *dbname, const char *newUser)
Definition: pg_backup_db.c:79
void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
Definition: string_utils.c:590
static void _doSetFixedOutputState(ArchiveHandle *AH)
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define free(a)
Definition: header.h:65
char * dbname
Definition: streamutil.c:50
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ _selectOutputSchema()

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

Definition at line 3301 of file pg_backup_archiver.c.

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

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

3302 {
3303  PQExpBuffer qry;
3304 
3305  /*
3306  * If there was a SEARCHPATH TOC entry, we're supposed to just stay with
3307  * that search_path rather than switching to entry-specific paths.
3308  * Otherwise, it's an old archive that will not restore correctly unless
3309  * we set the search_path as it's expecting.
3310  */
3311  if (AH->public.searchpath)
3312  return;
3313 
3314  if (!schemaName || *schemaName == '\0' ||
3315  (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
3316  return; /* no need to do anything */
3317 
3318  qry = createPQExpBuffer();
3319 
3320  appendPQExpBuffer(qry, "SET search_path = %s",
3321  fmtId(schemaName));
3322  if (strcmp(schemaName, "pg_catalog") != 0)
3323  appendPQExpBufferStr(qry, ", pg_catalog");
3324 
3325  if (RestoringToDB(AH))
3326  {
3327  PGresult *res;
3328 
3329  res = PQexec(AH->connection, qry->data);
3330 
3331  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3333  "could not set search_path to \"%s\": %s",
3334  schemaName, PQerrorMessage(AH->connection));
3335 
3336  PQclear(res);
3337  }
3338  else
3339  ahprintf(AH, "%s;\n\n", qry->data);
3340 
3341  if (AH->currSchema)
3342  free(AH->currSchema);
3343  AH->currSchema = pg_strdup(schemaName);
3344 
3345  destroyPQExpBuffer(qry);
3346 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
void warn_or_exit_horribly(ArchiveHandle *AH, const char *fmt,...)
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
char * searchpath
Definition: pg_backup.h:201
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define free(a)
Definition: header.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939

◆ _selectTableAccessMethod()

static void _selectTableAccessMethod ( ArchiveHandle AH,
const char *  tableam 
)
static

Definition at line 3414 of file pg_backup_archiver.c.

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

Referenced by _printTocEntry().

3415 {
3416  PQExpBuffer cmd;
3417  const char *want,
3418  *have;
3419 
3420  have = AH->currTableAm;
3421  want = tableam;
3422 
3423  if (!want)
3424  return;
3425 
3426  if (have && strcmp(want, have) == 0)
3427  return;
3428 
3429  cmd = createPQExpBuffer();
3430  appendPQExpBuffer(cmd, "SET default_table_access_method = %s;", fmtId(want));
3431 
3432  if (RestoringToDB(AH))
3433  {
3434  PGresult *res;
3435 
3436  res = PQexec(AH->connection, cmd->data);
3437 
3438  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3440  "could not set default_table_access_method: %s",
3441  PQerrorMessage(AH->connection));
3442 
3443  PQclear(res);
3444  }
3445  else
3446  ahprintf(AH, "%s\n\n", cmd->data);
3447 
3448  destroyPQExpBuffer(cmd);
3449 
3450  AH->currTableAm = pg_strdup(want);
3451 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
void warn_or_exit_horribly(ArchiveHandle *AH, const char *fmt,...)
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
void PQclear(PGresult *res)
Definition: fe-exec.c:694
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939

◆ _selectTablespace()

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

Definition at line 3353 of file pg_backup_archiver.c.

References ahprintf(), appendPQExpBuffer(), appendPQExpBufferStr(), _archiveHandle::connection, createPQExpBuffer(), _archiveHandle::currTablespace, PQExpBufferData::data, destroyPQExpBuffer(), fmtId(), free, _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().

3354 {
3355  RestoreOptions *ropt = AH->public.ropt;
3356  PQExpBuffer qry;
3357  const char *want,
3358  *have;
3359 
3360  /* do nothing in --no-tablespaces mode */
3361  if (ropt->noTablespace)
3362  return;
3363 
3364  have = AH->currTablespace;
3365  want = tablespace;
3366 
3367  /* no need to do anything for non-tablespace object */
3368  if (!want)
3369  return;
3370 
3371  if (have && strcmp(want, have) == 0)
3372  return; /* no need to do anything */
3373 
3374  qry = createPQExpBuffer();
3375 
3376  if (strcmp(want, "") == 0)
3377  {
3378  /* We want the tablespace to be the database's default */
3379  appendPQExpBufferStr(qry, "SET default_tablespace = ''");
3380  }
3381  else
3382  {
3383  /* We want an explicit tablespace */
3384  appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
3385  }
3386 
3387  if (RestoringToDB(AH))
3388  {
3389  PGresult *res;
3390 
3391  res = PQexec(AH->connection, qry->data);
3392 
3393  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3395  "could not set default_tablespace to %s: %s",
3396  fmtId(want), PQerrorMessage(AH->connection));
3397 
3398  PQclear(res);
3399  }
3400  else
3401  ahprintf(AH, "%s;\n\n", qry->data);
3402 
3403  if (AH->currTablespace)
3404  free(AH->currTablespace);
3405  AH->currTablespace = pg_strdup(want);
3406 
3407  destroyPQExpBuffer(qry);
3408 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
RestoreOptions * ropt
Definition: pg_backup.h:183
const char * fmtId(const char *rawid)
Definition: string_utils.c:64
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
void warn_or_exit_horribly(ArchiveHandle *AH, const char *fmt,...)
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
char * tablespace
Definition: pgbench.c:188
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
void PQclear(PGresult *res)
Definition: fe-exec.c:694
#define free(a)
Definition: header.h:65
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939

◆ _tocEntryIsACL()

static bool _tocEntryIsACL ( TocEntry te)
static

Definition at line 3103 of file pg_backup_archiver.c.

References _tocEntry::desc.

Referenced by _printTocEntry(), and _tocEntryRequired().

3104 {
3105  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3106  if (strcmp(te->desc, "ACL") == 0 ||
3107  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3108  strcmp(te->desc, "DEFAULT ACL") == 0)
3109  return true;
3110  return false;
3111 }

◆ _tocEntryRequired()

static teReqs _tocEntryRequired ( TocEntry te,
teSection  curSection,
ArchiveHandle AH 
)
static

Definition at line 2827 of file pg_backup_archiver.c.

References _tocEntryIsACL(), _restoreOptions::aclsSkip, _restoreOptions::binary_upgrade, _restoreOptions::createDB, _restoreOptions::dataOnly, _tocEntry::defn, _tocEntry::dependencies, _tocEntry::desc, DUMP_DATA, DUMP_POST_DATA, DUMP_PRE_DATA, _tocEntry::dumpId, _restoreOptions::dumpSections, _restoreOptions::functionNames, _tocEntry::hadDumper, SimpleStringList::head, _restoreOptions::idWanted, _restoreOptions::indexNames, _tocEntry::nDeps, _restoreOptions::no_comments, _restoreOptions::no_publications, _restoreOptions::no_security_labels, _restoreOptions::no_subscriptions, _archiveHandle::public, REQ_DATA, REQ_SCHEMA, REQ_SPECIAL, Archive::ropt, _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, TocIDRequired(), and _restoreOptions::triggerNames.

Referenced by PrintTOCSummary(), and ProcessArchiveRestoreOptions().

2828 {
2829  teReqs res = REQ_SCHEMA | REQ_DATA;
2830  RestoreOptions *ropt = AH->public.ropt;
2831 
2832  /* These items are treated specially */
2833  if (strcmp(te->desc, "ENCODING") == 0 ||
2834  strcmp(te->desc, "STDSTRINGS") == 0 ||
2835  strcmp(te->desc, "SEARCHPATH") == 0)
2836  return REQ_SPECIAL;
2837 
2838  /*
2839  * DATABASE and DATABASE PROPERTIES also have a special rule: they are
2840  * restored in createDB mode, and not restored otherwise, independently of
2841  * all else.
2842  */
2843  if (strcmp(te->desc, "DATABASE") == 0 ||
2844  strcmp(te->desc, "DATABASE PROPERTIES") == 0)
2845  {
2846  if (ropt->createDB)
2847  return REQ_SCHEMA;
2848  else
2849  return 0;
2850  }
2851 
2852  /*
2853  * Process exclusions that affect certain classes of TOC entries.
2854  */
2855 
2856  /* If it's an ACL, maybe ignore it */
2857  if (ropt->aclsSkip && _tocEntryIsACL(te))
2858  return 0;
2859 
2860  /* If it's a comment, maybe ignore it */
2861  if (ropt->no_comments && strcmp(te->desc, "COMMENT") == 0)
2862  return 0;
2863 
2864  /*
2865  * If it's a publication or a table part of a publication, maybe ignore
2866  * it.
2867  */
2868  if (ropt->no_publications &&
2869  (strcmp(te->desc, "PUBLICATION") == 0 ||
2870  strcmp(te->desc, "PUBLICATION TABLE") == 0))
2871  return 0;
2872 
2873  /* If it's a security label, maybe ignore it */
2874  if (ropt->no_security_labels && strcmp(te->desc, "SECURITY LABEL") == 0)
2875  return 0;
2876 
2877  /* If it's a subscription, maybe ignore it */
2878  if (ropt->no_subscriptions && strcmp(te->desc, "SUBSCRIPTION") == 0)
2879  return 0;
2880 
2881  /* Ignore it if section is not to be dumped/restored */
2882  switch (curSection)
2883  {
2884  case SECTION_PRE_DATA:
2885  if (!(ropt->dumpSections & DUMP_PRE_DATA))
2886  return 0;
2887  break;
2888  case SECTION_DATA:
2889  if (!(ropt->dumpSections & DUMP_DATA))
2890  return 0;
2891  break;
2892  case SECTION_POST_DATA:
2893  if (!(ropt->dumpSections & DUMP_POST_DATA))
2894  return 0;
2895  break;
2896  default:
2897  /* shouldn't get here, really, but ignore it */
2898  return 0;
2899  }
2900 
2901  /* Ignore it if rejected by idWanted[] (cf. SortTocFromFile) */
2902  if (ropt->idWanted && !ropt->idWanted[te->dumpId - 1])
2903  return 0;
2904 
2905  /*
2906  * Check options for selective dump/restore.
2907  */
2908  if (strcmp(te->desc, "ACL") == 0 ||
2909  strcmp(te->desc, "COMMENT") == 0 ||
2910  strcmp(te->desc, "SECURITY LABEL") == 0)
2911  {
2912  /* Database properties react to createDB, not selectivity options. */
2913  if (strncmp(te->tag, "DATABASE ", 9) == 0)
2914  {
2915  if (!ropt->createDB)
2916  return 0;
2917  }
2918  else if (ropt->schemaNames.head != NULL ||
2919  ropt->schemaExcludeNames.head != NULL ||
2920  ropt->selTypes)
2921  {
2922  /*
2923  * In a selective dump/restore, we want to restore these dependent
2924  * TOC entry types only if their parent object is being restored.
2925  * Without selectivity options, we let through everything in the
2926  * archive. Note there may be such entries with no parent, eg
2927  * non-default ACLs for built-in objects.
2928  *
2929  * This code depends on the parent having been marked already,
2930  * which should be the case; if it isn't, perhaps due to
2931  * SortTocFromFile rearrangement, skipping the dependent entry
2932  * seems prudent anyway.
2933  *
2934  * Ideally we'd handle, eg, table CHECK constraints this way too.
2935  * But it's hard to tell which of their dependencies is the one to
2936  * consult.
2937  */
2938  if (te->nDeps != 1 ||
2939  TocIDRequired(AH, te->dependencies[0]) == 0)
2940  return 0;
2941  }
2942  }
2943  else
2944  {
2945  /* Apply selective-restore rules for standalone TOC entries. */
2946  if (ropt->schemaNames.head != NULL)
2947  {
2948  /* If no namespace is specified, it means all. */
2949  if (!te->namespace)
2950  return 0;
2951  if (!simple_string_list_member(&ropt->schemaNames, te->namespace))
2952  return 0;
2953  }
2954 
2955  if (ropt->schemaExcludeNames.head != NULL &&
2956  te->namespace &&
2957  simple_string_list_member(&ropt->schemaExcludeNames, te->namespace))
2958  return 0;
2959 
2960  if (ropt->selTypes)
2961  {
2962  if (strcmp(te->desc, "TABLE") == 0 ||
2963  strcmp(te->desc, "TABLE DATA") == 0 ||
2964  strcmp(te->desc, "VIEW") == 0 ||
2965  strcmp(te->desc, "FOREIGN TABLE") == 0 ||
2966  strcmp(te->desc, "MATERIALIZED VIEW") == 0 ||
2967  strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0 ||
2968  strcmp(te->desc, "SEQUENCE") == 0 ||
2969  strcmp(te->desc, "SEQUENCE SET") == 0)
2970  {
2971  if (!ropt->selTable)
2972  return 0;
2973  if (ropt->tableNames.head != NULL &&
2975  return 0;
2976  }
2977  else if (strcmp(te->desc, "INDEX") == 0)
2978  {
2979  if (!ropt->selIndex)
2980  return 0;
2981  if (ropt->indexNames.head != NULL &&
2983  return 0;
2984  }
2985  else if (strcmp(te->desc, "FUNCTION") == 0 ||
2986  strcmp(te->desc, "AGGREGATE") == 0 ||
2987  strcmp(te->desc, "PROCEDURE") == 0)
2988  {
2989  if (!ropt->selFunction)
2990  return 0;
2991  if (ropt->functionNames.head != NULL &&
2993  return 0;
2994  }
2995  else if (strcmp(te->desc, "TRIGGER") == 0)
2996  {
2997  if (!ropt->selTrigger)
2998  return 0;
2999  if (ropt->triggerNames.head != NULL &&
3001  return 0;
3002  }
3003  else
3004  return 0;
3005  }
3006  }
3007 
3008  /*
3009  * Determine whether the TOC entry contains schema and/or data components,
3010  * and mask off inapplicable REQ bits. If it had a dataDumper, assume
3011  * it's both schema and data. Otherwise it's probably schema-only, but
3012  * there are exceptions.
3013  */
3014  if (!te->hadDumper)
3015  {
3016  /*
3017  * Special Case: If 'SEQUENCE SET' or anything to do with BLOBs, then
3018  * it is considered a data entry. We don't need to check for the
3019  * BLOBS entry or old-style BLOB COMMENTS, because they will have
3020  * hadDumper = true ... but we do need to check new-style BLOB ACLs,
3021  * comments, etc.
3022  */
3023  if (strcmp(te->desc, "SEQUENCE SET") == 0 ||
3024  strcmp(te->desc, "BLOB") == 0 ||
3025  (strcmp(te->desc, "ACL") == 0 &&
3026  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
3027  (strcmp(te->desc, "COMMENT") == 0 &&
3028  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
3029  (strcmp(te->desc, "SECURITY LABEL") == 0 &&
3030  strncmp(te->tag, "LARGE OBJECT ", 13) == 0))
3031  res = res & REQ_DATA;
3032  else
3033  res = res & ~REQ_DATA;
3034  }
3035 
3036  /* If there's no definition command, there's no schema component */
3037  if (!te->defn || !te->defn[0])
3038  res = res & ~REQ_SCHEMA;
3039 
3040  /*
3041  * Special case: <Init> type with <Max OID> tag; this is obsolete and we
3042  * always ignore it.
3043  */
3044  if ((strcmp(te->desc, "<Init>") == 0) && (strcmp(te->tag, "Max OID") == 0))
3045  return 0;
3046 
3047  /* Mask it if we only want schema */
3048  if (ropt->schemaOnly)
3049  {
3050  /*
3051  * The sequence_data option overrides schemaOnly for SEQUENCE SET.
3052  *
3053  * In binary-upgrade mode, even with schemaOnly set, we do not mask
3054  * out large objects. (Only large object definitions, comments and
3055  * other metadata should be generated in binary-upgrade mode, not the
3056  * actual data, but that need not concern us here.)
3057  */
3058  if (!(ropt->sequence_data && strcmp(te->desc, "SEQUENCE SET") == 0) &&
3059  !(ropt->binary_upgrade &&
3060  (strcmp(te->desc, "BLOB") == 0 ||
3061  (strcmp(te->desc, "ACL") == 0 &&
3062  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
3063  (strcmp(te->desc, "COMMENT") == 0 &&
3064  strncmp(te->tag, "LARGE OBJECT ", 13) == 0) ||
3065  (strcmp(te->desc, "SECURITY LABEL") == 0 &&
3066  strncmp(te->tag, "LARGE OBJECT ", 13) == 0))))
3067  res = res & REQ_SCHEMA;
3068  }
3069 
3070  /* Mask it if we only want data */
3071  if (ropt->dataOnly)
3072  res = res & REQ_DATA;
3073 
3074  return res;
3075 }
bool simple_string_list_member(SimpleStringList *list, const char *val)
Definition: simple_list.c:87
SimpleStringList triggerNames
Definition: pg_backup.h:106
RestoreOptions * ropt
Definition: pg_backup.h:183
SimpleStringList schemaNames
Definition: pg_backup.h:104
static bool _tocEntryIsACL(TocEntry *te)
bool * idWanted
Definition: pg_backup.h:122
SimpleStringList tableNames
Definition: pg_backup.h:107
DumpId * dependencies
SimpleStringList functionNames
Definition: pg_backup.h:103
int no_security_labels
Definition: pg_backup.h:79
int no_subscriptions
Definition: pg_backup.h:80
teReqs TocIDRequired(ArchiveHandle *AH, DumpId id)
SimpleStringListCell * head
Definition: simple_list.h:42
SimpleStringList indexNames
Definition: pg_backup.h:102
int no_publications
Definition: pg_backup.h:78
SimpleStringList schemaExcludeNames
Definition: pg_backup.h:105

◆ _tocEntryRestorePass()

static RestorePass _tocEntryRestorePass ( TocEntry te)
static

Definition at line 3083 of file pg_backup_archiver.c.

References _tocEntry::desc, RESTORE_PASS_ACL, and RESTORE_PASS_MAIN.

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

3084 {
3085  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3086  if (strcmp(te->desc, "ACL") == 0 ||
3087  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3088  strcmp(te->desc, "DEFAULT ACL") == 0)
3089  return RESTORE_PASS_ACL;
3090  if (strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0)
3091  return RESTORE_PASS_REFRESH;
3092  return RESTORE_PASS_MAIN;
3093 }

◆ ahprintf()

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

Definition at line 1606 of file pg_backup_archiver.c.

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

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

1607 {
1608  int save_errno = errno;
1609  char *p;
1610  size_t len = 128; /* initial assumption about buffer size */
1611  size_t cnt;
1612 
1613  for (;;)
1614  {
1615  va_list args;
1616 
1617  /* Allocate work buffer. */
1618  p = (char *) pg_malloc(len);
1619 
1620  /* Try to format the data. */
1621  errno = save_errno;
1622  va_start(args, fmt);
1623  cnt = pvsnprintf(p, len, fmt, args);
1624  va_end(args);
1625 
1626  if (cnt < len)
1627  break; /* success */
1628 
1629  /* Release buffer and loop around to try again with larger len. */
1630  free(p);
1631  len = cnt;
1632  }
1633 
1634  ahwrite(p, 1, cnt, AH);
1635  free(p);
1636  return (int) cnt;
1637 }
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:106
#define free(a)
Definition: header.h:65
void ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)

◆ ahwrite()

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

Definition at line 1696 of file pg_backup_archiver.c.

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

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

1697 {
1698  int bytes_written = 0;
1699 
1700  if (AH->writingBlob)
1701  {
1702  size_t remaining = size * nmemb;
1703 
1704  while (AH->lo_buf_used + remaining > AH->lo_buf_size)
1705  {
1706  size_t avail = AH->lo_buf_size - AH->lo_buf_used;
1707 
1708  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, avail);
1709  ptr = (const void *) ((const char *) ptr + avail);
1710  remaining -= avail;
1711  AH->lo_buf_used += avail;
1712  dump_lo_buf(AH);
1713  }
1714 
1715  memcpy((char *) AH->lo_buf + AH->lo_buf_used, ptr, remaining);
1716  AH->lo_buf_used += remaining;
1717 
1718  bytes_written = size * nmemb;
1719  }
1720  else if (AH->gzOut)
1721  bytes_written = GZWRITE(ptr, size, nmemb, AH->OF);
1722  else if (AH->CustomOutPtr)
1723  bytes_written = AH->CustomOutPtr(AH, ptr, size * nmemb);
1724 
1725  else
1726  {
1727  /*
1728  * If we're doing a restore, and it's direct to DB, and we're
1729  * connected then send it to the DB.
1730  */
1731  if (RestoringToDB(AH))
1732  bytes_written = ExecuteSqlCommandBuf(&AH->public, (const char *) ptr, size * nmemb);
1733  else
1734  bytes_written = fwrite(ptr, size, nmemb, AH->OF) * size;
1735  }
1736 
1737  if (bytes_written != size * nmemb)
1739 
1740  return;
1741 }
int remaining
Definition: informix.c:687
static int RestoringToDB(ArchiveHandle *AH)
int ExecuteSqlCommandBuf(Archive *AHX, const char *buf, size_t bufLen)
Definition: pg_backup_db.c:556
static void dump_lo_buf(ArchiveHandle *AH)
#define GZWRITE(p, s, n, fh)
CustomOutPtrType CustomOutPtr
#define WRITE_ERROR_EXIT

◆ ArchiveEntry()

TocEntry* ArchiveEntry ( Archive AHX,
CatalogId  catalogId,
DumpId  dumpId,
ArchiveOpts opts 
)

Definition at line 1063 of file pg_backup_archiver.c.

References _archiveHandle::ArchiveEntryPtr, _tocEntry::catalogId, _tocEntry::copyStmt, _tocEntry::dataDumper, _tocEntry::dataDumperArg, _tocEntry::dataLength, _tocEntry::defn, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dropStmt, _tocEntry::dumpId, _tocEntry::formatData, _tocEntry::hadDumper, _archiveHandle::maxDumpId, _tocEntry::nDeps, _tocEntry::next, _tocEntry::owner, pg_malloc(), pg_malloc0(), pg_strdup(), _tocEntry::prev, _tocEntry::section, _tocEntry::tableam, _tocEntry::tablespace, _tocEntry::tag, _archiveHandle::toc, _archiveHandle::tocCount, and true.

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

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

◆ archprintf()

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

Definition at line 1469 of file pg_backup_archiver.c.

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

1470 {
1471  int save_errno = errno;
1472  char *p;
1473  size_t len = 128; /* initial assumption about buffer size */
1474  size_t cnt;
1475 
1476  for (;;)
1477  {
1478  va_list args;
1479 
1480  /* Allocate work buffer. */
1481  p = (char *) pg_malloc(len);
1482 
1483  /* Try to format the data. */
1484  errno = save_errno;
1485  va_start(args, fmt);
1486  cnt = pvsnprintf(p, len, fmt, args);
1487  va_end(args);
1488 
1489  if (cnt < len)
1490  break; /* success */
1491 
1492  /* Release buffer and loop around to try again with larger len. */
1493  free(p);
1494  len = cnt;
1495  }
1496 
1497  WriteData(AH, p, cnt);
1498  free(p);
1499  return (int) cnt;
1500 }
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:106
void WriteData(Archive *AHX, const void *data, size_t dLen)
#define free(a)
Definition: header.h:65

◆ archputs()

void archputs ( const char *  s,
Archive AH 
)

Definition at line 1461 of file pg_backup_archiver.c.

References WriteData().

Referenced by dumpTableData_insert().

1462 {
1463  WriteData(AH, s, strlen(s));
1464  return;
1465 }
void WriteData(Archive *AHX, const void *data, size_t dLen)

◆ buildTocEntryArrays()

static void buildTocEntryArrays ( ArchiveHandle AH)
static

Definition at line 1837 of file pg_backup_archiver.c.

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

Referenced by getTocEntryByDumpId(), and RestoreArchive().

1838 {
1839  DumpId maxDumpId = AH->maxDumpId;
1840  TocEntry *te;
1841 
1842  AH->tocsByDumpId = (TocEntry **) pg_malloc0((maxDumpId + 1) * sizeof(TocEntry *));
1843  AH->tableDataId = (DumpId *) pg_malloc0((maxDumpId + 1) * sizeof(DumpId));
1844 
1845  for (te = AH->toc->next; te != AH->toc; te = te->next)
1846  {
1847  /* this check is purely paranoia, maxDumpId should be correct */
1848  if (te->dumpId <= 0 || te->dumpId > maxDumpId)
1849  fatal("bad dumpId");
1850 
1851  /* tocsByDumpId indexes all TOCs by their dump ID */
1852  AH->tocsByDumpId[te->dumpId] = te;
1853 
1854  /*
1855  * tableDataId provides the TABLE DATA item's dump ID for each TABLE
1856  * TOC entry that has a DATA item. We compute this by reversing the
1857  * TABLE DATA item's dependency, knowing that a TABLE DATA item has
1858  * just one dependency and it is the TABLE item.
1859  */
1860  if (strcmp(te->desc, "TABLE DATA") == 0 && te->nDeps > 0)
1861  {
1862  DumpId tableId = te->dependencies[0];
1863 
1864  /*
1865  * The TABLE item might not have been in the archive, if this was
1866  * a data-only dump; but its dump ID should be less than its data
1867  * item's dump ID, so there should be a place for it in the array.
1868  */
1869  if (tableId <= 0 || tableId > maxDumpId)
1870  fatal("bad table dumpId for TABLE DATA item");
1871 
1872  AH->tableDataId[tableId] = te->dumpId;
1873  }
1874  }
1875 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:234
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
struct _tocEntry * toc
DumpId * dependencies
#define fatal(...)
struct _tocEntry ** tocsByDumpId

◆ checkSeek()

bool checkSeek ( FILE *  fp)

Definition at line 3876 of file pg_backup_archiver.c.

References fseeko, ftello, and pgoff_t.

Referenced by InitArchiveFmt_Custom(), and InitArchiveFmt_Tar().

3877 {
3878  pgoff_t tpos;
3879 
3880  /*
3881  * If pgoff_t is wider than long, we must have "real" fseeko and not an
3882  * emulation using fseek. Otherwise report no seek capability.
3883  */
3884 #ifndef HAVE_FSEEKO
3885  if (sizeof(pgoff_t) > sizeof(long))
3886  return false;
3887 #endif
3888 
3889  /* Check that ftello works on this file */
3890  tpos = ftello(fp);
3891  if (tpos < 0)
3892  return false;
3893 
3894  /*
3895  * Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
3896  * this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
3897  * successful no-op even on files that are otherwise unseekable.
3898  */
3899  if (fseeko(fp, tpos, SEEK_SET) != 0)
3900  return false;
3901 
3902  return true;
3903 }
#define pgoff_t
Definition: win32_port.h:195
#define ftello(stream)
Definition: win32_port.h:204
#define fseeko(stream, offset, origin)
Definition: win32_port.h:201

◆ CloneArchive()

ArchiveHandle* CloneArchive ( ArchiveHandle AH)

Definition at line 4811 of file pg_backup_archiver.c.

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

Referenced by RunWorker().

4812 {
4813  ArchiveHandle *clone;
4814 
4815  /* Make a "flat" copy */
4816  clone = (ArchiveHandle *) pg_malloc(sizeof(ArchiveHandle));
4817  memcpy(clone, AH, sizeof(ArchiveHandle));
4818 
4819  /* Handle format-independent fields */
4820  memset(&(clone->sqlparse), 0, sizeof(clone->sqlparse));
4821 
4822  /* The clone will have its own connection, so disregard connection state */
4823  clone->connection = NULL;
4824  clone->connCancel = NULL;
4825  clone->currUser = NULL;
4826  clone->currSchema = NULL;
4827  clone->currTablespace = NULL;
4828 
4829  /* savedPassword must be local in case we change it while connecting */
4830  if (clone->savedPassword)
4831  clone->savedPassword = pg_strdup(clone->savedPassword);
4832 
4833  /* clone has its own error count, too */
4834  clone->public.n_errors = 0;
4835 
4836  /*
4837  * Connect our new clone object to the database: In parallel restore the
4838  * parent is already disconnected, because we can connect the worker
4839  * processes independently to the database (no snapshot sync required). In
4840  * parallel backup we clone the parent's existing connection.
4841  */
4842  if (AH->mode == archModeRead)
4843  {
4844  RestoreOptions *ropt = AH->public.ropt;
4845 
4846  Assert(AH->connection == NULL);
4847 
4848  /* this also sets clone->connection */
4849  ConnectDatabase((Archive *) clone, ropt->dbname,
4850  ropt->pghost, ropt->pgport, ropt->username,
4851  ropt->promptPassword);
4852 
4853  /* re-establish fixed state */
4854  _doSetFixedOutputState(clone);
4855  }
4856  else
4857  {
4859  char *pghost;
4860  char *pgport;
4861  char *username;
4862 
4863  Assert(AH->connection != NULL);
4864 
4865  /*
4866  * Even though we are technically accessing the parent's database
4867  * object here, these functions are fine to be called like that
4868  * because all just return a pointer and do not actually send/receive
4869  * any data to/from the database.
4870  */
4871  initPQExpBuffer(&connstr);
4872  appendPQExpBufferStr(&connstr, "dbname=");
4873  appendConnStrVal(&connstr, PQdb(AH->connection));
4874  pghost = PQhost(AH->connection);
4875  pgport = PQport(AH->connection);
4876  username = PQuser(AH->connection);
4877 
4878  /* this also sets clone->connection */
4879  ConnectDatabase((Archive *) clone, connstr.data,
4880  pghost, pgport, username, TRI_NO);
4881 
4882  termPQExpBuffer(&connstr);
4883  /* setupDumpWorker will fix up connection state */
4884  }
4885 
4886  /* Let the format-specific code have a chance too */
4887  clone->ClonePtr(clone);
4888 
4889  Assert(clone->connection != NULL);
4890  return clone;
4891 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
RestoreOptions * ropt
Definition: pg_backup.h:183
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
char * username
Definition: pg_backup.h:113
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:545
char * PQport(const PGconn *conn)
Definition: fe-connect.c:6536
int n_errors
Definition: pg_backup.h:206
PGcancel *volatile connCancel
char * PQuser(const PGconn *conn)
Definition: fe-connect.c:6475
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void _doSetFixedOutputState(ArchiveHandle *AH)
sqlparseInfo sqlparse
char * pghost
Definition: pgbench.c:242
static char * username
Definition: initdb.c:133
char * PQhost(const PGconn *conn)
Definition: fe-connect.c:6500
char * PQdb(const PGconn *conn)
Definition: fe-connect.c:6467
#define Assert(condition)
Definition: c.h:733
ClonePtrType ClonePtr
char * pgport
Definition: pgbench.c:243
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
void ConnectDatabase(Archive *AH, const char *dbname, const char *pghost, const char *pgport, const char *username, trivalue prompt_password)
Definition: pg_backup_db.c:236
static char * connstr
Definition: pg_dumpall.c:61
trivalue promptPassword
Definition: pg_backup.h:115

◆ CloseArchive()

void CloseArchive ( Archive AHX)

Definition at line 257 of file pg_backup_archiver.c.

References _archiveHandle::ClosePtr, fatal, GZCLOSE, _archiveHandle::gzOut, _archiveHandle::OF, and generate_unaccent_rules::stdout.

Referenced by main().

258 {
259  int res = 0;
260  ArchiveHandle *AH = (ArchiveHandle *) AHX;
261 
262  AH->ClosePtr(AH);
263 
264  /* Close the output */
265  if (AH->gzOut)
266  res = GZCLOSE(AH->OF);
267  else if (AH->OF != stdout)
268  res = fclose(AH->OF);
269 
270  if (res != 0)
271  fatal("could not close output file: %m");
272 }
#define fatal(...)
#define GZCLOSE(fh)
ClosePtrType ClosePtr

◆ CreateArchive()

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

Definition at line 234 of file pg_backup_archiver.c.

References _allocAH().

Referenced by main().

238 {
239  ArchiveHandle *AH = _allocAH(FileSpec, fmt, compression, dosync,
241 
242  return (Archive *) AH;
243 }
static PgChecksumMode mode
Definition: pg_checksums.c:61
static ArchiveHandle * _allocAH(const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupWorkerPtr)
static bool dosync
Definition: pg_dump.c:92
static void setupDumpWorker(Archive *AHX)
Definition: pg_dump.c:1226

◆ DeCloneArchive()

void DeCloneArchive ( ArchiveHandle AH)

Definition at line 4899 of file pg_backup_archiver.c.

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

Referenced by RunWorker().

4900 {
4901  /* Should not have an open database connection */
4902  Assert(AH->connection == NULL);
4903 
4904  /* Clear format-specific state */
4905  AH->DeClonePtr(AH);
4906 
4907  /* Clear state allocated by CloneArchive */
4908  if (AH->sqlparse.curCmd)
4910 
4911  /* Clear any connection-local state */
4912  if (AH->currUser)
4913  free(AH->currUser);
4914  if (AH->currSchema)
4915  free(AH->currSchema);
4916  if (AH->currTablespace)
4917  free(AH->currTablespace);
4918  if (AH->currTableAm)
4919  free(AH->currTableAm);
4920  if (AH->savedPassword)
4921  free(AH->savedPassword);
4922 
4923  free(AH);
4924 }
PQExpBuffer curCmd
DeClonePtrType DeClonePtr
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
sqlparseInfo sqlparse
#define free(a)
Definition: header.h:65
#define Assert(condition)
Definition: c.h:733

◆ dump_lo_buf()

static void dump_lo_buf ( ArchiveHandle AH)
static

Definition at line 1654 of file pg_backup_archiver.c.

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

Referenced by ahwrite(), and EndRestoreBlob().

1655 {
1656  if (AH->connection)
1657  {
1658  size_t res;
1659 
1660  res = lo_write(AH->connection, AH->loFd, AH->lo_buf, AH->lo_buf_used);
1661  pg_log_debug(ngettext("wrote %lu byte of large object data (result = %lu)",
1662  "wrote %lu bytes of large object data (result = %lu)",
1663  AH->lo_buf_used),
1664  (unsigned long) AH->lo_buf_used, (unsigned long) res);
1665  if (res != AH->lo_buf_used)
1666  fatal("could not write to large object (result: %lu, expected: %lu)",
1667  (unsigned long) res, (unsigned long) AH->lo_buf_used);
1668  }
1669  else
1670  {
1672 
1674  (const unsigned char *) AH->lo_buf,
1675  AH->lo_buf_used,
1676  AH);
1677 
1678  /* Hack: turn off writingBlob so ahwrite doesn't recurse to here */
1679  AH->writingBlob = 0;
1680  ahprintf(AH, "SELECT pg_catalog.lowrite(0, %s);\n", buf->data);
1681  AH->writingBlob = 1;
1682 
1683  destroyPQExpBuffer(buf);
1684  }
1685  AH->lo_buf_used = 0;
1686 }
#define appendByteaLiteralAHX(buf, str, len, AH)
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
#define pg_log_debug(...)
Definition: logging.h:91
static char * buf
Definition: pg_test_fsync.c:67
int lo_write(int fd, const char *buf, int len)
Definition: be-fsstubs.c:170
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define ngettext(s, p, n)
Definition: c.h:1128
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
#define fatal(...)

◆ dumpOptionsFromRestoreOptions()

DumpOptions* dumpOptionsFromRestoreOptions ( RestoreOptions ropt)

Definition at line 176 of file pg_backup_archiver.c.

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

Referenced by SetArchiveOptions().

177 {
178  DumpOptions *dopt = NewDumpOptions();
179 
180  /* this is the inverse of what's at the end of pg_dump.c's main() */
181  dopt->outputClean = ropt->dropSchema;
182  dopt->dataOnly = ropt->dataOnly;
183  dopt->schemaOnly = ropt->schemaOnly;
184  dopt->if_exists = ropt->if_exists;
185  dopt->column_inserts = ropt->column_inserts;
186  dopt->dumpSections = ropt->dumpSections;
187  dopt->aclsSkip = ropt->aclsSkip;
188  dopt->outputSuperuser = ropt->superuser;
189  dopt->outputCreateDB = ropt->createDB;
190  dopt->outputNoOwner = ropt->noOwner;
191  dopt->outputNoTablespaces = ropt->noTablespace;
192  dopt->disable_triggers = ropt->disable_triggers;
193  dopt->use_setsessauth = ropt->use_setsessauth;
195  dopt->dump_inserts = ropt->dump_inserts;
196  dopt->no_comments = ropt->no_comments;
197  dopt->no_publications = ropt->no_publications;
199  dopt->no_subscriptions = ropt->no_subscriptions;
200  dopt->lockWaitTimeout = ropt->lockWaitTimeout;
203  dopt->sequence_data = ropt->sequence_data;
204 
205  return dopt;
206 }
int column_inserts
Definition: pg_backup.h:147
int disable_triggers
Definition: pg_backup.h:156
int disable_dollar_quoting
Definition: pg_backup.h:73
bool schemaOnly
Definition: pg_backup.h:138
int no_subscriptions
Definition: pg_backup.h:152
int no_publications
Definition: pg_backup.h:151
DumpOptions * NewDumpOptions(void)
int sequence_data
Definition: pg_backup.h:172
const char * lockWaitTimeout
Definition: pg_backup.h:89
int use_setsessauth
Definition: pg_backup.h:158
int disable_dollar_quoting
Definition: pg_backup.h:146
int column_inserts
Definition: pg_backup.h:75
const char * lockWaitTimeout
Definition: pg_backup.h:142
bool dataOnly
Definition: pg_backup.h:139
bool include_everything
Definition: pg_backup.h:163
char * outputSuperuser
Definition: pg_backup.h:170
int include_everything
Definition: pg_backup.h:90
int no_security_labels
Definition: pg_backup.h:79
int dumpSections
Definition: pg_backup.h:140
int enable_row_security
Definition: pg_backup.h:123
int dump_inserts
Definition: pg_backup.h:143
int outputNoOwner
Definition: pg_backup.h:169
int no_security_labels
Definition: pg_backup.h:150
int no_subscriptions
Definition: pg_backup.h:80
char * superuser
Definition: pg_backup.h:70
bool aclsSkip
Definition: pg_backup.h:141
int use_setsessauth
Definition: pg_backup.h:68
int enable_row_security
Definition: pg_backup.h:159
int outputCreateDB
Definition: pg_backup.h:166
int outputClean
Definition: pg_backup.h:165
int no_comments
Definition: pg_backup.h:149
int outputNoTablespaces
Definition: pg_backup.h:157
int no_publications
Definition: pg_backup.h:78
int disable_triggers
Definition: pg_backup.h:66

◆ dumpTimestamp()

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

Definition at line 3910 of file pg_backup_archiver.c.

References ahprintf(), buf, and PGDUMP_STRFTIME_FMT.

Referenced by RestoreArchive().

3911 {
3912  char buf[64];
3913 
3914  if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&tim)) != 0)
3915  ahprintf(AH, "-- %s %s\n\n", msg, buf);
3916 }
static char * buf
Definition: pg_test_fsync.c:67
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define PGDUMP_STRFTIME_FMT
Definition: dumputils.h:33

◆ EndBlob()

int EndBlob ( Archive AHX,
Oid  oid 
)

Definition at line 1239 of file pg_backup_archiver.c.

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

Referenced by dumpBlobs().

1240 {
1241  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1242 
1243  if (AH->EndBlobPtr)
1244  AH->EndBlobPtr(AH, AH->currToc, oid);
1245 
1246  return 1;
1247 }
struct _tocEntry * currToc
EndBlobPtrType EndBlobPtr

◆ EndRestoreBlob()

void EndRestoreBlob ( ArchiveHandle AH,
Oid  oid 
)

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

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

◆ EndRestoreBlobs()

void EndRestoreBlobs ( ArchiveHandle AH)

Definition at line 1276 of file pg_backup_archiver.c.

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

Referenced by _LoadBlobs().

1277 {
1278  RestoreOptions *ropt = AH->public.ropt;
1279 
1280  if (!ropt->single_txn)
1281  {
1282  if (AH->connection)
1283  CommitTransaction(&AH->public);
1284  else
1285  ahprintf(AH, "COMMIT;\n\n");
1286  }
1287 
1288  pg_log_info(ngettext("restored %d large object",
1289  "restored %d large objects",
1290  AH->blobCount),
1291  AH->blobCount);
1292 }
RestoreOptions * ropt
Definition: pg_backup.h:183
int ahprintf(ArchiveHandle *AH, const char *fmt,...)
#define ngettext(s, p, n)
Definition: c.h:1128
static void CommitTransaction(void)
Definition: xact.c:2045
#define pg_log_info(...)
Definition: logging.h:87

◆ fix_dependencies()

static void fix_dependencies ( ArchiveHandle AH)
static

Definition at line 4508 of file pg_backup_archiver.c.

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

Referenced by IndexSetParentIndex(), and restore_toc_entries_prefork().

4509 {
4510  TocEntry *te;
4511  int i;
4512 
4513  /*
4514  * Initialize the depCount/revDeps/nRevDeps fields, and make sure the TOC
4515  * items are marked as not being in any parallel-processing list.
4516  */
4517  for (te = AH->toc->next; te != AH->toc; te = te->next)
4518  {
4519  te->depCount = te->nDeps;
4520  te->revDeps = NULL;
4521  te->nRevDeps = 0;
4522  te->pending_prev = NULL;
4523  te->pending_next = NULL;
4524  }
4525 
4526  /*
4527  * POST_DATA items that are shown as depending on a table need to be
4528  * re-pointed to depend on that table's data, instead. This ensures they
4529  * won't get scheduled until the data has been loaded.
4530  */
4532 
4533  /*
4534  * Pre-8.4 versions of pg_dump neglected to set up a dependency from BLOB
4535  * COMMENTS to BLOBS. Cope. (We assume there's only one BLOBS and only
4536  * one BLOB COMMENTS in such files.)
4537  */
4538  if (AH->version < K_VERS_1_11)
4539  {
4540  for (te = AH->toc->next; te != AH->toc; te = te->next)
4541  {
4542  if (strcmp(te->desc, "BLOB COMMENTS") == 0 && te->nDeps == 0)
4543  {
4544  TocEntry *te2;
4545 
4546  for (te2 = AH->toc->next; te2 != AH->toc; te2 = te2->next)
4547  {
4548  if (strcmp(te2->desc, "BLOBS") == 0)
4549  {
4550  te->dependencies = (DumpId *) pg_malloc(sizeof(DumpId));
4551  te->dependencies[0] = te2->dumpId;
4552  te->nDeps++;
4553  te->depCount++;
4554  break;
4555  }
4556  }
4557  break;
4558  }
4559  }
4560  }
4561 
4562  /*
4563  * At this point we start to build the revDeps reverse-dependency arrays,
4564  * so all changes of dependencies must be complete.
4565  */
4566 
4567  /*
4568  * Count the incoming dependencies for each item. Also, it is possible
4569  * that the dependencies list items that are not in the archive at all
4570  * (that should not happen in 9.2 and later, but is highly likely in older
4571  * archives). Subtract such items from the depCounts.
4572  */
4573  for (te = AH->toc->next; te != AH->toc; te = te->next)
4574  {
4575  for (i = 0; i < te->nDeps; i++)
4576  {
4577  DumpId depid = te->dependencies[i];
4578 
4579  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4580  AH->tocsByDumpId[depid]->nRevDeps++;
4581  else
4582  te->depCount--;
4583  }
4584  }
4585 
4586  /*
4587  * Allocate space for revDeps[] arrays, and reset nRevDeps so we can use
4588  * it as a counter below.
4589  */
4590  for (te = AH->toc->next; te != AH->toc; te = te->next)
4591  {
4592  if (te->nRevDeps > 0)
4593  te->revDeps = (DumpId *) pg_malloc(te->nRevDeps * sizeof(DumpId));
4594  te->nRevDeps = 0;
4595  }
4596 
4597  /*
4598  * Build the revDeps[] arrays of incoming-dependency dumpIds. This had
4599  * better agree with the loops above.
4600  */
4601  for (te = AH->toc->next; te != AH->toc; te = te->next)
4602  {
4603  for (i = 0; i < te->nDeps; i++)
4604  {
4605  DumpId depid = te->dependencies[i];
4606 
4607  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL)
4608  {
4609  TocEntry *otherte = AH->tocsByDumpId[depid];
4610 
4611  otherte->revDeps[otherte->nRevDeps++] = te->dumpId;
4612  }
4613  }
4614  }
4615 
4616  /*
4617  * Lastly, work out the locking dependencies.
4618  */
4619  for (te = AH->toc->next; te != AH->toc; te = te->next)
4620  {
4621  te->lockDeps = NULL;
4622  te->nLockDeps = 0;
4624  }
4625 }
struct _tocEntry * next
int DumpId
Definition: pg_backup.h:234
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
struct _tocEntry * pending_prev
DumpId * lockDeps
struct _tocEntry * pending_next
struct _tocEntry * toc
DumpId * dependencies
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)

◆ getTocEntryByDumpId()

TocEntry* getTocEntryByDumpId ( ArchiveHandle AH,
DumpId  id 
)

Definition at line 1878 of file pg_backup_archiver.c.

References buildTocEntryArrays(), and _archiveHandle::tocsByDumpId.

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

1879 {
1880  /* build index arrays if we didn't already */
1881  if (AH->tocsByDumpId == NULL)
1882  buildTocEntryArrays(AH);
1883 
1884  if (id > 0 && id <= AH->maxDumpId)
1885  return AH->tocsByDumpId[id];
1886 
1887  return NULL;
1888 }
static void buildTocEntryArrays(ArchiveHandle *AH)
struct _tocEntry ** tocsByDumpId

◆ has_lock_conflicts()

static bool has_lock_conflicts ( TocEntry te1,
TocEntry te2 
)
static

Definition at line 4199 of file pg_backup_archiver.c.

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

Referenced by pop_next_work_item().

4200 {
4201  int j,
4202  k;
4203 
4204  for (j = 0; j < te1->nLockDeps; j++)
4205  {
4206  for (k = 0; k < te2->nDeps; k++)
4207  {
4208  if (te1->lockDeps[j] == te2->dependencies[k])
4209  return true;
4210  }
4211  }
4212  return false;
4213 }
DumpId * lockDeps
DumpId * dependencies

◆ identify_locking_dependencies()

static void identify_locking_dependencies ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4672 of file pg_backup_archiver.c.

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

Referenced by fix_dependencies().

4673 {
4674  DumpId *lockids;
4675  int nlockids;
4676  int i;
4677 
4678  /*
4679  * We only care about this for POST_DATA items. PRE_DATA items are not
4680  * run in parallel, and DATA items are all independent by assumption.
4681  */
4682  if (te->section != SECTION_POST_DATA)
4683  return;
4684 
4685  /* Quick exit if no dependencies at all */
4686  if (te->nDeps == 0)
4687  return;
4688 
4689  /*
4690  * Most POST_DATA items are ALTER TABLEs or some moral equivalent of that,
4691  * and hence require exclusive lock. However, we know that CREATE INDEX
4692  * does not. (Maybe someday index-creating CONSTRAINTs will fall in that
4693  * category too ... but today is not that day.)
4694  */
4695  if (strcmp(te->desc, "INDEX") == 0)
4696  return;
4697 
4698  /*
4699  * We assume the entry requires exclusive lock on each TABLE or TABLE DATA
4700  * item listed among its dependencies. Originally all of these would have
4701  * been TABLE items, but repoint_table_dependencies would have repointed
4702  * them to the TABLE DATA items if those are present (which they might not
4703  * be, eg in a schema-only dump). Note that all of the entries we are
4704  * processing here are POST_DATA; otherwise there might be a significant
4705  * difference between a dependency on a table and a dependency on its
4706  * data, so that closer analysis would be needed here.
4707  */
4708  lockids = (DumpId *) pg_malloc(te->nDeps * sizeof(DumpId));
4709  nlockids = 0;
4710  for (i = 0; i < te->nDeps; i++)
4711  {
4712  DumpId depid = te->dependencies[i];
4713 
4714  if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL &&
4715  ((strcmp(AH->tocsByDumpId[depid]->desc, "TABLE DATA") == 0) ||
4716  strcmp(AH->tocsByDumpId[depid]->desc, "TABLE") == 0))
4717  lockids[nlockids++] = depid;
4718  }
4719 
4720  if (nlockids == 0)
4721  {
4722  free(lockids);
4723  return;
4724  }
4725 
4726  te->lockDeps = pg_realloc(lockids, nlockids * sizeof(DumpId));
4727  te->nLockDeps = nlockids;
4728 }
int DumpId
Definition: pg_backup.h:234
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
DumpId * lockDeps
teSection section
DumpId * dependencies
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
#define free(a)
Definition: header.h:65
struct _tocEntry ** tocsByDumpId
int i

◆ inhibit_data_for_failed_table()

static void inhibit_data_for_failed_table ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 4791 of file pg_backup_archiver.c.

References _tocEntry::dumpId, pg_log_info, _tocEntry::reqs, _archiveHandle::tableDataId, _tocEntry::tag, and _archiveHandle::tocsByDumpId.

Referenced by mark_restore_job_done(), and restore_toc_entry().

4792 {
4793  pg_log_info("table \"%s\" could not be created, will not restore its data",
4794  te->tag);
4795 
4796  if (AH->tableDataId[te->dumpId] != 0)
4797  {
4798  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4799 
4800  ted->reqs = 0;
4801  }
4802 }
struct _tocEntry ** tocsByDumpId
#define pg_log_info(...)
Definition: logging.h:87

◆ InitDumpOptions()

void InitDumpOptions ( DumpOptions opts)

Definition at line 163 of file pg_backup_archiver.c.

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

Referenced by main(), and NewDumpOptions().

164 {
165  memset(opts, 0, sizeof(DumpOptions));
166  /* set any fields that shouldn't default to zeroes */
167  opts->include_everything = true;
169 }
bool include_everything
Definition: pg_backup.h:163
int dumpSections
Definition: pg_backup.h:140

◆ mark_create_done()

static void mark_create_done ( ArchiveHandle AH,
TocEntry te 
)
static

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

4777 {
4778  if (AH->tableDataId[te->dumpId] != 0)
4779  {
4780  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4781 
4782  ted->created = true;
4783  }
4784 }
struct _tocEntry ** tocsByDumpId

◆ mark_dump_job_done()

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

Definition at line 2461 of file pg_backup_archiver.c.

References _tocEntry::desc, _tocEntry::dumpId, fatal, pg_log_info, and _tocEntry::tag.

Referenced by WriteDataChunks().

2465 {
2466  pg_log_info("finished item %d %s %s",
2467  te->dumpId, te->desc, te->tag);
2468 
2469  if (status != 0)
2470  fatal("worker process failed: exit code %d",
2471  status);
2472 }
#define fatal(...)
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:226
#define pg_log_info(...)
Definition: logging.h:87

◆ mark_restore_job_done()

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

Definition at line 4467 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entries_parallel().

4471 {
4472  ParallelReadyList *ready_list = (ParallelReadyList *) callback_data;
4473 
4474  pg_log_info("finished item %d %s %s",
4475  te->dumpId, te->desc, te->tag);
4476 
4477  if (status == WORKER_CREATE_DONE)
4478  mark_create_done(AH, te);
4479  else if (status == WORKER_INHIBIT_DATA)
4480  {
4482  AH->public.n_errors++;
4483  }
4484  else if (status == WORKER_IGNORED_ERRORS)
4485  AH->public.n_errors++;
4486  else if (status != 0)
4487  fatal("worker process failed: exit code %d",
4488  status);
4489 
4490  reduce_dependencies(AH, te, ready_list);
4491 }
#define WORKER_CREATE_DONE
int n_errors
Definition: pg_backup.h:206
#define WORKER_IGNORED_ERRORS
static void reduce_dependencies(ArchiveHandle *AH, TocEntry *te, ParallelReadyList *ready_list)
static void inhibit_data_for_failed_table(ArchiveHandle *AH, TocEntry *te)
#define WORKER_INHIBIT_DATA
static void mark_create_done(ArchiveHandle *AH, TocEntry *te)
#define fatal(...)
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:226
#define pg_log_info(...)
Definition: logging.h:87

◆ move_to_ready_list()

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

Definition at line 4352 of file pg_backup_archiver.c.

References _tocEntryRestorePass(), _tocEntry::depCount, pending_list_remove(), _tocEntry::pending_next, and ready_list_insert().

Referenced by restore_toc_entries_parallel().

4355 {
4356  TocEntry *te;
4357  TocEntry *next_te;
4358 
4359  for (te = pending_list->pending_next; te != pending_list; te = next_te)
4360  {
4361  /* must save list link before possibly removing te from list */
4362  next_te = te->pending_next;
4363 
4364  if (te->depCount == 0 &&
4365  _tocEntryRestorePass(te) == pass)
4366  {
4367  /* Remove it from pending_list ... */
4368  pending_list_remove(te);
4369  /* ... and add to ready_list */
4370  ready_list_insert(ready_list, te);
4371  }
4372  }
4373 }
struct _tocEntry * pending_next
static RestorePass _tocEntryRestorePass(TocEntry *te)
static void pending_list_remove(TocEntry *te)
static void ready_list_insert(ParallelReadyList *ready_list, TocEntry *te)

◆ NewDumpOptions()

DumpOptions* NewDumpOptions ( void  )

Definition at line 151 of file pg_backup_archiver.c.

References InitDumpOptions(), and pg_malloc().

Referenced by dumpOptionsFromRestoreOptions().

152 {
153  DumpOptions *opts = (DumpOptions *) pg_malloc(sizeof(DumpOptions));
154 
155  InitDumpOptions(opts);
156  return opts;
157 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
void InitDumpOptions(DumpOptions *opts)

◆ NewRestoreOptions()

RestoreOptions* NewRestoreOptions ( void  )

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

969 {
970  RestoreOptions *opts;
971 
972  opts = (RestoreOptions *) pg_malloc0(sizeof(RestoreOptions));
973 
974  /* set any fields that shouldn't default to zeroes */
975  opts->format = archUnknown;
976  opts->promptPassword = TRI_DEFAULT;
978 
979  return opts;
980 }
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
trivalue promptPassword
Definition: pg_backup.h:115

◆ OpenArchive()

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

Definition at line 248 of file pg_backup_archiver.c.

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

Referenced by main().

249 {
250  ArchiveHandle *AH = _allocAH(FileSpec, fmt, 0, true, archModeRead, setupRestoreWorker);
251 
252  return (Archive *) AH;
253 }
static ArchiveHandle * _allocAH(const char *FileSpec, const ArchiveFormat fmt, const int compression, bool dosync, ArchiveMode mode, SetupWorkerPtrType setupWorkerPtr)
static void setupRestoreWorker(Archive *AHX)

◆ parallel_restore()

int parallel_restore ( ArchiveHandle AH,
TocEntry te 
)

Definition at line 4444 of file pg_backup_archiver.c.

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

Referenced by _WorkerJobRestoreCustom(), and _WorkerJobRestoreDirectory().

4445 {
4446  int status;
4447 
4448  Assert(AH->connection != NULL);
4449 
4450  /* Count only errors associated with this TOC entry */
4451  AH->public.n_errors = 0;
4452 
4453  /* Restore the TOC item */
4454  status = restore_toc_entry(AH, te, true);
4455 
4456  return status;
4457 }
int n_errors
Definition: pg_backup.h:206
static int restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
#define Assert(condition)
Definition: c.h:733
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:226

◆ pending_list_append()

static void pending_list_append ( TocEntry l,
TocEntry te 
)
static

Definition at line 4231 of file pg_backup_archiver.c.

References _tocEntry::pending_next, and _tocEntry::pending_prev.

Referenced by restore_toc_entries_prefork().

4232 {
4233  te->pending_prev = l->pending_prev;
4234  l->pending_prev->pending_next = te;
4235  l->pending_prev = te;
4236  te->pending_next = l;
4237 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pending_list_header_init()

static void pending_list_header_init ( TocEntry l)
static

Definition at line 4224 of file pg_backup_archiver.c.

References _tocEntry::pending_next, and _tocEntry::pending_prev.

Referenced by RestoreArchive().

4225 {
4226  l->pending_prev = l->pending_next = l;
4227 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pending_list_remove()

static void pending_list_remove ( TocEntry te)
static

Definition at line 4241 of file pg_backup_archiver.c.

References _tocEntry::pending_next, and _tocEntry::pending_prev.

Referenced by move_to_ready_list(), and reduce_dependencies().

4242 {
4245  te->pending_prev = NULL;
4246  te->pending_next = NULL;
4247 }
struct _tocEntry * pending_prev
struct _tocEntry * pending_next

◆ pop_next_work_item()

static TocEntry * pop_next_work_item ( ArchiveHandle AH,
ParallelReadyList ready_list,
ParallelState pstate 
)
static

Definition at line 4387 of file pg_backup_archiver.c.

References _parallelReadyList::first_te, has_lock_conflicts(), i, ParallelState::numWorkers, pg_log_debug, ready_list_remove(), ready_list_sort(), ParallelState::te, and _parallelReadyList::tes.

Referenced by restore_toc_entries_parallel().

4389 {
4390  /*
4391  * Sort the ready_list so that we'll tackle larger jobs first.
4392  */
4393  ready_list_sort(ready_list);
4394 
4395  /*
4396  * Search the ready_list until we find a suitable item.
4397  */
4398  for (int i = ready_list->first_te; i <= ready_list->last_te; i++)
4399  {
4400  TocEntry *te = ready_list->tes[i];
4401  bool conflicts = false;
4402 
4403  /*
4404  * Check to see if the item would need exclusive lock on something
4405  * that a currently running item also needs lock on, or vice versa. If
4406  * so, we don't want to schedule them together.
4407  */
4408  for (int k = 0; k < pstate->numWorkers; k++)
4409  {
4410  TocEntry *running_te = pstate->te[k];
4411 
4412  if (running_te == NULL)
4413  continue;
4414  if (has_lock_conflicts(te, running_te) ||
4415  has_lock_conflicts(running_te, te))
4416  {
4417  conflicts = true;
4418  break;
4419  }
4420  }
4421 
4422  if (conflicts)
4423  continue;
4424 
4425  /* passed all tests, so this item can run */
4426  ready_list_remove(ready_list, i);
4427  return te;
4428  }
4429 
4430  pg_log_debug("no item ready");
4431  return NULL;
4432 }
static void ready_list_remove(ParallelReadyList *ready_list, int i)
static void ready_list_sort(ParallelReadyList *ready_list)
#define pg_log_debug(...)
Definition: logging.h:91
TocEntry ** te
Definition: parallel.h:44
int i
static bool has_lock_conflicts(TocEntry *te1, TocEntry *te2)
int numWorkers
Definition: parallel.h:42

◆ PrintTOCSummary()

void PrintTOCSummary ( Archive AHX)

Definition at line 1121 of file pg_backup_archiver.c.

References _tocEntryRequired(), ahprintf(), archCustom, _archiveHandle::archdbname, archDirectory, ARCHIVE_MAJOR, ARCHIVE_MINOR, ARCHIVE_REV, _archiveHandle::archiveDumpVersion, _archiveHandle::archiveRemoteVersion, archTar, _tocEntry::catalogId, _archiveHandle::compression, _archiveHandle::createDate, _tocEntry::dependencies, _tocEntry::desc, _tocEntry::dumpId, _restoreOptions::filename, _archiveHandle::format, free, i, _archiveHandle::intSize, _tocEntry::nDeps, _tocEntry::next, _archiveHandle::offSize, CatalogId::oid, _tocEntry::owner, PGDUMP_STRFTIME_FMT, _archiveHandle::public, REQ_DATA, REQ_SCHEMA, RestoreOutput(), Archive::ropt, sanitize_line(), 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().

1122 {
1123  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1124  RestoreOptions *ropt = AH->public.ropt;
1125  TocEntry *te;
1126  teSection curSection;
1127  OutputContext sav;
1128  const char *fmtName;
1129  char stamp_str[64];
1130 
1131  sav = SaveOutput(AH);
1132  if (ropt->filename)
1133  SetOutput(AH, ropt->filename, 0 /* no compression */ );
1134 
1135  if (strftime(stamp_str, sizeof(stamp_str), PGDUMP_STRFTIME_FMT,
1136  localtime(&AH->createDate)) == 0)
1137  strcpy(stamp_str, "[unknown]");
1138 
1139  ahprintf(AH, ";\n; Archive created at %s\n", stamp_str);
1140  ahprintf(AH, "; dbname: %s\n; TOC Entries: %d\n; Compression: %d\n",
1141  sanitize_line(AH->archdbname, false),
1142  AH->tocCount, AH->compression);
1143 
1144  switch (AH->format)
1145  {
1146  case archCustom:
1147  fmtName = "CUSTOM";
1148  break;
1149  case archDirectory:
1150  fmtName = "DIRECTORY";
1151  break;
1152  case archTar:
1153  fmtName = "TAR";
1154  break;
1155  default:
1156  fmtName = "UNKNOWN";
1157  }
1158 
1159  ahprintf(AH, "; Dump Version: %d.%d-%d\n",
1161  ahprintf(AH, "; Format: %s\n", fmtName);
1162  ahprintf(AH, "; Integer: %d bytes\n", (int) AH->intSize);
1163  ahprintf(AH, "; Offset: %d bytes\n", (int) AH->offSize);
1164  if (AH->archiveRemoteVersion)
1165  ahprintf(AH, "; Dumped from database version: %s\n",
1166  AH->archiveRemoteVersion);
1167  if (AH->archiveDumpVersion)
1168  ahprintf(AH, "; Dumped by pg_dump version: %s\n",
1169  AH->archiveDumpVersion);
1170 
1171  ahprintf(AH, ";\n;\n; Selected TOC Entries:\n;\n");
1172 
1173  curSection = SECTION_PRE_DATA;
1174  for (te = AH->toc->next; te != AH->toc; te = te->next)
1175  {
1176  if (te->section != SECTION_NONE)
1177  curSection = te->section;
1178  if (ropt->verbose ||
1179  (_tocEntryRequired(te, curSection, AH) & (REQ_SCHEMA | REQ_DATA)) != 0)
1180  {
1181  char *sanitized_name;
1182  char *sanitized_schema;
1183  char *sanitized_owner;
1184 
1185  /*
1186  */
1187  sanitized_name = sanitize_line(te->tag, false);
1188  sanitized_schema = sanitize_line(te->namespace, true);
1189  sanitized_owner = sanitize_line(te->owner, false);
1190 
1191  ahprintf(AH, "%d; %u %u %s %s %s %s\n", te->dumpId,
1192  te->catalogId.tableoid, te->catalogId.oid,
1193  te->desc, sanitized_schema, sanitized_name,
1194  sanitized_owner);
1195 
1196  free(sanitized_name);
1197  free(sanitized_schema);
1198  free(sanitized_owner);
1199  }
1200  if (ropt->verbose && te->nDeps > 0)
1201  {
1202  int i;
1203 
1204  ahprintf(AH, ";\tdepends on:");
1205  for (i = 0; i < te->nDeps; i++)
1206  ahprintf(AH, " %d", te->dependencies[i]);
1207  ahprintf(AH, "\n");
1208  }
1209  }
1210 
1211  /* Enforce strict names checking */
1212  if (ropt->strict_names)
1213  StrictNamesCheck(ropt);
1214 
1215  if (ropt->filename)
1216  RestoreOutput(AH, sav);
1217 }
struct _tocEntry * next
Oid tableoid
Definition: pg_backup.h:230
RestoreOptions * ropt
Definition: pg_backup.h:183
CatalogId catalogId
static void SetOutput(ArchiveHandle *AH, const char *filename, int compression)
teSection section
const char * filename
Definition: pg_backup.h:83
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)
#define free(a)
Definition: header.h:65
enum _teSection teSection
#define PGDUMP_STRFTIME_FMT
Definition: dumputils.h:33
static void RestoreOutput(ArchiveHandle *AH, OutputContext savedContext)
int i
static char * sanitize_line(const char *str, bool want_hyphen)
static teReqs _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH)

◆ ProcessArchiveRestoreOptions()

void ProcessArchiveRestoreOptions ( Archive AHX)

Definition at line 289 of file pg_backup_archiver.c.

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

Referenced by main().

290 {
291  ArchiveHandle *AH = (ArchiveHandle *) AHX;
292  RestoreOptions *ropt = AH->public.ropt;
293  TocEntry *te;
294  teSection curSection;
295 
296  /* Decide which TOC entries will be dumped/restored, and mark them */
297  curSection = SECTION_PRE_DATA;
298  for (te = AH->toc->next; te != AH->toc; te = te->next)
299  {
300  /*
301  * When writing an archive, we also take this opportunity to check
302  * that we have generated the entries in a sane order that respects
303  * the section divisions. When reading, don't complain, since buggy
304  * old versions of pg_dump might generate out-of-order archives.
305  */
306  if (AH->mode != archModeRead)
307  {
308  switch (te->section)
309  {
310  case SECTION_NONE:
311  /* ok to be anywhere */
312  break;
313  case SECTION_PRE_DATA:
314  if (curSection != SECTION_PRE_DATA)
315  pg_log_warning("archive items not in correct section order");
316  break;
317  case SECTION_DATA:
318  if (curSection == SECTION_POST_DATA)
319  pg_log_warning("archive items not in correct section order");
320  break;
321  case SECTION_POST_DATA:
322  /* ok no matter which section we were in */
323  break;
324  default:
325  fatal("unexpected section code %d",
326  (int) te->section);
327  break;
328  }
329  }
330 
331  if (te->section != SECTION_NONE)
332  curSection = te->section;
333 
334  te->reqs = _tocEntryRequired(te, curSection, AH);
335  }
336 
337  /* Enforce strict names checking */
338  if (ropt->strict_names)
339  StrictNamesCheck(ropt);
340 }
struct _tocEntry * next
RestoreOptions * ropt
Definition: pg_backup.h:183
teSection section
struct _tocEntry * toc
static void StrictNamesCheck(RestoreOptions *ropt)
enum _teSection teSection
#define fatal(...)
static teReqs _tocEntryRequired(TocEntry *te, teSection curSection, ArchiveHandle *AH)
#define pg_log_warning(...)
Definition: pgfnames.c:24

◆ processEncodingEntry()

static void processEncodingEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2723 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

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

◆ processSearchPathEntry()

static void processSearchPathEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2767 of file pg_backup_archiver.c.

References _tocEntry::defn, pg_strdup(), _archiveHandle::public, and Archive::searchpath.

Referenced by ReadToc().

2768 {
2769  /*
2770  * te->defn should contain a command to set search_path. We just copy it
2771  * verbatim for use later.
2772  */
2773  AH->public.searchpath = pg_strdup(te->defn);
2774 }
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
char * searchpath
Definition: pg_backup.h:201

◆ processStdStringsEntry()

static void processStdStringsEntry ( ArchiveHandle AH,
TocEntry te 
)
static

Definition at line 2751 of file pg_backup_archiver.c.

References _tocEntry::defn, fatal, _archiveHandle::public, and Archive::std_strings.

Referenced by ReadToc().

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

◆ ReadHead()

void ReadHead ( ArchiveHandle AH)

Definition at line 3773 of file pg_backup_archiver.c.

References _archiveHandle::archdbname, _archiveHandle::archiveDumpVersion, _archiveHandle::archiveRemoteVersion, _archiveHandle::compression, _archiveHandle::createDate, fatal, _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, _archiveHandle::offSize, pg_log_warning, _archiveHandle::ReadBufPtr, _archiveHandle::ReadBytePtr, _archiveHandle::readHeader, ReadInt(), ReadStr(), tm, _archiveHandle::version, and Z_DEFAULT_COMPRESSION.

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

3774 {
3775  char tmpMag[7];
3776  int fmt;
3777  struct tm crtm;
3778 
3779  /*
3780  * If we haven't already read the header, do so.
3781  *
3782  * NB: this code must agree with _discoverArchiveFormat(). Maybe find a
3783  * way to unify the cases?
3784  */
3785  if (!AH->readHeader)
3786  {
3787  char vmaj,
3788  vmin,
3789  vrev;
3790 
3791  AH->ReadBufPtr(AH, tmpMag, 5);
3792 
3793  if (strncmp(tmpMag, "PGDMP", 5) != 0)
3794  fatal("did not find magic string in file header");
3795 
3796  vmaj = AH->ReadBytePtr(AH);
3797  vmin = AH->ReadBytePtr(AH);
3798 
3799  if (vmaj > 1 || (vmaj == 1 && vmin > 0)) /* Version > 1.0 */
3800  vrev = AH->ReadBytePtr(AH);
3801  else
3802  vrev = 0;
3803 
3804  AH->version = MAKE_ARCHIVE_VERSION(vmaj, vmin, vrev);
3805 
3806  if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
3807  fatal("unsupported version (%d.%d) in file header",
3808  vmaj, vmin);
3809 
3810  AH->intSize = AH->ReadBytePtr(AH);
3811  if (AH->intSize > 32)
3812  fatal("sanity check on integer size (%lu) failed",
3813  (unsigned long) AH->intSize);
3814 
3815  if (AH->intSize > sizeof(int))
3816  pg_log_warning("archive was made on a machine with larger integers, some operations might fail");
3817 
3818  if (AH->version >= K_VERS_1_7)
3819  AH->offSize = AH->ReadBytePtr(AH);
3820  else
3821  AH->offSize = AH->intSize;
3822 
3823  fmt = AH->ReadBytePtr(AH);
3824 
3825  if (AH->format != fmt)
3826  fatal("expected format (%d) differs from format found in file (%d)",
3827  AH->format, fmt);
3828  }
3829 
3830  if (AH->version >= K_VERS_1_2)
3831  {
3832  if (AH->version < K_VERS_1_4)
3833  AH->compression = AH->ReadBytePtr(AH);
3834  else
3835  AH->compression = ReadInt(AH);
3836  }
3837  else
3839 
3840 #ifndef HAVE_LIBZ
3841  if (AH->compression != 0)
3842  pg_log_warning("archive is compressed, but this installation does not support compression -- no data will be available");
3843 #endif
3844 
3845  if (AH->version >= K_VERS_1_4)
3846  {
3847  crtm.tm_sec = ReadInt(AH);
3848  crtm.tm_min = ReadInt(AH);
3849  crtm.tm_hour = ReadInt(AH);
3850  crtm.tm_mday = ReadInt(AH);
3851  crtm.tm_mon = ReadInt(AH);
3852  crtm.tm_year = ReadInt(AH);
3853  crtm.tm_isdst = ReadInt(AH);
3854 
3855  AH->archdbname = ReadStr(AH);
3856 
3857  AH->createDate = mktime(&crtm);
3858 
3859  if (AH->createDate == (time_t) -1)
3860  pg_log_warning("invalid creation date in header");
3861  }
3862 
3863  if (AH->version >= K_VERS_1_10)
3864  {
3865  AH->archiveRemoteVersion = ReadStr(AH);
3866  AH->archiveDumpVersion = ReadStr(AH);
3867  }
3868 }
ReadBufPtrType ReadBufPtr
#define Z_DEFAULT_COMPRESSION
#define K_VERS_1_0
int ReadInt(ArchiveHandle *AH)
#define K_VERS_1_4
ReadBytePtrType ReadBytePtr
static struct pg_tm tm
Definition: localtime.c:108
#define K_VERS_1_7
#define MAKE_ARCHIVE_VERSION(major, minor, rev)
#define K_VERS_1_2
#define K_VERS_1_10
ArchiveFormat format
#define K_VERS_MAX
char * ReadStr(ArchiveHandle *AH)
#define fatal(...)
#define pg_log_warning(...)
Definition: pgfnames.c:24

◆ ReadInt()

int ReadInt ( ArchiveHandle AH)

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

2015 {
2016  int res = 0;
2017  int bv,
2018  b;
2019  int sign = 0; /* Default positive */
2020  int bitShift = 0;
2021 
2022  if (AH->version > K_VERS_1_0)
2023  /* Read a sign byte */
2024  sign = AH->ReadBytePtr(AH);
2025 
2026  for (b = 0; b < AH->intSize; b++)
2027  {
2028  bv = AH->ReadBytePtr(AH) & 0xFF;
2029  if (bv != 0)
2030  res = res + (bv << bitShift);
2031  bitShift += 8;
2032  }
2033 
2034  if (sign)
2035  res = -res;
2036 
2037  return res;
2038 }
#define K_VERS_1_0
ReadBytePtrType ReadBytePtr
char sign
Definition: informix.c:688

◆ ReadOffset()

int ReadOffset ( ArchiveHandle AH,
pgoff_t o 
)

Definition at line 1919 of file pg_backup_archiver.c.

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

Referenced by _ReadExtraToc().

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

◆ ReadStr()

char* ReadStr ( ArchiveHandle AH)

Definition at line 2060 of file pg_backup_archiver.c.

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

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

2061 {
2062  char *buf;
2063  int l;
2064 
2065  l = ReadInt(AH);
2066  if (l < 0)
2067  buf = NULL;
2068  else
2069  {
2070  buf = (char *) pg_malloc(l + 1);
2071  AH->ReadBufPtr(AH, (void *) buf, l);
2072 
2073  buf[l] = '\0';
2074  }
2075 
2076  return buf;
2077 }
ReadBufPtrType ReadBufPtr
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
int ReadInt(ArchiveHandle *AH)
static char * buf
Definition: pg_test_fsync.c:67

◆ ReadToc()

void ReadToc ( ArchiveHandle AH)

Definition at line 2568 of file pg_backup_archiver.c.

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

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

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

◆ ready_list_free()

static void ready_list_free ( ParallelReadyList ready_list)
static

Definition at line 4267 of file pg_backup_archiver.c.

References pg_free(), and _parallelReadyList::tes.

Referenced by restore_toc_entries_parallel().

4268 {
4269  pg_free(ready_list->tes);
4270 }
void pg_free(void *ptr)
Definition: fe_memutils.c:105

◆ ready_list_init()

static void ready_list_init ( ParallelReadyList ready_list,
int  tocCount 
)
static

Definition at line 4254 of file pg_backup_archiver.c.

References _parallelReadyList::first_te, _parallelReadyList::last_te, pg_malloc(), _parallelReadyList::sorted, and _parallelReadyList::tes.

Referenced by restore_toc_entries_parallel().

4255 {
4256  ready_list->tes = (TocEntry **)
4257  pg_malloc(tocCount * sizeof(TocEntry *));
4258  ready_list->first_te = 0;
4259  ready_list->last_te = -1;
4260  ready_list->sorted = false;
4261 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47

◆ ready_list_insert()

static void ready_list_insert ( ParallelReadyList ready_list,
TocEntry te 
)
static

Definition at line 4274 of file pg_backup_archiver.c.

References _parallelReadyList::last_te, _parallelReadyList::sorted, and _parallelReadyList::tes.

Referenced by move_to_ready_list(), and reduce_dependencies().

4275 {
4276  ready_list->tes[++ready_list->last_te] = te;
4277  /* List is (probably) not sorted anymore. */
4278  ready_list->sorted = false;
4279 }

◆ ready_list_remove()

static void ready_list_remove ( ParallelReadyList ready_list,
int  i 
)
static

Definition at line 4283 of file pg_backup_archiver.c.

References Assert, _parallelReadyList::first_te, memmove, and _parallelReadyList::tes.

Referenced by pop_next_work_item().

4284 {
4285  int f = ready_list->first_te;
4286 
4287  Assert(i >= f && i <= ready_list->last_te);
4288 
4289  /*
4290  * In the typical case where the item to be removed is the first ready
4291  * entry, we need only increment first_te to remove it. Otherwise, move
4292  * the entries before it to compact the list. (This preserves sortedness,
4293  * if any.) We could alternatively move the entries after i, but there
4294  * are typically many more of those.
4295  */
4296  if (i > f)
4297  {
4298  TocEntry **first_te_ptr = &ready_list->tes[f];
4299 
4300  memmove(first_te_ptr + 1, first_te_ptr, (i - f) * sizeof(TocEntry *));
4301  }
4302  ready_list->first_te++;
4303 }
#define memmove(d, s, c)
Definition: c.h:1261
#define Assert(condition)
Definition: c.h:733
int i

◆ ready_list_sort()

static void ready_list_sort ( ParallelReadyList ready_list)
static

Definition at line 4307 of file pg_backup_archiver.c.

References _parallelReadyList::first_te, _parallelReadyList::last_te, qsort, _parallelReadyList::sorted, _parallelReadyList::tes, and TocEntrySizeCompare().

Referenced by pop_next_work_item().

4308 {
4309  if (!ready_list->sorted)
4310  {
4311  int n = ready_list->last_te - ready_list->first_te + 1;
4312 
4313  if (n > 1)
4314  qsort(ready_list->tes + ready_list->first_te, n,
4315  sizeof(TocEntry *),
4317  ready_list->sorted = true;
4318  }
4319 }
static int TocEntrySizeCompare(const void *p1, const void *p2)
#define qsort(a, b, c, d)
Definition: port.h:492

◆ reduce_dependencies()