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

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

3294 {
3295  RestoreOptions *ropt = AH->public.ropt;
3296 
3297  if (ropt && (ropt->noOwner || !ropt->use_setsessauth))
3298  return;
3299 
3300  _becomeUser(AH, te->owner);
3301 }
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 3269 of file pg_backup_archiver.c.

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

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

3270 {
3271  if (!user)
3272  user = ""; /* avoid null pointers */
3273 
3274  if (AH->currUser && strcmp(AH->currUser, user) == 0)
3275  return; /* no need to do anything */
3276 
3277  _doSetSessionAuth(AH, user);
3278 
3279  /*
3280  * NOTE: currUser keeps track of what the imaginary session user in our
3281  * script is
3282  */
3283  if (AH->currUser)
3284  free(AH->currUser);
3285  AH->currUser = pg_strdup(user);
3286 }
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:93

◆ _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 2075 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().

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

◆ _doSetFixedOutputState()

static void _doSetFixedOutputState ( ArchiveHandle AH)
static

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

3127 {
3128  RestoreOptions *ropt = AH->public.ropt;
3129 
3130  /*
3131  * Disable timeouts to allow for slow commands, idle parallel workers, etc
3132  */
3133  ahprintf(AH, "SET statement_timeout = 0;\n");
3134  ahprintf(AH, "SET lock_timeout = 0;\n");
3135  ahprintf(AH, "SET idle_in_transaction_session_timeout = 0;\n");
3136 
3137  /* Select the correct character set encoding */
3138  ahprintf(AH, "SET client_encoding = '%s';\n",
3140 
3141  /* Select the correct string literal syntax */
3142  ahprintf(AH, "SET standard_conforming_strings = %s;\n",
3143  AH->public.std_strings ? "on" : "off");
3144 
3145  /* Select the role to be used during restore */
3146  if (ropt && ropt->use_role)
3147  ahprintf(AH, "SET ROLE %s;\n", fmtId(ropt->use_role));
3148 
3149  /* Select the dump-time search_path */
3150  if (AH->public.searchpath)
3151  ahprintf(AH, "%s", AH->public.searchpath);
3152 
3153  /* Make sure function checking is disabled */
3154  ahprintf(AH, "SET check_function_bodies = false;\n");
3155 
3156  /* Ensure that all valid XML data will be accepted */
3157  ahprintf(AH, "SET xmloption = content;\n");
3158 
3159  /* Avoid annoying notices etc */
3160  ahprintf(AH, "SET client_min_messages = warning;\n");
3161  if (!AH->public.std_strings)
3162  ahprintf(AH, "SET escape_string_warning = off;\n");
3163 
3164  /* Adjust row-security state */
3165  if (ropt && ropt->enable_row_security)
3166  ahprintf(AH, "SET row_security = on;\n");
3167  else
3168  ahprintf(AH, "SET row_security = off;\n");
3169 
3170  ahprintf(AH, "\n");
3171 }
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:588
bool std_strings
Definition: pg_backup.h:198

◆ _doSetSessionAuth()

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

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

3180 {
3182 
3183  appendPQExpBufferStr(cmd, "SET SESSION AUTHORIZATION ");
3184 
3185  /*
3186  * SQL requires a string literal here. Might as well be correct.
3187  */
3188  if (user && *user)
3189  appendStringLiteralAHX(cmd, user, AH);
3190  else
3191  appendPQExpBufferStr(cmd, "DEFAULT");
3192  appendPQExpBufferChar(cmd, ';');
3193 
3194  if (RestoringToDB(AH))
3195  {
3196  PGresult *res;
3197 
3198  res = PQexec(AH->connection, cmd->data);
3199 
3200  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3201  /* NOT warn_or_exit_horribly... use -O instead to skip this. */
3202  fatal("could not set session user to \"%s\": %s",
3204 
3205  PQclear(res);
3206  }
3207  else
3208  ahprintf(AH, "%s\n\n", cmd->data);
3209 
3210  destroyPQExpBuffer(cmd);
3211 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
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:93
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 3467 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().

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

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

Referenced by SortTocFromFile().

1808 {
1809  /* Unlink te from list */
1810  te->prev->next = te->next;
1811  te->next->prev = te->prev;
1812 
1813  /* and insert it before "pos" */
1814  te->prev = pos->prev;
1815  te->next = pos;
1816  pos->prev->next = te;
1817  pos->prev = te;
1818 }
struct _tocEntry * next
struct _tocEntry * prev

◆ _printTocEntry()

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

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

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

3225 {
3226  if (RestoringToDB(AH))
3227  ReconnectToServer(AH, dbname, NULL);
3228  else
3229  {
3230  if (dbname)
3231  {
3232  PQExpBufferData connectbuf;
3233 
3234  initPQExpBuffer(&connectbuf);
3235  appendPsqlMetaConnect(&connectbuf, dbname);
3236  ahprintf(AH, "%s\n", connectbuf.data);
3237  termPQExpBuffer(&connectbuf);
3238  }
3239  else
3240  ahprintf(AH, "%s\n", "\\connect -\n");
3241  }
3242 
3243  /*
3244  * NOTE: currUser keeps track of what the imaginary session user in our
3245  * script is. It's now effectively reset to the original userID.
3246  */
3247  if (AH->currUser)
3248  free(AH->currUser);
3249  AH->currUser = NULL;
3250 
3251  /* don't assume we still know the output schema, tablespace, etc either */
3252  if (AH->currSchema)
3253  free(AH->currSchema);
3254  AH->currSchema = NULL;
3255  if (AH->currTablespace)
3256  free(AH->currTablespace);
3257  AH->currTablespace = NULL;
3258 
3259  /* re-establish fixed state */
3261 }
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 3309 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().

3310 {
3311  PQExpBuffer qry;
3312 
3313  /*
3314  * If there was a SEARCHPATH TOC entry, we're supposed to just stay with
3315  * that search_path rather than switching to entry-specific paths.
3316  * Otherwise, it's an old archive that will not restore correctly unless
3317  * we set the search_path as it's expecting.
3318  */
3319  if (AH->public.searchpath)
3320  return;
3321 
3322  if (!schemaName || *schemaName == '\0' ||
3323  (AH->currSchema && strcmp(AH->currSchema, schemaName) == 0))
3324  return; /* no need to do anything */
3325 
3326  qry = createPQExpBuffer();
3327 
3328  appendPQExpBuffer(qry, "SET search_path = %s",
3329  fmtId(schemaName));
3330  if (strcmp(schemaName, "pg_catalog") != 0)
3331  appendPQExpBufferStr(qry, ", pg_catalog");
3332 
3333  if (RestoringToDB(AH))
3334  {
3335  PGresult *res;
3336 
3337  res = PQexec(AH->connection, qry->data);
3338 
3339  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3341  "could not set search_path to \"%s\": %s",
3342  schemaName, PQerrorMessage(AH->connection));
3343 
3344  PQclear(res);
3345  }
3346  else
3347  ahprintf(AH, "%s;\n\n", qry->data);
3348 
3349  if (AH->currSchema)
3350  free(AH->currSchema);
3351  AH->currSchema = pg_strdup(schemaName);
3352 
3353  destroyPQExpBuffer(qry);
3354 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
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 3422 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().

3423 {
3424  PQExpBuffer cmd;
3425  const char *want,
3426  *have;
3427 
3428  have = AH->currTableAm;
3429  want = tableam;
3430 
3431  if (!want)
3432  return;
3433 
3434  if (have && strcmp(want, have) == 0)
3435  return;
3436 
3437  cmd = createPQExpBuffer();
3438  appendPQExpBuffer(cmd, "SET default_table_access_method = %s;", fmtId(want));
3439 
3440  if (RestoringToDB(AH))
3441  {
3442  PGresult *res;
3443 
3444  res = PQexec(AH->connection, cmd->data);
3445 
3446  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3448  "could not set default_table_access_method: %s",
3449  PQerrorMessage(AH->connection));
3450 
3451  PQclear(res);
3452  }
3453  else
3454  ahprintf(AH, "%s\n\n", cmd->data);
3455 
3456  destroyPQExpBuffer(cmd);
3457 
3458  AH->currTableAm = pg_strdup(want);
3459 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
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 3361 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().

3362 {
3363  RestoreOptions *ropt = AH->public.ropt;
3364  PQExpBuffer qry;
3365  const char *want,
3366  *have;
3367 
3368  /* do nothing in --no-tablespaces mode */
3369  if (ropt->noTablespace)
3370  return;
3371 
3372  have = AH->currTablespace;
3373  want = tablespace;
3374 
3375  /* no need to do anything for non-tablespace object */
3376  if (!want)
3377  return;
3378 
3379  if (have && strcmp(want, have) == 0)
3380  return; /* no need to do anything */
3381 
3382  qry = createPQExpBuffer();
3383 
3384  if (strcmp(want, "") == 0)
3385  {
3386  /* We want the tablespace to be the database's default */
3387  appendPQExpBufferStr(qry, "SET default_tablespace = ''");
3388  }
3389  else
3390  {
3391  /* We want an explicit tablespace */
3392  appendPQExpBuffer(qry, "SET default_tablespace = %s", fmtId(want));
3393  }
3394 
3395  if (RestoringToDB(AH))
3396  {
3397  PGresult *res;
3398 
3399  res = PQexec(AH->connection, qry->data);
3400 
3401  if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
3403  "could not set default_tablespace to %s: %s",
3404  fmtId(want), PQerrorMessage(AH->connection));
3405 
3406  PQclear(res);
3407  }
3408  else
3409  ahprintf(AH, "%s;\n\n", qry->data);
3410 
3411  if (AH->currTablespace)
3412  free(AH->currTablespace);
3413  AH->currTablespace = pg_strdup(want);
3414 
3415  destroyPQExpBuffer(qry);
3416 }
static int RestoringToDB(ArchiveHandle *AH)
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6672
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 3111 of file pg_backup_archiver.c.

References _tocEntry::desc.

Referenced by _printTocEntry(), and _tocEntryRequired().

3112 {
3113  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3114  if (strcmp(te->desc, "ACL") == 0 ||
3115  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3116  strcmp(te->desc, "DEFAULT ACL") == 0)
3117  return true;
3118  return false;
3119 }

◆ _tocEntryRequired()

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

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

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

References _tocEntry::desc, RESTORE_PASS_ACL, RESTORE_PASS_MAIN, and _tocEntry::tag.

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

3079 {
3080  /* "ACL LANGUAGE" was a crock emitted only in PG 7.4 */
3081  if (strcmp(te->desc, "ACL") == 0 ||
3082  strcmp(te->desc, "ACL LANGUAGE") == 0 ||
3083  strcmp(te->desc, "DEFAULT ACL") == 0)
3084  return RESTORE_PASS_ACL;
3085  if (strcmp(te->desc, "EVENT TRIGGER") == 0 ||
3086  strcmp(te->desc, "MATERIALIZED VIEW DATA") == 0)
3087  return RESTORE_PASS_POST_ACL;
3088 
3089  /*
3090  * Comments need to be emitted in the same pass as their parent objects.
3091  * ACLs haven't got comments, and neither do matview data objects, but
3092  * event triggers do. (Fortunately, event triggers haven't got ACLs, or
3093  * we'd need yet another weird special case.)
3094  */
3095  if (strcmp(te->desc, "COMMENT") == 0 &&
3096  strncmp(te->tag, "EVENT TRIGGER ", 14) == 0)
3097  return RESTORE_PASS_POST_ACL;
3098 
3099  /* All else can be handled in the main pass. */
3100  return RESTORE_PASS_MAIN;
3101 }

◆ ahprintf()

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

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

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

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

1063 {
1064  ArchiveHandle *AH = (ArchiveHandle *) AHX;
1065  TocEntry *newToc;
1066 
1067  newToc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
1068 
1069  AH->tocCount++;
1070  if (dumpId > AH->maxDumpId)
1071  AH->maxDumpId = dumpId;
1072 
1073  newToc->prev = AH->toc->prev;
1074  newToc->next = AH->toc;
1075  AH->toc->prev->next = newToc;
1076  AH->toc->prev = newToc;
1077 
1078  newToc->catalogId = catalogId;
1079  newToc->dumpId = dumpId;
1080  newToc->section = opts->section;
1081 
1082  newToc->tag = pg_strdup(opts->tag);
1083  newToc->namespace = opts->namespace ? pg_strdup(opts->namespace) : NULL;
1084  newToc->tablespace = opts->tablespace ? pg_strdup(opts->tablespace) : NULL;
1085  newToc->tableam = opts->tableam ? pg_strdup(opts->tableam) : NULL;
1086  newToc->owner = opts->owner ? pg_strdup(opts->owner) : NULL;
1087  newToc->desc = pg_strdup(opts->description);
1088  newToc->defn = opts->createStmt ? pg_strdup(opts->createStmt) : NULL;
1089  newToc->dropStmt = opts->dropStmt ? pg_strdup(opts->dropStmt) : NULL;
1090  newToc->copyStmt = opts->copyStmt ? pg_strdup(opts->copyStmt) : NULL;
1091 
1092  if (opts->nDeps > 0)
1093  {
1094  newToc->dependencies = (DumpId *) pg_malloc(opts->nDeps * sizeof(DumpId));
1095  memcpy(newToc->dependencies, opts->deps, opts->nDeps * sizeof(DumpId));
1096  newToc->nDeps = opts->nDeps;
1097  }
1098  else
1099  {
1100  newToc->dependencies = NULL;
1101  newToc->nDeps = 0;
1102  }
1103 
1104  newToc->dataDumper = opts->dumpFn;
1105  newToc->dataDumperArg = opts->dumpArg;
1106  newToc->hadDumper = opts->dumpFn ? true : false;
1107 
1108  newToc->formatData = NULL;
1109  newToc->dataLength = 0;
1110 
1111  if (AH->ArchiveEntryPtr != NULL)
1112  AH->ArchiveEntryPtr(AH, newToc);
1113 
1114  return newToc;
1115 }
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:328
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 1466 of file pg_backup_archiver.c.

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

1467 {
1468  int save_errno = errno;
1469  char *p;
1470  size_t len = 128; /* initial assumption about buffer size */
1471  size_t cnt;
1472 
1473  for (;;)
1474  {
1475  va_list args;
1476 
1477  /* Allocate work buffer. */
1478  p = (char *) pg_malloc(len);
1479 
1480  /* Try to format the data. */
1481  errno = save_errno;
1482  va_start(args, fmt);
1483  cnt = pvsnprintf(p, len, fmt, args);
1484  va_end(args);
1485 
1486  if (cnt < len)
1487  break; /* success */
1488 
1489  /* Release buffer and loop around to try again with larger len. */
1490  free(p);
1491  len = cnt;
1492  }
1493 
1494  WriteData(AH, p, cnt);
1495  free(p);
1496  return (int) cnt;
1497 }
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 1459 of file pg_backup_archiver.c.

References WriteData().

Referenced by dumpTableData_insert().

1460 {
1461  WriteData(AH, s, strlen(s));
1462 }
void WriteData(Archive *AHX, const void *data, size_t dLen)

◆ buildTocEntryArrays()

static void buildTocEntryArrays ( ArchiveHandle AH)
static

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

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

References fseeko, ftello, and pgoff_t.

Referenced by InitArchiveFmt_Custom(), and InitArchiveFmt_Tar().

3885 {
3886  pgoff_t tpos;
3887 
3888  /* Check that ftello works on this file */
3889  tpos = ftello(fp);
3890  if (tpos < 0)
3891  return false;
3892 
3893  /*
3894  * Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
3895  * this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
3896  * successful no-op even on files that are otherwise unseekable.
3897  */
3898  if (fseeko(fp, tpos, SEEK_SET) != 0)
3899  return false;
3900 
3901  return true;
3902 }
#define pgoff_t
Definition: win32_port.h:194
#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 4810 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().

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

◆ DeCloneArchive()

void DeCloneArchive ( ArchiveHandle AH)

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

4899 {
4900  /* Should not have an open database connection */
4901  Assert(AH->connection == NULL);
4902 
4903  /* Clear format-specific state */
4904  AH->DeClonePtr(AH);
4905 
4906  /* Clear state allocated by CloneArchive */
4907  if (AH->sqlparse.curCmd)
4909 
4910  /* Clear any connection-local state */
4911  if (AH->currUser)
4912  free(AH->currUser);
4913  if (AH->currSchema)
4914  free(AH->currSchema);
4915  if (AH->currTablespace)
4916  free(AH->currTablespace);
4917  if (AH->currTableAm)
4918  free(AH->currTableAm);
4919  if (AH->savedPassword)
4920  free(AH->savedPassword);
4921 
4922  free(AH);
4923 }
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:745

◆ dump_lo_buf()

static void dump_lo_buf ( ArchiveHandle AH)
static

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

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

References ahprintf(), buf, and PGDUMP_STRFTIME_FMT.

Referenced by RestoreArchive().

3910 {
3911  char buf[64];
3912 
3913  if (strftime(buf, sizeof(buf), PGDUMP_STRFTIME_FMT, localtime(&tim)) != 0)
3914  ahprintf(AH, "-- %s %s\n\n", msg, buf);
3915 }
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 1237 of file pg_backup_archiver.c.

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

Referenced by dumpBlobs().

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

◆ EndRestoreBlob()

void EndRestoreBlob ( ArchiveHandle AH,
Oid  oid 
)

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

1342 {
1343  if (AH->lo_buf_used > 0)
1344  {
1345  /* Write remaining bytes from the LO buffer */
1346  dump_lo_buf(AH);
1347  }
1348 
1349  AH->writingBlob = 0;
1350 
1351  if (AH->connection)
1352  {
1353  lo_close(AH->connection, AH->loFd);
1354  AH->loFd = -1;
1355  }
1356  else
1357  {
1358  ahprintf(AH, "SELECT pg_catalog.lo_close(0);\n\n");
1359  }
1360 }
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 1274 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().

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

◆ fix_dependencies()

static void fix_dependencies ( ArchiveHandle AH)
static

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

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

References buildTocEntryArrays(), and _archiveHandle::tocsByDumpId.

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

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

◆ has_lock_conflicts()

static bool has_lock_conflicts ( TocEntry te1,
TocEntry te2 
)
static

Definition at line 4198 of file pg_backup_archiver.c.

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

Referenced by pop_next_work_item().

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

◆ identify_locking_dependencies()

static void identify_locking_dependencies ( ArchiveHandle AH,
TocEntry te 
)
static

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

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

4791 {
4792  pg_log_info("table \"%s\" could not be created, will not restore its data",
4793  te->tag);
4794 
4795  if (AH->tableDataId[te->dumpId] != 0)
4796  {
4797  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4798 
4799  ted->reqs = 0;
4800  }
4801 }
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 4775 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().

4776 {
4777  if (AH->tableDataId[te->dumpId] != 0)
4778  {
4779  TocEntry *ted = AH->tocsByDumpId[AH->tableDataId[te->dumpId]];
4780 
4781  ted->created = true;
4782  }
4783 }
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 2456 of file pg_backup_archiver.c.

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

Referenced by WriteDataChunks().

2460 {
2461  pg_log_info("finished item %d %s %s",
2462  te->dumpId, te->desc, te->tag);
2463 
2464  if (status != 0)
2465  fatal("worker process failed: exit code %d",
2466  status);
2467 }
#define fatal(...)
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225
#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 4466 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().

4470 {
4471  ParallelReadyList *ready_list = (ParallelReadyList *) callback_data;
4472 
4473  pg_log_info("finished item %d %s %s",
4474  te->dumpId, te->desc, te->tag);
4475 
4476  if (status == WORKER_CREATE_DONE)
4477  mark_create_done(AH, te);
4478  else if (status == WORKER_INHIBIT_DATA)
4479  {
4481  AH->public.n_errors++;
4482  }
4483  else if (status == WORKER_IGNORED_ERRORS)
4484  AH->public.n_errors++;
4485  else if (status != 0)
4486  fatal("worker process failed: exit code %d",
4487  status);
4488 
4489  reduce_dependencies(AH, te, ready_list);
4490 }
#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:225
#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 4351 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().

4354 {
4355  TocEntry *te;
4356  TocEntry *next_te;
4357 
4358  for (te = pending_list->pending_next; te != pending_list; te = next_te)
4359  {
4360  /* must save list link before possibly removing te from list */
4361  next_te = te->pending_next;
4362 
4363  if (te->depCount == 0 &&
4364  _tocEntryRestorePass(te) == pass)
4365  {
4366  /* Remove it from pending_list ... */
4367  pending_list_remove(te);
4368  /* ... and add to ready_list */
4369  ready_list_insert(ready_list, te);
4370  }
4371  }
4372 }
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 4443 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().

4444 {
4445  int status;
4446 
4447  Assert(AH->connection != NULL);
4448 
4449  /* Count only errors associated with this TOC entry */
4450  AH->public.n_errors = 0;
4451 
4452  /* Restore the TOC item */
4453  status = restore_toc_entry(AH, te, true);
4454 
4455  return status;
4456 }
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:745
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225

◆ pending_list_append()

static void pending_list_append ( TocEntry l,
TocEntry te 
)
static

Definition at line 4230 of file pg_backup_archiver.c.

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

Referenced by restore_toc_entries_prefork().

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

◆ pending_list_header_init()

static void pending_list_header_init ( TocEntry l)
static

Definition at line 4223 of file pg_backup_archiver.c.

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

Referenced by RestoreArchive().

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

◆ pending_list_remove()

static void pending_list_remove ( TocEntry te)
static

Definition at line 4240 of file pg_backup_archiver.c.

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

Referenced by move_to_ready_list(), and reduce_dependencies().

4241 {
4244  te->pending_prev = NULL;
4245  te->pending_next = NULL;
4246 }
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 4386 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().

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

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

2719 {
2720  /* te->defn should have the form SET client_encoding = 'foo'; */
2721  char *defn = pg_strdup(te->defn);
2722  char *ptr1;
2723  char *ptr2 = NULL;
2724  int encoding;
2725 
2726  ptr1 = strchr(defn, '\'');
2727  if (ptr1)
2728  ptr2 = strchr(++ptr1, '\'');
2729  if (ptr2)
2730  {
2731  *ptr2 = '\0';
2732  encoding = pg_char_to_encoding(ptr1);
2733  if (encoding < 0)
2734  fatal("unrecognized encoding \"%s\"",
2735  ptr1);
2736  AH->public.encoding = encoding;
2737  }
2738  else
2739  fatal("invalid ENCODING item: %s",
2740  te->defn);
2741 
2742  free(defn);
2743 }
int pg_char_to_encoding(const char *name)
Definition: encnames.c:550
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 2762 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

2763 {
2764  /*
2765  * te->defn should contain a command to set search_path. We just copy it
2766  * verbatim for use later.
2767  */
2768  AH->public.searchpath = pg_strdup(te->defn);
2769 }
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 2746 of file pg_backup_archiver.c.

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

Referenced by ReadToc().

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

◆ ReadHead()

void ReadHead ( ArchiveHandle AH)

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

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

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

◆ ReadOffset()

int ReadOffset ( ArchiveHandle AH,
pgoff_t o 
)

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

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

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

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

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

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

References pg_free(), and _parallelReadyList::tes.

Referenced by restore_toc_entries_parallel().

4267 {
4268  pg_free(ready_list->tes);
4269 }
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 4253 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().

4254 {
4255  ready_list->tes = (TocEntry **)
4256  pg_malloc(tocCount * sizeof(TocEntry *));
4257  ready_list->first_te = 0;
4258  ready_list->last_te = -1;
4259  ready_list->sorted = false;
4260 }
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 4273 of file pg_backup_archiver.c.

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

Referenced by move_to_ready_list(), and reduce_dependencies().

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

◆ ready_list_remove()

static void ready_list_remove ( ParallelReadyList ready_list,
int  i 
)
static

Definition at line 4282 of file pg_backup_archiver.c.

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

Referenced by pop_next_work_item().

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

◆ ready_list_sort()

static void ready_list_sort ( ParallelReadyList ready_list)
static

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

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

◆ reduce_dependencies()

static void reduce_dependencies ( ArchiveHandle AH,
TocEntry te,
ParallelReadyList ready_list 
)
static